@artemy-tech/datepicker 0.6.1 → 0.7.0
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 +61 -130
- package/dist/{DateRangePicker-C8_RSTkZ.d.cts → DateRangePicker-DMprhiDL.d.cts} +7 -2
- package/dist/{DateRangePicker-C8_RSTkZ.d.ts → DateRangePicker-DMprhiDL.d.ts} +7 -2
- package/dist/{chunk-I3ID2PSC.js → chunk-66Q5CMWV.js} +204 -80
- package/dist/chunk-66Q5CMWV.js.map +1 -0
- package/dist/index.cjs +201 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/rhf.cjs +201 -78
- package/dist/rhf.cjs.map +1 -1
- package/dist/rhf.d.cts +2 -1
- package/dist/rhf.d.ts +2 -1
- package/dist/rhf.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-I3ID2PSC.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,18 +6,21 @@
|
|
|
6
6
|
[](https://codecov.io/gh/artemydottech/datepicker)
|
|
7
7
|
[](https://packagephobia.com/result?p=@artemy-tech/datepicker)
|
|
8
8
|
|
|
9
|
-
React DatePicker с
|
|
9
|
+
React DatePicker с маской ввода, поддержкой произвольных локалей и форматов даты, выбором диапазона и времени, опциональной интеграцией с react-hook-form. Построен на [react-day-picker v9](https://daypicker.dev/) и [date-fns v4](https://date-fns.org/).
|
|
10
|
+
|
|
11
|
+
**📚 [Документация и примеры →](https://artemydottech.github.io/datepicker)**
|
|
10
12
|
|
|
11
13
|
## Возможности
|
|
12
14
|
|
|
13
|
-
-
|
|
15
|
+
- Одиночная дата и диапазон
|
|
14
16
|
- Контролируемый и неконтролируемый режимы
|
|
15
17
|
- Выбор времени (`showTime`)
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
+
- **Произвольная локаль** через проп `locale` (любая локаль `date-fns`)
|
|
19
|
+
- **Произвольный формат даты** через проп `dateFormat` (`dd.MM.yyyy`, `MM/dd/yyyy`, `yyyy-MM-dd`, …) — маска ввода генерится автоматически
|
|
20
|
+
- Кастомный триггер (`customTrigger`) и кастомный инпут (`renderInput`) — интеграция с Ant Design, MUI, shadcn/ui и др.
|
|
18
21
|
- Интеграция с react-hook-form (нулевые издержки если не используется)
|
|
19
|
-
- Стилизация через CSS-переменные
|
|
20
|
-
- Полная поддержка TypeScript
|
|
22
|
+
- Стилизация через CSS-переменные `--datepicker-*`
|
|
23
|
+
- Полная поддержка TypeScript, в т.ч. дженерики для RHF-компонентов
|
|
21
24
|
|
|
22
25
|
## Установка
|
|
23
26
|
|
|
@@ -25,37 +28,34 @@ React DatePicker с опциональной поддержкой react-hook-for
|
|
|
25
28
|
npm install @artemy-tech/datepicker
|
|
26
29
|
```
|
|
27
30
|
|
|
28
|
-
Для интеграции с react-hook-form
|
|
31
|
+
Для интеграции с react-hook-form установите его как peer-зависимость:
|
|
29
32
|
|
|
30
33
|
```bash
|
|
31
|
-
npm install
|
|
34
|
+
npm install react-hook-form
|
|
32
35
|
```
|
|
33
36
|
|
|
34
|
-
##
|
|
35
|
-
|
|
36
|
-
```text
|
|
37
|
-
react >= 17.0.0
|
|
38
|
-
react-hook-form >= 7.0.0 # опционально
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Использование
|
|
42
|
-
|
|
43
|
-
### Подключение стилей
|
|
37
|
+
## Quick start
|
|
44
38
|
|
|
45
39
|
```tsx
|
|
46
40
|
import '@artemy-tech/datepicker/styles';
|
|
41
|
+
import { DatePicker } from '@artemy-tech/datepicker';
|
|
42
|
+
|
|
43
|
+
export const Example = () => <DatePicker label="Дата рождения" />;
|
|
47
44
|
```
|
|
48
45
|
|
|
46
|
+
## Примеры
|
|
47
|
+
|
|
49
48
|
### DatePicker
|
|
50
49
|
|
|
51
50
|
```tsx
|
|
52
|
-
import {
|
|
51
|
+
import { useState } from 'react';
|
|
52
|
+
import { DatePicker } from '@artemy-tech/datepicker';
|
|
53
53
|
|
|
54
54
|
// Неконтролируемый
|
|
55
55
|
<DatePicker label="Дата рождения" />
|
|
56
56
|
|
|
57
57
|
// Контролируемый
|
|
58
|
-
const [date, setDate] = useState<Date | undefined>()
|
|
58
|
+
const [date, setDate] = useState<Date | undefined>();
|
|
59
59
|
<DatePicker label="Дата" value={date} onChange={setDate} />
|
|
60
60
|
|
|
61
61
|
// С выбором времени
|
|
@@ -68,147 +68,92 @@ const [date, setDate] = useState<Date | undefined>()
|
|
|
68
68
|
### DateRangePicker
|
|
69
69
|
|
|
70
70
|
```tsx
|
|
71
|
-
import {
|
|
72
|
-
import type
|
|
71
|
+
import { useState } from 'react';
|
|
72
|
+
import { DateRangePicker, type DateRange } from '@artemy-tech/datepicker';
|
|
73
73
|
|
|
74
|
-
const [range, setRange] = useState<DateRange | undefined>()
|
|
74
|
+
const [range, setRange] = useState<DateRange | undefined>();
|
|
75
75
|
|
|
76
76
|
<DateRangePicker
|
|
77
77
|
label="Период проживания"
|
|
78
78
|
value={range}
|
|
79
79
|
onChange={setRange}
|
|
80
80
|
calendarLayout="horizontal"
|
|
81
|
-
|
|
81
|
+
/>;
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
###
|
|
84
|
+
### Локали и форматы
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
По умолчанию: `locale = ru`, `dateFormat = 'dd.MM.yyyy'`. Любую локаль `date-fns` можно подключить точечно — маска и плейсхолдер пересчитаются автоматически.
|
|
87
87
|
|
|
88
88
|
```tsx
|
|
89
|
-
import {
|
|
89
|
+
import { enUS, de } from 'date-fns/locale';
|
|
90
|
+
import { DatePicker, DateRangePicker } from '@artemy-tech/datepicker';
|
|
90
91
|
|
|
91
92
|
<DatePicker
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
)}
|
|
97
|
-
/>;
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### Кастомный инпут (`renderInput`)
|
|
101
|
-
|
|
102
|
-
Через `renderInput` можно заменить встроенный `<input>` на компонент из любой UI-библиотеки. Вся логика маски, валидации и попапа остаётся внутри `DatePicker`.
|
|
103
|
-
|
|
104
|
-
```tsx
|
|
105
|
-
import { Input } from 'antd';
|
|
106
|
-
import type { InputRef } from 'antd';
|
|
107
|
-
import { DatePicker } from '@artemy-tech/datepicker';
|
|
93
|
+
locale={enUS}
|
|
94
|
+
dateFormat="MM/dd/yyyy"
|
|
95
|
+
label="Birth date"
|
|
96
|
+
/>
|
|
108
97
|
|
|
109
98
|
<DatePicker
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
99
|
+
locale={enUS}
|
|
100
|
+
dateFormat="yyyy-MM-dd"
|
|
101
|
+
label="ISO date"
|
|
102
|
+
/>
|
|
103
|
+
|
|
104
|
+
<DateRangePicker
|
|
105
|
+
locale={de}
|
|
106
|
+
dateFormat="dd.MM.yyyy"
|
|
107
|
+
label="Zeitraum"
|
|
108
|
+
/>
|
|
114
109
|
```
|
|
115
110
|
|
|
111
|
+
Поддерживаемые токены в `dateFormat`: `dd`, `MM`, `yyyy`. Разделители — любые одиночные символы (`.`, `/`, `-`, ` `). Время добавляется через проп `showTime`, а не через `dateFormat`.
|
|
112
|
+
|
|
116
113
|
### С react-hook-form
|
|
117
114
|
|
|
115
|
+
`RHFDatePicker` и `RHFDateRangePicker` принимают дженерик-параметр — тип значений формы. Это даёт автокомплит и типобезопасность для `name`:
|
|
116
|
+
|
|
118
117
|
```tsx
|
|
119
118
|
import { FormProvider, useForm } from 'react-hook-form';
|
|
120
119
|
import { RHFDatePicker, RHFDateRangePicker } from '@artemy-tech/datepicker/rhf';
|
|
121
120
|
import type { DateRange } from '@artemy-tech/datepicker';
|
|
122
121
|
|
|
123
|
-
interface
|
|
122
|
+
interface BookingFormValues {
|
|
124
123
|
checkIn: Date | undefined;
|
|
125
124
|
period: DateRange | undefined;
|
|
126
125
|
}
|
|
127
126
|
|
|
128
|
-
|
|
129
|
-
const methods = useForm<
|
|
127
|
+
const BookingForm = () => {
|
|
128
|
+
const methods = useForm<BookingFormValues>({
|
|
130
129
|
defaultValues: { checkIn: undefined, period: undefined },
|
|
131
130
|
});
|
|
132
131
|
|
|
133
132
|
return (
|
|
134
133
|
<FormProvider {...methods}>
|
|
135
134
|
<form onSubmit={methods.handleSubmit(console.log)}>
|
|
136
|
-
<RHFDatePicker
|
|
135
|
+
<RHFDatePicker<BookingFormValues>
|
|
137
136
|
name="checkIn"
|
|
138
137
|
label="Дата заезда"
|
|
139
138
|
rules={{ validate: (v) => v !== undefined || 'Выберите дату' }}
|
|
140
139
|
/>
|
|
141
|
-
<RHFDateRangePicker
|
|
140
|
+
<RHFDateRangePicker<BookingFormValues>
|
|
142
141
|
name="period"
|
|
143
142
|
label="Период"
|
|
144
|
-
rules={{
|
|
145
|
-
validate: (v) => v?.from !== undefined || 'Выберите период',
|
|
146
|
-
}}
|
|
143
|
+
rules={{ validate: (v) => v?.from !== undefined || 'Выберите период' }}
|
|
147
144
|
/>
|
|
148
145
|
<button type="submit">Отправить</button>
|
|
149
146
|
</form>
|
|
150
147
|
</FormProvider>
|
|
151
148
|
);
|
|
152
|
-
}
|
|
149
|
+
};
|
|
153
150
|
```
|
|
154
151
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
### DatePicker — пропсы
|
|
158
|
-
|
|
159
|
-
| Prop | Тип | По умолчанию | Описание |
|
|
160
|
-
| --------------- | --------------------------------------------------- | ------------------ | ---------------------------------------------- |
|
|
161
|
-
| `value` | `Date` | — | Контролируемое значение |
|
|
162
|
-
| `defaultValue` | `Date` | — | Значение по умолчанию (неконтролируемый режим) |
|
|
163
|
-
| `onChange` | `(date: Date \| undefined) => void` | — | Callback при изменении |
|
|
164
|
-
| `label` | `string` | — | Плавающий лейбл |
|
|
165
|
-
| `placeholder` | `string` | `дд.мм.гггг` | Плейсхолдер |
|
|
166
|
-
| `fromDate` | `Date` | — | Минимально допустимая дата |
|
|
167
|
-
| `toDate` | `Date` | — | Максимально допустимая дата |
|
|
168
|
-
| `showTime` | `boolean \| { format: 'HH:mm' \| 'HH:mm:ss' }` | — | Включить выбор времени |
|
|
169
|
-
| `noCalendar` | `boolean` | `false` | Только ввод, без попапа |
|
|
170
|
-
| `size` | `'s' \| 'm' \| 'l'` | `'m'` | Размер |
|
|
171
|
-
| `disabled` | `boolean` | `false` | |
|
|
172
|
-
| `failed` | `boolean` | `false` | Состояние ошибки |
|
|
173
|
-
| `loading` | `boolean` | `false` | Состояние загрузки |
|
|
174
|
-
| `icon` | `ReactNode \| false` | `<CalendarIcon />` | Иконка (`false` — скрыть) |
|
|
175
|
-
| `iconPosition` | `'start' \| 'end'` | `'end'` | Позиция иконки |
|
|
176
|
-
| `renderInput` | `(props: DatePickerInputProps) => ReactNode` | — | Кастомный `<input>`; маска и попап сохраняются |
|
|
177
|
-
| `customTrigger` | `(value: string, onClick: () => void) => ReactNode` | — | Render-функция для произвольного триггера |
|
|
178
|
-
| `className` | `string` | — | CSS-класс на корневом элементе |
|
|
179
|
-
|
|
180
|
-
### DateRangePicker — пропсы
|
|
181
|
-
|
|
182
|
-
| Prop | Тип | По умолчанию | Описание |
|
|
183
|
-
| ---------------- | ---------------------------------------------- | ------------------ | --------------------------- |
|
|
184
|
-
| `value` | `DateRange` | — | Контролируемое значение |
|
|
185
|
-
| `defaultValue` | `DateRange` | — | Значение по умолчанию |
|
|
186
|
-
| `onChange` | `(range: DateRange \| undefined) => void` | — | Callback при изменении |
|
|
187
|
-
| `label` | `string` | — | Плавающий лейбл |
|
|
188
|
-
| `fromDate` | `Date` | — | Минимально допустимая дата |
|
|
189
|
-
| `toDate` | `Date` | — | Максимально допустимая дата |
|
|
190
|
-
| `calendarLayout` | `'vertical' \| 'horizontal'` | `'horizontal'` | Расположение двух месяцев |
|
|
191
|
-
| `showTime` | `boolean \| { format: 'HH:mm' \| 'HH:mm:ss' }` | — | Включить выбор времени |
|
|
192
|
-
| `size` | `'s' \| 'm' \| 'l'` | `'m'` | Размер |
|
|
193
|
-
| `disabled` | `boolean` | `false` | |
|
|
194
|
-
| `failed` | `boolean` | `false` | |
|
|
195
|
-
| `loading` | `boolean` | `false` | |
|
|
196
|
-
| `icon` | `ReactNode \| false` | `<CalendarIcon />` | Иконка |
|
|
197
|
-
| `iconPosition` | `'start' \| 'end'` | `'end'` | |
|
|
198
|
-
| `className` | `string` | — | |
|
|
199
|
-
|
|
200
|
-
### RHFDatePicker / RHFDateRangePicker — пропсы
|
|
201
|
-
|
|
202
|
-
Принимают все пропсы соответствующего компонента, плюс:
|
|
203
|
-
|
|
204
|
-
| Prop | Тип | Описание |
|
|
205
|
-
| ------- | ----------------- | --------------------------------- |
|
|
206
|
-
| `name` | `string` | Имя поля в форме |
|
|
207
|
-
| `rules` | `RegisterOptions` | Правила валидации react-hook-form |
|
|
152
|
+
> Полные рецепты для **Zod**, **Joi** и **shadcn/ui Form** — на [странице документации](https://artemydottech.github.io/datepicker/recipes).
|
|
208
153
|
|
|
209
154
|
## Стилизация
|
|
210
155
|
|
|
211
|
-
Подключите базовые стили и переопределите нужные
|
|
156
|
+
Подключите базовые стили и переопределите нужные CSS-переменные:
|
|
212
157
|
|
|
213
158
|
```css
|
|
214
159
|
@import '@artemy-tech/datepicker/styles';
|
|
@@ -216,31 +161,17 @@ function BookingForm() {
|
|
|
216
161
|
:root {
|
|
217
162
|
--datepicker-color-accent: #6366f1;
|
|
218
163
|
--datepicker-radius: 8px;
|
|
219
|
-
--datepicker-font-size: 14px;
|
|
220
|
-
--datepicker-border-color: #e0e0e0;
|
|
221
164
|
--datepicker-border-color-focus: #6366f1;
|
|
222
|
-
--datepicker-bg: #ffffff;
|
|
223
|
-
--datepicker-color-text: #1a1a1a;
|
|
224
|
-
--datepicker-color-placeholder: #9e9e9e;
|
|
225
165
|
}
|
|
226
166
|
```
|
|
227
167
|
|
|
228
|
-
Состояния задаются через `data-*`-атрибуты на корневом
|
|
168
|
+
Состояния задаются через `data-*`-атрибуты на корневом элементе (`data-focused`, `data-filled`, `data-failed`, `data-disabled`) — стилизуются без JS.
|
|
229
169
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
.datepicker
|
|
235
|
-
...;
|
|
236
|
-
}
|
|
237
|
-
.datepicker[data-failed] {
|
|
238
|
-
...;
|
|
239
|
-
}
|
|
240
|
-
.datepicker[data-disabled] {
|
|
241
|
-
...;
|
|
242
|
-
}
|
|
243
|
-
```
|
|
170
|
+
Полный список токенов и data-атрибутов — в [разделе Theming](https://artemydottech.github.io/datepicker/theming).
|
|
171
|
+
|
|
172
|
+
## API
|
|
173
|
+
|
|
174
|
+
Подробная справка по пропсам, типам и edge-cases — в [документации](https://artemydottech.github.io/datepicker).
|
|
244
175
|
|
|
245
176
|
## Лицензия
|
|
246
177
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
+
import { Locale } from 'date-fns/locale';
|
|
3
4
|
import { DateRange } from 'react-day-picker';
|
|
4
5
|
|
|
5
6
|
type DatePickerSize = 's' | 'm' | 'l';
|
|
@@ -43,8 +44,10 @@ interface DatePickerProps {
|
|
|
43
44
|
className?: string;
|
|
44
45
|
renderInput?: (props: DatePickerInputProps) => ReactNode;
|
|
45
46
|
customTrigger?: (value: string, onClick: () => void) => ReactNode;
|
|
47
|
+
locale?: Locale;
|
|
48
|
+
dateFormat?: string;
|
|
46
49
|
}
|
|
47
|
-
declare function DatePicker({ value, defaultValue, onChange, label, placeholder, fromDate, toDate, disabled, failed, loading, size, noCalendar, showTime, icon, iconPosition, className, renderInput, customTrigger, }: 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, customTrigger, locale, dateFormat: dateFormatProp, }: DatePickerProps): react_jsx_runtime.JSX.Element;
|
|
48
51
|
|
|
49
52
|
type DateRangePickerSize = 's' | 'm' | 'l';
|
|
50
53
|
type DateRangePickerCalendarLayout = 'vertical' | 'horizontal';
|
|
@@ -64,7 +67,9 @@ interface DateRangePickerProps {
|
|
|
64
67
|
icon?: ReactNode | false;
|
|
65
68
|
iconPosition?: 'start' | 'end';
|
|
66
69
|
className?: string;
|
|
70
|
+
locale?: Locale;
|
|
71
|
+
dateFormat?: string;
|
|
67
72
|
}
|
|
68
|
-
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;
|
|
73
|
+
declare function DateRangePicker({ value, defaultValue, onChange, label, fromDate: fromConstraint, toDate: toConstraint, disabled, failed, loading, size, calendarLayout, showTime, icon, iconPosition, className, locale, dateFormat: dateFormatProp, }: DateRangePickerProps): react_jsx_runtime.JSX.Element;
|
|
69
74
|
|
|
70
75
|
export { DatePicker as D, type DatePickerInputProps as a, type DatePickerProps as b, type DatePickerShowTime as c, DateRangePicker as d, type DateRangePickerProps as e };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
+
import { Locale } from 'date-fns/locale';
|
|
3
4
|
import { DateRange } from 'react-day-picker';
|
|
4
5
|
|
|
5
6
|
type DatePickerSize = 's' | 'm' | 'l';
|
|
@@ -43,8 +44,10 @@ interface DatePickerProps {
|
|
|
43
44
|
className?: string;
|
|
44
45
|
renderInput?: (props: DatePickerInputProps) => ReactNode;
|
|
45
46
|
customTrigger?: (value: string, onClick: () => void) => ReactNode;
|
|
47
|
+
locale?: Locale;
|
|
48
|
+
dateFormat?: string;
|
|
46
49
|
}
|
|
47
|
-
declare function DatePicker({ value, defaultValue, onChange, label, placeholder, fromDate, toDate, disabled, failed, loading, size, noCalendar, showTime, icon, iconPosition, className, renderInput, customTrigger, }: 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, customTrigger, locale, dateFormat: dateFormatProp, }: DatePickerProps): react_jsx_runtime.JSX.Element;
|
|
48
51
|
|
|
49
52
|
type DateRangePickerSize = 's' | 'm' | 'l';
|
|
50
53
|
type DateRangePickerCalendarLayout = 'vertical' | 'horizontal';
|
|
@@ -64,7 +67,9 @@ interface DateRangePickerProps {
|
|
|
64
67
|
icon?: ReactNode | false;
|
|
65
68
|
iconPosition?: 'start' | 'end';
|
|
66
69
|
className?: string;
|
|
70
|
+
locale?: Locale;
|
|
71
|
+
dateFormat?: string;
|
|
67
72
|
}
|
|
68
|
-
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;
|
|
73
|
+
declare function DateRangePicker({ value, defaultValue, onChange, label, fromDate: fromConstraint, toDate: toConstraint, disabled, failed, loading, size, calendarLayout, showTime, icon, iconPosition, className, locale, dateFormat: dateFormatProp, }: DateRangePickerProps): react_jsx_runtime.JSX.Element;
|
|
69
74
|
|
|
70
75
|
export { DatePicker as D, type DatePickerInputProps as a, type DatePickerProps as b, type DatePickerShowTime as c, DateRangePicker as d, type DateRangePickerProps as e };
|