feat(component): remove react-datepicker (#5681)

This commit is contained in:
Cats Juice
2024-02-21 13:09:44 +00:00
parent 8d746f17de
commit 67dffc2a5a
8 changed files with 2 additions and 418 deletions

View File

@@ -1,37 +0,0 @@
import type { Meta, StoryFn } from '@storybook/react';
import dayjs from 'dayjs';
import { useState } from 'react';
import { AFFiNEDatePicker } from '.';
export default {
title: 'UI/Date Picker/AFFiNE Date Picker',
} satisfies Meta<typeof AFFiNEDatePicker>;
const _format = 'YYYY-MM-DD';
const Template: StoryFn<typeof AFFiNEDatePicker> = args => {
const [date, setDate] = useState(dayjs().format(_format));
return (
<div style={{ minHeight: 400, maxWidth: 600, margin: '0 auto' }}>
<div style={{ marginBottom: 20 }}>Selected Date: {date}</div>
<AFFiNEDatePicker
value={date}
{...args}
onChange={e => {
setDate(dayjs(e, _format).format(_format));
}}
/>
</div>
);
};
export const Basic: StoryFn<typeof AFFiNEDatePicker> = Template.bind(undefined);
Basic.args = {};
export const Inline: StoryFn<typeof AFFiNEDatePicker> =
Template.bind(undefined);
Inline.args = {
inline: true,
};

View File

@@ -1,274 +0,0 @@
import {
ArrowDownSmallIcon,
ArrowLeftSmallIcon,
ArrowRightSmallIcon,
} from '@blocksuite/icons';
import clsx from 'clsx';
import dayjs from 'dayjs';
import { type HTMLAttributes, useCallback, useEffect, useState } from 'react';
import DatePicker, { type ReactDatePickerProps } from 'react-datepicker';
import * as styles from './index.css';
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];
export interface AFFiNEDatePickerProps
extends Omit<ReactDatePickerProps, 'onChange' | 'onSelect'> {
value?: string;
onChange?: (value: string) => void;
onSelect?: (value: string) => void;
}
interface HeaderLayoutProps extends HTMLAttributes<HTMLDivElement> {
length: number;
left: React.ReactNode;
right: React.ReactNode;
}
/**
* The `DatePicker` should work with different width
* This is a hack to make header's item align with calendar cell's label, **instead of the cell**
* @param length: number of items that calendar body row has
*/
const HeaderLayout = ({
length,
left,
right,
className,
...attrs
}: HeaderLayoutProps) => {
return (
<div className={clsx(styles.row, className)} {...attrs}>
{Array.from({ length })
.fill(0)
.map((_, index) => {
const isLeft = index === 0;
const isRight = index === length - 1;
return (
<div
key={index}
data-is-left={isLeft}
data-is-right={isRight}
className={styles.headerLayoutCell}
>
<div className={styles.headerLayoutCellOrigin}>
{isLeft ? left : isRight ? right : null}
</div>
</div>
);
})}
</div>
);
};
export const AFFiNEDatePicker = ({
value,
onChange,
onSelect,
calendarClassName,
...props
}: AFFiNEDatePickerProps) => {
const [openMonthPicker, setOpenMonthPicker] = useState(false);
const [selectedDate, setSelectedDate] = useState<Date | null>(
value ? dayjs(value).toDate() : null
);
const handleOpenMonthPicker = useCallback(() => {
setOpenMonthPicker(true);
}, []);
const handleCloseMonthPicker = useCallback(() => {
setOpenMonthPicker(false);
}, []);
const handleDateChange = (date: Date | null) => {
if (date) {
setSelectedDate(date);
onChange?.(dayjs(date).format('YYYY-MM-DD'));
setOpenMonthPicker(false);
}
};
const handleDateSelect = (date: Date | null) => {
if (date) {
onSelect?.(dayjs(date).format('YYYY-MM-DD'));
setOpenMonthPicker(false);
}
};
const renderCustomHeader = ({
date,
decreaseMonth,
increaseMonth,
prevMonthButtonDisabled,
nextMonthButtonDisabled,
}: {
date: Date;
decreaseMonth: () => void;
increaseMonth: () => void;
prevMonthButtonDisabled: boolean;
nextMonthButtonDisabled: boolean;
}) => {
const selectedYear = dayjs(date).year();
const selectedMonth = dayjs(date).month();
return (
<HeaderLayout
length={7}
className={styles.headerStyle}
left={
<div className={styles.headerLabel}>
<div
data-testid="date-picker-current-month"
className={styles.mouthStyle}
>
{months[selectedMonth]}
</div>
<div
data-testid="date-picker-current-year"
className={styles.yearStyle}
>
{selectedYear}
</div>
<div
data-testid="month-picker-button"
className={styles.arrowDownStyle}
onClick={handleOpenMonthPicker}
>
<ArrowDownSmallIcon />
</div>
</div>
}
right={
<div className={styles.headerActionWrapper}>
<button
data-testid="date-picker-prev-button"
className={styles.headerAction}
onClick={decreaseMonth}
disabled={prevMonthButtonDisabled}
>
<ArrowLeftSmallIcon />
</button>
<button
data-testid="date-picker-next-button"
className={styles.headerAction}
onClick={increaseMonth}
disabled={nextMonthButtonDisabled}
>
<ArrowRightSmallIcon />
</button>
</div>
}
/>
);
};
const renderCustomMonthHeader = ({
date,
decreaseYear,
increaseYear,
prevYearButtonDisabled,
nextYearButtonDisabled,
}: {
date: Date;
decreaseYear: () => void;
increaseYear: () => void;
prevYearButtonDisabled: boolean;
nextYearButtonDisabled: boolean;
}) => {
const selectedYear = dayjs(date).year();
return (
<HeaderLayout
length={3}
className={styles.monthHeaderStyle}
left={
<div
data-testid="month-picker-current-year"
className={styles.monthTitleStyle}
>
{selectedYear}
</div>
}
right={
<div className={styles.headerActionWrapper}>
<button
data-testid="month-picker-prev-button"
className={styles.headerAction}
onClick={decreaseYear}
disabled={prevYearButtonDisabled}
>
<ArrowLeftSmallIcon />
</button>
<button
data-testid="month-picker-next-button"
className={styles.headerAction}
onClick={increaseYear}
disabled={nextYearButtonDisabled}
>
<ArrowRightSmallIcon />
</button>
</div>
}
/>
);
};
useEffect(() => {
setSelectedDate(value ? dayjs(value).toDate() : null);
}, [value]);
return (
<DatePicker
onClickOutside={handleCloseMonthPicker}
className={styles.inputStyle}
calendarClassName={clsx(styles.calendarStyle, calendarClassName)}
weekDayClassName={() => styles.weekStyle}
dayClassName={() => styles.dayStyle}
popperClassName={styles.popperStyle}
monthClassName={() => styles.mouthsStyle}
selected={selectedDate}
onChange={handleDateChange}
onSelect={handleDateSelect}
showPopperArrow={false}
dateFormat="MMM dd"
showMonthYearPicker={openMonthPicker}
shouldCloseOnSelect={!openMonthPicker}
renderCustomHeader={({
date,
decreaseYear,
increaseYear,
decreaseMonth,
increaseMonth,
prevYearButtonDisabled,
nextYearButtonDisabled,
prevMonthButtonDisabled,
nextMonthButtonDisabled,
}) =>
openMonthPicker
? renderCustomMonthHeader({
date,
decreaseYear,
increaseYear,
prevYearButtonDisabled,
nextYearButtonDisabled,
})
: renderCustomHeader({
date,
decreaseMonth,
increaseMonth,
prevMonthButtonDisabled,
nextMonthButtonDisabled,
})
}
{...props}
/>
);
};
export default AFFiNEDatePicker;

View File

@@ -1,15 +0,0 @@
import type { Meta, StoryFn } from '@storybook/react';
import { BlocksuiteDatePicker } from './blocksuite-date-picker';
export default {
title: 'UI/Date Picker/Blocksuite Date Picker',
} satisfies Meta<typeof BlocksuiteDatePicker>;
export const Basic: StoryFn<typeof BlocksuiteDatePicker> = () => {
return (
<div style={{ width: 300 }}>
<BlocksuiteDatePicker />
</div>
);
};

View File

@@ -1,11 +0,0 @@
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { DatePicker } from '@blocksuite/blocks/src/_common/components/date-picker/index';
import { createComponent } from '@lit/react';
import React from 'react';
export const BlocksuiteDatePicker = createComponent({
tagName: 'date-picker',
elementClass: DatePicker,
react: React,
events: {},
});

View File

@@ -1,3 +1,2 @@
export * from './affine-date-picker';
export * from './calendar';
export * from './week-date-picker';