-
-
+
+
{(([, month, , year]) => `${month}, ${year}`)(
- new Date(currentDate.getFullYear(), selectMonth, 0).toDateString().split(' '),
+ new Date(currentDate.getFullYear(), selectMonth + 1, 0).toDateString().split(' '),
)}
diff --git a/packages/ui/lib/Calendar/DayItem.tsx b/packages/ui/lib/Calendar/DayItem.tsx
index 9d82ac8..7f3c49a 100644
--- a/packages/ui/lib/Calendar/DayItem.tsx
+++ b/packages/ui/lib/Calendar/DayItem.tsx
@@ -4,7 +4,7 @@ import styles from './Calendar.module.scss';
interface DayItemProps {
index: number;
isOtherMonth: 'pre' | 'this' | 'after';
- selectDate: Date;
+ selectDate?: Date;
currentDate: Date;
onChange: (value: Date) => void;
selectMonth: number;
@@ -32,16 +32,20 @@ const DayItem = memo(function otherMonthItem({
break;
}
- function isSameDay(date1: Date, date2: Date) {
+ function isSameDay(date1?: Date, date2?: Date) {
return (
- date1.getFullYear() === date2.getFullYear() &&
- date1.getMonth() === date2.getMonth() &&
- date1.getDate() === date2.getDate()
+ date1?.getFullYear() === date2?.getFullYear() &&
+ date1?.getMonth() === date2?.getMonth() &&
+ date1?.getDate() === date2?.getDate()
);
}
const thisDate = new Date(currentDate.getFullYear(), month, index);
+ const handleClick = () => {
+ thisDate && onChange(thisDate);
+ };
+
return (
onChange(thisDate)}
+ onClick={handleClick}
>
{index}
diff --git a/packages/ui/lib/DatePicker/DatePicker.module.scss b/packages/ui/lib/DatePicker/DatePicker.module.scss
new file mode 100644
index 0000000..2517945
--- /dev/null
+++ b/packages/ui/lib/DatePicker/DatePicker.module.scss
@@ -0,0 +1,59 @@
+@mixin animation($type) {
+ animation-name: #{$type};
+ animation-duration: 200ms;
+ animation-timing-function: ease-in-out;
+ animation-fill-mode: forwards;
+}
+.date-picker-button {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ color: var(--shadow-color) !important;
+ transition: all 0.2s ease-in-out;
+ padding: 10px 15px !important;
+ width: 280px;
+ &.select {
+ color: var(--primary-color) !important;
+ svg {
+ fill: var(--primary-color) !important;
+ }
+ }
+ svg {
+ fill: var(--shadow-color);
+ transition: all 0.2s ease-in-out;
+ }
+ &:hover {
+ color: var(--primary-color) !important;
+ svg {
+ fill: var(--primary-color);
+ }
+ }
+}
+.calendar-container {
+ position: absolute;
+ margin-top: 5px;
+ &.in {
+ @include animation(in);
+ }
+ &.hide {
+ @include animation(hide);
+ }
+}
+
+@keyframes in {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes hide {
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
diff --git a/packages/ui/lib/DatePicker/DatePicker.stories.tsx b/packages/ui/lib/DatePicker/DatePicker.stories.tsx
new file mode 100644
index 0000000..e5b39c8
--- /dev/null
+++ b/packages/ui/lib/DatePicker/DatePicker.stories.tsx
@@ -0,0 +1,55 @@
+import type { Meta, StoryObj } from '@storybook/react';
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import React from 'react';
+import { DatePicker, type DatePickerProps } from './DatePicker';
+
+const test = (value: Date) => {
+ console.log('selectDate', value);
+};
+
+function generateRandomDate() {
+ const startTimestamp = new Date(2000, 0, 1).getTime(); // 开始日期的时间戳,这里设置为2000年1月1日
+ const endTimestamp = new Date().getTime(); // 当前日期的时间戳,作为结束日期
+
+ const randomTimestamp = Math.random() * (endTimestamp - startTimestamp) + startTimestamp;
+ const randomDate = new Date(randomTimestamp);
+
+ return randomDate;
+}
+
+const meta = {
+ title: 'Components/DatePicker',
+ component: DatePicker,
+ parameters: {
+ layout: 'centered',
+ },
+ tags: ['autodocs'],
+ argTypes: {},
+} satisfies Meta
;
+
+export default meta;
+
+type Story = StoryObj;
+
+const defaultProps: DatePickerProps = {
+ onchange: test,
+};
+
+export const DefaultDatePicker: Story = {
+ args: {
+ ...defaultProps,
+ },
+};
+
+export const RandomDefaultDatePicker: Story = {
+ args: {
+ ...defaultProps,
+ defaultPickDate: new Date(),
+ },
+};
+
+export const RandomDatePicker: Story = {
+ args: {
+ pickDate: generateRandomDate(),
+ },
+};
diff --git a/packages/ui/lib/DatePicker/DatePicker.tsx b/packages/ui/lib/DatePicker/DatePicker.tsx
new file mode 100644
index 0000000..b992acd
--- /dev/null
+++ b/packages/ui/lib/DatePicker/DatePicker.tsx
@@ -0,0 +1,135 @@
+import React, { useEffect, useState } from 'react';
+import { Button, Calendar } from '..';
+import styles from './DatePicker.module.scss';
+
+export interface DatePickerProps extends React.HtmlHTMLAttributes {
+ /**
+ * onchange, the onchange of the datepicker
+ */
+ onchange?: (value: Date) => void;
+ /**
+ * defaultPickDate, the defaultPickDate of the datepicker
+ */
+ defaultPickDate?: Date;
+ /**
+ * pickDate, the pickDate of the datePicker
+ */
+ pickDate?: Date;
+}
+
+export const DatePicker = React.forwardRef(
+ ({ onchange, defaultPickDate, pickDate, ...rest }, ref) => {
+ const [calendarVisible, setCalendarVisible] = useState(false);
+ const [selectDate, setSelectDate] = useState(defaultPickDate);
+ const [selectDateString, setSelectDateString] = useState(
+ defaultPickDate?.toString(),
+ );
+ const [calendarIn, setCalendarIn] = useState(false);
+ const [calendarHide, setCalendarHide] = useState(false);
+
+ useEffect(() => {
+ if (pickDate) {
+ setSelectDate(pickDate);
+ setSelectDateString(pickDate.toString());
+ }
+ }, [pickDate]);
+
+ useEffect(() => {
+ selectDate && onchange && onchange(selectDate);
+ }, [selectDate, onchange]);
+
+ const handleDate = (value: Date) => {
+ setSelectDate(value);
+ if (value.toString() !== new Date().toString()) {
+ setSelectDateString(value.toString());
+ }
+ };
+
+ const handleCalendarVisible = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ const newCalendarVisible = !calendarVisible;
+ if (newCalendarVisible) {
+ openCalendar();
+ }
+ if (!newCalendarVisible) {
+ closeCalendar();
+ }
+ };
+
+ const openCalendar = () => {
+ document.body.addEventListener('click', closeCalendar);
+ setCalendarIn(true);
+ setCalendarVisible(true);
+ setTimeout(() => {
+ setCalendarIn(false);
+ }, 200);
+ };
+
+ const closeCalendar = () => {
+ document.body.removeEventListener('click', closeCalendar);
+ setCalendarHide(true);
+ setTimeout(() => {
+ setCalendarHide(false);
+ setCalendarVisible(false);
+ }, 200);
+ };
+
+ console.log('selectDateString', selectDateString);
+
+ return (
+ <>
+
+
+ {calendarVisible && (
+
+ {
+ e.stopPropagation();
+ }}
+ >
+
+ )}
+
+ >
+ );
+ },
+);
+
+DatePicker.displayName = 'DatePicker';
diff --git a/packages/ui/lib/DatePicker/index.ts b/packages/ui/lib/DatePicker/index.ts
new file mode 100644
index 0000000..a48b62e
--- /dev/null
+++ b/packages/ui/lib/DatePicker/index.ts
@@ -0,0 +1 @@
+export * from './DatePicker';
diff --git a/packages/ui/lib/Input/Input.tsx b/packages/ui/lib/Input/Input.tsx
index ee0ab92..ba8045d 100644
--- a/packages/ui/lib/Input/Input.tsx
+++ b/packages/ui/lib/Input/Input.tsx
@@ -57,14 +57,14 @@ export const Input = React.forwardRef(
onchange,
isFillFather = false,
value,
- defaultValue,
+ defaultValue = '',
...rest
},
ref,
) => {
//设置isUpLabel来调节Label上浮状态
const [isUpInputLabel, setIsUpInputLabel] = useState(false);
- const [inputValue, setInputValue] = useState(defaultValue);
+ const [inputValue, setInputValue] = useState(defaultValue);
const InputClass = classnames(
styles['base'],
styles[disabled ? 'disabled' : ''],
diff --git a/packages/ui/lib/Select/Select.tsx b/packages/ui/lib/Select/Select.tsx
index b472479..8885c86 100644
--- a/packages/ui/lib/Select/Select.tsx
+++ b/packages/ui/lib/Select/Select.tsx
@@ -56,6 +56,7 @@ export const Select = React.forwardRef(
optionsList.find((item) => item.key === defaultSelectKey),
);
const [options, setOptions] = useState(optionsList);
+ const [inputValue, setInputValue] = useState('');
const showOptions: MouseEventHandler = () => {
if (!disabled) setVisble(!visible);
@@ -67,15 +68,19 @@ export const Select = React.forwardRef(
function handleClick(value: OptionProps): void {
setSelectItem(value);
- onchange(value);
+ setInputValue(value.label);
}
+ useEffect(() => {
+ selectItem && onchange(selectItem);
+ selectItem?.value && setInputValue(selectItem?.value);
+ }, [selectItem, onchange]);
+
const handleOptions = (value: string) => {
if (value === '') {
setSelectItem(undefined);
}
- const results = fuzzySearch(optionsList, value);
- setOptions(results);
+ setInputValue(value);
};
function fuzzySearch(optionsList: OptionProps[], searchTerm: string): OptionProps[] {
@@ -89,6 +94,10 @@ export const Select = React.forwardRef(
}, 100);
};
+ useEffect(() => {
+ const results = fuzzySearch(optionsList, inputValue);
+ setOptions(results);
+ }, [inputValue, optionsList]);
return (
<>
(
>