@dalexto/lexsys-registry 0.0.6 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/index.js +211 -3
  2. package/dist/items/breadcrumb.d.ts +7 -0
  3. package/dist/items/data-table.d.ts +7 -0
  4. package/dist/items/date-picker.d.ts +7 -0
  5. package/dist/items/filter-toolbar.d.ts +7 -0
  6. package/dist/items/index.d.ts +8 -0
  7. package/dist/items/page-header.d.ts +7 -0
  8. package/dist/items/pagination.d.ts +7 -0
  9. package/dist/items/settings-page-layout.d.ts +7 -0
  10. package/dist/items/stats-card.d.ts +7 -0
  11. package/package.json +1 -1
  12. package/templates/blocks/CommandPalette/CommandPalette.tsx +12 -8
  13. package/templates/blocks/CommandPalette/CommandPalette.types.ts +2 -2
  14. package/templates/blocks/DataTable/DataTable.tsx +236 -0
  15. package/templates/blocks/DataTable/DataTable.types.ts +74 -0
  16. package/templates/blocks/DataTable/DataTable.variants.ts +23 -0
  17. package/templates/blocks/FilterToolbar/FilterToolbar.tsx +126 -0
  18. package/templates/blocks/FilterToolbar/FilterToolbar.types.ts +31 -0
  19. package/templates/blocks/FilterToolbar/FilterToolbar.variants.ts +24 -0
  20. package/templates/blocks/PageHeader/PageHeader.tsx +215 -0
  21. package/templates/blocks/PageHeader/PageHeader.types.ts +66 -0
  22. package/templates/blocks/PageHeader/PageHeader.variants.ts +48 -0
  23. package/templates/blocks/StatsCard/StatsCard.tsx +132 -0
  24. package/templates/blocks/StatsCard/StatsCard.types.ts +43 -0
  25. package/templates/blocks/StatsCard/StatsCard.variants.ts +28 -0
  26. package/templates/primitives/Breadcrumb/Breadcrumb.tsx +142 -0
  27. package/templates/primitives/Breadcrumb/Breadcrumb.types.ts +62 -0
  28. package/templates/primitives/Breadcrumb/Breadcrumb.variants.ts +37 -0
  29. package/templates/primitives/DatePicker/DatePicker.tsx +263 -0
  30. package/templates/primitives/DatePicker/DatePicker.types.ts +52 -0
  31. package/templates/primitives/DatePicker/DatePicker.variants.ts +76 -0
  32. package/templates/primitives/Pagination/Pagination.tsx +160 -0
  33. package/templates/primitives/Pagination/Pagination.types.ts +54 -0
  34. package/templates/primitives/Pagination/Pagination.variants.ts +47 -0
  35. package/templates/primitives/Toolbar/Toolbar.variants.ts +15 -15
  36. package/templates/styles/theme.css +1 -1
  37. package/templates/styles/tokens.css +334 -1
  38. package/templates/templates/SettingsPageLayout/SettingsPageLayout.tsx +198 -0
  39. package/templates/templates/SettingsPageLayout/SettingsPageLayout.types.ts +55 -0
  40. package/templates/templates/SettingsPageLayout/SettingsPageLayout.variants.ts +42 -0
@@ -0,0 +1,132 @@
1
+ /**
2
+ * StatsCard.tsx
3
+ *
4
+ * Reference StatsCard block — compound Card metric summary.
5
+ */
6
+
7
+ import {
8
+ Card,
9
+ CardContent,
10
+ CardDescription,
11
+ CardFooter,
12
+ CardHeader,
13
+ CardTitle,
14
+ } from "@/components/primitives/Card"
15
+ import type {
16
+ StatsCardContentProps,
17
+ StatsCardDescriptionProps,
18
+ StatsCardFooterProps,
19
+ StatsCardHeaderProps,
20
+ StatsCardProps,
21
+ StatsCardTitleProps,
22
+ StatsCardTrendProps,
23
+ StatsCardValueProps,
24
+ } from "./StatsCard.types"
25
+ import {
26
+ statsCardClasses,
27
+ statsCardTrendClasses,
28
+ statsCardValueClasses,
29
+ } from "./StatsCard.variants"
30
+ import { cn } from "@/lib/utils"
31
+
32
+ const StatsCard = ({
33
+ ref,
34
+ variant,
35
+ className,
36
+ children,
37
+ ...cardProps
38
+ }: StatsCardProps) => {
39
+ return (
40
+ <Card
41
+ ref={ref}
42
+ variant={variant}
43
+ className={cn(statsCardClasses(), className)}
44
+ {...cardProps}
45
+ >
46
+ {children}
47
+ </Card>
48
+ )
49
+ }
50
+
51
+ StatsCard.displayName = "StatsCard"
52
+
53
+ const StatsCardHeader = ({
54
+ ref,
55
+ className,
56
+ ...props
57
+ }: StatsCardHeaderProps) => {
58
+ return <CardHeader ref={ref} className={className} {...props} />
59
+ }
60
+
61
+ StatsCardHeader.displayName = "StatsCardHeader"
62
+
63
+ const StatsCardTitle = ({ ref, className, ...props }: StatsCardTitleProps) => {
64
+ return <CardTitle ref={ref} className={className} {...props} />
65
+ }
66
+
67
+ StatsCardTitle.displayName = "StatsCardTitle"
68
+
69
+ const StatsCardDescription = ({
70
+ ref,
71
+ className,
72
+ ...props
73
+ }: StatsCardDescriptionProps) => {
74
+ return <CardDescription ref={ref} className={className} {...props} />
75
+ }
76
+
77
+ StatsCardDescription.displayName = "StatsCardDescription"
78
+
79
+ const StatsCardContent = ({
80
+ ref,
81
+ className,
82
+ ...props
83
+ }: StatsCardContentProps) => {
84
+ return <CardContent ref={ref} className={className} {...props} />
85
+ }
86
+
87
+ StatsCardContent.displayName = "StatsCardContent"
88
+
89
+ const StatsCardValue = ({ ref, className, ...props }: StatsCardValueProps) => {
90
+ return (
91
+ <p
92
+ ref={ref}
93
+ className={cn(statsCardValueClasses(), className)}
94
+ {...props}
95
+ />
96
+ )
97
+ }
98
+
99
+ StatsCardValue.displayName = "StatsCardValue"
100
+
101
+ const StatsCardTrend = ({ ref, className, ...props }: StatsCardTrendProps) => {
102
+ return (
103
+ <span
104
+ ref={ref}
105
+ className={cn(statsCardTrendClasses(), className)}
106
+ {...props}
107
+ />
108
+ )
109
+ }
110
+
111
+ StatsCardTrend.displayName = "StatsCardTrend"
112
+
113
+ const StatsCardFooter = ({
114
+ ref,
115
+ className,
116
+ ...props
117
+ }: StatsCardFooterProps) => {
118
+ return <CardFooter ref={ref} className={className} {...props} />
119
+ }
120
+
121
+ StatsCardFooter.displayName = "StatsCardFooter"
122
+
123
+ export {
124
+ StatsCard,
125
+ StatsCardHeader,
126
+ StatsCardTitle,
127
+ StatsCardDescription,
128
+ StatsCardContent,
129
+ StatsCardValue,
130
+ StatsCardTrend,
131
+ StatsCardFooter,
132
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * StatsCard.types.ts
3
+ *
4
+ * Public types for the StatsCard block.
5
+ */
6
+
7
+ import type { HTMLAttributes, ReactNode, Ref } from "react"
8
+ import type {
9
+ CardContentProps,
10
+ CardDescriptionProps,
11
+ CardFooterProps,
12
+ CardHeaderProps,
13
+ CardProps,
14
+ CardTitleProps,
15
+ } from "@/components/primitives/Card"
16
+
17
+ export interface StatsCardProps extends Omit<CardProps, "children"> {
18
+ ref?: Ref<HTMLDivElement>
19
+ className?: CardProps["className"]
20
+ children?: ReactNode
21
+ }
22
+
23
+ export type StatsCardHeaderProps = CardHeaderProps
24
+
25
+ export type StatsCardTitleProps = CardTitleProps
26
+
27
+ export type StatsCardDescriptionProps = CardDescriptionProps
28
+
29
+ export type StatsCardContentProps = CardContentProps
30
+
31
+ export interface StatsCardValueProps extends HTMLAttributes<HTMLParagraphElement> {
32
+ ref?: Ref<HTMLParagraphElement>
33
+ className?: string
34
+ children?: ReactNode
35
+ }
36
+
37
+ export interface StatsCardTrendProps extends HTMLAttributes<HTMLSpanElement> {
38
+ ref?: Ref<HTMLSpanElement>
39
+ className?: string
40
+ children?: ReactNode
41
+ }
42
+
43
+ export type StatsCardFooterProps = CardFooterProps
@@ -0,0 +1,28 @@
1
+ /**
2
+ * StatsCard.variants.ts
3
+ *
4
+ * Variant classes for the StatsCard block.
5
+ */
6
+
7
+ export const statsCardClasses = (): string => {
8
+ return "lex-stats-card"
9
+ }
10
+
11
+ export const statsCardValueClasses = (): string => {
12
+ return [
13
+ "lex-stats-card__value",
14
+ "text-(length:--lex-typography-heading-md-font-size)",
15
+ "font-(--lex-typography-heading-md-font-weight)",
16
+ "leading-(--lex-typography-heading-md-font-line-height)",
17
+ "text-(--lex-color-text-primary)",
18
+ "m-0",
19
+ ].join(" ")
20
+ }
21
+
22
+ export const statsCardTrendClasses = (): string => {
23
+ return [
24
+ "lex-stats-card__trend",
25
+ "text-(length:--lex-typography-body-xs-font-size)",
26
+ "text-(--lex-color-text-secondary)",
27
+ ].join(" ")
28
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Breadcrumb.tsx
3
+ *
4
+ * Reference Breadcrumb component implementation.
5
+ */
6
+
7
+ import { ChevronRight, MoreHorizontal } from "lucide-react"
8
+ import type {
9
+ BreadcrumbEllipsisProps,
10
+ BreadcrumbItemProps,
11
+ BreadcrumbLinkProps,
12
+ BreadcrumbListProps,
13
+ BreadcrumbPageProps,
14
+ BreadcrumbProps,
15
+ BreadcrumbSeparatorProps,
16
+ } from "./Breadcrumb.types"
17
+ import {
18
+ breadcrumbEllipsisVariants,
19
+ breadcrumbItemVariants,
20
+ breadcrumbLinkVariants,
21
+ breadcrumbListVariants,
22
+ breadcrumbPageVariants,
23
+ breadcrumbRootVariants,
24
+ breadcrumbSeparatorVariants,
25
+ } from "./Breadcrumb.variants"
26
+ import { cn } from "@/lib/utils"
27
+
28
+ const Breadcrumb = ({ ref, className, ...props }: BreadcrumbProps) => {
29
+ return (
30
+ <nav
31
+ ref={ref}
32
+ aria-label="breadcrumb"
33
+ className={cn(breadcrumbRootVariants(), className)}
34
+ {...props}
35
+ />
36
+ )
37
+ }
38
+
39
+ Breadcrumb.displayName = "Breadcrumb"
40
+
41
+ const BreadcrumbList = ({ ref, className, ...props }: BreadcrumbListProps) => {
42
+ return (
43
+ <ol
44
+ ref={ref}
45
+ className={cn(breadcrumbListVariants(), className)}
46
+ {...props}
47
+ />
48
+ )
49
+ }
50
+
51
+ BreadcrumbList.displayName = "BreadcrumbList"
52
+
53
+ const BreadcrumbItem = ({ ref, className, ...props }: BreadcrumbItemProps) => {
54
+ return (
55
+ <li
56
+ ref={ref}
57
+ className={cn(breadcrumbItemVariants(), className)}
58
+ {...props}
59
+ />
60
+ )
61
+ }
62
+
63
+ BreadcrumbItem.displayName = "BreadcrumbItem"
64
+
65
+ const BreadcrumbLink = ({ ref, className, ...props }: BreadcrumbLinkProps) => {
66
+ return (
67
+ <a
68
+ ref={ref}
69
+ className={cn(breadcrumbLinkVariants(), className)}
70
+ {...props}
71
+ />
72
+ )
73
+ }
74
+
75
+ BreadcrumbLink.displayName = "BreadcrumbLink"
76
+
77
+ const BreadcrumbPage = ({ ref, className, ...props }: BreadcrumbPageProps) => {
78
+ return (
79
+ <span
80
+ ref={ref}
81
+ role="link"
82
+ aria-disabled="true"
83
+ aria-current="page"
84
+ className={cn(breadcrumbPageVariants(), className)}
85
+ {...props}
86
+ />
87
+ )
88
+ }
89
+
90
+ BreadcrumbPage.displayName = "BreadcrumbPage"
91
+
92
+ const BreadcrumbSeparator = ({
93
+ ref,
94
+ className,
95
+ children,
96
+ ...props
97
+ }: BreadcrumbSeparatorProps) => {
98
+ return (
99
+ <span
100
+ ref={ref}
101
+ role="presentation"
102
+ aria-hidden="true"
103
+ className={cn(breadcrumbSeparatorVariants(), className)}
104
+ {...props}
105
+ >
106
+ {children ?? <ChevronRight size={14} />}
107
+ </span>
108
+ )
109
+ }
110
+
111
+ BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
112
+
113
+ const BreadcrumbEllipsis = ({
114
+ ref,
115
+ className,
116
+ ...props
117
+ }: BreadcrumbEllipsisProps) => {
118
+ return (
119
+ <span
120
+ ref={ref}
121
+ role="presentation"
122
+ aria-hidden="true"
123
+ className={cn(breadcrumbEllipsisVariants(), className)}
124
+ {...props}
125
+ >
126
+ <MoreHorizontal size={14} />
127
+ <span className="sr-only">More</span>
128
+ </span>
129
+ )
130
+ }
131
+
132
+ BreadcrumbEllipsis.displayName = "BreadcrumbEllipsis"
133
+
134
+ export {
135
+ Breadcrumb,
136
+ BreadcrumbList,
137
+ BreadcrumbItem,
138
+ BreadcrumbLink,
139
+ BreadcrumbPage,
140
+ BreadcrumbSeparator,
141
+ BreadcrumbEllipsis,
142
+ }
@@ -0,0 +1,62 @@
1
+ import type { AnchorHTMLAttributes, HTMLAttributes, Ref } from "react"
2
+ /**
3
+ * Breadcrumb.types.ts
4
+ *
5
+ * Public and internal types for Breadcrumb component.
6
+ */
7
+
8
+ export interface BreadcrumbProps extends Omit<
9
+ HTMLAttributes<HTMLElement>,
10
+ "className"
11
+ > {
12
+ ref?: Ref<HTMLElement>
13
+ className?: string
14
+ }
15
+
16
+ export interface BreadcrumbListProps extends Omit<
17
+ HTMLAttributes<HTMLOListElement>,
18
+ "className"
19
+ > {
20
+ ref?: Ref<HTMLOListElement>
21
+ className?: string
22
+ }
23
+
24
+ export interface BreadcrumbItemProps extends Omit<
25
+ HTMLAttributes<HTMLLIElement>,
26
+ "className"
27
+ > {
28
+ ref?: Ref<HTMLLIElement>
29
+ className?: string
30
+ }
31
+
32
+ export interface BreadcrumbLinkProps extends Omit<
33
+ AnchorHTMLAttributes<HTMLAnchorElement>,
34
+ "className"
35
+ > {
36
+ ref?: Ref<HTMLAnchorElement>
37
+ className?: string
38
+ }
39
+
40
+ export interface BreadcrumbPageProps extends Omit<
41
+ HTMLAttributes<HTMLSpanElement>,
42
+ "className"
43
+ > {
44
+ ref?: Ref<HTMLSpanElement>
45
+ className?: string
46
+ }
47
+
48
+ export interface BreadcrumbSeparatorProps extends Omit<
49
+ HTMLAttributes<HTMLSpanElement>,
50
+ "className"
51
+ > {
52
+ ref?: Ref<HTMLSpanElement>
53
+ className?: string
54
+ }
55
+
56
+ export interface BreadcrumbEllipsisProps extends Omit<
57
+ HTMLAttributes<HTMLSpanElement>,
58
+ "className"
59
+ > {
60
+ ref?: Ref<HTMLSpanElement>
61
+ className?: string
62
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Breadcrumb.variants.ts
3
+ *
4
+ * Defines visual variants using class composition.
5
+ */
6
+
7
+ import { cva } from "class-variance-authority"
8
+
9
+ export const breadcrumbRootVariants = cva("w-full")
10
+
11
+ export const breadcrumbListVariants = cva(
12
+ "flex flex-wrap items-center gap-(--lex-breadcrumb-list-gap) break-words text-(length:--lex-breadcrumb-link-font-size) leading-(--lex-breadcrumb-link-font-line-height)",
13
+ )
14
+
15
+ export const breadcrumbItemVariants = cva(
16
+ "inline-flex items-center gap-(--lex-breadcrumb-item-gap)",
17
+ )
18
+
19
+ export const breadcrumbLinkVariants = cva(
20
+ [
21
+ "text-(--lex-breadcrumb-link-foreground) font-(--lex-breadcrumb-link-font-weight) transition-colors duration-(--lex-breadcrumb-transition-duration) ease-(--lex-breadcrumb-transition-easing)",
22
+ "hover:text-(--lex-breadcrumb-link-hover-foreground)",
23
+ "outline-none focus-visible:underline",
24
+ ].join(" "),
25
+ )
26
+
27
+ export const breadcrumbPageVariants = cva(
28
+ "font-(--lex-breadcrumb-page-font-weight) text-(--lex-breadcrumb-page-foreground)",
29
+ )
30
+
31
+ export const breadcrumbSeparatorVariants = cva(
32
+ "inline-flex items-center text-(--lex-breadcrumb-separator-foreground)",
33
+ )
34
+
35
+ export const breadcrumbEllipsisVariants = cva(
36
+ "inline-flex h-(--lex-breadcrumb-ellipsis-size) w-(--lex-breadcrumb-ellipsis-size) items-center justify-center text-(--lex-breadcrumb-ellipsis-foreground)",
37
+ )
@@ -0,0 +1,263 @@
1
+ /**
2
+ * DatePicker.tsx
3
+ *
4
+ * Reference DatePicker component implementation.
5
+ */
6
+
7
+ import { useState } from "react"
8
+ import { ChevronLeft, ChevronRight } from "lucide-react"
9
+ import { Input } from "../Input/Input"
10
+ import {
11
+ Popover,
12
+ PopoverPortal,
13
+ PopoverPositioner,
14
+ PopoverPopup,
15
+ PopoverTrigger,
16
+ } from "../Popover/Popover"
17
+ import type {
18
+ DatePickerCalendarProps,
19
+ DatePickerContentProps,
20
+ DatePickerDayProps,
21
+ DatePickerInputProps,
22
+ DatePickerProps,
23
+ DatePickerTriggerProps,
24
+ } from "./DatePicker.types"
25
+ import {
26
+ datePickerCalendarVariants,
27
+ datePickerContentVariants,
28
+ datePickerDayVariants,
29
+ datePickerGridVariants,
30
+ datePickerHeaderVariants,
31
+ datePickerMonthLabelVariants,
32
+ datePickerNavButtonVariants,
33
+ datePickerWeekdayVariants,
34
+ datePickerWeekdaysVariants,
35
+ } from "./DatePicker.variants"
36
+ import { cn } from "@/lib/utils"
37
+
38
+ const WEEKDAY_LABELS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"] as const
39
+
40
+ const isSameDay = (left: Date, right: Date): boolean => {
41
+ return (
42
+ left.getFullYear() === right.getFullYear() &&
43
+ left.getMonth() === right.getMonth() &&
44
+ left.getDate() === right.getDate()
45
+ )
46
+ }
47
+
48
+ const buildCalendarDays = (
49
+ month: Date,
50
+ ): Array<{ date: Date; inMonth: boolean }> => {
51
+ const year = month.getFullYear()
52
+ const monthIndex = month.getMonth()
53
+ const firstDay = new Date(year, monthIndex, 1)
54
+ const lastDay = new Date(year, monthIndex + 1, 0)
55
+ const startOffset = firstDay.getDay()
56
+ const days: Array<{ date: Date; inMonth: boolean }> = []
57
+
58
+ for (let offset = startOffset - 1; offset >= 0; offset -= 1) {
59
+ days.push({
60
+ date: new Date(year, monthIndex, -offset),
61
+ inMonth: false,
62
+ })
63
+ }
64
+
65
+ for (let day = 1; day <= lastDay.getDate(); day += 1) {
66
+ days.push({
67
+ date: new Date(year, monthIndex, day),
68
+ inMonth: true,
69
+ })
70
+ }
71
+
72
+ while (days.length % 7 !== 0) {
73
+ const trailingDay = days.length - startOffset - lastDay.getDate() + 1
74
+ days.push({
75
+ date: new Date(year, monthIndex + 1, trailingDay),
76
+ inMonth: false,
77
+ })
78
+ }
79
+
80
+ return days
81
+ }
82
+
83
+ const formatMonthLabel = (month: Date): string => {
84
+ return month.toLocaleString("default", { month: "long", year: "numeric" })
85
+ }
86
+
87
+ const DatePicker = <Payload = unknown,>(props: DatePickerProps<Payload>) => {
88
+ return <Popover {...props} />
89
+ }
90
+
91
+ DatePicker.displayName = "DatePicker"
92
+
93
+ const DatePickerTrigger = <Payload = unknown,>({
94
+ ref,
95
+ ...props
96
+ }: DatePickerTriggerProps<Payload>) => {
97
+ return <PopoverTrigger ref={ref} {...props} />
98
+ }
99
+
100
+ DatePickerTrigger.displayName = "DatePickerTrigger"
101
+
102
+ const DatePickerInput = ({
103
+ ref,
104
+ className,
105
+ ...props
106
+ }: DatePickerInputProps) => {
107
+ return <Input ref={ref} className={className} {...props} />
108
+ }
109
+
110
+ DatePickerInput.displayName = "DatePickerInput"
111
+
112
+ const DatePickerContent = ({
113
+ ref,
114
+ className,
115
+ children,
116
+ ...props
117
+ }: DatePickerContentProps) => {
118
+ return (
119
+ <PopoverPortal>
120
+ <PopoverPositioner>
121
+ <PopoverPopup
122
+ ref={ref}
123
+ className={cn(datePickerContentVariants(), className)}
124
+ {...props}
125
+ >
126
+ {children}
127
+ </PopoverPopup>
128
+ </PopoverPositioner>
129
+ </PopoverPortal>
130
+ )
131
+ }
132
+
133
+ DatePickerContent.displayName = "DatePickerContent"
134
+
135
+ const DatePickerDay = ({
136
+ ref,
137
+ className,
138
+ date,
139
+ isSelected,
140
+ isOutside,
141
+ isToday,
142
+ type = "button",
143
+ ...props
144
+ }: DatePickerDayProps) => {
145
+ return (
146
+ <button
147
+ ref={ref}
148
+ type={type}
149
+ className={cn(
150
+ datePickerDayVariants({ isSelected, isOutside, isToday }),
151
+ className,
152
+ )}
153
+ {...props}
154
+ >
155
+ {date.getDate()}
156
+ </button>
157
+ )
158
+ }
159
+
160
+ DatePickerDay.displayName = "DatePickerDay"
161
+
162
+ const DatePickerCalendar = ({
163
+ ref,
164
+ className,
165
+ value,
166
+ defaultMonth,
167
+ month,
168
+ onMonthChange,
169
+ onSelect,
170
+ ...props
171
+ }: DatePickerCalendarProps) => {
172
+ const [internalMonth, setInternalMonth] = useState(
173
+ () => defaultMonth ?? value ?? new Date(),
174
+ )
175
+ const viewedMonth = month ?? internalMonth
176
+ const today = new Date()
177
+ const days = buildCalendarDays(viewedMonth)
178
+
179
+ const setMonth = (nextMonth: Date) => {
180
+ if (month === undefined) {
181
+ setInternalMonth(nextMonth)
182
+ }
183
+ onMonthChange?.(nextMonth)
184
+ }
185
+
186
+ return (
187
+ <div
188
+ ref={ref}
189
+ className={cn(datePickerCalendarVariants(), className)}
190
+ {...props}
191
+ >
192
+ <div className={datePickerHeaderVariants()}>
193
+ <button
194
+ type="button"
195
+ aria-label="Previous month"
196
+ className={datePickerNavButtonVariants()}
197
+ onClick={() =>
198
+ setMonth(
199
+ new Date(
200
+ viewedMonth.getFullYear(),
201
+ viewedMonth.getMonth() - 1,
202
+ 1,
203
+ ),
204
+ )
205
+ }
206
+ >
207
+ <ChevronLeft aria-hidden="true" size={16} />
208
+ </button>
209
+ <div className={datePickerMonthLabelVariants()}>
210
+ {formatMonthLabel(viewedMonth)}
211
+ </div>
212
+ <button
213
+ type="button"
214
+ aria-label="Next month"
215
+ className={datePickerNavButtonVariants()}
216
+ onClick={() =>
217
+ setMonth(
218
+ new Date(
219
+ viewedMonth.getFullYear(),
220
+ viewedMonth.getMonth() + 1,
221
+ 1,
222
+ ),
223
+ )
224
+ }
225
+ >
226
+ <ChevronRight aria-hidden="true" size={16} />
227
+ </button>
228
+ </div>
229
+
230
+ <div className={datePickerWeekdaysVariants()}>
231
+ {WEEKDAY_LABELS.map((label) => (
232
+ <span key={label} className={datePickerWeekdayVariants()}>
233
+ {label}
234
+ </span>
235
+ ))}
236
+ </div>
237
+
238
+ <div className={datePickerGridVariants()}>
239
+ {days.map(({ date, inMonth }) => (
240
+ <DatePickerDay
241
+ key={date.toISOString()}
242
+ date={date}
243
+ isOutside={!inMonth}
244
+ isSelected={value ? isSameDay(date, value) : false}
245
+ isToday={isSameDay(date, today)}
246
+ onClick={() => onSelect?.(date)}
247
+ />
248
+ ))}
249
+ </div>
250
+ </div>
251
+ )
252
+ }
253
+
254
+ DatePickerCalendar.displayName = "DatePickerCalendar"
255
+
256
+ export {
257
+ DatePicker,
258
+ DatePickerTrigger,
259
+ DatePickerInput,
260
+ DatePickerContent,
261
+ DatePickerCalendar,
262
+ DatePickerDay,
263
+ }