laif-ds 0.2.69 → 0.2.71
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/agent-docs/components/AppForm.md +4 -1
- package/dist/agent-docs/components/AppTimePicker.md +304 -0
- package/dist/agent-docs/components/DatePicker.md +178 -43
- package/dist/agent-docs/components-list.md +2 -1
- package/dist/components/ui/app-kanban.js +155 -112
- package/dist/components/ui/app-time-picker.js +244 -0
- package/dist/components/ui/date-picker.js +221 -125
- package/dist/components/ui/kanban.js +414 -285
- package/dist/components/ui/textarea.js +21 -20
- package/dist/index.d.ts +89 -0
- package/dist/index.js +41 -39
- package/dist/styles.v3.css +1 -1
- package/package.json +1 -1
|
@@ -212,6 +212,8 @@ Date picker component with optional range selection via `calendarRange`. Use `da
|
|
|
212
212
|
- `firstDate`: First available date (disables dates before)
|
|
213
213
|
- `lastDate`: Last available date (disables dates after)
|
|
214
214
|
- `availableDates`: Array of specific dates that are selectable
|
|
215
|
+
- `showTime`: Show time picker columns (HH, MM)
|
|
216
|
+
- `withSeconds`: Show seconds column in the time picker (requires `showTime`)
|
|
215
217
|
- And other DatePicker props
|
|
216
218
|
|
|
217
219
|
**Example with English locale:**
|
|
@@ -227,7 +229,8 @@ const items: AppFormItem[] = [
|
|
|
227
229
|
placeholder: "Pick a date",
|
|
228
230
|
datePickerProps: {
|
|
229
231
|
locale: enUS,
|
|
230
|
-
dateFormat: "MM/dd/yyyy",
|
|
232
|
+
dateFormat: "MM/dd/yyyy HH:mm",
|
|
233
|
+
showTime: true,
|
|
231
234
|
},
|
|
232
235
|
},
|
|
233
236
|
{
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# AppTimePicker
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Standalone time picker component for selecting hours, minutes, and optionally seconds. Displays a trigger with a clock icon and opens a popover with scrollable columns for each time unit. Supports controlled/uncontrolled usage, UTC mode, clearable selection, min/max time constraints, multiple sizes, and visual variants.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| ---------------- | ----------------------------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------ |
|
|
13
|
+
| `value` | `Date` | `undefined` | Controlled selected time as a Date object. |
|
|
14
|
+
| `onChange` | `(date: Date \| undefined) => void` | `undefined` | Callback fired when the selected time changes. |
|
|
15
|
+
| `onClear` | `() => void` | `undefined` | Callback fired when the value is cleared. |
|
|
16
|
+
| `label` | `string \| React.ReactNode` | `undefined` | Label displayed above the trigger. |
|
|
17
|
+
| `placeholder` | `string` | `"Seleziona orario"` | Placeholder text shown when no time is selected. |
|
|
18
|
+
| `disabled` | `boolean` | `false` | Disables the time picker. |
|
|
19
|
+
| `clearable` | `boolean` | `false` | Show a clear (X) button in the trigger to reset the selection. |
|
|
20
|
+
| `className` | `string` | `""` | Additional CSS classes applied to the trigger element. |
|
|
21
|
+
| `labelClassName` | `string` | `""` | CSS classes for the label element. |
|
|
22
|
+
| `wrpClassName` | `string` | `""` | CSS classes for the outer wrapper `<div>`. |
|
|
23
|
+
| `size` | `"sm" \| "default" \| "lg"` | `"default"` | Size variant of the trigger. |
|
|
24
|
+
| `variant` | `"default" \| "destructive" \| "outline" \| "secondary" \| "ghost" \| "link"` | `"default"` | Visual variant of the trigger. |
|
|
25
|
+
| `useUtc` | `boolean` | `false` | Use UTC time instead of local time. Shows a "UTC" badge. |
|
|
26
|
+
| `withSeconds` | `boolean` | `false` | Show a seconds column in the time picker. |
|
|
27
|
+
| `minTime` | `Date` | `undefined` | Minimum selectable time. Hours/minutes/seconds before this are disabled. |
|
|
28
|
+
| `maxTime` | `Date` | `undefined` | Maximum selectable time. Hours/minutes/seconds after this are disabled. |
|
|
29
|
+
| `id` | `string` | `undefined` | HTML `id` for the trigger element. |
|
|
30
|
+
| `data-testid` | `string` | `undefined` | `data-testid` attribute for E2E testing (e.g. Playwright). |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Behavior
|
|
35
|
+
|
|
36
|
+
### Time Selection
|
|
37
|
+
|
|
38
|
+
- **Columns**: The popover displays scrollable columns for hours (00–23) and minutes (00–59). An optional seconds column (00–59) is shown when `withSeconds` is `true`.
|
|
39
|
+
- **Scroll-to-selected**: When the popover opens, the selected value is automatically scrolled into view.
|
|
40
|
+
- **Display format**: The trigger shows time in `HH:MM` format (or `HH:MM:SS` with `withSeconds`).
|
|
41
|
+
|
|
42
|
+
### Controlled vs Uncontrolled
|
|
43
|
+
|
|
44
|
+
- **Controlled**: Pass `value` and `onChange` to manage state externally. The component detects controlled mode by checking if the `value` prop is provided (even if `undefined`).
|
|
45
|
+
- **Uncontrolled**: Omit the `value` prop entirely. The component manages its own internal state.
|
|
46
|
+
|
|
47
|
+
### Clearable
|
|
48
|
+
|
|
49
|
+
- **Trigger clear button**: When `clearable` is `true` and a value is selected, an X button appears in the trigger.
|
|
50
|
+
- **Popover clear button**: A "Clear" button always appears at the bottom of the popover when a value is selected.
|
|
51
|
+
- **Callbacks**: Both `onChange(undefined)` and `onClear()` are called when clearing.
|
|
52
|
+
|
|
53
|
+
### Min/Max Time Constraints
|
|
54
|
+
|
|
55
|
+
- **Disabled options**: When `minTime` or `maxTime` is set, out-of-range hours are visually disabled and not selectable.
|
|
56
|
+
- **Cascading constraints**: Minutes are constrained only when the selected hour matches the boundary hour. Seconds are constrained only when both hour and minute match.
|
|
57
|
+
- **UTC-aware**: Constraints respect the `useUtc` setting.
|
|
58
|
+
|
|
59
|
+
### UTC Mode
|
|
60
|
+
|
|
61
|
+
- When `useUtc` is `true`, all time reading/writing uses UTC methods (`getUTCHours`, `setUTCHours`, etc.).
|
|
62
|
+
- A small "UTC" badge is displayed in the trigger.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Exported Types
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
type AppTimePickerSize = "sm" | "default" | "lg";
|
|
70
|
+
|
|
71
|
+
type AppTimePickerVariant =
|
|
72
|
+
| "default"
|
|
73
|
+
| "destructive"
|
|
74
|
+
| "outline"
|
|
75
|
+
| "secondary"
|
|
76
|
+
| "ghost"
|
|
77
|
+
| "link";
|
|
78
|
+
|
|
79
|
+
interface AppTimePickerProps {
|
|
80
|
+
/* see Props table above */
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Examples
|
|
87
|
+
|
|
88
|
+
### Basic
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import { AppTimePicker } from "laif-ds";
|
|
92
|
+
import { useState } from "react";
|
|
93
|
+
|
|
94
|
+
export function BasicTimePicker() {
|
|
95
|
+
const [time, setTime] = useState<Date | undefined>();
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<AppTimePicker
|
|
99
|
+
value={time}
|
|
100
|
+
onChange={setTime}
|
|
101
|
+
label="Select Time"
|
|
102
|
+
placeholder="Pick a time"
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### With Seconds
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
import { AppTimePicker } from "laif-ds";
|
|
112
|
+
import { useState } from "react";
|
|
113
|
+
|
|
114
|
+
export function TimePickerWithSeconds() {
|
|
115
|
+
const [time, setTime] = useState<Date | undefined>();
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<AppTimePicker
|
|
119
|
+
value={time}
|
|
120
|
+
onChange={setTime}
|
|
121
|
+
withSeconds
|
|
122
|
+
label="Time with Seconds"
|
|
123
|
+
/>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Clearable
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
import { AppTimePicker } from "laif-ds";
|
|
132
|
+
import { useState } from "react";
|
|
133
|
+
|
|
134
|
+
export function ClearableTimePicker() {
|
|
135
|
+
const [time, setTime] = useState<Date | undefined>(new Date());
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<AppTimePicker
|
|
139
|
+
value={time}
|
|
140
|
+
onChange={setTime}
|
|
141
|
+
clearable
|
|
142
|
+
label="Clearable Picker"
|
|
143
|
+
/>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### UTC Mode
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { AppTimePicker } from "laif-ds";
|
|
152
|
+
import { useState } from "react";
|
|
153
|
+
|
|
154
|
+
export function UtcTimePicker() {
|
|
155
|
+
const [time, setTime] = useState<Date | undefined>(new Date());
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<AppTimePicker
|
|
159
|
+
value={time}
|
|
160
|
+
onChange={setTime}
|
|
161
|
+
useUtc
|
|
162
|
+
label="UTC Time Picker"
|
|
163
|
+
/>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Min/Max Time Constraints
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
import { AppTimePicker } from "laif-ds";
|
|
172
|
+
import { useState } from "react";
|
|
173
|
+
|
|
174
|
+
export function BusinessHoursTimePicker() {
|
|
175
|
+
const [time, setTime] = useState<Date | undefined>();
|
|
176
|
+
|
|
177
|
+
const minTime = new Date();
|
|
178
|
+
minTime.setHours(9, 0, 0, 0);
|
|
179
|
+
|
|
180
|
+
const maxTime = new Date();
|
|
181
|
+
maxTime.setHours(17, 30, 0, 0);
|
|
182
|
+
|
|
183
|
+
return (
|
|
184
|
+
<AppTimePicker
|
|
185
|
+
value={time}
|
|
186
|
+
onChange={setTime}
|
|
187
|
+
minTime={minTime}
|
|
188
|
+
maxTime={maxTime}
|
|
189
|
+
label="Business Hours Only"
|
|
190
|
+
/>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Sizes and Variants
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
import { AppTimePicker } from "laif-ds";
|
|
199
|
+
|
|
200
|
+
export function TimePickerVariants() {
|
|
201
|
+
return (
|
|
202
|
+
<div className="flex flex-col gap-4">
|
|
203
|
+
<AppTimePicker size="sm" label="Small" />
|
|
204
|
+
<AppTimePicker size="default" label="Default" />
|
|
205
|
+
<AppTimePicker size="lg" label="Large" />
|
|
206
|
+
<AppTimePicker variant="outline" label="Outline Variant" />
|
|
207
|
+
<AppTimePicker variant="ghost" label="Ghost Variant" />
|
|
208
|
+
</div>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Disabled
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
import { AppTimePicker } from "laif-ds";
|
|
217
|
+
|
|
218
|
+
export function DisabledTimePicker() {
|
|
219
|
+
return <AppTimePicker value={new Date()} disabled label="Disabled Picker" />;
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### In Dialog
|
|
224
|
+
|
|
225
|
+
```tsx
|
|
226
|
+
import { AppTimePicker } from "laif-ds";
|
|
227
|
+
import { AppDialog } from "laif-ds";
|
|
228
|
+
import { Button } from "laif-ds";
|
|
229
|
+
import { useState } from "react";
|
|
230
|
+
|
|
231
|
+
export function TimePickerInDialog() {
|
|
232
|
+
const [time, setTime] = useState<Date | undefined>();
|
|
233
|
+
const [open, setOpen] = useState(false);
|
|
234
|
+
|
|
235
|
+
return (
|
|
236
|
+
<AppDialog
|
|
237
|
+
open={open}
|
|
238
|
+
onOpenChange={setOpen}
|
|
239
|
+
title="Seleziona Orario"
|
|
240
|
+
description="Scegli l'orario per la tua prenotazione."
|
|
241
|
+
trigger={<Button>Apri Time Picker Dialog</Button>}
|
|
242
|
+
footer={
|
|
243
|
+
<>
|
|
244
|
+
<Button variant="outline" onClick={() => setOpen(false)}>
|
|
245
|
+
Annulla
|
|
246
|
+
</Button>
|
|
247
|
+
<Button onClick={() => setOpen(false)}>Conferma</Button>
|
|
248
|
+
</>
|
|
249
|
+
}
|
|
250
|
+
asChild
|
|
251
|
+
>
|
|
252
|
+
<div className="space-y-4">
|
|
253
|
+
<AppTimePicker
|
|
254
|
+
value={time}
|
|
255
|
+
onChange={setTime}
|
|
256
|
+
label="Orario di inizio"
|
|
257
|
+
placeholder="Seleziona un'orario"
|
|
258
|
+
clearable
|
|
259
|
+
/>
|
|
260
|
+
{time && (
|
|
261
|
+
<div className="bg-d-muted/50 flex items-center gap-2 rounded border p-3 text-sm">
|
|
262
|
+
<span className="text-d-muted-foreground">Orario selezionato:</span>
|
|
263
|
+
<span className="font-medium tabular-nums">
|
|
264
|
+
{time.toLocaleTimeString("it-IT", {
|
|
265
|
+
hour: "2-digit",
|
|
266
|
+
minute: "2-digit",
|
|
267
|
+
})}
|
|
268
|
+
</span>
|
|
269
|
+
</div>
|
|
270
|
+
)}
|
|
271
|
+
</div>
|
|
272
|
+
</AppDialog>
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Helper Component: TimePickerColumn
|
|
280
|
+
|
|
281
|
+
The `TimePickerColumn` component is exported and can be used independently (e.g., inside the `DatePicker` component for datetime selection).
|
|
282
|
+
|
|
283
|
+
### TimePickerColumn Props
|
|
284
|
+
|
|
285
|
+
| Prop | Type | Default | Description |
|
|
286
|
+
| ---------------- | -------------------------------- | ----------- | ------------------------------------------------------- |
|
|
287
|
+
| `options` | `number[]` | — | Array of numeric options to display. |
|
|
288
|
+
| `value` | `number \| undefined` | `undefined` | Currently selected value. |
|
|
289
|
+
| `onChange` | `(value: number) => void` | — | Callback fired when an option is selected. |
|
|
290
|
+
| `type` | `"hour" \| "minute" \| "second"` | — | Column type — determines the header label (HH, MM, SS). |
|
|
291
|
+
| `className` | `string` | `""` | Additional CSS classes for the column wrapper. |
|
|
292
|
+
| `disabledValues` | `Set<number>` | `undefined` | Set of values that should be disabled (not selectable). |
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Notes
|
|
297
|
+
|
|
298
|
+
- **Sizing**: Use `size` to control the trigger height (sm: h-8, default: h-9, lg: h-10).
|
|
299
|
+
- **Variants**: Use `variant` to change the trigger's visual style (background, border, text color).
|
|
300
|
+
- **UTC badge**: When `useUtc` is `true`, a small "UTC" label appears in the trigger for clarity.
|
|
301
|
+
- **Controlled detection**: The component uses `props.hasOwnProperty("value")` to detect controlled mode, so passing `value={undefined}` keeps it controlled.
|
|
302
|
+
- **Performance**: Option arrays (0–23 for hours, 0–59 for minutes/seconds) are memoized to avoid re-creation on every render.
|
|
303
|
+
- **Accessibility**: The trigger has proper ARIA attributes. Disabled options in the columns are not focusable.
|
|
304
|
+
- **Integration with DatePicker**: The `TimePickerColumn` sub-component is reused by `DatePicker` when `showTime` is enabled.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
Date picker component that supports both **single date** and **date range** selection. Composed of a trigger with calendar icon and a `Calendar` component in a popover. Supports min/max date constraints, allowed dates, custom display format, sizes, localization, and initial calendar month.
|
|
5
|
+
Date picker component that supports both **single date** and **date range** selection, with optional **time picker** columns. Composed of a trigger with calendar icon and a `Calendar` component in a popover. Supports min/max date constraints, allowed dates, custom display format, sizes, localization, clearable selection, and initial calendar month.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -10,34 +10,45 @@ Date picker component that supports both **single date** and **date range** sele
|
|
|
10
10
|
|
|
11
11
|
### Common Props
|
|
12
12
|
|
|
13
|
-
| Prop | Type | Default | Description
|
|
14
|
-
| ---------------------- | --------------------------------------- | ------------------ |
|
|
15
|
-
| `mode` | `"single" \| "range"` | `"single"` | Selection mode: single date or date range.
|
|
16
|
-
| `placeholder` | `string` | `"Seleziona data"` | Text when no date is selected.
|
|
17
|
-
| `dateFormat` | `string` | `"dd/MM/yyyy"` | `date-fns` format string for the trigger text.
|
|
18
|
-
| `className` | `string` | `""` | Additional classes for the trigger.
|
|
19
|
-
| `wrpClassName` | `string` | `""` | Additional classes for the wrapper
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
| `
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| ---------------------- | --------------------------------------- | ------------------ | ---------------------------------------------------------------------------- |
|
|
15
|
+
| `mode` | `"single" \| "range"` | `"single"` | Selection mode: single date or date range. |
|
|
16
|
+
| `placeholder` | `string` | `"Seleziona data"` | Text when no date is selected. |
|
|
17
|
+
| `dateFormat` | `string` | `"dd/MM/yyyy"` | `date-fns` format string for the trigger text. Auto-adjusts with `showTime`. |
|
|
18
|
+
| `className` | `string` | `""` | Additional classes for the trigger element. |
|
|
19
|
+
| `wrpClassName` | `string` | `""` | Additional classes for the outer wrapper `<div>`. |
|
|
20
|
+
| `labelClassName` | `string` | `""` | Additional classes for the label element. |
|
|
21
|
+
| `label` | `string \| React.ReactNode` | `undefined` | Label displayed above the date picker. |
|
|
22
|
+
| `disabled` | `boolean` | `false` | Disables interactions and the popover. |
|
|
23
|
+
| `size` | `"sm" \| "default" \| "lg"` | `"default"` | Trigger size affecting height and icon size. |
|
|
24
|
+
| `clearable` | `boolean` | `false` | Show a clear (X) button to reset the selection. |
|
|
25
|
+
| `onClear` | `() => void` | `undefined` | Callback fired when the value is cleared via the clear button. |
|
|
26
|
+
| `minDate` | `Date` | `undefined` | Minimum selectable date. Dates before this are disabled. |
|
|
27
|
+
| `maxDate` | `Date` | `undefined` | Maximum selectable date. Dates after this are disabled. |
|
|
28
|
+
| `availableDates` | `Date[]` | `undefined` | Only these dates are selectable; all others are disabled. |
|
|
29
|
+
| `locale` | `Partial<Locale>` | `it` (Italian) | Locale for date formatting (from date-fns). |
|
|
30
|
+
| `initialCalendarMonth` | `Date` | `undefined` | Initial month to display in calendar (overridden by value). |
|
|
31
|
+
| `numberOfMonths` | `number` | `1` | Number of months to display side-by-side (useful for range mode). |
|
|
32
|
+
| `customCalendarProps` | `React.ComponentProps<typeof Calendar>` | `undefined` | Custom props forwarded to the underlying Calendar component. |
|
|
33
|
+
| `id` | `string` | auto-generated | HTML id attribute for the trigger element. |
|
|
34
|
+
| `data-testid` | `string` | `undefined` | Test identifier attribute for E2E testing (e.g. Playwright). |
|
|
35
|
+
|
|
36
|
+
#### Deprecated Common Props
|
|
37
|
+
|
|
38
|
+
| Prop | Type | Replacement | Description |
|
|
39
|
+
| --------------- | -------- | ----------- | ---------------------------------------------------------- |
|
|
40
|
+
| `firstDate` | `Date` | `minDate` | ⚠️ Deprecated. Use `minDate` instead. |
|
|
41
|
+
| `lastDate` | `Date` | `maxDate` | ⚠️ Deprecated. Use `maxDate` instead. |
|
|
42
|
+
| `buttonVariant` | `string` | `className` | ⚠️ Deprecated. This prop is unused. Style via `className`. |
|
|
34
43
|
|
|
35
44
|
### Single Mode Props (mode="single" or undefined)
|
|
36
45
|
|
|
37
|
-
| Prop
|
|
38
|
-
|
|
|
39
|
-
| `value`
|
|
40
|
-
| `onChange`
|
|
46
|
+
| Prop | Type | Default | Description |
|
|
47
|
+
| ------------- | ----------------------------------- | ----------- | ------------------------------------------------------------- |
|
|
48
|
+
| `value` | `Date` | `undefined` | Controlled selected date. |
|
|
49
|
+
| `onChange` | `(date: Date \| undefined) => void` | `undefined` | Called when the date changes. |
|
|
50
|
+
| `showTime` | `boolean` | `false` | Show time picker columns (HH, MM) alongside the calendar. |
|
|
51
|
+
| `withSeconds` | `boolean` | `false` | Show seconds column in the time picker (requires `showTime`). |
|
|
41
52
|
|
|
42
53
|
### Range Mode Props (mode="range")
|
|
43
54
|
|
|
@@ -61,9 +72,23 @@ Date picker component that supports both **single date** and **date range** sele
|
|
|
61
72
|
- **Display**: Shows "from - to" format in the trigger (e.g., "13/01/2025 - 20/01/2025").
|
|
62
73
|
- **Multiple months**: Use `numberOfMonths={2}` to show two months side by side for easier range selection.
|
|
63
74
|
|
|
75
|
+
### Time Picker (Single Mode Only)
|
|
76
|
+
|
|
77
|
+
- **Activation**: Set `showTime` to display hour and minute columns next to the calendar.
|
|
78
|
+
- **Seconds**: Set `withSeconds` alongside `showTime` to add a seconds column.
|
|
79
|
+
- **Auto-close**: When `showTime` is enabled, the popover stays open after selecting a date so the user can adjust the time. Without `showTime`, the popover closes on date selection.
|
|
80
|
+
- **Format auto-detection**: If no `dateFormat` is provided, the component automatically uses `"dd/MM/yyyy HH:mm"` (or `"dd/MM/yyyy HH:mm:ss"` with `withSeconds`).
|
|
81
|
+
- **Time preservation**: When changing the date, the previously selected time is preserved.
|
|
82
|
+
|
|
83
|
+
### Clearable
|
|
84
|
+
|
|
85
|
+
- **Clear button**: When `clearable` is `true` and a value is selected, an X button appears in the trigger.
|
|
86
|
+
- **Callback**: The `onClear` callback fires when the clear button is clicked.
|
|
87
|
+
- **Works in both modes**: Clearing resets the value to `undefined` in both single and range modes.
|
|
88
|
+
|
|
64
89
|
### Common Behavior
|
|
65
90
|
|
|
66
|
-
- **Disabled dates**: `
|
|
91
|
+
- **Disabled dates**: `minDate`, `maxDate`, and `availableDates` are combined into the `Calendar`'s `disabled` matcher array. Legacy `firstDate`/`lastDate` are also supported.
|
|
67
92
|
- **Disabled state**: When `disabled` is true, the popover will not open and the trigger is non-interactive with reduced opacity.
|
|
68
93
|
- **Formatting**: `dateFormat` is applied via `date-fns/format` to the selected date(s) in the trigger.
|
|
69
94
|
- **Calendar month**: The calendar displays the month of the selected date (or `from` date in range mode), or `initialCalendarMonth` if no date is selected.
|
|
@@ -180,19 +205,65 @@ export function RangeWithConstraints() {
|
|
|
180
205
|
}
|
|
181
206
|
```
|
|
182
207
|
|
|
183
|
-
###
|
|
208
|
+
### Clearable
|
|
184
209
|
|
|
185
210
|
```tsx
|
|
186
211
|
import { DatePicker } from "laif-ds";
|
|
212
|
+
import { useState } from "react";
|
|
213
|
+
|
|
214
|
+
export function ClearableDatePicker() {
|
|
215
|
+
const [date, setDate] = useState<Date | undefined>(new Date());
|
|
187
216
|
|
|
188
|
-
export function ConfigurableDatePicker() {
|
|
189
217
|
return (
|
|
190
218
|
<DatePicker
|
|
191
|
-
value={
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
219
|
+
value={date}
|
|
220
|
+
onChange={setDate}
|
|
221
|
+
placeholder="Seleziona data"
|
|
222
|
+
clearable
|
|
223
|
+
onClear={() => console.log("cleared!")}
|
|
224
|
+
label="Data cancellabile"
|
|
225
|
+
/>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### With Time Picker
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
import { DatePicker } from "laif-ds";
|
|
234
|
+
import { useState } from "react";
|
|
235
|
+
|
|
236
|
+
export function DateTimePicker() {
|
|
237
|
+
const [date, setDate] = useState<Date | undefined>();
|
|
238
|
+
|
|
239
|
+
return (
|
|
240
|
+
<DatePicker
|
|
241
|
+
value={date}
|
|
242
|
+
onChange={setDate}
|
|
243
|
+
showTime
|
|
244
|
+
label="Data e ora"
|
|
245
|
+
placeholder="Seleziona data e ora"
|
|
246
|
+
/>
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### With Time Picker and Seconds
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
import { DatePicker } from "laif-ds";
|
|
255
|
+
import { useState } from "react";
|
|
256
|
+
|
|
257
|
+
export function DateTimeWithSeconds() {
|
|
258
|
+
const [date, setDate] = useState<Date | undefined>(new Date());
|
|
259
|
+
|
|
260
|
+
return (
|
|
261
|
+
<DatePicker
|
|
262
|
+
value={date}
|
|
263
|
+
onChange={setDate}
|
|
264
|
+
showTime
|
|
265
|
+
withSeconds
|
|
266
|
+
label="Data e ora con secondi"
|
|
196
267
|
/>
|
|
197
268
|
);
|
|
198
269
|
}
|
|
@@ -202,14 +273,18 @@ export function ConfigurableDatePicker() {
|
|
|
202
273
|
|
|
203
274
|
```tsx
|
|
204
275
|
import { DatePicker } from "laif-ds";
|
|
276
|
+
import { useState } from "react";
|
|
205
277
|
|
|
206
278
|
export function WithMinMaxDates() {
|
|
279
|
+
const [date, setDate] = useState<Date | undefined>();
|
|
280
|
+
|
|
207
281
|
return (
|
|
208
282
|
<DatePicker
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
283
|
+
value={date}
|
|
284
|
+
onChange={setDate}
|
|
285
|
+
placeholder="Seleziona una data nel range"
|
|
286
|
+
minDate={new Date("2025-09-20")}
|
|
287
|
+
maxDate={new Date("2025-09-28")}
|
|
213
288
|
/>
|
|
214
289
|
);
|
|
215
290
|
}
|
|
@@ -219,17 +294,21 @@ export function WithMinMaxDates() {
|
|
|
219
294
|
|
|
220
295
|
```tsx
|
|
221
296
|
import { DatePicker } from "laif-ds";
|
|
297
|
+
import { useState } from "react";
|
|
222
298
|
|
|
223
299
|
export function WithAvailableDates() {
|
|
300
|
+
const [date, setDate] = useState<Date | undefined>();
|
|
301
|
+
|
|
224
302
|
return (
|
|
225
303
|
<DatePicker
|
|
304
|
+
value={date}
|
|
305
|
+
onChange={setDate}
|
|
226
306
|
placeholder="Scegli una delle date disponibili"
|
|
227
307
|
availableDates={[
|
|
228
308
|
new Date("2025-09-22"),
|
|
229
309
|
new Date("2025-09-25"),
|
|
230
310
|
new Date("2025-09-27"),
|
|
231
311
|
]}
|
|
232
|
-
buttonVariant="outline"
|
|
233
312
|
/>
|
|
234
313
|
);
|
|
235
314
|
}
|
|
@@ -335,17 +414,73 @@ export function DatePickerInDialog() {
|
|
|
335
414
|
}
|
|
336
415
|
```
|
|
337
416
|
|
|
417
|
+
### In Drawer
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
import { DatePicker } from "laif-ds";
|
|
421
|
+
import {
|
|
422
|
+
Drawer,
|
|
423
|
+
DrawerContent,
|
|
424
|
+
DrawerTrigger,
|
|
425
|
+
DrawerHeader,
|
|
426
|
+
DrawerTitle,
|
|
427
|
+
DrawerDescription,
|
|
428
|
+
DrawerFooter,
|
|
429
|
+
DrawerClose,
|
|
430
|
+
} from "laif-ds";
|
|
431
|
+
import { Button } from "laif-ds";
|
|
432
|
+
import { useState } from "react";
|
|
433
|
+
|
|
434
|
+
export function DatePickerInDrawer() {
|
|
435
|
+
const [date, setDate] = useState<Date | undefined>(new Date("2023-08-12"));
|
|
436
|
+
|
|
437
|
+
return (
|
|
438
|
+
<Drawer>
|
|
439
|
+
<DrawerTrigger asChild>
|
|
440
|
+
<Button variant="outline">Apri Drawer con DatePicker</Button>
|
|
441
|
+
</DrawerTrigger>
|
|
442
|
+
<DrawerContent>
|
|
443
|
+
<DrawerHeader>
|
|
444
|
+
<DrawerTitle>Seleziona una data</DrawerTitle>
|
|
445
|
+
<DrawerDescription>
|
|
446
|
+
Scegli una data dal calendario qui sotto.
|
|
447
|
+
</DrawerDescription>
|
|
448
|
+
</DrawerHeader>
|
|
449
|
+
<div className="px-4 py-4">
|
|
450
|
+
<DatePicker
|
|
451
|
+
placeholder="Seleziona una data"
|
|
452
|
+
value={date}
|
|
453
|
+
onChange={setDate}
|
|
454
|
+
/>
|
|
455
|
+
</div>
|
|
456
|
+
{date && (
|
|
457
|
+
<div className="text-d-secondary-foreground px-4 text-sm">
|
|
458
|
+
Data selezionata: {date.toLocaleDateString("it-IT")}
|
|
459
|
+
</div>
|
|
460
|
+
)}
|
|
461
|
+
<DrawerFooter>
|
|
462
|
+
<DrawerClose asChild>
|
|
463
|
+
<Button variant="outline">Chiudi</Button>
|
|
464
|
+
</DrawerClose>
|
|
465
|
+
</DrawerFooter>
|
|
466
|
+
</DrawerContent>
|
|
467
|
+
</Drawer>
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
338
472
|
---
|
|
339
473
|
|
|
340
474
|
## Notes
|
|
341
475
|
|
|
342
476
|
- **Sizing**: Use `size` to control the trigger height and icon size (sm: h-8, default: h-9, lg: h-10).
|
|
343
|
-
- **Popover width**: The popover content automatically sizes to fit the Calendar
|
|
477
|
+
- **Popover width**: The popover content automatically sizes to fit the Calendar (and time columns when `showTime` is enabled).
|
|
344
478
|
- **Internationalization**: Use `locale` prop for calendar localization and `dateFormat` for display formatting.
|
|
345
|
-
- **
|
|
346
|
-
- **Button variant**: The `buttonVariant` prop is deprecated and not used in the current implementation.
|
|
479
|
+
- **Deprecated props**: `firstDate`/`lastDate` → use `minDate`/`maxDate`. `buttonVariant` → use `className`.
|
|
347
480
|
- **Accessibility**: The trigger has proper ARIA attributes and keyboard navigation support.
|
|
348
481
|
- **State management**: Component maintains internal state but syncs with external `value` prop.
|
|
349
|
-
- **Range mode**: Use `mode="range"` for date range selection. The `value` and `onChange` types change accordingly.
|
|
482
|
+
- **Range mode**: Use `mode="range"` for date range selection. The `value` and `onChange` types change accordingly. `showTime` is not available in range mode.
|
|
350
483
|
- **Multiple months**: In range mode, use `numberOfMonths={2}` to display two months side by side for better UX.
|
|
351
484
|
- **DateRange type**: Import `DateRange` from `react-day-picker` when using range mode: `{ from?: Date, to?: Date }`.
|
|
485
|
+
- **Clearable**: Use `clearable` to allow users to reset the selection. Works in both single and range modes.
|
|
486
|
+
- **Label styling**: Use `labelClassName` to apply custom styles to the label element.
|
|
@@ -30,7 +30,8 @@ This document provides a complete mapping of all components available in the lai
|
|
|
30
30
|
- **AsyncSelect** - Select component with asynchronous data loading capabilities
|
|
31
31
|
- **AppSelect** - Enhanced select dropdown with search and multi-select capabilities
|
|
32
32
|
- **Checkbox** - Binary selection input for forms
|
|
33
|
-
- **
|
|
33
|
+
- **AppTimePicker** - Standalone time picker with hours, minutes, seconds columns, min/max constraints, UTC mode, and clearable selection
|
|
34
|
+
- **DatePicker** - Calendar-based date and datetime selection input with single/range modes, time picker, and clearable support
|
|
34
35
|
- **Form** - Form wrapper component with validation support
|
|
35
36
|
- **Input** - Text input field with multiple variants and features
|
|
36
37
|
- **InputOtp** - One-time password input component
|