@artemy-tech/datepicker 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +165 -13
- package/dist/{DateRangePicker-Bp95dxDX.d.cts → DateRangePicker-uJd_I9OI.d.cts} +26 -3
- package/dist/{DateRangePicker-Bp95dxDX.d.ts → DateRangePicker-uJd_I9OI.d.ts} +26 -3
- package/dist/{chunk-DQSX6QKR.js → chunk-IIIOWD5F.js} +144 -44
- package/dist/chunk-IIIOWD5F.js.map +1 -0
- package/dist/index.cjs +134 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/rhf.cjs +134 -39
- package/dist/rhf.cjs.map +1 -1
- package/dist/rhf.d.cts +1 -1
- package/dist/rhf.d.ts +1 -1
- package/dist/rhf.js +1 -1
- package/package.json +2 -1
- package/dist/chunk-DQSX6QKR.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,10 +6,12 @@ React DatePicker с опциональной поддержкой react-hook-for
|
|
|
6
6
|
|
|
7
7
|
- Выбор одиночной даты и диапазона дат
|
|
8
8
|
- Контролируемый и неконтролируемый режимы
|
|
9
|
+
- Выбор времени (`showTime`)
|
|
10
|
+
- Кастомный триггер через `customInput` — любой элемент (кнопка, chip) открывает попап, `forwardRef` не нужен
|
|
11
|
+
- Кастомный инпут через `renderInput` — интеграция с любой UI-библиотекой (Ant Design, MUI, shadcn и др.)
|
|
9
12
|
- Интеграция с react-hook-form (нулевые издержки если не используется)
|
|
10
13
|
- Стилизация через CSS-переменные (`--datepicker-*`)
|
|
11
14
|
- Полная поддержка TypeScript
|
|
12
|
-
- Доступность (через react-day-picker)
|
|
13
15
|
|
|
14
16
|
## Установка
|
|
15
17
|
|
|
@@ -25,7 +27,7 @@ npm install @artemy-tech/datepicker react-hook-form
|
|
|
25
27
|
|
|
26
28
|
## Peer-зависимости
|
|
27
29
|
|
|
28
|
-
```
|
|
30
|
+
```text
|
|
29
31
|
react >= 17.0.0
|
|
30
32
|
react-dom >= 17.0.0
|
|
31
33
|
react-hook-form >= 7.0.0 # опционально
|
|
@@ -33,43 +35,171 @@ react-hook-form >= 7.0.0 # опционально
|
|
|
33
35
|
|
|
34
36
|
## Использование
|
|
35
37
|
|
|
38
|
+
### Подключение стилей
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import '@artemy-tech/datepicker/styles';
|
|
42
|
+
```
|
|
43
|
+
|
|
36
44
|
### DatePicker
|
|
37
45
|
|
|
38
46
|
```tsx
|
|
39
47
|
import { DatePicker } from '@artemy-tech/datepicker'
|
|
40
|
-
import '@artemy-tech/datepicker/styles'
|
|
41
48
|
|
|
42
49
|
// Неконтролируемый
|
|
43
|
-
<DatePicker />
|
|
50
|
+
<DatePicker label="Дата рождения" />
|
|
44
51
|
|
|
45
52
|
// Контролируемый
|
|
46
|
-
const [date, setDate] = useState<Date>()
|
|
47
|
-
<DatePicker value={date} onChange={setDate} />
|
|
53
|
+
const [date, setDate] = useState<Date | undefined>()
|
|
54
|
+
<DatePicker label="Дата" value={date} onChange={setDate} />
|
|
55
|
+
|
|
56
|
+
// С выбором времени
|
|
57
|
+
<DatePicker label="Дата и время" showTime={{ format: 'HH:mm' }} />
|
|
58
|
+
|
|
59
|
+
// Ограничение диапазона
|
|
60
|
+
<DatePicker label="Дата заезда" fromDate={new Date()} />
|
|
48
61
|
```
|
|
49
62
|
|
|
50
63
|
### DateRangePicker
|
|
51
64
|
|
|
52
65
|
```tsx
|
|
53
66
|
import { DateRangePicker } from '@artemy-tech/datepicker'
|
|
67
|
+
import type { DateRange } from '@artemy-tech/datepicker'
|
|
68
|
+
|
|
69
|
+
const [range, setRange] = useState<DateRange | undefined>()
|
|
70
|
+
|
|
71
|
+
<DateRangePicker
|
|
72
|
+
label="Период проживания"
|
|
73
|
+
value={range}
|
|
74
|
+
onChange={setRange}
|
|
75
|
+
calendarLayout="horizontal"
|
|
76
|
+
/>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Кастомный триггер (`customInput`)
|
|
80
|
+
|
|
81
|
+
Через `customInput` можно передать любой элемент-триггер — кнопку, chip и т.д. `DatePicker` инжектит в него `value` (отформатированная дата) и `onClick` (открыть/закрыть календарь). `forwardRef` не нужен.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import { DatePicker } from '@artemy-tech/datepicker';
|
|
85
|
+
|
|
86
|
+
<DatePicker
|
|
87
|
+
customInput={<button type="button">Выбрать дату</button>}
|
|
88
|
+
/>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Кастомный инпут (`renderInput`)
|
|
54
92
|
|
|
55
|
-
|
|
56
|
-
|
|
93
|
+
Через `renderInput` можно заменить встроенный `<input>` на компонент из любой UI-библиотеки. Вся логика маски, валидации и попапа остаётся внутри `DatePicker`.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { Input } from 'antd';
|
|
97
|
+
import type { InputRef } from 'antd';
|
|
98
|
+
import { DatePicker } from '@artemy-tech/datepicker';
|
|
99
|
+
|
|
100
|
+
<DatePicker
|
|
101
|
+
renderInput={({ ref, className, ...props }) => (
|
|
102
|
+
<Input ref={ref as React.Ref<InputRef>} {...props} />
|
|
103
|
+
)}
|
|
104
|
+
/>;
|
|
57
105
|
```
|
|
58
106
|
|
|
59
107
|
### С react-hook-form
|
|
60
108
|
|
|
61
109
|
```tsx
|
|
62
|
-
import { useForm } from 'react-hook-form'
|
|
63
|
-
import { RHFDatePicker } from '@artemy-tech/datepicker/rhf'
|
|
110
|
+
import { FormProvider, useForm } from 'react-hook-form';
|
|
111
|
+
import { RHFDatePicker, RHFDateRangePicker } from '@artemy-tech/datepicker/rhf';
|
|
112
|
+
import type { DateRange } from '@artemy-tech/datepicker';
|
|
64
113
|
|
|
65
|
-
|
|
114
|
+
interface FormValues {
|
|
115
|
+
checkIn: Date | undefined;
|
|
116
|
+
period: DateRange | undefined;
|
|
117
|
+
}
|
|
66
118
|
|
|
67
|
-
|
|
119
|
+
function BookingForm() {
|
|
120
|
+
const methods = useForm<FormValues>({
|
|
121
|
+
defaultValues: { checkIn: undefined, period: undefined },
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<FormProvider {...methods}>
|
|
126
|
+
<form onSubmit={methods.handleSubmit(console.log)}>
|
|
127
|
+
<RHFDatePicker
|
|
128
|
+
name="checkIn"
|
|
129
|
+
label="Дата заезда"
|
|
130
|
+
rules={{ validate: (v) => v !== undefined || 'Выберите дату' }}
|
|
131
|
+
/>
|
|
132
|
+
<RHFDateRangePicker
|
|
133
|
+
name="period"
|
|
134
|
+
label="Период"
|
|
135
|
+
rules={{
|
|
136
|
+
validate: (v) => v?.from !== undefined || 'Выберите период',
|
|
137
|
+
}}
|
|
138
|
+
/>
|
|
139
|
+
<button type="submit">Отправить</button>
|
|
140
|
+
</form>
|
|
141
|
+
</FormProvider>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
68
144
|
```
|
|
69
145
|
|
|
146
|
+
## Props
|
|
147
|
+
|
|
148
|
+
### DatePicker — пропсы
|
|
149
|
+
|
|
150
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
151
|
+
| -------------- | ----------------------------------------------- | ------------------ | --------------------------------------------------- |
|
|
152
|
+
| `value` | `Date` | — | Контролируемое значение |
|
|
153
|
+
| `defaultValue` | `Date` | — | Значение по умолчанию (неконтролируемый режим) |
|
|
154
|
+
| `onChange` | `(date: Date \| undefined) => void` | — | Callback при изменении |
|
|
155
|
+
| `label` | `string` | — | Плавающий лейбл |
|
|
156
|
+
| `placeholder` | `string` | `дд.мм.гггг` | Плейсхолдер |
|
|
157
|
+
| `fromDate` | `Date` | — | Минимально допустимая дата |
|
|
158
|
+
| `toDate` | `Date` | — | Максимально допустимая дата |
|
|
159
|
+
| `showTime` | `boolean \| { format: 'HH:mm' \| 'HH:mm:ss' }` | — | Включить выбор времени |
|
|
160
|
+
| `noCalendar` | `boolean` | `false` | Только ввод, без попапа |
|
|
161
|
+
| `size` | `'s' \| 'm' \| 'l'` | `'m'` | Размер |
|
|
162
|
+
| `disabled` | `boolean` | `false` | |
|
|
163
|
+
| `failed` | `boolean` | `false` | Состояние ошибки |
|
|
164
|
+
| `loading` | `boolean` | `false` | Состояние загрузки |
|
|
165
|
+
| `icon` | `ReactNode \| false` | `<CalendarIcon />` | Иконка (`false` — скрыть) |
|
|
166
|
+
| `iconPosition` | `'start' \| 'end'` | `'end'` | Позиция иконки |
|
|
167
|
+
| `renderInput` | `(props: DatePickerInputProps) => ReactNode` | — | Кастомный `<input>`; маска и попап сохраняются |
|
|
168
|
+
| `customInput` | `ReactElement` | — | Триггер-элемент; получает `value` и `onClick` |
|
|
169
|
+
| `className` | `string` | — | CSS-класс на корневом элементе |
|
|
170
|
+
|
|
171
|
+
### DateRangePicker — пропсы
|
|
172
|
+
|
|
173
|
+
| Prop | Тип | По умолчанию | Описание |
|
|
174
|
+
| ---------------- | ---------------------------------------------- | ------------------ | --------------------------- |
|
|
175
|
+
| `value` | `DateRange` | — | Контролируемое значение |
|
|
176
|
+
| `defaultValue` | `DateRange` | — | Значение по умолчанию |
|
|
177
|
+
| `onChange` | `(range: DateRange \| undefined) => void` | — | Callback при изменении |
|
|
178
|
+
| `label` | `string` | — | Плавающий лейбл |
|
|
179
|
+
| `fromDate` | `Date` | — | Минимально допустимая дата |
|
|
180
|
+
| `toDate` | `Date` | — | Максимально допустимая дата |
|
|
181
|
+
| `calendarLayout` | `'vertical' \| 'horizontal'` | `'horizontal'` | Расположение двух месяцев |
|
|
182
|
+
| `showTime` | `boolean \| { format: 'HH:mm' \| 'HH:mm:ss' }` | — | Включить выбор времени |
|
|
183
|
+
| `size` | `'s' \| 'm' \| 'l'` | `'m'` | Размер |
|
|
184
|
+
| `disabled` | `boolean` | `false` | |
|
|
185
|
+
| `failed` | `boolean` | `false` | |
|
|
186
|
+
| `loading` | `boolean` | `false` | |
|
|
187
|
+
| `icon` | `ReactNode \| false` | `<CalendarIcon />` | Иконка |
|
|
188
|
+
| `iconPosition` | `'start' \| 'end'` | `'end'` | |
|
|
189
|
+
| `className` | `string` | — | |
|
|
190
|
+
|
|
191
|
+
### RHFDatePicker / RHFDateRangePicker — пропсы
|
|
192
|
+
|
|
193
|
+
Принимают все пропсы соответствующего компонента, плюс:
|
|
194
|
+
|
|
195
|
+
| Prop | Тип | Описание |
|
|
196
|
+
| ------- | ----------------- | --------------------------------- |
|
|
197
|
+
| `name` | `string` | Имя поля в форме |
|
|
198
|
+
| `rules` | `RegisterOptions` | Правила валидации react-hook-form |
|
|
199
|
+
|
|
70
200
|
## Стилизация
|
|
71
201
|
|
|
72
|
-
Подключите базовые стили и переопределите
|
|
202
|
+
Подключите базовые стили и переопределите нужные токены:
|
|
73
203
|
|
|
74
204
|
```css
|
|
75
205
|
@import '@artemy-tech/datepicker/styles';
|
|
@@ -78,6 +208,28 @@ const { control } = useForm()
|
|
|
78
208
|
--datepicker-color-accent: #6366f1;
|
|
79
209
|
--datepicker-radius: 8px;
|
|
80
210
|
--datepicker-font-size: 14px;
|
|
211
|
+
--datepicker-border-color: #e0e0e0;
|
|
212
|
+
--datepicker-border-color-focus: #6366f1;
|
|
213
|
+
--datepicker-bg: #ffffff;
|
|
214
|
+
--datepicker-color-text: #1a1a1a;
|
|
215
|
+
--datepicker-color-placeholder: #9e9e9e;
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Состояния задаются через `data-*`-атрибуты на корневом элементе, что позволяет стилизовать их без JS:
|
|
220
|
+
|
|
221
|
+
```css
|
|
222
|
+
.datepicker[data-focused] {
|
|
223
|
+
...;
|
|
224
|
+
}
|
|
225
|
+
.datepicker[data-filled] {
|
|
226
|
+
...;
|
|
227
|
+
}
|
|
228
|
+
.datepicker[data-failed] {
|
|
229
|
+
...;
|
|
230
|
+
}
|
|
231
|
+
.datepicker[data-disabled] {
|
|
232
|
+
...;
|
|
81
233
|
}
|
|
82
234
|
```
|
|
83
235
|
|
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
3
|
import { DateRange } from 'react-day-picker';
|
|
4
4
|
|
|
5
5
|
type DatePickerSize = 's' | 'm' | 'l';
|
|
6
6
|
type DatePickerShowTime = boolean | {
|
|
7
7
|
format: 'HH:mm' | 'HH:mm:ss';
|
|
8
8
|
};
|
|
9
|
+
interface DatePickerInputProps {
|
|
10
|
+
ref: React.Ref<HTMLInputElement>;
|
|
11
|
+
type: 'text';
|
|
12
|
+
inputMode: 'numeric';
|
|
13
|
+
className: string;
|
|
14
|
+
value: string;
|
|
15
|
+
placeholder: string | undefined;
|
|
16
|
+
disabled: boolean;
|
|
17
|
+
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
|
18
|
+
onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;
|
|
19
|
+
onPaste: React.ClipboardEventHandler<HTMLInputElement>;
|
|
20
|
+
onFocus: React.FocusEventHandler<HTMLInputElement>;
|
|
21
|
+
onBlur: React.FocusEventHandler<HTMLInputElement>;
|
|
22
|
+
'aria-label': string;
|
|
23
|
+
'aria-expanded': boolean | undefined;
|
|
24
|
+
'aria-haspopup': 'dialog' | undefined;
|
|
25
|
+
'aria-invalid': true | undefined;
|
|
26
|
+
}
|
|
9
27
|
interface DatePickerProps {
|
|
10
28
|
value?: Date;
|
|
11
29
|
defaultValue?: Date;
|
|
@@ -23,8 +41,13 @@ interface DatePickerProps {
|
|
|
23
41
|
icon?: ReactNode | false;
|
|
24
42
|
iconPosition?: 'start' | 'end';
|
|
25
43
|
className?: string;
|
|
44
|
+
renderInput?: (props: DatePickerInputProps) => ReactNode;
|
|
45
|
+
customInput?: ReactElement<{
|
|
46
|
+
value?: string;
|
|
47
|
+
onClick?: () => void;
|
|
48
|
+
}>;
|
|
26
49
|
}
|
|
27
|
-
declare function DatePicker({ value, defaultValue, onChange, label, placeholder, fromDate, toDate, disabled, failed, loading, size, noCalendar, showTime, icon, iconPosition, className, }: DatePickerProps): react_jsx_runtime.JSX.Element;
|
|
50
|
+
declare function DatePicker({ value, defaultValue, onChange, label, placeholder, fromDate, toDate, disabled, failed, loading, size, noCalendar, showTime, icon, iconPosition, className, renderInput, customInput, }: DatePickerProps): react_jsx_runtime.JSX.Element;
|
|
28
51
|
|
|
29
52
|
type DateRangePickerSize = 's' | 'm' | 'l';
|
|
30
53
|
type DateRangePickerCalendarLayout = 'vertical' | 'horizontal';
|
|
@@ -47,4 +70,4 @@ interface DateRangePickerProps {
|
|
|
47
70
|
}
|
|
48
71
|
declare function DateRangePicker({ value, defaultValue, onChange, label, fromDate: fromConstraint, toDate: toConstraint, disabled, failed, loading, size, calendarLayout, showTime, icon, iconPosition, className, }: DateRangePickerProps): react_jsx_runtime.JSX.Element;
|
|
49
72
|
|
|
50
|
-
export { DatePicker as D, type
|
|
73
|
+
export { DatePicker as D, type DatePickerInputProps as a, type DatePickerProps as b, type DatePickerShowTime as c, DateRangePicker as d, type DateRangePickerProps as e };
|
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
3
|
import { DateRange } from 'react-day-picker';
|
|
4
4
|
|
|
5
5
|
type DatePickerSize = 's' | 'm' | 'l';
|
|
6
6
|
type DatePickerShowTime = boolean | {
|
|
7
7
|
format: 'HH:mm' | 'HH:mm:ss';
|
|
8
8
|
};
|
|
9
|
+
interface DatePickerInputProps {
|
|
10
|
+
ref: React.Ref<HTMLInputElement>;
|
|
11
|
+
type: 'text';
|
|
12
|
+
inputMode: 'numeric';
|
|
13
|
+
className: string;
|
|
14
|
+
value: string;
|
|
15
|
+
placeholder: string | undefined;
|
|
16
|
+
disabled: boolean;
|
|
17
|
+
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
|
18
|
+
onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;
|
|
19
|
+
onPaste: React.ClipboardEventHandler<HTMLInputElement>;
|
|
20
|
+
onFocus: React.FocusEventHandler<HTMLInputElement>;
|
|
21
|
+
onBlur: React.FocusEventHandler<HTMLInputElement>;
|
|
22
|
+
'aria-label': string;
|
|
23
|
+
'aria-expanded': boolean | undefined;
|
|
24
|
+
'aria-haspopup': 'dialog' | undefined;
|
|
25
|
+
'aria-invalid': true | undefined;
|
|
26
|
+
}
|
|
9
27
|
interface DatePickerProps {
|
|
10
28
|
value?: Date;
|
|
11
29
|
defaultValue?: Date;
|
|
@@ -23,8 +41,13 @@ interface DatePickerProps {
|
|
|
23
41
|
icon?: ReactNode | false;
|
|
24
42
|
iconPosition?: 'start' | 'end';
|
|
25
43
|
className?: string;
|
|
44
|
+
renderInput?: (props: DatePickerInputProps) => ReactNode;
|
|
45
|
+
customInput?: ReactElement<{
|
|
46
|
+
value?: string;
|
|
47
|
+
onClick?: () => void;
|
|
48
|
+
}>;
|
|
26
49
|
}
|
|
27
|
-
declare function DatePicker({ value, defaultValue, onChange, label, placeholder, fromDate, toDate, disabled, failed, loading, size, noCalendar, showTime, icon, iconPosition, className, }: DatePickerProps): react_jsx_runtime.JSX.Element;
|
|
50
|
+
declare function DatePicker({ value, defaultValue, onChange, label, placeholder, fromDate, toDate, disabled, failed, loading, size, noCalendar, showTime, icon, iconPosition, className, renderInput, customInput, }: DatePickerProps): react_jsx_runtime.JSX.Element;
|
|
28
51
|
|
|
29
52
|
type DateRangePickerSize = 's' | 'm' | 'l';
|
|
30
53
|
type DateRangePickerCalendarLayout = 'vertical' | 'horizontal';
|
|
@@ -47,4 +70,4 @@ interface DateRangePickerProps {
|
|
|
47
70
|
}
|
|
48
71
|
declare function DateRangePicker({ value, defaultValue, onChange, label, fromDate: fromConstraint, toDate: toConstraint, disabled, failed, loading, size, calendarLayout, showTime, icon, iconPosition, className, }: DateRangePickerProps): react_jsx_runtime.JSX.Element;
|
|
49
72
|
|
|
50
|
-
export { DatePicker as D, type
|
|
73
|
+
export { DatePicker as D, type DatePickerInputProps as a, type DatePickerProps as b, type DatePickerShowTime as c, DateRangePicker as d, type DateRangePickerProps as e };
|