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