@daxence/flexy-date-picker 1.0.1 → 1.0.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/dist/features/date-picker/components/calendar/calendar.d.ts +7 -0
- package/dist/features/date-picker/components/calendar/index.d.ts +1 -0
- package/dist/features/date-picker/components/calendar-day/calendar-day.d.ts +7 -0
- package/dist/features/date-picker/components/calendar-day/index.d.ts +1 -0
- package/dist/features/date-picker/components/calendar-header/calendar-header.d.ts +7 -0
- package/dist/features/date-picker/components/calendar-header/index.d.ts +1 -0
- package/dist/features/date-picker/components/calendar-legend/calendar-legend.d.ts +11 -0
- package/dist/features/date-picker/components/calendar-legend/calendar-legend.stories.d.ts +17 -0
- package/dist/features/date-picker/components/calendar-legend/index.d.ts +2 -0
- package/dist/features/date-picker/components/date-input/date-input.d.ts +20 -0
- package/dist/features/date-picker/components/date-input/index.d.ts +1 -0
- package/dist/features/date-picker/components/date-picker/date-picker.d.ts +2 -0
- package/dist/features/date-picker/components/date-picker/date-picker.stories.d.ts +525 -0
- package/dist/features/date-picker/components/date-picker/index.d.ts +1 -0
- package/dist/features/date-picker/components/tooltip/index.d.ts +1 -0
- package/dist/features/date-picker/components/tooltip/tooltip.d.ts +15 -0
- package/dist/features/date-picker/context/date-picker-context.d.ts +30 -0
- package/dist/features/date-picker/context/index.d.ts +2 -0
- package/dist/features/date-picker/index.d.ts +10 -0
- package/dist/features/date-picker/styles/theme-vars.d.ts +3 -0
- package/dist/features/date-picker/types/date-picker.types.d.ts +355 -0
- package/dist/features/date-picker/types/index.d.ts +1 -0
- package/dist/features/date-picker/utils/date-utils.d.ts +37 -0
- package/dist/features/date-picker/utils/index.d.ts +1 -0
- package/dist/features/time-picker/components/time-picker/index.d.ts +2 -0
- package/dist/features/time-picker/components/time-picker/time-picker.d.ts +61 -0
- package/dist/features/time-picker/components/time-picker/time-picker.stories.d.ts +62 -0
- package/dist/features/time-picker/components/time-slot-list/index.d.ts +2 -0
- package/dist/features/time-picker/components/time-slot-list/time-slot-list.d.ts +16 -0
- package/dist/features/time-picker/index.d.ts +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/shared/utils/cx.d.ts +2 -0
- package/dist/styles.d.ts +1 -0
- package/package.json +7 -4
- package/dist/types/index.d.ts +0 -2
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface CalendarProps {
|
|
2
|
+
/** For multi-month views, the offset index (0 = first month shown) */
|
|
3
|
+
panelIndex?: number;
|
|
4
|
+
totalPanels?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function Calendar({ panelIndex, totalPanels }: CalendarProps): import("react").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Calendar } from './calendar';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CalendarDay } from './calendar-day';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface CalendarHeaderProps {
|
|
2
|
+
/** When showing multiple months, which panel index this is */
|
|
3
|
+
panelIndex?: number;
|
|
4
|
+
totalPanels?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function CalendarHeader({ panelIndex, totalPanels }: CalendarHeaderProps): import("react").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CalendarHeader } from './calendar-header';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
export interface LegendItem {
|
|
3
|
+
label: string | ReactNode;
|
|
4
|
+
className: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CalendarLegendProps {
|
|
7
|
+
items?: LegendItem[];
|
|
8
|
+
className?: string;
|
|
9
|
+
style?: CSSProperties;
|
|
10
|
+
}
|
|
11
|
+
export declare function CalendarLegend({ items, className, style, }: CalendarLegendProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { StoryObj } from '@storybook/react';
|
|
2
|
+
import { CalendarLegend } from './calendar-legend';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof CalendarLegend;
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: string;
|
|
8
|
+
};
|
|
9
|
+
tags: string[];
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
type Story = StoryObj<typeof meta>;
|
|
13
|
+
export declare const Default: Story;
|
|
14
|
+
export declare const CustomItems: Story;
|
|
15
|
+
export declare const WithCustomStyling: Story;
|
|
16
|
+
export declare const SingleItem: Story;
|
|
17
|
+
export declare const WithReactNodeLabels: Story;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DatePickerClassNames, DatePickerStyles, DateValue, DateRange, PickerMode, RenderInputProps } from '../../types';
|
|
2
|
+
interface DateInputProps {
|
|
3
|
+
mode: PickerMode;
|
|
4
|
+
singleValue: DateValue;
|
|
5
|
+
rangeValue: DateRange;
|
|
6
|
+
format: string;
|
|
7
|
+
locale?: string;
|
|
8
|
+
placeholder: string | [string, string];
|
|
9
|
+
isOpen: boolean;
|
|
10
|
+
isDisabled: boolean;
|
|
11
|
+
readOnly: boolean;
|
|
12
|
+
clearable: boolean;
|
|
13
|
+
classNames: DatePickerClassNames;
|
|
14
|
+
styles: DatePickerStyles;
|
|
15
|
+
onOpen: () => void;
|
|
16
|
+
onClear: () => void;
|
|
17
|
+
renderInput?: (props: RenderInputProps) => React.ReactNode;
|
|
18
|
+
}
|
|
19
|
+
export declare function DateInput({ mode, singleValue, rangeValue, format, locale, placeholder, isOpen, isDisabled, readOnly, clearable, classNames, styles: slotStyles, onOpen, onClear, renderInput, }: DateInputProps): import("react").JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DateInput } from './date-input';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { DatePickerProps } from '../../types';
|
|
2
|
+
export declare function DatePicker({ mode, value, defaultValue, rangeValue, defaultRangeValue, format, locale, lang, weekStartsOn, enableTime, timeStep, timeFormat, minTime, maxTime, disabledTime, timeSchedule, defaultTimeSchedule, minDate, maxDate, placeholder, disabled, isDisabled, readOnly, clearable, highlightToday, showAdjacentMonthDays, showOutsideDays, tooltip, tooltipDelay, theme, classNames: classNamesProp, styles: stylesProp, className, style, numberOfMonths, showMonthYearSelectors, inline, placement, renderDay, renderNavButton, renderInput, onDateChange, onRangeChange, onTimeChange, onMonthChange, onYearChange, onDayHover, onOpen, onClose, onClear, onBeforeSelect, onAfterSelect, }: DatePickerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
import { StoryObj } from '@storybook/react';
|
|
2
|
+
import { DatePicker } from './date-picker';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof DatePicker;
|
|
6
|
+
argTypes: {
|
|
7
|
+
mode: {
|
|
8
|
+
control: "select";
|
|
9
|
+
options: string[];
|
|
10
|
+
description: string;
|
|
11
|
+
table: {
|
|
12
|
+
category: string;
|
|
13
|
+
defaultValue: {
|
|
14
|
+
summary: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
value: {
|
|
19
|
+
control: false;
|
|
20
|
+
description: string;
|
|
21
|
+
table: {
|
|
22
|
+
category: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
defaultValue: {
|
|
26
|
+
control: false;
|
|
27
|
+
description: string;
|
|
28
|
+
table: {
|
|
29
|
+
category: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
rangeValue: {
|
|
33
|
+
control: false;
|
|
34
|
+
description: string;
|
|
35
|
+
table: {
|
|
36
|
+
category: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
defaultRangeValue: {
|
|
40
|
+
control: false;
|
|
41
|
+
description: string;
|
|
42
|
+
table: {
|
|
43
|
+
category: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
format: {
|
|
47
|
+
control: "text";
|
|
48
|
+
description: string;
|
|
49
|
+
table: {
|
|
50
|
+
category: string;
|
|
51
|
+
defaultValue: {
|
|
52
|
+
summary: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
locale: {
|
|
57
|
+
control: "text";
|
|
58
|
+
description: string;
|
|
59
|
+
table: {
|
|
60
|
+
category: string;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
lang: {
|
|
64
|
+
control: "text";
|
|
65
|
+
description: string;
|
|
66
|
+
table: {
|
|
67
|
+
category: string;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
weekStartsOn: {
|
|
71
|
+
control: "select";
|
|
72
|
+
options: number[];
|
|
73
|
+
description: string;
|
|
74
|
+
table: {
|
|
75
|
+
category: string;
|
|
76
|
+
defaultValue: {
|
|
77
|
+
summary: string;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
numberOfMonths: {
|
|
82
|
+
control: {
|
|
83
|
+
type: "number";
|
|
84
|
+
min: number;
|
|
85
|
+
max: number;
|
|
86
|
+
step: number;
|
|
87
|
+
};
|
|
88
|
+
description: string;
|
|
89
|
+
table: {
|
|
90
|
+
category: string;
|
|
91
|
+
defaultValue: {
|
|
92
|
+
summary: string;
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
showAdjacentMonthDays: {
|
|
97
|
+
control: "boolean";
|
|
98
|
+
description: string;
|
|
99
|
+
table: {
|
|
100
|
+
category: string;
|
|
101
|
+
defaultValue: {
|
|
102
|
+
summary: string;
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
highlightToday: {
|
|
107
|
+
control: "boolean";
|
|
108
|
+
description: string;
|
|
109
|
+
table: {
|
|
110
|
+
category: string;
|
|
111
|
+
defaultValue: {
|
|
112
|
+
summary: string;
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
inline: {
|
|
117
|
+
control: "boolean";
|
|
118
|
+
description: string;
|
|
119
|
+
table: {
|
|
120
|
+
category: string;
|
|
121
|
+
defaultValue: {
|
|
122
|
+
summary: string;
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
minDate: {
|
|
127
|
+
control: false;
|
|
128
|
+
description: string;
|
|
129
|
+
table: {
|
|
130
|
+
category: string;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
maxDate: {
|
|
134
|
+
control: false;
|
|
135
|
+
description: string;
|
|
136
|
+
table: {
|
|
137
|
+
category: string;
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
disabled: {
|
|
141
|
+
control: false;
|
|
142
|
+
description: string;
|
|
143
|
+
table: {
|
|
144
|
+
category: string;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
isDisabled: {
|
|
148
|
+
control: "boolean";
|
|
149
|
+
description: string;
|
|
150
|
+
table: {
|
|
151
|
+
category: string;
|
|
152
|
+
defaultValue: {
|
|
153
|
+
summary: string;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
readOnly: {
|
|
158
|
+
control: "boolean";
|
|
159
|
+
description: string;
|
|
160
|
+
table: {
|
|
161
|
+
category: string;
|
|
162
|
+
defaultValue: {
|
|
163
|
+
summary: string;
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
placeholder: {
|
|
168
|
+
control: "text";
|
|
169
|
+
description: string;
|
|
170
|
+
table: {
|
|
171
|
+
category: string;
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
clearable: {
|
|
175
|
+
control: "boolean";
|
|
176
|
+
description: string;
|
|
177
|
+
table: {
|
|
178
|
+
category: string;
|
|
179
|
+
defaultValue: {
|
|
180
|
+
summary: string;
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
enableTime: {
|
|
185
|
+
control: "boolean";
|
|
186
|
+
description: string;
|
|
187
|
+
table: {
|
|
188
|
+
category: string;
|
|
189
|
+
defaultValue: {
|
|
190
|
+
summary: string;
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
timeStep: {
|
|
195
|
+
control: {
|
|
196
|
+
type: "number";
|
|
197
|
+
min: number;
|
|
198
|
+
max: number;
|
|
199
|
+
step: number;
|
|
200
|
+
};
|
|
201
|
+
description: string;
|
|
202
|
+
table: {
|
|
203
|
+
category: string;
|
|
204
|
+
defaultValue: {
|
|
205
|
+
summary: string;
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
timeFormat: {
|
|
210
|
+
control: "text";
|
|
211
|
+
description: string;
|
|
212
|
+
table: {
|
|
213
|
+
category: string;
|
|
214
|
+
defaultValue: {
|
|
215
|
+
summary: string;
|
|
216
|
+
};
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
minTime: {
|
|
220
|
+
control: "text";
|
|
221
|
+
description: string;
|
|
222
|
+
table: {
|
|
223
|
+
category: string;
|
|
224
|
+
defaultValue: {
|
|
225
|
+
summary: string;
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
maxTime: {
|
|
230
|
+
control: "text";
|
|
231
|
+
description: string;
|
|
232
|
+
table: {
|
|
233
|
+
category: string;
|
|
234
|
+
defaultValue: {
|
|
235
|
+
summary: string;
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
disabledTime: {
|
|
240
|
+
control: false;
|
|
241
|
+
description: string;
|
|
242
|
+
table: {
|
|
243
|
+
category: string;
|
|
244
|
+
};
|
|
245
|
+
};
|
|
246
|
+
tooltip: {
|
|
247
|
+
control: "text";
|
|
248
|
+
description: string;
|
|
249
|
+
table: {
|
|
250
|
+
category: string;
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
tooltipDelay: {
|
|
254
|
+
control: {
|
|
255
|
+
type: "number";
|
|
256
|
+
min: number;
|
|
257
|
+
max: number;
|
|
258
|
+
step: number;
|
|
259
|
+
};
|
|
260
|
+
description: string;
|
|
261
|
+
table: {
|
|
262
|
+
category: string;
|
|
263
|
+
defaultValue: {
|
|
264
|
+
summary: string;
|
|
265
|
+
};
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
theme: {
|
|
269
|
+
control: "object";
|
|
270
|
+
description: string;
|
|
271
|
+
table: {
|
|
272
|
+
category: string;
|
|
273
|
+
};
|
|
274
|
+
};
|
|
275
|
+
classNames: {
|
|
276
|
+
control: "object";
|
|
277
|
+
description: string;
|
|
278
|
+
table: {
|
|
279
|
+
category: string;
|
|
280
|
+
};
|
|
281
|
+
};
|
|
282
|
+
styles: {
|
|
283
|
+
control: "object";
|
|
284
|
+
description: string;
|
|
285
|
+
table: {
|
|
286
|
+
category: string;
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
className: {
|
|
290
|
+
control: "text";
|
|
291
|
+
description: string;
|
|
292
|
+
table: {
|
|
293
|
+
category: string;
|
|
294
|
+
};
|
|
295
|
+
};
|
|
296
|
+
renderDay: {
|
|
297
|
+
control: false;
|
|
298
|
+
description: string;
|
|
299
|
+
table: {
|
|
300
|
+
category: string;
|
|
301
|
+
};
|
|
302
|
+
};
|
|
303
|
+
renderNavButton: {
|
|
304
|
+
control: false;
|
|
305
|
+
description: string;
|
|
306
|
+
table: {
|
|
307
|
+
category: string;
|
|
308
|
+
};
|
|
309
|
+
};
|
|
310
|
+
renderInput: {
|
|
311
|
+
control: false;
|
|
312
|
+
description: string;
|
|
313
|
+
table: {
|
|
314
|
+
category: string;
|
|
315
|
+
};
|
|
316
|
+
};
|
|
317
|
+
onDateChange: {
|
|
318
|
+
action: string;
|
|
319
|
+
description: string;
|
|
320
|
+
table: {
|
|
321
|
+
category: string;
|
|
322
|
+
};
|
|
323
|
+
};
|
|
324
|
+
onRangeChange: {
|
|
325
|
+
action: string;
|
|
326
|
+
description: string;
|
|
327
|
+
table: {
|
|
328
|
+
category: string;
|
|
329
|
+
};
|
|
330
|
+
};
|
|
331
|
+
onTimeChange: {
|
|
332
|
+
action: string;
|
|
333
|
+
description: string;
|
|
334
|
+
table: {
|
|
335
|
+
category: string;
|
|
336
|
+
};
|
|
337
|
+
};
|
|
338
|
+
onMonthChange: {
|
|
339
|
+
action: string;
|
|
340
|
+
description: string;
|
|
341
|
+
table: {
|
|
342
|
+
category: string;
|
|
343
|
+
};
|
|
344
|
+
};
|
|
345
|
+
onYearChange: {
|
|
346
|
+
action: string;
|
|
347
|
+
description: string;
|
|
348
|
+
table: {
|
|
349
|
+
category: string;
|
|
350
|
+
};
|
|
351
|
+
};
|
|
352
|
+
onDayHover: {
|
|
353
|
+
action: string;
|
|
354
|
+
description: string;
|
|
355
|
+
table: {
|
|
356
|
+
category: string;
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
onOpen: {
|
|
360
|
+
action: string;
|
|
361
|
+
description: string;
|
|
362
|
+
table: {
|
|
363
|
+
category: string;
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
onClose: {
|
|
367
|
+
action: string;
|
|
368
|
+
description: string;
|
|
369
|
+
table: {
|
|
370
|
+
category: string;
|
|
371
|
+
};
|
|
372
|
+
};
|
|
373
|
+
onClear: {
|
|
374
|
+
action: string;
|
|
375
|
+
description: string;
|
|
376
|
+
table: {
|
|
377
|
+
category: string;
|
|
378
|
+
};
|
|
379
|
+
};
|
|
380
|
+
onBeforeSelect: {
|
|
381
|
+
control: false;
|
|
382
|
+
description: string;
|
|
383
|
+
table: {
|
|
384
|
+
category: string;
|
|
385
|
+
};
|
|
386
|
+
};
|
|
387
|
+
onAfterSelect: {
|
|
388
|
+
action: string;
|
|
389
|
+
description: string;
|
|
390
|
+
table: {
|
|
391
|
+
category: string;
|
|
392
|
+
};
|
|
393
|
+
};
|
|
394
|
+
};
|
|
395
|
+
};
|
|
396
|
+
export default meta;
|
|
397
|
+
type Story = StoryObj<typeof meta>;
|
|
398
|
+
/**
|
|
399
|
+
* The out-of-the-box experience with no props set.
|
|
400
|
+
* Click the input to open the calendar and pick a date.
|
|
401
|
+
*/
|
|
402
|
+
export declare const Default: Story;
|
|
403
|
+
/**
|
|
404
|
+
* Full interactive playground — every prop is wired to a Storybook Control.
|
|
405
|
+
* Use the **Controls** panel below to toggle features in real time.
|
|
406
|
+
*/
|
|
407
|
+
export declare const Playground: Story;
|
|
408
|
+
/**
|
|
409
|
+
* Renders the calendar inline — no input trigger or popover.
|
|
410
|
+
* Useful for embedding the picker directly in a form or page.
|
|
411
|
+
*/
|
|
412
|
+
export declare const Inline: Story;
|
|
413
|
+
/**
|
|
414
|
+
* Range selection — click a start date then an end date.
|
|
415
|
+
* The `onRangeChange` action logs each selection step.
|
|
416
|
+
*/
|
|
417
|
+
export declare const RangeSelection: Story;
|
|
418
|
+
/**
|
|
419
|
+
* Dual-panel range picker rendered inline — two months side by side.
|
|
420
|
+
*/
|
|
421
|
+
export declare const RangeInline: Story;
|
|
422
|
+
/**
|
|
423
|
+
* Adds a time-slot panel next to the calendar.
|
|
424
|
+
* The step is 30 minutes and the selectable range is 08:00 – 20:00.
|
|
425
|
+
*/
|
|
426
|
+
export declare const WithTime: Story;
|
|
427
|
+
/**
|
|
428
|
+
* Inline calendar with time selector.
|
|
429
|
+
*/
|
|
430
|
+
export declare const InlineWithTime: Story;
|
|
431
|
+
/**
|
|
432
|
+
* Demonstrates the `disabled` prop with multiple strategies:
|
|
433
|
+
* - Entire weekends via `predicate`
|
|
434
|
+
* - A specific date list
|
|
435
|
+
* - Before / after bounds
|
|
436
|
+
*/
|
|
437
|
+
export declare const DisabledDates: Story;
|
|
438
|
+
/**
|
|
439
|
+
* Constrain selection to a specific window using `minDate` + `maxDate`.
|
|
440
|
+
*/
|
|
441
|
+
export declare const MinMaxDates: Story;
|
|
442
|
+
/**
|
|
443
|
+
* Picker with an initial date selected via `defaultValue`.
|
|
444
|
+
*/
|
|
445
|
+
export declare const PreSelectedDate: Story;
|
|
446
|
+
/**
|
|
447
|
+
* Range picker with a default range via `defaultRangeValue`.
|
|
448
|
+
*/
|
|
449
|
+
export declare const PreSelectedRange: Story;
|
|
450
|
+
/**
|
|
451
|
+
* With `showAdjacentMonthDays: true` the grid is filled with greyed-out
|
|
452
|
+
* days from the previous and next months.
|
|
453
|
+
*/
|
|
454
|
+
export declare const ShowAdjacentMonthDays: Story;
|
|
455
|
+
/**
|
|
456
|
+
* `weekStartsOn: 1` shifts the week grid so Monday is the first column.
|
|
457
|
+
*/
|
|
458
|
+
export declare const WeekStartsMonday: Story;
|
|
459
|
+
/**
|
|
460
|
+
* `numberOfMonths: 3` renders three consecutive calendar panels at once.
|
|
461
|
+
*/
|
|
462
|
+
export declare const MultiMonth: Story;
|
|
463
|
+
/**
|
|
464
|
+
* `isDisabled: true` greys out the input and prevents all interaction.
|
|
465
|
+
*/
|
|
466
|
+
export declare const Disabled: Story;
|
|
467
|
+
/**
|
|
468
|
+
* `readOnly: true` shows the value but prevents changes.
|
|
469
|
+
*/
|
|
470
|
+
export declare const ReadOnly: Story;
|
|
471
|
+
/**
|
|
472
|
+
* `clearable: false` hides the × button — useful when the field is required.
|
|
473
|
+
*/
|
|
474
|
+
export declare const NoClear: Story;
|
|
475
|
+
/**
|
|
476
|
+
* A static string tooltip shown on every day cell.
|
|
477
|
+
*/
|
|
478
|
+
export declare const WithTooltip: Story;
|
|
479
|
+
/**
|
|
480
|
+
* Dynamic tooltip using a render function — shows rich contextual info.
|
|
481
|
+
*/
|
|
482
|
+
export declare const TooltipWithFunction: Story;
|
|
483
|
+
/**
|
|
484
|
+
* Hotel-style range tooltip: labels check-in/check-out and shows a live
|
|
485
|
+
* "X nights" count while hovering the candidate end date or once both
|
|
486
|
+
* dates are selected. Uses the `nights`, `isRangeStart`, `isRangeEnd` and
|
|
487
|
+
* `isPreviewRangeEnd` render props.
|
|
488
|
+
*/
|
|
489
|
+
export declare const TooltipNights: Story;
|
|
490
|
+
/**
|
|
491
|
+
* Override CSS tokens via the `theme` prop to apply a teal accent.
|
|
492
|
+
*/
|
|
493
|
+
export declare const ThemeTeal: Story;
|
|
494
|
+
/**
|
|
495
|
+
* Violet / purple brand accent.
|
|
496
|
+
*/
|
|
497
|
+
export declare const ThemePurple: Story;
|
|
498
|
+
/**
|
|
499
|
+
* Rose / red brand accent with a sharp square border radius.
|
|
500
|
+
*/
|
|
501
|
+
export declare const ThemeRose: Story;
|
|
502
|
+
/**
|
|
503
|
+
* Dark surface + amber accent — simulates a dark mode.
|
|
504
|
+
*/
|
|
505
|
+
export declare const ThemeDark: Story;
|
|
506
|
+
/**
|
|
507
|
+
* `renderDay` lets you inject any content into each day cell.
|
|
508
|
+
* This example adds a red dot indicator for the next 5 days.
|
|
509
|
+
*/
|
|
510
|
+
export declare const CustomDayRenderer: Story;
|
|
511
|
+
/**
|
|
512
|
+
* `renderNavButton` replaces the default ‹ / › buttons with custom elements.
|
|
513
|
+
*/
|
|
514
|
+
export declare const CustomNavButtons: Story;
|
|
515
|
+
/**
|
|
516
|
+
* The `locale` prop switches day/month labels to French.
|
|
517
|
+
*
|
|
518
|
+
* > **Note**: you must import the dayjs locale in your app:
|
|
519
|
+
* > `import 'dayjs/locale/fr'`
|
|
520
|
+
*/
|
|
521
|
+
export declare const LocaleFrench: Story;
|
|
522
|
+
/**
|
|
523
|
+
* `classNames` lets you attach custom CSS classes to individual UI slots.
|
|
524
|
+
*/
|
|
525
|
+
export declare const SlotClassNames: Story;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DatePicker } from './date-picker';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Tooltip } from './tooltip';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { default as React, ReactElement } from 'react';
|
|
2
|
+
import { Placement } from '@floating-ui/react';
|
|
3
|
+
import { TooltipContent, TooltipRenderProps, DatePickerStyles, DatePickerClassNames } from '../../types';
|
|
4
|
+
type AnyProps = Record<string, unknown>;
|
|
5
|
+
interface TooltipProps {
|
|
6
|
+
content: TooltipContent;
|
|
7
|
+
renderProps: TooltipRenderProps;
|
|
8
|
+
delay?: number;
|
|
9
|
+
placement?: Placement;
|
|
10
|
+
classNames?: DatePickerClassNames;
|
|
11
|
+
styles?: DatePickerStyles;
|
|
12
|
+
children: ReactElement<AnyProps>;
|
|
13
|
+
}
|
|
14
|
+
export declare function Tooltip({ content, renderProps, delay, placement, classNames, styles: slotStyles, children, }: TooltipProps): React.JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Dayjs } from 'dayjs';
|
|
2
|
+
import { DateValue, DateRange, PickerMode, DisabledConfig, DatePickerClassNames, DatePickerStyles, TooltipContent, DatePickerEvents } from '../types';
|
|
3
|
+
export interface DatePickerContextValue extends DatePickerEvents {
|
|
4
|
+
mode: PickerMode;
|
|
5
|
+
singleValue: DateValue;
|
|
6
|
+
rangeValue: DateRange;
|
|
7
|
+
hoveredDate: Dayjs | null;
|
|
8
|
+
currentYear: number;
|
|
9
|
+
currentMonth: number;
|
|
10
|
+
setCurrentYear: (y: number) => void;
|
|
11
|
+
setCurrentMonth: (m: number) => void;
|
|
12
|
+
selectDate: (date: Dayjs) => void;
|
|
13
|
+
setHoveredDate: (date: Dayjs | null) => void;
|
|
14
|
+
weekStartsOn: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
15
|
+
locale?: string;
|
|
16
|
+
showMonthYearSelectors?: boolean;
|
|
17
|
+
disabled?: DisabledConfig | boolean;
|
|
18
|
+
isDisabled: boolean;
|
|
19
|
+
readOnly: boolean;
|
|
20
|
+
highlightToday: boolean;
|
|
21
|
+
showAdjacentMonthDays: boolean;
|
|
22
|
+
tooltip?: TooltipContent;
|
|
23
|
+
tooltipDelay: number;
|
|
24
|
+
format: string;
|
|
25
|
+
classNames: DatePickerClassNames;
|
|
26
|
+
styles: DatePickerStyles;
|
|
27
|
+
}
|
|
28
|
+
declare const DatePickerContext: import('react').Context<DatePickerContextValue | null>;
|
|
29
|
+
export declare function useDatePickerContext(): DatePickerContextValue;
|
|
30
|
+
export { DatePickerContext };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { DatePicker } from './components/date-picker';
|
|
2
|
+
export { Calendar } from './components/calendar';
|
|
3
|
+
export { CalendarHeader } from './components/calendar-header';
|
|
4
|
+
export { CalendarDay } from './components/calendar-day';
|
|
5
|
+
export { Tooltip } from './components/tooltip';
|
|
6
|
+
export { CalendarLegend } from './components/calendar-legend';
|
|
7
|
+
export { DatePickerContext, useDatePickerContext } from './context';
|
|
8
|
+
export { isSameDay, isBetween, isRangeStart, isRangeEnd, isInRange, isDateDisabled, generateCalendarDays, getWeekdayLabels, getMonthNames, generateTimeSlots, isTimeDisabled, } from './utils';
|
|
9
|
+
export type { DatePickerProps, DateRange, DateValue, PickerMode, DatePickerClassNames, DatePickerStyles, DatePickerTheme, DatePickerEvents, DisabledConfig, DisabledTimeConfig, TimeRange, DateSchedule, TooltipContent, TooltipRenderProps, DateSelectionMeta, DateSelectionPhase, RenderInputProps, } from './types';
|
|
10
|
+
export type { CalendarLegendProps, LegendItem } from './components/calendar-legend';
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import { Dayjs } from 'dayjs';
|
|
2
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
3
|
+
export type DateValue = Dayjs | null;
|
|
4
|
+
export interface DateRange {
|
|
5
|
+
start: DateValue;
|
|
6
|
+
end: DateValue;
|
|
7
|
+
}
|
|
8
|
+
export type PickerMode = 'single' | 'range';
|
|
9
|
+
export type DateSelectionPhase = 'single' | 'range-start' | 'range-end';
|
|
10
|
+
export interface DateSelectionMeta {
|
|
11
|
+
mode: PickerMode;
|
|
12
|
+
phase: DateSelectionPhase;
|
|
13
|
+
currentValue: DateValue;
|
|
14
|
+
currentRange: DateRange;
|
|
15
|
+
nextValue: DateValue | DateRange;
|
|
16
|
+
}
|
|
17
|
+
export interface DatePickerClassNames {
|
|
18
|
+
/** Outermost wrapper */
|
|
19
|
+
root?: string;
|
|
20
|
+
/** The input trigger area */
|
|
21
|
+
inputWrapper?: string;
|
|
22
|
+
/** Individual text input */
|
|
23
|
+
input?: string;
|
|
24
|
+
/** The separator between range inputs (e.g. "→") */
|
|
25
|
+
separator?: string;
|
|
26
|
+
/** Clear button */
|
|
27
|
+
clearButton?: string;
|
|
28
|
+
/** Calendar popover container */
|
|
29
|
+
popover?: string;
|
|
30
|
+
/** Calendar wrapper */
|
|
31
|
+
calendar?: string;
|
|
32
|
+
/** Calendar header row */
|
|
33
|
+
calendarHeader?: string;
|
|
34
|
+
/** Prev/next navigation buttons */
|
|
35
|
+
navButton?: string;
|
|
36
|
+
/** Month/year label */
|
|
37
|
+
monthYearLabel?: string;
|
|
38
|
+
/** Weekday name row */
|
|
39
|
+
weekdays?: string;
|
|
40
|
+
/** Individual weekday label */
|
|
41
|
+
weekday?: string;
|
|
42
|
+
/** Days grid */
|
|
43
|
+
daysGrid?: string;
|
|
44
|
+
/** Individual day cell */
|
|
45
|
+
day?: string;
|
|
46
|
+
/** Today's day */
|
|
47
|
+
dayToday?: string;
|
|
48
|
+
/** Selected single day */
|
|
49
|
+
daySelected?: string;
|
|
50
|
+
/** Range start day */
|
|
51
|
+
dayRangeStart?: string;
|
|
52
|
+
/** Range end day */
|
|
53
|
+
dayRangeEnd?: string;
|
|
54
|
+
/** Days between start and end */
|
|
55
|
+
dayInRange?: string;
|
|
56
|
+
/** Disabled day */
|
|
57
|
+
dayDisabled?: string;
|
|
58
|
+
/** Day outside current month */
|
|
59
|
+
dayOutside?: string;
|
|
60
|
+
/** Day being hovered */
|
|
61
|
+
dayHovered?: string;
|
|
62
|
+
/** Time picker wrapper */
|
|
63
|
+
timePicker?: string;
|
|
64
|
+
/** Time picker title */
|
|
65
|
+
timeTitle?: string;
|
|
66
|
+
/** Time slots list */
|
|
67
|
+
timeSlotList?: string;
|
|
68
|
+
/** Time slot item */
|
|
69
|
+
timeSlot?: string;
|
|
70
|
+
/** Selected time slot */
|
|
71
|
+
timeSlotSelected?: string;
|
|
72
|
+
/** Disabled time slot */
|
|
73
|
+
timeSlotDisabled?: string;
|
|
74
|
+
/** Tooltip container */
|
|
75
|
+
tooltip?: string;
|
|
76
|
+
}
|
|
77
|
+
export interface DatePickerStyles {
|
|
78
|
+
root?: CSSProperties;
|
|
79
|
+
inputWrapper?: CSSProperties;
|
|
80
|
+
input?: CSSProperties;
|
|
81
|
+
separator?: CSSProperties;
|
|
82
|
+
clearButton?: CSSProperties;
|
|
83
|
+
popover?: CSSProperties;
|
|
84
|
+
calendar?: CSSProperties;
|
|
85
|
+
calendarHeader?: CSSProperties;
|
|
86
|
+
navButton?: CSSProperties;
|
|
87
|
+
monthYearLabel?: CSSProperties;
|
|
88
|
+
weekdays?: CSSProperties;
|
|
89
|
+
weekday?: CSSProperties;
|
|
90
|
+
daysGrid?: CSSProperties;
|
|
91
|
+
day?: CSSProperties;
|
|
92
|
+
dayToday?: CSSProperties;
|
|
93
|
+
daySelected?: CSSProperties;
|
|
94
|
+
dayRangeStart?: CSSProperties;
|
|
95
|
+
dayRangeEnd?: CSSProperties;
|
|
96
|
+
dayInRange?: CSSProperties;
|
|
97
|
+
dayDisabled?: CSSProperties;
|
|
98
|
+
dayOutside?: CSSProperties;
|
|
99
|
+
dayHovered?: CSSProperties;
|
|
100
|
+
timePicker?: CSSProperties;
|
|
101
|
+
timeTitle?: CSSProperties;
|
|
102
|
+
timeSlotList?: CSSProperties;
|
|
103
|
+
timeSlot?: CSSProperties;
|
|
104
|
+
timeSlotSelected?: CSSProperties;
|
|
105
|
+
timeSlotDisabled?: CSSProperties;
|
|
106
|
+
tooltip?: CSSProperties;
|
|
107
|
+
}
|
|
108
|
+
export interface DisabledTimeConfig {
|
|
109
|
+
/** Disable times for specific weekdays: 0=Sun ... 6=Sat */
|
|
110
|
+
weekdays?: Partial<Record<0 | 1 | 2 | 3 | 4 | 5 | 6, string[]>>;
|
|
111
|
+
/** Disable times for specific dates by YYYY-MM-DD */
|
|
112
|
+
dates?: Record<string, string[]>;
|
|
113
|
+
/** Custom predicate for disabling a time slot */
|
|
114
|
+
predicate?: (date: Dayjs, time: string) => boolean;
|
|
115
|
+
}
|
|
116
|
+
/** A continuous block of time with its own slot interval */
|
|
117
|
+
export interface TimeRange {
|
|
118
|
+
/** Start time (inclusive) in HH:mm */
|
|
119
|
+
from: string;
|
|
120
|
+
/** End time (inclusive) in HH:mm */
|
|
121
|
+
to: string;
|
|
122
|
+
/** Slot interval in minutes for this range (e.g. 5, 15, 30) */
|
|
123
|
+
step: number;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Time availability schedule for a single date.
|
|
127
|
+
*
|
|
128
|
+
* - `ranges`: one or more time blocks, each with its own step interval.
|
|
129
|
+
* Gaps between ranges are simply absent from the slot list.
|
|
130
|
+
* - `unavailable`: set to `true` to hide the time picker entirely for this date.
|
|
131
|
+
*/
|
|
132
|
+
export interface DateSchedule {
|
|
133
|
+
ranges?: TimeRange[];
|
|
134
|
+
unavailable?: boolean;
|
|
135
|
+
}
|
|
136
|
+
export interface DatePickerTheme {
|
|
137
|
+
/** Primary/accent color */
|
|
138
|
+
primary?: string;
|
|
139
|
+
/** Primary hover color */
|
|
140
|
+
primaryHover?: string;
|
|
141
|
+
/** Text on primary background */
|
|
142
|
+
primaryForeground?: string;
|
|
143
|
+
/** Background of the popover/calendar */
|
|
144
|
+
background?: string;
|
|
145
|
+
/** Elevated surface used for trigger and menus */
|
|
146
|
+
surface?: string;
|
|
147
|
+
/** Stronger surface tone for hover/active states */
|
|
148
|
+
surfaceStrong?: string;
|
|
149
|
+
/** Default text color */
|
|
150
|
+
foreground?: string;
|
|
151
|
+
/** Muted background (in-range highlight) */
|
|
152
|
+
muted?: string;
|
|
153
|
+
/** Soft accent background */
|
|
154
|
+
accentSoft?: string;
|
|
155
|
+
/** Muted text */
|
|
156
|
+
mutedForeground?: string;
|
|
157
|
+
/** Border color */
|
|
158
|
+
border?: string;
|
|
159
|
+
/** Input background */
|
|
160
|
+
inputBackground?: string;
|
|
161
|
+
/** Border radius (e.g. "8px") */
|
|
162
|
+
borderRadius?: string;
|
|
163
|
+
/** Day cell border radius */
|
|
164
|
+
dayBorderRadius?: string;
|
|
165
|
+
/** Box shadow for popover */
|
|
166
|
+
shadow?: string;
|
|
167
|
+
/** Font family */
|
|
168
|
+
fontFamily?: string;
|
|
169
|
+
/** Font size base */
|
|
170
|
+
fontSize?: string;
|
|
171
|
+
/** Today indicator color */
|
|
172
|
+
todayColor?: string;
|
|
173
|
+
/** Disabled day opacity */
|
|
174
|
+
disabledOpacity?: string;
|
|
175
|
+
/** Transition duration */
|
|
176
|
+
transitionDuration?: string;
|
|
177
|
+
/** Popover z-index */
|
|
178
|
+
zIndex?: string;
|
|
179
|
+
}
|
|
180
|
+
export interface TooltipRenderProps {
|
|
181
|
+
date: Dayjs;
|
|
182
|
+
isToday: boolean;
|
|
183
|
+
isSelected: boolean;
|
|
184
|
+
isDisabled: boolean;
|
|
185
|
+
isRangeStart: boolean;
|
|
186
|
+
isRangeEnd: boolean;
|
|
187
|
+
isInRange: boolean;
|
|
188
|
+
/** True while user is selecting the end date in range mode */
|
|
189
|
+
isRangeSelecting?: boolean;
|
|
190
|
+
/** True for days inside the temporary hover preview range */
|
|
191
|
+
isInPreviewRange?: boolean;
|
|
192
|
+
/** True for the hovered candidate end date while selecting a range */
|
|
193
|
+
isPreviewRangeEnd?: boolean;
|
|
194
|
+
/** Range mode only: the committed or in-progress start date */
|
|
195
|
+
rangeStart?: Dayjs | null;
|
|
196
|
+
/** Range mode only: the committed end date, or the hovered candidate end while selecting */
|
|
197
|
+
rangeEnd?: Dayjs | null;
|
|
198
|
+
/**
|
|
199
|
+
* Range mode only: number of nights between `rangeStart` and `rangeEnd`
|
|
200
|
+
* (committed or previewed). `null` until both ends are known.
|
|
201
|
+
* Handy for hotel-style tooltips, e.g. `${nights} night(s)`.
|
|
202
|
+
*/
|
|
203
|
+
nights?: number | null;
|
|
204
|
+
}
|
|
205
|
+
export type TooltipContent = string | ReactNode | ((props: TooltipRenderProps) => ReactNode);
|
|
206
|
+
export interface DatePickerEvents {
|
|
207
|
+
/** Fired when a single date is selected */
|
|
208
|
+
onDateChange?: (date: DateValue) => void;
|
|
209
|
+
/** Fired when range selection changes */
|
|
210
|
+
onRangeChange?: (range: DateRange) => void;
|
|
211
|
+
/** Fired when the time changes for the current selection */
|
|
212
|
+
onTimeChange?: (date: DateValue, time: string) => void;
|
|
213
|
+
/** Fired before a date or range selection is committed; return false to cancel */
|
|
214
|
+
onBeforeSelect?: (date: Dayjs, meta: DateSelectionMeta) => boolean | void;
|
|
215
|
+
/** Fired after a date or range selection is committed */
|
|
216
|
+
onAfterSelect?: (date: Dayjs, meta: DateSelectionMeta) => void;
|
|
217
|
+
/** Fired when the viewed month changes */
|
|
218
|
+
onMonthChange?: (month: number, year: number) => void;
|
|
219
|
+
/** Fired when the viewed year changes */
|
|
220
|
+
onYearChange?: (year: number) => void;
|
|
221
|
+
/** Fired when a day is hovered */
|
|
222
|
+
onDayHover?: (date: Dayjs | null) => void;
|
|
223
|
+
/** Fired when the picker opens */
|
|
224
|
+
onOpen?: () => void;
|
|
225
|
+
/** Fired when the picker closes */
|
|
226
|
+
onClose?: () => void;
|
|
227
|
+
/** Fired when the picker is cleared */
|
|
228
|
+
onClear?: () => void;
|
|
229
|
+
}
|
|
230
|
+
export interface DisabledConfig {
|
|
231
|
+
/** Disable all dates before this date */
|
|
232
|
+
before?: Dayjs;
|
|
233
|
+
/** Disable all dates after this date */
|
|
234
|
+
after?: Dayjs;
|
|
235
|
+
/** Disable specific dates */
|
|
236
|
+
dates?: Dayjs[];
|
|
237
|
+
/** Custom predicate — return true to disable */
|
|
238
|
+
predicate?: (date: Dayjs) => boolean;
|
|
239
|
+
}
|
|
240
|
+
export interface DatePickerProps extends DatePickerEvents {
|
|
241
|
+
/** Selection mode */
|
|
242
|
+
mode?: PickerMode;
|
|
243
|
+
value?: DateValue;
|
|
244
|
+
defaultValue?: DateValue;
|
|
245
|
+
rangeValue?: DateRange;
|
|
246
|
+
defaultRangeValue?: DateRange;
|
|
247
|
+
/** Display format passed to dayjs .format() */
|
|
248
|
+
format?: string;
|
|
249
|
+
/** Locale string for dayjs (e.g. 'fr', 'ar') */
|
|
250
|
+
locale?: string;
|
|
251
|
+
/** Language alias for locale (e.g. 'fr', 'ar') */
|
|
252
|
+
lang?: string;
|
|
253
|
+
/** First day of the week: 0 = Sunday … 6 = Saturday */
|
|
254
|
+
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
255
|
+
/** Enable the time picker panel */
|
|
256
|
+
enableTime?: boolean;
|
|
257
|
+
/** Time slot interval in minutes (e.g. 5, 15, 30) */
|
|
258
|
+
timeStep?: number;
|
|
259
|
+
/** Time display format for slots, default HH:mm */
|
|
260
|
+
timeFormat?: string;
|
|
261
|
+
/** Earliest selectable time in HH:mm */
|
|
262
|
+
minTime?: string;
|
|
263
|
+
/** Latest selectable time in HH:mm */
|
|
264
|
+
maxTime?: string;
|
|
265
|
+
/** Disable specific time slots by weekday/date/predicate */
|
|
266
|
+
disabledTime?: DisabledTimeConfig;
|
|
267
|
+
/**
|
|
268
|
+
* Per-date time schedules — key is `YYYY-MM-DD`.
|
|
269
|
+
* When the selected date has an entry, its schedule overrides
|
|
270
|
+
* `timeStep` / `minTime` / `maxTime`.
|
|
271
|
+
*
|
|
272
|
+
* Example:
|
|
273
|
+
* ```ts
|
|
274
|
+
* timeSchedule={{
|
|
275
|
+
* '2026-06-15': { unavailable: true },
|
|
276
|
+
* '2026-06-16': {
|
|
277
|
+
* ranges: [
|
|
278
|
+
* { from: '08:00', to: '12:00', step: 15 },
|
|
279
|
+
* { from: '14:00', to: '16:00', step: 5 },
|
|
280
|
+
* { from: '16:00', to: '18:00', step: 10 },
|
|
281
|
+
* ],
|
|
282
|
+
* },
|
|
283
|
+
* }}
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
timeSchedule?: Record<string, DateSchedule>;
|
|
287
|
+
/**
|
|
288
|
+
* Default schedule applied to all dates not listed in `timeSchedule`.
|
|
289
|
+
* When provided, overrides `timeStep` / `minTime` / `maxTime`.
|
|
290
|
+
*/
|
|
291
|
+
defaultTimeSchedule?: DateSchedule;
|
|
292
|
+
/** Earliest selectable date */
|
|
293
|
+
minDate?: Dayjs;
|
|
294
|
+
/** Latest selectable date */
|
|
295
|
+
maxDate?: Dayjs;
|
|
296
|
+
/** Placeholder for single input or [start, end] for range */
|
|
297
|
+
placeholder?: string | [string, string];
|
|
298
|
+
/** Disable specific dates / ranges */
|
|
299
|
+
disabled?: DisabledConfig | boolean;
|
|
300
|
+
/** Whether the picker is disabled entirely */
|
|
301
|
+
isDisabled?: boolean;
|
|
302
|
+
/** Whether the picker is read-only */
|
|
303
|
+
readOnly?: boolean;
|
|
304
|
+
/** Show a clear button */
|
|
305
|
+
clearable?: boolean;
|
|
306
|
+
/** Show today's date highlight */
|
|
307
|
+
highlightToday?: boolean;
|
|
308
|
+
/** Show day numbers from previous/next months inside the current month grid */
|
|
309
|
+
showAdjacentMonthDays?: boolean;
|
|
310
|
+
/** @deprecated Use showAdjacentMonthDays instead */
|
|
311
|
+
showOutsideDays?: boolean;
|
|
312
|
+
/** Tooltip content for day cells */
|
|
313
|
+
tooltip?: TooltipContent;
|
|
314
|
+
/** Tooltip delay in ms */
|
|
315
|
+
tooltipDelay?: number;
|
|
316
|
+
/** CSS custom-property theme overrides */
|
|
317
|
+
theme?: DatePickerTheme;
|
|
318
|
+
/** Per-slot className overrides */
|
|
319
|
+
classNames?: DatePickerClassNames;
|
|
320
|
+
/** Per-slot inline style overrides */
|
|
321
|
+
styles?: DatePickerStyles;
|
|
322
|
+
/** Additional className on the root wrapper */
|
|
323
|
+
className?: string;
|
|
324
|
+
/** Additional style on the root wrapper */
|
|
325
|
+
style?: CSSProperties;
|
|
326
|
+
/** Number of months to show at once (range pickers often use 2) */
|
|
327
|
+
numberOfMonths?: number;
|
|
328
|
+
/** Show month/year dropdown selectors in header (default: true) */
|
|
329
|
+
showMonthYearSelectors?: boolean;
|
|
330
|
+
/** Render the calendar inline instead of using the trigger/popover UI */
|
|
331
|
+
inline?: boolean;
|
|
332
|
+
/**
|
|
333
|
+
* Preferred popover placement relative to the trigger.
|
|
334
|
+
* - `'bottom'` — always open below
|
|
335
|
+
* - `'top'` — always open above
|
|
336
|
+
* - `'auto'` — (default) open below when there is enough room, otherwise
|
|
337
|
+
* flip to above automatically; re-evaluates on window resize
|
|
338
|
+
*/
|
|
339
|
+
placement?: 'top' | 'bottom' | 'auto';
|
|
340
|
+
/** Render a custom day cell content */
|
|
341
|
+
renderDay?: (date: Dayjs, props: TooltipRenderProps) => ReactNode;
|
|
342
|
+
/** Render custom navigation buttons */
|
|
343
|
+
renderNavButton?: (direction: 'prev' | 'next', onClick: () => void) => ReactNode;
|
|
344
|
+
/** Custom input render */
|
|
345
|
+
renderInput?: (props: RenderInputProps) => ReactNode;
|
|
346
|
+
}
|
|
347
|
+
export interface RenderInputProps {
|
|
348
|
+
value: string;
|
|
349
|
+
onClick: () => void;
|
|
350
|
+
onClear: () => void;
|
|
351
|
+
isOpen: boolean;
|
|
352
|
+
placeholder: string;
|
|
353
|
+
isDisabled: boolean;
|
|
354
|
+
readOnly: boolean;
|
|
355
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from './date-picker.types';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Dayjs } from 'dayjs';
|
|
2
|
+
import { DateRange, DateSchedule, DisabledConfig, DisabledTimeConfig } from '../types';
|
|
3
|
+
export type { Dayjs };
|
|
4
|
+
/** Check if two Dayjs values represent the same calendar day */
|
|
5
|
+
export declare function isSameDay(a: Dayjs | null, b: Dayjs | null): boolean;
|
|
6
|
+
/** Check if `date` is strictly between `start` and `end` (exclusive) */
|
|
7
|
+
export declare function isBetween(date: Dayjs, start: Dayjs | null, end: Dayjs | null): boolean;
|
|
8
|
+
/** Check if `date` is the start of a range */
|
|
9
|
+
export declare function isRangeStart(date: Dayjs, range: DateRange): boolean;
|
|
10
|
+
/** Check if `date` is the end of a range */
|
|
11
|
+
export declare function isRangeEnd(date: Dayjs, range: DateRange): boolean;
|
|
12
|
+
/** Check if `date` falls within a completed range (inclusive) */
|
|
13
|
+
export declare function isInRange(date: Dayjs, range: DateRange): boolean;
|
|
14
|
+
/** Check if `date` is disabled per the DisabledConfig */
|
|
15
|
+
export declare function isDateDisabled(date: Dayjs, disabled?: DisabledConfig | boolean): boolean;
|
|
16
|
+
/** Generate all day cells for a calendar month view (including padding days) */
|
|
17
|
+
export declare function generateCalendarDays(year: number, month: number, weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6): Dayjs[];
|
|
18
|
+
/** Build ordered weekday labels starting from `weekStartsOn` */
|
|
19
|
+
export declare function getWeekdayLabels(weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6, locale?: string): string[];
|
|
20
|
+
/** Short month names for a given locale */
|
|
21
|
+
export declare function getMonthNames(locale?: string): string[];
|
|
22
|
+
/** Range of years around the current year */
|
|
23
|
+
export declare function getYearOptions(spread?: number): number[];
|
|
24
|
+
/** Generate time slots in HH:mm format between min and max using step minutes */
|
|
25
|
+
export declare function generateTimeSlots(stepMinutes?: number, minTime?: string, maxTime?: string): string[];
|
|
26
|
+
/**
|
|
27
|
+
* Generate time slots from a `DateSchedule`.
|
|
28
|
+
*
|
|
29
|
+
* - Returns `[]` when `schedule.unavailable` is `true`.
|
|
30
|
+
* - Concatenates slots from each `TimeRange` in `schedule.ranges`.
|
|
31
|
+
* Gaps between ranges produce no slots — just omit the time window.
|
|
32
|
+
* - Duplicate boundary values (e.g. `to:'12:00'` followed by `from:'12:00'`)
|
|
33
|
+
* are deduplicated while preserving order.
|
|
34
|
+
*/
|
|
35
|
+
export declare function generateSlotsForSchedule(schedule: DateSchedule): string[];
|
|
36
|
+
/** Check if a time slot should be disabled for a given date */
|
|
37
|
+
export declare function isTimeDisabled(date: Dayjs, time: string, disabledTime?: DisabledTimeConfig): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { isSameDay, isBetween, isRangeStart, isRangeEnd, isInRange, isDateDisabled, generateCalendarDays, getWeekdayLabels, getMonthNames, getYearOptions, generateTimeSlots, generateSlotsForSchedule, isTimeDisabled, } from './date-utils';
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
import { Dayjs } from 'dayjs';
|
|
3
|
+
import { DateSchedule, DisabledTimeConfig } from '../../../date-picker/types';
|
|
4
|
+
export interface TimePickerProps {
|
|
5
|
+
/** Controlled value in `HH:mm` (24-hour) format */
|
|
6
|
+
value?: string;
|
|
7
|
+
/** Initial value when uncontrolled */
|
|
8
|
+
defaultValue?: string;
|
|
9
|
+
/** Called with the selected `HH:mm` string, or `''` after clear */
|
|
10
|
+
onChange?: (time: string) => void;
|
|
11
|
+
/** Uniform interval in minutes (default 15). Ignored when `schedule` is set. */
|
|
12
|
+
timeStep?: number;
|
|
13
|
+
/** Earliest slot in `HH:mm` (default `'00:00'`). Ignored when `schedule` is set. */
|
|
14
|
+
minTime?: string;
|
|
15
|
+
/** Latest slot in `HH:mm` (default `'23:59'`). Ignored when `schedule` is set. */
|
|
16
|
+
maxTime?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Schedule-based slot generation. Each range has its own step interval.
|
|
19
|
+
* Gaps between ranges produce no slots.
|
|
20
|
+
* Overrides `timeStep` / `minTime` / `maxTime` when provided.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* schedule={{
|
|
24
|
+
* ranges: [
|
|
25
|
+
* { from: '08:00', to: '12:00', step: 15 },
|
|
26
|
+
* { from: '14:00', to: '17:00', step: 30 },
|
|
27
|
+
* ],
|
|
28
|
+
* }}
|
|
29
|
+
*/
|
|
30
|
+
schedule?: DateSchedule;
|
|
31
|
+
/** dayjs format string for slot labels and input display (default `'HH:mm'`) */
|
|
32
|
+
timeFormat?: string;
|
|
33
|
+
/** Placeholder shown in the input when no time is selected */
|
|
34
|
+
placeholder?: string;
|
|
35
|
+
/** dayjs locale string (e.g. `'fr'`, `'ar'`) */
|
|
36
|
+
locale?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Reference date used by `disabledTime` predicates.
|
|
39
|
+
* Defaults to today when omitted.
|
|
40
|
+
*/
|
|
41
|
+
date?: Dayjs;
|
|
42
|
+
/** Disable specific slots by weekday / date / predicate */
|
|
43
|
+
disabledTime?: DisabledTimeConfig;
|
|
44
|
+
/**
|
|
45
|
+
* Render the slot list directly inside the element (no input trigger,
|
|
46
|
+
* no popover). Useful when embedding in a custom layout.
|
|
47
|
+
*/
|
|
48
|
+
inline?: boolean;
|
|
49
|
+
/** Disable all interaction */
|
|
50
|
+
isDisabled?: boolean;
|
|
51
|
+
/** Prevent selection while still showing the picker */
|
|
52
|
+
readOnly?: boolean;
|
|
53
|
+
/** Show a clear (×) button when a time is selected */
|
|
54
|
+
clearable?: boolean;
|
|
55
|
+
onOpen?: () => void;
|
|
56
|
+
onClose?: () => void;
|
|
57
|
+
onClear?: () => void;
|
|
58
|
+
className?: string;
|
|
59
|
+
style?: CSSProperties;
|
|
60
|
+
}
|
|
61
|
+
export declare function TimePicker({ value, defaultValue, onChange, timeStep, minTime, maxTime, schedule, timeFormat, placeholder, locale, date, disabledTime, inline, isDisabled, readOnly, clearable, onOpen, onClose, onClear, className, style, }: TimePickerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { StoryObj } from '@storybook/react';
|
|
2
|
+
import { TimePicker } from './time-picker';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof TimePicker;
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: string;
|
|
8
|
+
};
|
|
9
|
+
argTypes: {
|
|
10
|
+
value: {
|
|
11
|
+
control: false;
|
|
12
|
+
description: string;
|
|
13
|
+
};
|
|
14
|
+
defaultValue: {
|
|
15
|
+
control: false;
|
|
16
|
+
description: string;
|
|
17
|
+
};
|
|
18
|
+
timeStep: {
|
|
19
|
+
control: {
|
|
20
|
+
type: "number";
|
|
21
|
+
min: number;
|
|
22
|
+
max: number;
|
|
23
|
+
step: number;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
minTime: {
|
|
27
|
+
control: "text";
|
|
28
|
+
};
|
|
29
|
+
maxTime: {
|
|
30
|
+
control: "text";
|
|
31
|
+
};
|
|
32
|
+
timeFormat: {
|
|
33
|
+
control: "text";
|
|
34
|
+
};
|
|
35
|
+
inline: {
|
|
36
|
+
control: "boolean";
|
|
37
|
+
};
|
|
38
|
+
isDisabled: {
|
|
39
|
+
control: "boolean";
|
|
40
|
+
};
|
|
41
|
+
readOnly: {
|
|
42
|
+
control: "boolean";
|
|
43
|
+
};
|
|
44
|
+
clearable: {
|
|
45
|
+
control: "boolean";
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
tags: string[];
|
|
49
|
+
};
|
|
50
|
+
export default meta;
|
|
51
|
+
type Story = StoryObj<typeof meta>;
|
|
52
|
+
export declare const Default: Story;
|
|
53
|
+
export declare const Controlled: Story;
|
|
54
|
+
export declare const Inline: Story;
|
|
55
|
+
export declare const WithSchedule: Story;
|
|
56
|
+
export declare const InlineWithSchedule: Story;
|
|
57
|
+
export declare const DisabledSlots: Story;
|
|
58
|
+
export declare const Disabled: Story;
|
|
59
|
+
export declare const ReadOnly: Story;
|
|
60
|
+
export declare const NoClear: Story;
|
|
61
|
+
export declare const CustomFormat: Story;
|
|
62
|
+
export declare const CustomPlaceholder: Story;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Dayjs } from 'dayjs';
|
|
2
|
+
import { DatePickerClassNames, DatePickerStyles, DisabledTimeConfig } from '../../../date-picker/types';
|
|
3
|
+
export interface TimeSlotListProps {
|
|
4
|
+
timeSlots: string[];
|
|
5
|
+
selectedTime: string;
|
|
6
|
+
onSelectTime: (slot: string) => void;
|
|
7
|
+
timeFormat: string;
|
|
8
|
+
locale?: string;
|
|
9
|
+
targetDate: Dayjs;
|
|
10
|
+
disabledTime?: DisabledTimeConfig;
|
|
11
|
+
isDisabled: boolean;
|
|
12
|
+
readOnly: boolean;
|
|
13
|
+
classNames?: Partial<DatePickerClassNames>;
|
|
14
|
+
styles?: Partial<DatePickerStyles>;
|
|
15
|
+
}
|
|
16
|
+
export declare function TimeSlotList({ timeSlots, selectedTime, onSelectTime, timeFormat, locale, targetDate, disabledTime, isDisabled, readOnly, classNames, styles, }: TimeSlotListProps): import("react").JSX.Element;
|
package/dist/index.d.ts
ADDED
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daxence/flexy-date-picker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A fully customizable React date picker with single & range selection, injectable CSS theming, tooltips, and full event support.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/flexy-date-picker.umd.cjs",
|
|
7
7
|
"module": "./dist/flexy-date-picker.js",
|
|
8
|
-
"types": "./dist/
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
11
|
"import": "./dist/flexy-date-picker.js",
|
|
12
12
|
"require": "./dist/flexy-date-picker.umd.cjs",
|
|
13
|
-
"types": "./dist/
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
14
|
},
|
|
15
|
-
"./styles":
|
|
15
|
+
"./styles": {
|
|
16
|
+
"types": "./dist/styles.d.ts",
|
|
17
|
+
"default": "./dist/style.css"
|
|
18
|
+
}
|
|
16
19
|
},
|
|
17
20
|
"files": [
|
|
18
21
|
"dist"
|
package/dist/types/index.d.ts
DELETED