@catalystsoftware/ui 1.0.4 → 1.0.5
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/data/tailwind.config.js +261 -3821
- package/dist/components/catalyst-ui/buttons/burger.tsx +207 -0
- package/dist/components/catalyst-ui/core/data-display/timeline.tsx +210 -0
- package/dist/components/catalyst-ui/core/feedback/alert.tsx +491 -0
- package/dist/components/catalyst-ui/core/feedback/spinner-1.tsx +65 -0
- package/dist/components/catalyst-ui/core/feedback/toast.tsx +1857 -0
- package/dist/components/catalyst-ui/core/navigation/menu.tsx +164 -0
- package/dist/components/catalyst-ui/forms/toggle-class.tsx +176 -0
- package/dist/components/catalyst-ui/hooks/use-copy-to-clipboard.tsx +419 -0
- package/dist/components/catalyst-ui/hooks/use-counter.tsx +13 -0
- package/dist/components/catalyst-ui/hooks/use-event-listener.tsx +23 -0
- package/dist/components/catalyst-ui/hooks/use-export-markdown.tsx +47 -0
- package/dist/components/catalyst-ui/hooks/use-focus.tsx +17 -0
- package/dist/components/catalyst-ui/hooks/use-interval.tsx +23 -0
- package/dist/components/catalyst-ui/hooks/use-is-client.tsx +16 -0
- package/dist/components/catalyst-ui/hooks/use-media-query.tsx +19 -0
- package/dist/components/catalyst-ui/hooks/use-mobile.tsx +19 -0
- package/dist/components/catalyst-ui/hooks/use-resize-observer.tsx +81 -0
- package/dist/components/catalyst-ui/hooks/use-timeout.tsx +21 -0
- package/dist/components/catalyst-ui/hooks/use-timer.tsx +209 -0
- package/dist/components/catalyst-ui/hooks/use-toggle.tsx +12 -0
- package/dist/components/catalyst-ui/media/image.tsx +13 -0
- package/dist/components/catalyst-ui/overlays/dual-sidebar.tsx +4142 -0
- package/dist/components/catalyst-ui/overlays/sidebar-original.tsx +726 -0
- package/dist/components/catalyst-ui/primitives/accordion.tsx +250 -0
- package/dist/components/catalyst-ui/primitives/alert-dialog.tsx +126 -0
- package/dist/components/catalyst-ui/primitives/aspect-ratio.tsx +9 -0
- package/dist/components/catalyst-ui/primitives/avatar.tsx +296 -0
- package/dist/components/catalyst-ui/primitives/badge.tsx +57 -0
- package/dist/components/catalyst-ui/primitives/breadcrumb.tsx +101 -0
- package/dist/components/catalyst-ui/primitives/button.tsx +265 -0
- package/dist/components/catalyst-ui/primitives/calendar-v4.tsx +208 -0
- package/dist/components/catalyst-ui/primitives/calendar.tsx +295 -0
- package/dist/components/catalyst-ui/primitives/card.tsx +618 -0
- package/dist/components/catalyst-ui/primitives/carousel.tsx +238 -0
- package/dist/components/catalyst-ui/primitives/chart.tsx +347 -0
- package/dist/components/catalyst-ui/primitives/checkbox.tsx +225 -0
- package/dist/components/catalyst-ui/primitives/collapsible.tsx +212 -0
- package/dist/components/catalyst-ui/primitives/command.tsx +393 -0
- package/dist/components/catalyst-ui/primitives/context-menu.tsx +236 -0
- package/dist/components/catalyst-ui/primitives/dialog.tsx +471 -0
- package/dist/components/catalyst-ui/primitives/drawer.tsx +761 -0
- package/dist/components/catalyst-ui/primitives/dropdown-menu.tsx +290 -0
- package/dist/components/catalyst-ui/primitives/empty.tsx +104 -0
- package/dist/components/catalyst-ui/primitives/field.tsx +244 -0
- package/dist/components/catalyst-ui/primitives/hover-card.tsx +124 -0
- package/dist/components/catalyst-ui/primitives/input-otp.tsx +76 -0
- package/dist/components/catalyst-ui/primitives/input.tsx +64 -0
- package/dist/components/catalyst-ui/primitives/item.tsx +196 -0
- package/dist/components/catalyst-ui/primitives/kbd.tsx +75 -0
- package/dist/components/catalyst-ui/primitives/label.tsx +24 -0
- package/dist/components/catalyst-ui/primitives/navigation-menu.tsx +150 -0
- package/dist/components/catalyst-ui/primitives/pagination.tsx +198 -0
- package/dist/components/catalyst-ui/primitives/popover.tsx +232 -0
- package/dist/components/catalyst-ui/primitives/progress.tsx +34 -0
- package/dist/components/catalyst-ui/primitives/radio-group.tsx +43 -0
- package/dist/components/catalyst-ui/primitives/resizable.tsx +56 -0
- package/dist/components/catalyst-ui/primitives/select.tsx +155 -0
- package/dist/components/catalyst-ui/primitives/separator.tsx +74 -0
- package/dist/components/catalyst-ui/primitives/sheet.tsx +126 -0
- package/dist/components/catalyst-ui/primitives/skeleton.tsx +15 -0
- package/dist/components/catalyst-ui/primitives/slider.tsx +27 -0
- package/dist/components/catalyst-ui/primitives/switch.tsx +187 -0
- package/dist/components/catalyst-ui/primitives/tabs.tsx +335 -0
- package/dist/components/catalyst-ui/primitives/textarea.tsx +24 -0
- package/dist/components/catalyst-ui/primitives/toggle-group.tsx +55 -0
- package/dist/components/catalyst-ui/primitives/toggle.tsx +42 -0
- package/dist/components/catalyst-ui/primitives/tooltip.tsx +116 -0
- package/dist/components/catalyst-ui/utils/basic-auth.tsx +40 -0
- package/dist/components/catalyst-ui/utils/context-storage.tsx +19 -0
- package/dist/components/catalyst-ui/utils/cors-middleware.tsx +71 -0
- package/dist/components/catalyst-ui/utils/deferred-content.tsx +595 -0
- package/dist/components/catalyst-ui/utils/honeypot-middleware.tsx +38 -0
- package/dist/components/catalyst-ui/utils/incId.tsx +75 -0
- package/dist/components/catalyst-ui/utils/jwk-auth.tsx +36 -0
- package/dist/components/catalyst-ui/utils/request-id.tsx +14 -0
- package/dist/components/catalyst-ui/utils/secure-headers.tsx +37 -0
- package/dist/components/catalyst-ui/utils/server-timing.tsx +23 -0
- package/dist/components/catalyst-ui/utils/utils.ts +43 -0
- package/dist/components/catalyst-ui/utils/with-cookie.tsx +43 -0
- package/dist/components/catalyst-ui/x/accordian-x.tsx +428 -0
- package/dist/components/catalyst-ui/x/alert-x.tsx +413 -0
- package/dist/components/catalyst-ui/x/animated-text-x.tsx +2242 -0
- package/dist/components/catalyst-ui/x/avatar-x.tsx +515 -0
- package/dist/components/catalyst-ui/x/badge-x.tsx +670 -0
- package/dist/components/catalyst-ui/x/button-X.tsx +2857 -0
- package/dist/components/catalyst-ui/x/button-group-x.tsx +847 -0
- package/dist/components/catalyst-ui/x/calendar-x.tsx +1910 -0
- package/dist/components/catalyst-ui/x/card-x.tsx +2597 -0
- package/dist/components/catalyst-ui/x/checkbox-x.tsx +656 -0
- package/dist/components/catalyst-ui/x/collapsible-x.tsx +1360 -0
- package/dist/components/catalyst-ui/x/combobox-x.tsx +911 -0
- package/dist/components/catalyst-ui/x/data-table-x.tsx +1753 -0
- package/dist/components/catalyst-ui/x/date-picker-x.tsx +648 -0
- package/dist/components/catalyst-ui/x/dialog-x.tsx +659 -0
- package/dist/components/catalyst-ui/x/dropdown-menu-x.tsx +612 -0
- package/dist/components/catalyst-ui/x/hover-card-x.tsx +375 -0
- package/dist/components/catalyst-ui/x/icon-x.tsx +840 -0
- package/dist/components/catalyst-ui/x/input-mask-x.tsx +981 -0
- package/dist/components/catalyst-ui/x/input-otp-x.tsx +659 -0
- package/dist/components/catalyst-ui/x/loader-x.tsx +1757 -0
- package/dist/components/catalyst-ui/x/pagination-x.tsx +622 -0
- package/dist/components/catalyst-ui/x/popover-x.tsx +744 -0
- package/dist/components/catalyst-ui/x/radio-group-x.tsx +499 -0
- package/dist/components/catalyst-ui/x/select-x.tsx +1127 -0
- package/dist/components/catalyst-ui/x/sheet-x.tsx +668 -0
- package/dist/components/catalyst-ui/x/switch-x.tsx +681 -0
- package/dist/components/catalyst-ui/x/table-x.tsx +574 -0
- package/dist/components/catalyst-ui/x/tabs-x.tsx +839 -0
- package/dist/components/catalyst-ui/x/textarea-x.tsx +1263 -0
- package/dist/components/catalyst-ui/x/tooltip-x.tsx +396 -0
- package/dist/components/catalyst-ui/x/tracker-x.tsx +560 -0
- package/dist/data/bg-data.tsx +901 -0
- package/dist/data/buttons-data.tsx +2327 -0
- package/dist/data/charts-data.tsx +102 -0
- package/dist/data/chat-data.tsx +83 -0
- package/dist/data/code-data.tsx +1040 -0
- package/dist/data/comboboxes-data.tsx +1843 -0
- package/dist/data/command-data.tsx +1381 -0
- package/dist/data/core-data.tsx +15953 -0
- package/dist/data/crm-data.tsx +47 -0
- package/dist/data/data.tsx +159 -0
- package/dist/data/date-and-time-data.tsx +554 -0
- package/dist/data/dependencies.tsx +7 -0
- package/dist/data/ecommerce-data.tsx +1387 -0
- package/dist/data/forms-data.tsx +7890 -0
- package/dist/data/hooks-data.tsx +5487 -0
- package/dist/data/index.ts +34 -0
- package/dist/data/inputs-data.tsx +557 -0
- package/dist/data/interactive-data.tsx +5394 -0
- package/dist/data/lofi-data.tsx +18295 -0
- package/dist/data/marketing-data.tsx +2546 -0
- package/dist/data/media-data.tsx +1510 -0
- package/dist/data/motion-data.tsx +5801 -0
- package/dist/data/overlay-data.tsx +4136 -0
- package/dist/data/pdf-data.tsx +124 -0
- package/dist/data/pos-data.tsx +213 -0
- package/dist/data/postcss.config.js +6 -0
- package/dist/data/primitive-data.tsx +5170 -0
- package/dist/data/prompt-data.tsx +1226 -0
- package/dist/data/requiredLibs.ts +4 -0
- package/dist/data/sandbox-data.tsx +1 -0
- package/dist/data/sidebars-data.tsx +5421 -0
- package/dist/data/stacks-data.tsx +32 -0
- package/dist/data/table-data.tsx +706 -0
- package/dist/data/tailwind.config.js +270 -0
- package/dist/data/tailwind.config.ngin.js +3830 -0
- package/dist/data/tailwind.css +431 -0
- package/dist/data/tools-data.tsx +6910 -0
- package/dist/data/typography-data.tsx +2050 -0
- package/dist/data/utils-data.tsx +6500 -0
- package/dist/data/x-data.tsx +1171 -0
- package/dist/data.tsx +159 -0
- package/package.json +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -362
|
@@ -0,0 +1,648 @@
|
|
|
1
|
+
/**
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export function DatePickerX({ datePicker = 'default', children, ...props }: any) {
|
|
9
|
+
switch (datePicker) {
|
|
10
|
+
case 'Closable':
|
|
11
|
+
break
|
|
12
|
+
default:
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const DatePickerDemo = () => {
|
|
18
|
+
const [open, setOpen] = useState(false)
|
|
19
|
+
const [date, setDate] = useState<Date | undefined>(undefined)
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className='w-full max-w-xs space-y-2'>
|
|
23
|
+
<Label htmlFor='date' className='px-1'>
|
|
24
|
+
Date picker
|
|
25
|
+
</Label>
|
|
26
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
27
|
+
<PopoverTrigger asChild>
|
|
28
|
+
<Button variant='outline' id='date' className='w-full justify-between font-normal'>
|
|
29
|
+
{date ? date.toLocaleDateString() : 'Pick a date'}
|
|
30
|
+
<ChevronDownIcon />
|
|
31
|
+
</Button>
|
|
32
|
+
</PopoverTrigger>
|
|
33
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='start'>
|
|
34
|
+
<Calendar
|
|
35
|
+
mode='single'
|
|
36
|
+
selected={date}
|
|
37
|
+
onSelect={date => {
|
|
38
|
+
setDate(date)
|
|
39
|
+
setOpen(false)
|
|
40
|
+
}}
|
|
41
|
+
/>
|
|
42
|
+
</PopoverContent>
|
|
43
|
+
</Popover>
|
|
44
|
+
</div>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const DatePickerRangeDemo = () => {
|
|
49
|
+
const [range, setRange] = useState<DateRange | undefined>(undefined)
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<div className='w-full max-w-xs space-y-2'>
|
|
53
|
+
<Label htmlFor='dates' className='px-1'>
|
|
54
|
+
Range date picker
|
|
55
|
+
</Label>
|
|
56
|
+
<Popover>
|
|
57
|
+
<PopoverTrigger asChild>
|
|
58
|
+
<Button variant='outline' id='dates' className='w-full justify-between font-normal'>
|
|
59
|
+
{range?.from && range?.to
|
|
60
|
+
? `${range.from.toLocaleDateString()} - ${range.to.toLocaleDateString()}`
|
|
61
|
+
: 'Pick a date'}
|
|
62
|
+
<ChevronDownIcon />
|
|
63
|
+
</Button>
|
|
64
|
+
</PopoverTrigger>
|
|
65
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='start'>
|
|
66
|
+
<Calendar
|
|
67
|
+
mode='range'
|
|
68
|
+
selected={range}
|
|
69
|
+
onSelect={range => {
|
|
70
|
+
setRange(range)
|
|
71
|
+
}}
|
|
72
|
+
/>
|
|
73
|
+
</PopoverContent>
|
|
74
|
+
</Popover>
|
|
75
|
+
</div>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const DatePickerWithIconDemo = () => {
|
|
80
|
+
const [open, setOpen] = useState(false)
|
|
81
|
+
const [date, setDate] = useState<Date | undefined>(undefined)
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<div className='w-full max-w-xs space-y-2'>
|
|
85
|
+
<Label htmlFor='date' className='px-1'>
|
|
86
|
+
Date picker with icon
|
|
87
|
+
</Label>
|
|
88
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
89
|
+
<PopoverTrigger asChild>
|
|
90
|
+
<Button variant='outline' id='date' className='w-full justify-between font-normal'>
|
|
91
|
+
<span className='flex items-center'>
|
|
92
|
+
<CalendarIcon className='mr-2' />
|
|
93
|
+
{date ? date.toLocaleDateString() : 'Pick a date'}
|
|
94
|
+
</span>
|
|
95
|
+
<ChevronDownIcon />
|
|
96
|
+
</Button>
|
|
97
|
+
</PopoverTrigger>
|
|
98
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='start'>
|
|
99
|
+
<Calendar
|
|
100
|
+
mode='single'
|
|
101
|
+
selected={date}
|
|
102
|
+
onSelect={date => {
|
|
103
|
+
setDate(date)
|
|
104
|
+
setOpen(false)
|
|
105
|
+
}}
|
|
106
|
+
/>
|
|
107
|
+
</PopoverContent>
|
|
108
|
+
</Popover>
|
|
109
|
+
</div>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const DatePickerWithinInputDemo = () => {
|
|
114
|
+
const [open, setOpen] = useState(false)
|
|
115
|
+
const [date, setDate] = useState<Date | undefined>(new Date())
|
|
116
|
+
const [month, setMonth] = useState<Date | undefined>(date)
|
|
117
|
+
const [value, setValue] = useState(formatDate(date))
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<div className='w-full max-w-xs space-y-2'>
|
|
121
|
+
<Label htmlFor='date' className='px-1'>
|
|
122
|
+
Date picker within input
|
|
123
|
+
</Label>
|
|
124
|
+
<div className='relative flex gap-2'>
|
|
125
|
+
<Input
|
|
126
|
+
id='date'
|
|
127
|
+
value={value}
|
|
128
|
+
placeholder='January 01, 2025'
|
|
129
|
+
className='bg-background pr-10'
|
|
130
|
+
onChange={e => {
|
|
131
|
+
const date = new Date(e.target.value)
|
|
132
|
+
|
|
133
|
+
setValue(e.target.value)
|
|
134
|
+
|
|
135
|
+
if (isValidDate(date)) {
|
|
136
|
+
setDate(date)
|
|
137
|
+
setMonth(date)
|
|
138
|
+
}
|
|
139
|
+
}}
|
|
140
|
+
onKeyDown={e => {
|
|
141
|
+
if (e.key === 'ArrowDown') {
|
|
142
|
+
e.preventDefault()
|
|
143
|
+
setOpen(true)
|
|
144
|
+
}
|
|
145
|
+
}}
|
|
146
|
+
/>
|
|
147
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
148
|
+
<PopoverTrigger asChild>
|
|
149
|
+
<Button id='date-picker' variant='ghost' className='absolute top-1/2 right-2 size-6 -translate-y-1/2'>
|
|
150
|
+
<CalendarIcon className='size-3.5' />
|
|
151
|
+
<span className='sr-only'>Pick a date</span>
|
|
152
|
+
</Button>
|
|
153
|
+
</PopoverTrigger>
|
|
154
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='end' alignOffset={-8} sideOffset={10}>
|
|
155
|
+
<Calendar
|
|
156
|
+
mode='single'
|
|
157
|
+
selected={date}
|
|
158
|
+
month={month}
|
|
159
|
+
onMonthChange={setMonth}
|
|
160
|
+
onSelect={date => {
|
|
161
|
+
setDate(date)
|
|
162
|
+
setValue(formatDate(date))
|
|
163
|
+
setOpen(false)
|
|
164
|
+
}}
|
|
165
|
+
/>
|
|
166
|
+
</PopoverContent>
|
|
167
|
+
</Popover>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const DatePickerWithNaturalLanguageDemo = () => {
|
|
174
|
+
const [open, setOpen] = useState(false)
|
|
175
|
+
const [value, setValue] = useState('In 2 days')
|
|
176
|
+
const [date, setDate] = useState<Date | undefined>(parseDate(value) || undefined)
|
|
177
|
+
const [month, setMonth] = useState<Date | undefined>(date)
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<div className='w-full max-w-xs space-y-2'>
|
|
181
|
+
<Label htmlFor='date' className='px-1'>
|
|
182
|
+
Date picker with natural language input
|
|
183
|
+
</Label>
|
|
184
|
+
<div className='relative flex gap-2'>
|
|
185
|
+
<Input
|
|
186
|
+
id='date'
|
|
187
|
+
value={value}
|
|
188
|
+
placeholder='Tomorrow or next week'
|
|
189
|
+
className='bg-background pr-10'
|
|
190
|
+
onChange={e => {
|
|
191
|
+
setValue(e.target.value)
|
|
192
|
+
const date = parseDate(e.target.value)
|
|
193
|
+
|
|
194
|
+
if (date) {
|
|
195
|
+
setDate(date)
|
|
196
|
+
setMonth(date)
|
|
197
|
+
}
|
|
198
|
+
}}
|
|
199
|
+
onKeyDown={e => {
|
|
200
|
+
if (e.key === 'ArrowDown') {
|
|
201
|
+
e.preventDefault()
|
|
202
|
+
setOpen(true)
|
|
203
|
+
}
|
|
204
|
+
}}
|
|
205
|
+
/>
|
|
206
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
207
|
+
<PopoverTrigger asChild>
|
|
208
|
+
<Button id='date-picker' variant='ghost' className='absolute top-1/2 right-2 size-6 -translate-y-1/2'>
|
|
209
|
+
<CalendarIcon className='size-3.5' />
|
|
210
|
+
<span className='sr-only'>Pick a date</span>
|
|
211
|
+
</Button>
|
|
212
|
+
</PopoverTrigger>
|
|
213
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='end' alignOffset={-8} sideOffset={10}>
|
|
214
|
+
<Calendar
|
|
215
|
+
mode='single'
|
|
216
|
+
selected={date}
|
|
217
|
+
month={month}
|
|
218
|
+
onMonthChange={setMonth}
|
|
219
|
+
onSelect={date => {
|
|
220
|
+
setDate(date)
|
|
221
|
+
setValue(formatDate(date))
|
|
222
|
+
setOpen(false)
|
|
223
|
+
}}
|
|
224
|
+
/>
|
|
225
|
+
</PopoverContent>
|
|
226
|
+
</Popover>
|
|
227
|
+
</div>
|
|
228
|
+
<div className='text-muted-foreground px-1 text-sm'>
|
|
229
|
+
Your post will be published on <span className='font-medium'>{formatDate(date)}</span>.
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const DatePickerWithShortDateDisplayDemo = () => {
|
|
236
|
+
const [range, setRange] = useState<DateRange | undefined>({
|
|
237
|
+
from: new Date(2025, 10, 20),
|
|
238
|
+
to: new Date(2025, 10, 24)
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
return (
|
|
242
|
+
<div className='w-full max-w-xs space-y-2'>
|
|
243
|
+
<Label htmlFor='dates' className='px-1'>
|
|
244
|
+
Date picker with short date
|
|
245
|
+
</Label>
|
|
246
|
+
<Popover>
|
|
247
|
+
<PopoverTrigger asChild>
|
|
248
|
+
<Button variant='outline' id='dates' className='w-full justify-between font-normal'>
|
|
249
|
+
{range?.from && range?.to
|
|
250
|
+
? formatDateRange(range.from, range.to, {
|
|
251
|
+
includeTime: false
|
|
252
|
+
})
|
|
253
|
+
: 'Pick a date'}
|
|
254
|
+
<ChevronDownIcon />
|
|
255
|
+
</Button>
|
|
256
|
+
</PopoverTrigger>
|
|
257
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='start'>
|
|
258
|
+
<Calendar
|
|
259
|
+
mode='range'
|
|
260
|
+
selected={range}
|
|
261
|
+
onSelect={range => {
|
|
262
|
+
setRange(range)
|
|
263
|
+
}}
|
|
264
|
+
/>
|
|
265
|
+
</PopoverContent>
|
|
266
|
+
</Popover>
|
|
267
|
+
</div>
|
|
268
|
+
)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const DatePickerDisableOutsideDaysDemo = () => {
|
|
272
|
+
const [open, setOpen] = useState(false)
|
|
273
|
+
const [date, setDate] = useState<Date | undefined>(undefined)
|
|
274
|
+
|
|
275
|
+
return (
|
|
276
|
+
<div className='w-full max-w-xs space-y-2'>
|
|
277
|
+
<Label htmlFor='date' className='px-1'>
|
|
278
|
+
Disable outside days
|
|
279
|
+
</Label>
|
|
280
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
281
|
+
<PopoverTrigger asChild>
|
|
282
|
+
<Button variant='outline' id='date' className='w-full justify-between font-normal'>
|
|
283
|
+
{date ? date.toLocaleDateString() : 'Pick a date'}
|
|
284
|
+
<ChevronDownIcon />
|
|
285
|
+
</Button>
|
|
286
|
+
</PopoverTrigger>
|
|
287
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='start'>
|
|
288
|
+
<Calendar
|
|
289
|
+
mode='single'
|
|
290
|
+
selected={date}
|
|
291
|
+
showOutsideDays={false}
|
|
292
|
+
onSelect={date => {
|
|
293
|
+
setDate(date)
|
|
294
|
+
setOpen(false)
|
|
295
|
+
}}
|
|
296
|
+
/>
|
|
297
|
+
</PopoverContent>
|
|
298
|
+
</Popover>
|
|
299
|
+
</div>
|
|
300
|
+
)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const DatePickerDemo = () => {
|
|
304
|
+
return (
|
|
305
|
+
<div className='w-full max-w-xs space-y-2'>
|
|
306
|
+
<Label htmlFor='time-picker' className='px-1'>
|
|
307
|
+
Time input
|
|
308
|
+
</Label>
|
|
309
|
+
<Input
|
|
310
|
+
type='time'
|
|
311
|
+
id='time-picker'
|
|
312
|
+
step='1'
|
|
313
|
+
defaultValue='08:30:00'
|
|
314
|
+
className='bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none'
|
|
315
|
+
/>
|
|
316
|
+
</div>
|
|
317
|
+
)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const TimePickerWithIconDemo = () => {
|
|
321
|
+
return (
|
|
322
|
+
<div className='w-full max-w-xs space-y-2'>
|
|
323
|
+
<Label htmlFor='timepicker'>Time input with start icon</Label>
|
|
324
|
+
<div className='relative'>
|
|
325
|
+
<div className='text-muted-foreground pointer-events-none absolute inset-y-0 left-0 flex items-center justify-center pl-3 peer-disabled:opacity-50'>
|
|
326
|
+
<Clock8Icon className='size-4' />
|
|
327
|
+
<span className='sr-only'>User</span>
|
|
328
|
+
</div>
|
|
329
|
+
<Input
|
|
330
|
+
type='time'
|
|
331
|
+
id='time-picker'
|
|
332
|
+
step='1'
|
|
333
|
+
defaultValue='08:30:00'
|
|
334
|
+
className='peer bg-background appearance-none pl-9 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none'
|
|
335
|
+
/>
|
|
336
|
+
</div>
|
|
337
|
+
</div>
|
|
338
|
+
)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const DatePickerAndTimePickerDemo = () => {
|
|
342
|
+
const [open, setOpen] = useState(false)
|
|
343
|
+
const [date, setDate] = useState<Date | undefined>(undefined)
|
|
344
|
+
|
|
345
|
+
return (
|
|
346
|
+
<div className='flex gap-4'>
|
|
347
|
+
<div className='flex flex-col gap-3'>
|
|
348
|
+
<Label htmlFor='date-picker' className='px-1'>
|
|
349
|
+
Date picker
|
|
350
|
+
</Label>
|
|
351
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
352
|
+
<PopoverTrigger asChild>
|
|
353
|
+
<Button variant='outline' id='date-picker' className='justify-between font-normal'>
|
|
354
|
+
{date ? date.toLocaleDateString() : 'Pick a date'}
|
|
355
|
+
<ChevronDownIcon />
|
|
356
|
+
</Button>
|
|
357
|
+
</PopoverTrigger>
|
|
358
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='start'>
|
|
359
|
+
<Calendar
|
|
360
|
+
mode='single'
|
|
361
|
+
selected={date}
|
|
362
|
+
onSelect={date => {
|
|
363
|
+
setDate(date)
|
|
364
|
+
setOpen(false)
|
|
365
|
+
}}
|
|
366
|
+
/>
|
|
367
|
+
</PopoverContent>
|
|
368
|
+
</Popover>
|
|
369
|
+
</div>
|
|
370
|
+
<div className='flex flex-col gap-3'>
|
|
371
|
+
<Label htmlFor='time-picker' className='px-1'>
|
|
372
|
+
Time input
|
|
373
|
+
</Label>
|
|
374
|
+
<Input
|
|
375
|
+
type='time'
|
|
376
|
+
id='time-picker'
|
|
377
|
+
step='1'
|
|
378
|
+
defaultValue='06:30:00'
|
|
379
|
+
className='bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none'
|
|
380
|
+
/>
|
|
381
|
+
</div>
|
|
382
|
+
</div>
|
|
383
|
+
)
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const DatePickerAndTimeRangePicker = () => {
|
|
387
|
+
const [open, setOpen] = useState(false)
|
|
388
|
+
const [date, setDate] = useState<Date | undefined>(undefined)
|
|
389
|
+
|
|
390
|
+
return (
|
|
391
|
+
<div className='flex flex-col gap-6'>
|
|
392
|
+
<div className='flex w-full max-w-xs flex-col gap-3'>
|
|
393
|
+
<Label htmlFor='date' className='px-1'>
|
|
394
|
+
Date
|
|
395
|
+
</Label>
|
|
396
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
397
|
+
<PopoverTrigger asChild>
|
|
398
|
+
<Button variant='outline' id='date' className='w-full justify-between font-normal'>
|
|
399
|
+
{date ? date.toLocaleDateString() : 'Pick a date'}
|
|
400
|
+
<ChevronDownIcon />
|
|
401
|
+
</Button>
|
|
402
|
+
</PopoverTrigger>
|
|
403
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='start'>
|
|
404
|
+
<Calendar
|
|
405
|
+
mode='single'
|
|
406
|
+
selected={date}
|
|
407
|
+
onSelect={date => {
|
|
408
|
+
setDate(date)
|
|
409
|
+
setOpen(false)
|
|
410
|
+
}}
|
|
411
|
+
/>
|
|
412
|
+
</PopoverContent>
|
|
413
|
+
</Popover>
|
|
414
|
+
</div>
|
|
415
|
+
<div className='flex gap-4'>
|
|
416
|
+
<div className='flex flex-col gap-3'>
|
|
417
|
+
<Label htmlFor='time-from' className='px-1'>
|
|
418
|
+
From
|
|
419
|
+
</Label>
|
|
420
|
+
<Input
|
|
421
|
+
type='time'
|
|
422
|
+
id='time-from'
|
|
423
|
+
step='1'
|
|
424
|
+
defaultValue='01:30:00'
|
|
425
|
+
className='bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none'
|
|
426
|
+
/>
|
|
427
|
+
</div>
|
|
428
|
+
<div className='flex flex-col gap-3'>
|
|
429
|
+
<Label htmlFor='time-to' className='px-1'>
|
|
430
|
+
To
|
|
431
|
+
</Label>
|
|
432
|
+
<Input
|
|
433
|
+
type='time'
|
|
434
|
+
id='time-to'
|
|
435
|
+
step='1'
|
|
436
|
+
defaultValue='02:30:00'
|
|
437
|
+
className='bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none'
|
|
438
|
+
/>
|
|
439
|
+
</div>
|
|
440
|
+
</div>
|
|
441
|
+
</div>
|
|
442
|
+
)
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const DatePickerRangeAndTimePickerDemo = () => {
|
|
446
|
+
const [openFrom, setOpenFrom] = useState(false)
|
|
447
|
+
const [openTo, setOpenTo] = useState(false)
|
|
448
|
+
const [dateFrom, setDateFrom] = useState<Date | undefined>(new Date('2025-06-18'))
|
|
449
|
+
const [dateTo, setDateTo] = useState<Date | undefined>(new Date('2025-06-25'))
|
|
450
|
+
|
|
451
|
+
return (
|
|
452
|
+
<div className='flex w-full max-w-64 min-w-0 flex-col gap-6'>
|
|
453
|
+
<div className='flex gap-4'>
|
|
454
|
+
<div className='flex flex-1 flex-col gap-3'>
|
|
455
|
+
<Label htmlFor='date-from' className='px-1'>
|
|
456
|
+
Departure date
|
|
457
|
+
</Label>
|
|
458
|
+
<Popover open={openFrom} onOpenChange={setOpenFrom}>
|
|
459
|
+
<PopoverTrigger asChild>
|
|
460
|
+
<Button variant='outline' id='date-from' className='w-full justify-between font-normal'>
|
|
461
|
+
{dateFrom
|
|
462
|
+
? dateFrom.toLocaleDateString('en-US', {
|
|
463
|
+
day: '2-digit',
|
|
464
|
+
month: 'short',
|
|
465
|
+
year: 'numeric'
|
|
466
|
+
})
|
|
467
|
+
: 'Pick a date'}
|
|
468
|
+
<ChevronDownIcon />
|
|
469
|
+
</Button>
|
|
470
|
+
</PopoverTrigger>
|
|
471
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='start'>
|
|
472
|
+
<Calendar
|
|
473
|
+
mode='single'
|
|
474
|
+
selected={dateFrom}
|
|
475
|
+
onSelect={date => {
|
|
476
|
+
setDateFrom(date)
|
|
477
|
+
setOpenFrom(false)
|
|
478
|
+
}}
|
|
479
|
+
/>
|
|
480
|
+
</PopoverContent>
|
|
481
|
+
</Popover>
|
|
482
|
+
</div>
|
|
483
|
+
<div className='flex flex-col gap-3'>
|
|
484
|
+
<Label htmlFor='time-from' className='invisible px-1'>
|
|
485
|
+
From
|
|
486
|
+
</Label>
|
|
487
|
+
<Input
|
|
488
|
+
type='time'
|
|
489
|
+
id='time-from'
|
|
490
|
+
step='1'
|
|
491
|
+
defaultValue='09:30:00'
|
|
492
|
+
className='bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none'
|
|
493
|
+
/>
|
|
494
|
+
</div>
|
|
495
|
+
</div>
|
|
496
|
+
<div className='flex gap-4'>
|
|
497
|
+
<div className='flex flex-1 flex-col gap-3'>
|
|
498
|
+
<Label htmlFor='date-to' className='px-1'>
|
|
499
|
+
Return date
|
|
500
|
+
</Label>
|
|
501
|
+
<Popover open={openTo} onOpenChange={setOpenTo}>
|
|
502
|
+
<PopoverTrigger asChild>
|
|
503
|
+
<Button variant='outline' id='date-to' className='w-full justify-between font-normal'>
|
|
504
|
+
{dateTo
|
|
505
|
+
? dateTo.toLocaleDateString('en-US', {
|
|
506
|
+
day: '2-digit',
|
|
507
|
+
month: 'short',
|
|
508
|
+
year: 'numeric'
|
|
509
|
+
})
|
|
510
|
+
: 'Pick a date'}
|
|
511
|
+
<ChevronDownIcon />
|
|
512
|
+
</Button>
|
|
513
|
+
</PopoverTrigger>
|
|
514
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='start'>
|
|
515
|
+
<Calendar
|
|
516
|
+
mode='single'
|
|
517
|
+
selected={dateTo}
|
|
518
|
+
captionLayout='dropdown'
|
|
519
|
+
onSelect={date => {
|
|
520
|
+
setDateTo(date)
|
|
521
|
+
setOpenTo(false)
|
|
522
|
+
}}
|
|
523
|
+
disabled={dateFrom && { before: dateFrom }}
|
|
524
|
+
/>
|
|
525
|
+
</PopoverContent>
|
|
526
|
+
</Popover>
|
|
527
|
+
</div>
|
|
528
|
+
<div className='flex flex-col gap-3'>
|
|
529
|
+
<Label htmlFor='time-to' className='invisible px-1'>
|
|
530
|
+
To
|
|
531
|
+
</Label>
|
|
532
|
+
<Input
|
|
533
|
+
type='time'
|
|
534
|
+
id='time-to'
|
|
535
|
+
step='1'
|
|
536
|
+
defaultValue='18:30:00'
|
|
537
|
+
className='bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none'
|
|
538
|
+
/>
|
|
539
|
+
</div>
|
|
540
|
+
</div>
|
|
541
|
+
</div>
|
|
542
|
+
)
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
const ChartFilterDemo = () => {
|
|
546
|
+
const [range, setRange] = useState<DateRange | undefined>({
|
|
547
|
+
from: new Date(2025, 0, 1),
|
|
548
|
+
to: new Date(2025, 0, 31)
|
|
549
|
+
})
|
|
550
|
+
|
|
551
|
+
const filteredData = useMemo(() => {
|
|
552
|
+
if (!range?.from && !range?.to) {
|
|
553
|
+
return chartData
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
return chartData.filter(item => {
|
|
557
|
+
const date = new Date(item.date)
|
|
558
|
+
|
|
559
|
+
return date >= range.from! && date <= range.to!
|
|
560
|
+
})
|
|
561
|
+
}, [range])
|
|
562
|
+
|
|
563
|
+
return (
|
|
564
|
+
<Card className='@container/card w-full max-w-xl'>
|
|
565
|
+
<CardHeader className='flex flex-col border-b @md/card:grid'>
|
|
566
|
+
<CardTitle>Web Analytics</CardTitle>
|
|
567
|
+
<CardDescription>Showing total visitors for this month.</CardDescription>
|
|
568
|
+
<CardAction className='mt-2 @md/card:mt-0'>
|
|
569
|
+
<Popover>
|
|
570
|
+
<PopoverTrigger asChild>
|
|
571
|
+
<Button variant='outline'>
|
|
572
|
+
<CalendarIcon />
|
|
573
|
+
{range?.from && range?.to
|
|
574
|
+
? `${range.from.toLocaleDateString()} - ${range.to.toLocaleDateString()}`
|
|
575
|
+
: 'January 2025'}
|
|
576
|
+
</Button>
|
|
577
|
+
</PopoverTrigger>
|
|
578
|
+
<PopoverContent className='w-auto overflow-hidden p-0' align='end'>
|
|
579
|
+
<Calendar
|
|
580
|
+
className='w-full'
|
|
581
|
+
mode='range'
|
|
582
|
+
defaultMonth={range?.from}
|
|
583
|
+
selected={range}
|
|
584
|
+
onSelect={setRange}
|
|
585
|
+
startMonth={range?.from}
|
|
586
|
+
fixedWeeks
|
|
587
|
+
showOutsideDays
|
|
588
|
+
disabled={{
|
|
589
|
+
after: new Date(2025, 0, 31),
|
|
590
|
+
before: new Date(2025, 0, 1)
|
|
591
|
+
}}
|
|
592
|
+
/>
|
|
593
|
+
</PopoverContent>
|
|
594
|
+
</Popover>
|
|
595
|
+
</CardAction>
|
|
596
|
+
</CardHeader>
|
|
597
|
+
<CardContent className='px-4'>
|
|
598
|
+
<ChartContainer config={chartConfig} className='aspect-auto h-62 w-full'>
|
|
599
|
+
<BarChart
|
|
600
|
+
accessibilityLayer
|
|
601
|
+
data={filteredData}
|
|
602
|
+
margin={{
|
|
603
|
+
left: 12,
|
|
604
|
+
right: 12
|
|
605
|
+
}}
|
|
606
|
+
>
|
|
607
|
+
<CartesianGrid vertical={false} />
|
|
608
|
+
<XAxis
|
|
609
|
+
dataKey='date'
|
|
610
|
+
tickLine={false}
|
|
611
|
+
axisLine={false}
|
|
612
|
+
tickMargin={8}
|
|
613
|
+
minTickGap={20}
|
|
614
|
+
tickFormatter={value => {
|
|
615
|
+
const date = new Date(value)
|
|
616
|
+
|
|
617
|
+
return date.toLocaleDateString('en-US', {
|
|
618
|
+
day: 'numeric'
|
|
619
|
+
})
|
|
620
|
+
}}
|
|
621
|
+
/>
|
|
622
|
+
<ChartTooltip
|
|
623
|
+
content={
|
|
624
|
+
<ChartTooltipContent
|
|
625
|
+
className='w-[150px]'
|
|
626
|
+
nameKey='visitors'
|
|
627
|
+
labelFormatter={value => {
|
|
628
|
+
return new Date(value).toLocaleDateString('en-US', {
|
|
629
|
+
month: 'short',
|
|
630
|
+
day: 'numeric',
|
|
631
|
+
year: 'numeric'
|
|
632
|
+
})
|
|
633
|
+
}}
|
|
634
|
+
/>
|
|
635
|
+
}
|
|
636
|
+
/>
|
|
637
|
+
<Bar dataKey='visitors' fill={`var(--color-visitors)`} radius={4} />
|
|
638
|
+
</BarChart>
|
|
639
|
+
</ChartContainer>
|
|
640
|
+
</CardContent>
|
|
641
|
+
<CardFooter className='border-t'>
|
|
642
|
+
<div className='text-sm'>
|
|
643
|
+
You had <span className='font-semibold'>{total.toLocaleString()}</span> visitors for the month of January.
|
|
644
|
+
</div>
|
|
645
|
+
</CardFooter>
|
|
646
|
+
</Card>
|
|
647
|
+
)
|
|
648
|
+
} */
|