@boyernick/standard-ui-react 0.1.1-canary.2 → 0.1.1-canary.4
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/package.json +1 -1
- package/src/accordion.tsx +1 -1
- package/src/autocomplete.tsx +10 -11
- package/src/badge.tsx +73 -9
- package/src/breadcrumb.tsx +39 -21
- package/src/button.tsx +2 -2
- package/src/calendar.tsx +22 -11
- package/src/card.tsx +57 -14
- package/src/carousel.tsx +163 -6
- package/src/checkbox.tsx +1 -1
- package/src/date-picker.tsx +169 -0
- package/src/drawer.tsx +1 -1
- package/src/field.tsx +1 -1
- package/src/icons.tsx +27 -0
- package/src/index.ts +18 -0
- package/src/input.tsx +1 -1
- package/src/lib/motion.ts +113 -18
- package/src/menu.tsx +3 -3
- package/src/meter.tsx +1 -1
- package/src/navigation-menu.tsx +2 -2
- package/src/progress.tsx +1 -1
- package/src/scroll-area.tsx +1 -1
- package/src/slider.tsx +1 -1
- package/src/switch.tsx +2 -2
- package/src/text-animate.tsx +2 -2
- package/src/textarea.tsx +1 -1
- package/src/toast.tsx +2 -2
package/src/carousel.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
useCallback,
|
|
9
9
|
useContext,
|
|
10
10
|
useEffect,
|
|
11
|
+
useRef,
|
|
11
12
|
useSyncExternalStore,
|
|
12
13
|
type ComponentProps,
|
|
13
14
|
type KeyboardEvent,
|
|
@@ -21,6 +22,9 @@ type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
|
|
|
21
22
|
type CarouselOptions = UseCarouselParameters[0]
|
|
22
23
|
type CarouselPlugin = UseCarouselParameters[1]
|
|
23
24
|
|
|
25
|
+
const TRACKPAD_SWIPE_THRESHOLD = 24
|
|
26
|
+
const TRACKPAD_GESTURE_END_DELAY = 140
|
|
27
|
+
|
|
24
28
|
type CarouselContextValue = {
|
|
25
29
|
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
|
|
26
30
|
api: CarouselApi
|
|
@@ -46,6 +50,8 @@ export type CarouselProps = ComponentProps<"div"> & {
|
|
|
46
50
|
plugins?: CarouselPlugin
|
|
47
51
|
orientation?: "horizontal" | "vertical"
|
|
48
52
|
setApi?: (api: CarouselApi) => void
|
|
53
|
+
/** Adds directional edge fades wherever more slides are available. */
|
|
54
|
+
fade?: boolean
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
export type CarouselContentProps = ComponentProps<"div">
|
|
@@ -53,16 +59,54 @@ export type CarouselItemProps = ComponentProps<"div">
|
|
|
53
59
|
export type CarouselPreviousProps = ComponentProps<typeof Button>
|
|
54
60
|
export type CarouselNextProps = ComponentProps<typeof Button>
|
|
55
61
|
|
|
62
|
+
const CarouselEdgeFades = () => {
|
|
63
|
+
const { orientation, canScrollPrev, canScrollNext } = useCarousel()
|
|
64
|
+
const horizontal = orientation === "horizontal"
|
|
65
|
+
const sharedClassName =
|
|
66
|
+
"pointer-events-none absolute z-10 opacity-0 transition-opacity duration-[var(--duration-lg)] ease-enter data-[visible=true]:opacity-100 motion-reduce:transition-none"
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<>
|
|
70
|
+
<div
|
|
71
|
+
aria-hidden="true"
|
|
72
|
+
data-slot={horizontal ? "carousel-fade-left" : "carousel-fade-top"}
|
|
73
|
+
data-visible={canScrollPrev}
|
|
74
|
+
className={cn(
|
|
75
|
+
sharedClassName,
|
|
76
|
+
horizontal
|
|
77
|
+
? "-top-px -bottom-px -left-px w-20 bg-linear-to-r from-surface via-surface/60 via-40% to-transparent"
|
|
78
|
+
: "-top-px -right-px -left-px h-20 bg-linear-to-b from-surface via-surface/60 via-40% to-transparent",
|
|
79
|
+
)}
|
|
80
|
+
/>
|
|
81
|
+
<div
|
|
82
|
+
aria-hidden="true"
|
|
83
|
+
data-slot={horizontal ? "carousel-fade-right" : "carousel-fade-bottom"}
|
|
84
|
+
data-visible={canScrollNext}
|
|
85
|
+
className={cn(
|
|
86
|
+
sharedClassName,
|
|
87
|
+
horizontal
|
|
88
|
+
? "-top-px -right-px -bottom-px w-20 bg-linear-to-l from-surface via-surface/60 via-40% to-transparent"
|
|
89
|
+
: "-right-px -bottom-px -left-px h-20 bg-linear-to-t from-surface via-surface/60 via-40% to-transparent",
|
|
90
|
+
)}
|
|
91
|
+
/>
|
|
92
|
+
</>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
|
|
56
96
|
export const Carousel = ({
|
|
57
97
|
orientation = "horizontal",
|
|
98
|
+
fade = false,
|
|
58
99
|
opts,
|
|
59
100
|
setApi,
|
|
60
101
|
plugins,
|
|
61
102
|
className,
|
|
62
103
|
children,
|
|
63
104
|
onKeyDownCapture,
|
|
105
|
+
tabIndex,
|
|
106
|
+
ref: forwardedRef,
|
|
64
107
|
...props
|
|
65
108
|
}: CarouselProps) => {
|
|
109
|
+
const carouselRootRef = useRef<HTMLDivElement | null>(null)
|
|
66
110
|
const [carouselRef, api] = useEmblaCarousel(
|
|
67
111
|
{
|
|
68
112
|
...opts,
|
|
@@ -107,6 +151,35 @@ export const Carousel = ({
|
|
|
107
151
|
api?.scrollNext()
|
|
108
152
|
}, [api])
|
|
109
153
|
|
|
154
|
+
const canScrollPrevRef = useRef(canScrollPrev)
|
|
155
|
+
const canScrollNextRef = useRef(canScrollNext)
|
|
156
|
+
const scrollPrevRef = useRef(scrollPrev)
|
|
157
|
+
const scrollNextRef = useRef(scrollNext)
|
|
158
|
+
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
canScrollPrevRef.current = canScrollPrev
|
|
161
|
+
canScrollNextRef.current = canScrollNext
|
|
162
|
+
scrollPrevRef.current = scrollPrev
|
|
163
|
+
scrollNextRef.current = scrollNext
|
|
164
|
+
}, [canScrollNext, canScrollPrev, scrollNext, scrollPrev])
|
|
165
|
+
|
|
166
|
+
const trackpadDelta = useRef(0)
|
|
167
|
+
const trackpadGestureHandled = useRef(false)
|
|
168
|
+
const trackpadGestureTimeout = useRef<ReturnType<typeof setTimeout> | null>(
|
|
169
|
+
null,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
const scheduleTrackpadGestureEnd = useCallback(() => {
|
|
173
|
+
if (trackpadGestureTimeout.current) {
|
|
174
|
+
clearTimeout(trackpadGestureTimeout.current)
|
|
175
|
+
}
|
|
176
|
+
trackpadGestureTimeout.current = setTimeout(() => {
|
|
177
|
+
trackpadDelta.current = 0
|
|
178
|
+
trackpadGestureHandled.current = false
|
|
179
|
+
trackpadGestureTimeout.current = null
|
|
180
|
+
}, TRACKPAD_GESTURE_END_DELAY)
|
|
181
|
+
}, [])
|
|
182
|
+
|
|
110
183
|
const handleKeyDown = useCallback(
|
|
111
184
|
(event: KeyboardEvent<HTMLDivElement>) => {
|
|
112
185
|
onKeyDownCapture?.(event)
|
|
@@ -122,6 +195,72 @@ export const Carousel = ({
|
|
|
122
195
|
[onKeyDownCapture, scrollNext, scrollPrev],
|
|
123
196
|
)
|
|
124
197
|
|
|
198
|
+
const handleWheel = useCallback(
|
|
199
|
+
(event: globalThis.WheelEvent) => {
|
|
200
|
+
if (event.defaultPrevented || orientation !== "horizontal") return
|
|
201
|
+
|
|
202
|
+
const deltaMultiplier =
|
|
203
|
+
event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? 100 : 1
|
|
204
|
+
const horizontalDelta = event.deltaX * deltaMultiplier
|
|
205
|
+
const verticalDelta = event.deltaY * deltaMultiplier
|
|
206
|
+
|
|
207
|
+
if (
|
|
208
|
+
Math.abs(horizontalDelta) <= Math.abs(verticalDelta) ||
|
|
209
|
+
Math.abs(horizontalDelta) < 1
|
|
210
|
+
) {
|
|
211
|
+
return
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (trackpadGestureHandled.current) {
|
|
215
|
+
event.preventDefault()
|
|
216
|
+
scheduleTrackpadGestureEnd()
|
|
217
|
+
return
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const canScrollInDirection =
|
|
221
|
+
horizontalDelta > 0
|
|
222
|
+
? canScrollNextRef.current
|
|
223
|
+
: canScrollPrevRef.current
|
|
224
|
+
if (!canScrollInDirection) return
|
|
225
|
+
|
|
226
|
+
event.preventDefault()
|
|
227
|
+
trackpadDelta.current += horizontalDelta
|
|
228
|
+
scheduleTrackpadGestureEnd()
|
|
229
|
+
|
|
230
|
+
if (Math.abs(trackpadDelta.current) < TRACKPAD_SWIPE_THRESHOLD) return
|
|
231
|
+
|
|
232
|
+
trackpadGestureHandled.current = true
|
|
233
|
+
trackpadDelta.current = 0
|
|
234
|
+
if (horizontalDelta > 0) scrollNextRef.current()
|
|
235
|
+
else scrollPrevRef.current()
|
|
236
|
+
},
|
|
237
|
+
[orientation, scheduleTrackpadGestureEnd],
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
useEffect(() => {
|
|
241
|
+
const root = carouselRootRef.current
|
|
242
|
+
if (!root) return
|
|
243
|
+
|
|
244
|
+
root.addEventListener("wheel", handleWheel, { passive: false })
|
|
245
|
+
return () => {
|
|
246
|
+
root.removeEventListener("wheel", handleWheel)
|
|
247
|
+
if (trackpadGestureTimeout.current) {
|
|
248
|
+
clearTimeout(trackpadGestureTimeout.current)
|
|
249
|
+
}
|
|
250
|
+
trackpadDelta.current = 0
|
|
251
|
+
trackpadGestureHandled.current = false
|
|
252
|
+
}
|
|
253
|
+
}, [handleWheel])
|
|
254
|
+
|
|
255
|
+
const setCarouselRootRef = useCallback(
|
|
256
|
+
(node: HTMLDivElement | null) => {
|
|
257
|
+
carouselRootRef.current = node
|
|
258
|
+
if (typeof forwardedRef === "function") forwardedRef(node)
|
|
259
|
+
else if (forwardedRef) forwardedRef.current = node
|
|
260
|
+
},
|
|
261
|
+
[forwardedRef],
|
|
262
|
+
)
|
|
263
|
+
|
|
125
264
|
useEffect(() => {
|
|
126
265
|
if (!api || !setApi) return
|
|
127
266
|
setApi(api)
|
|
@@ -140,14 +279,23 @@ export const Carousel = ({
|
|
|
140
279
|
}}
|
|
141
280
|
>
|
|
142
281
|
<div
|
|
282
|
+
ref={setCarouselRootRef}
|
|
143
283
|
role="region"
|
|
144
284
|
aria-roledescription="carousel"
|
|
145
285
|
data-slot="carousel"
|
|
146
|
-
|
|
286
|
+
data-fade={fade || undefined}
|
|
287
|
+
className={cn(
|
|
288
|
+
"relative",
|
|
289
|
+
fade &&
|
|
290
|
+
"rounded-xl outline-none focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20",
|
|
291
|
+
className,
|
|
292
|
+
)}
|
|
147
293
|
onKeyDownCapture={handleKeyDown}
|
|
294
|
+
tabIndex={tabIndex ?? (fade ? 0 : undefined)}
|
|
148
295
|
{...props}
|
|
149
296
|
>
|
|
150
297
|
{children}
|
|
298
|
+
{fade ? <CarouselEdgeFades /> : null}
|
|
151
299
|
</div>
|
|
152
300
|
</CarouselContext.Provider>
|
|
153
301
|
)
|
|
@@ -160,7 +308,16 @@ export const CarouselContent = ({
|
|
|
160
308
|
const { carouselRef, orientation } = useCarousel()
|
|
161
309
|
|
|
162
310
|
return (
|
|
163
|
-
<div
|
|
311
|
+
<div
|
|
312
|
+
ref={carouselRef}
|
|
313
|
+
className={cn(
|
|
314
|
+
"overflow-hidden",
|
|
315
|
+
orientation === "horizontal"
|
|
316
|
+
? "touch-pan-y overscroll-x-contain"
|
|
317
|
+
: "touch-pan-x overscroll-y-contain",
|
|
318
|
+
)}
|
|
319
|
+
data-slot="carousel-viewport"
|
|
320
|
+
>
|
|
164
321
|
<div
|
|
165
322
|
data-slot="carousel-content"
|
|
166
323
|
className={cn(
|
|
@@ -194,7 +351,7 @@ export const CarouselItem = ({ className, ...props }: CarouselItemProps) => {
|
|
|
194
351
|
|
|
195
352
|
export const CarouselPrevious = ({
|
|
196
353
|
className,
|
|
197
|
-
variant = "
|
|
354
|
+
variant = "ghost",
|
|
198
355
|
size = "md",
|
|
199
356
|
...props
|
|
200
357
|
}: CarouselPreviousProps) => {
|
|
@@ -211,7 +368,7 @@ export const CarouselPrevious = ({
|
|
|
211
368
|
aria-label="Previous slide"
|
|
212
369
|
data-slot="carousel-previous"
|
|
213
370
|
className={cn(
|
|
214
|
-
"absolute size-9",
|
|
371
|
+
"absolute size-9 border-0 focus-visible:border-0",
|
|
215
372
|
orientation === "horizontal"
|
|
216
373
|
? "top-1/2 -left-12 -translate-y-1/2 active:!-translate-y-1/2"
|
|
217
374
|
: "-top-12 left-1/2 -translate-x-1/2 rotate-90 active:!-translate-x-1/2 active:!translate-y-0",
|
|
@@ -227,7 +384,7 @@ export const CarouselPrevious = ({
|
|
|
227
384
|
|
|
228
385
|
export const CarouselNext = ({
|
|
229
386
|
className,
|
|
230
|
-
variant = "
|
|
387
|
+
variant = "ghost",
|
|
231
388
|
size = "md",
|
|
232
389
|
...props
|
|
233
390
|
}: CarouselNextProps) => {
|
|
@@ -244,7 +401,7 @@ export const CarouselNext = ({
|
|
|
244
401
|
aria-label="Next slide"
|
|
245
402
|
data-slot="carousel-next"
|
|
246
403
|
className={cn(
|
|
247
|
-
"absolute size-9",
|
|
404
|
+
"absolute size-9 border-0 focus-visible:border-0",
|
|
248
405
|
orientation === "horizontal"
|
|
249
406
|
? "top-1/2 -right-12 -translate-y-1/2 active:!-translate-y-1/2"
|
|
250
407
|
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90 active:!-translate-x-1/2 active:!translate-y-0",
|
package/src/checkbox.tsx
CHANGED
|
@@ -10,7 +10,7 @@ export type CheckboxProps = ComponentProps<typeof BaseCheckbox.Root>
|
|
|
10
10
|
export const Checkbox = ({ className, ...props }: CheckboxProps) => (
|
|
11
11
|
<BaseCheckbox.Root
|
|
12
12
|
className={cn(
|
|
13
|
-
"group flex size-4 shrink-0 items-center justify-center rounded-sm border border-border-secondary bg-surface transition-colors duration-
|
|
13
|
+
"group flex size-4 shrink-0 items-center justify-center rounded-sm border border-border-secondary bg-surface transition-colors duration-[var(--duration-sm)] ease-enter motion-reduce:transition-none outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 data-checked:border-brand-primary data-checked:bg-brand-primary data-indeterminate:border-brand-primary data-indeterminate:bg-brand-primary data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
14
14
|
className,
|
|
15
15
|
)}
|
|
16
16
|
{...props}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { useState, type ReactNode } from "react"
|
|
4
|
+
import type { DateRange, PropsBase } from "react-day-picker"
|
|
5
|
+
import { Button } from "./button"
|
|
6
|
+
import { Calendar } from "./calendar"
|
|
7
|
+
import { IconCalendar1 } from "./icons"
|
|
8
|
+
import { cn } from "./lib/cn"
|
|
9
|
+
import {
|
|
10
|
+
Popover,
|
|
11
|
+
PopoverPopup,
|
|
12
|
+
PopoverPortal,
|
|
13
|
+
PopoverPositioner,
|
|
14
|
+
PopoverTrigger,
|
|
15
|
+
} from "./popover"
|
|
16
|
+
|
|
17
|
+
const dateFormatter = new Intl.DateTimeFormat("en-US", {
|
|
18
|
+
month: "short",
|
|
19
|
+
day: "numeric",
|
|
20
|
+
year: "numeric",
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const formatDate = (date: Date) => dateFormatter.format(date)
|
|
24
|
+
|
|
25
|
+
type DatePickerBaseProps = {
|
|
26
|
+
/** Options forwarded to Calendar, excluding its selection mode. */
|
|
27
|
+
calendarProps?: Omit<PropsBase, "mode" | "required">
|
|
28
|
+
/** Classes applied to the trigger button. */
|
|
29
|
+
className?: string
|
|
30
|
+
/** Disables the trigger button. */
|
|
31
|
+
disabled?: boolean
|
|
32
|
+
/** Placeholder shown when no date is selected. */
|
|
33
|
+
placeholder?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type DatePickerSingleProps = DatePickerBaseProps & {
|
|
37
|
+
mode?: "single"
|
|
38
|
+
selected?: Date
|
|
39
|
+
onSelect?: (date: Date | undefined) => void
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type DatePickerRangeProps = DatePickerBaseProps & {
|
|
43
|
+
mode: "range"
|
|
44
|
+
selected?: DateRange
|
|
45
|
+
onSelect?: (range: DateRange | undefined) => void
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type DatePickerProps = DatePickerSingleProps | DatePickerRangeProps
|
|
49
|
+
|
|
50
|
+
const DatePickerTrigger = ({
|
|
51
|
+
className,
|
|
52
|
+
disabled,
|
|
53
|
+
empty,
|
|
54
|
+
label,
|
|
55
|
+
}: {
|
|
56
|
+
className?: string
|
|
57
|
+
disabled?: boolean
|
|
58
|
+
empty: boolean
|
|
59
|
+
label: string
|
|
60
|
+
}) => (
|
|
61
|
+
<PopoverTrigger
|
|
62
|
+
render={
|
|
63
|
+
<Button
|
|
64
|
+
type="button"
|
|
65
|
+
size="sm"
|
|
66
|
+
variant="outline"
|
|
67
|
+
disabled={disabled}
|
|
68
|
+
prefix={<IconCalendar1 aria-hidden />}
|
|
69
|
+
className={cn("w-56 justify-start", className)}
|
|
70
|
+
/>
|
|
71
|
+
}
|
|
72
|
+
>
|
|
73
|
+
<span
|
|
74
|
+
className={cn(
|
|
75
|
+
"min-w-0 flex-1 truncate text-left",
|
|
76
|
+
empty && "text-fg-tertiary",
|
|
77
|
+
)}
|
|
78
|
+
>
|
|
79
|
+
{label}
|
|
80
|
+
</span>
|
|
81
|
+
</PopoverTrigger>
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
const DatePickerPopup = ({ children }: { children: ReactNode }) => (
|
|
85
|
+
<PopoverPortal>
|
|
86
|
+
<PopoverPositioner align="start" sideOffset={6}>
|
|
87
|
+
<PopoverPopup className="w-auto gap-0 p-0">{children}</PopoverPopup>
|
|
88
|
+
</PopoverPositioner>
|
|
89
|
+
</PopoverPortal>
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
const SingleDatePicker = ({
|
|
93
|
+
calendarProps,
|
|
94
|
+
className,
|
|
95
|
+
disabled,
|
|
96
|
+
onSelect,
|
|
97
|
+
placeholder = "Pick a date",
|
|
98
|
+
selected,
|
|
99
|
+
}: DatePickerSingleProps) => {
|
|
100
|
+
const [open, setOpen] = useState(false)
|
|
101
|
+
|
|
102
|
+
const handleSelect = (date: Date | undefined) => {
|
|
103
|
+
onSelect?.(date)
|
|
104
|
+
if (date) setOpen(false)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
109
|
+
<DatePickerTrigger
|
|
110
|
+
className={className}
|
|
111
|
+
disabled={disabled}
|
|
112
|
+
empty={!selected}
|
|
113
|
+
label={selected ? formatDate(selected) : placeholder}
|
|
114
|
+
/>
|
|
115
|
+
<DatePickerPopup>
|
|
116
|
+
<Calendar
|
|
117
|
+
{...calendarProps}
|
|
118
|
+
className={cn("border-0", calendarProps?.className)}
|
|
119
|
+
mode="single"
|
|
120
|
+
selected={selected}
|
|
121
|
+
onSelect={handleSelect}
|
|
122
|
+
/>
|
|
123
|
+
</DatePickerPopup>
|
|
124
|
+
</Popover>
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const RangeDatePicker = ({
|
|
129
|
+
calendarProps,
|
|
130
|
+
className,
|
|
131
|
+
disabled,
|
|
132
|
+
onSelect,
|
|
133
|
+
placeholder = "Pick a date range",
|
|
134
|
+
selected,
|
|
135
|
+
}: DatePickerRangeProps) => {
|
|
136
|
+
const [open, setOpen] = useState(false)
|
|
137
|
+
const label = selected?.from
|
|
138
|
+
? selected.to
|
|
139
|
+
? `${formatDate(selected.from)} – ${formatDate(selected.to)}`
|
|
140
|
+
: `${formatDate(selected.from)} – Select end date`
|
|
141
|
+
: placeholder
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
145
|
+
<DatePickerTrigger
|
|
146
|
+
className={className}
|
|
147
|
+
disabled={disabled}
|
|
148
|
+
empty={!selected?.from}
|
|
149
|
+
label={label}
|
|
150
|
+
/>
|
|
151
|
+
<DatePickerPopup>
|
|
152
|
+
<Calendar
|
|
153
|
+
{...calendarProps}
|
|
154
|
+
className={cn("border-0", calendarProps?.className)}
|
|
155
|
+
mode="range"
|
|
156
|
+
selected={selected}
|
|
157
|
+
onSelect={onSelect}
|
|
158
|
+
/>
|
|
159
|
+
</DatePickerPopup>
|
|
160
|
+
</Popover>
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export const DatePicker = (props: DatePickerProps) =>
|
|
165
|
+
props.mode === "range" ? (
|
|
166
|
+
<RangeDatePicker {...props} />
|
|
167
|
+
) : (
|
|
168
|
+
<SingleDatePicker {...props} />
|
|
169
|
+
)
|
package/src/drawer.tsx
CHANGED
|
@@ -69,7 +69,7 @@ export const DrawerPopup = ({ className, ...props }: DrawerPopupProps) => (
|
|
|
69
69
|
<BaseDrawer.Popup
|
|
70
70
|
className={cn(
|
|
71
71
|
"fixed z-50 flex flex-col border-border-primary bg-surface shadow-md outline-none",
|
|
72
|
-
"transition-[transform,opacity] duration-
|
|
72
|
+
"transition-[transform,opacity] duration-[var(--duration-lg)] ease-move motion-reduce:transition-none",
|
|
73
73
|
"data-swiping:duration-0",
|
|
74
74
|
// Right panel (swipeDirection="right")
|
|
75
75
|
"data-[swipe-direction=right]:top-0 data-[swipe-direction=right]:right-0 data-[swipe-direction=right]:h-full data-[swipe-direction=right]:w-full data-[swipe-direction=right]:max-w-sm data-[swipe-direction=right]:border-l",
|
package/src/field.tsx
CHANGED
|
@@ -49,7 +49,7 @@ export const FieldError = ({ className, ...props }: FieldErrorProps) => (
|
|
|
49
49
|
export const FieldControl = ({ className, ...props }: FieldControlProps) => (
|
|
50
50
|
<BaseField.Control
|
|
51
51
|
className={cn(
|
|
52
|
-
"text-sm flex h-9 w-full cursor-text rounded-md border border-border-secondary bg-surface px-3 text-fg-primary inset-shadow-outline-top outline-none transition-[color,box-shadow] duration-
|
|
52
|
+
"text-sm flex h-9 w-full cursor-text rounded-md border border-border-secondary bg-surface px-3 text-fg-primary inset-shadow-outline-top outline-none transition-[color,box-shadow] duration-[var(--duration-sm)] ease-enter placeholder:text-fg-quaternary",
|
|
53
53
|
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20",
|
|
54
54
|
"data-invalid:border-destructive data-invalid:focus-visible:border-destructive data-invalid:focus-visible:ring-destructive/20",
|
|
55
55
|
"aria-invalid:border-destructive aria-invalid:focus-visible:border-destructive aria-invalid:focus-visible:ring-destructive/20",
|
package/src/icons.tsx
CHANGED
|
@@ -2,13 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
import type { CentralIconBaseProps } from "@central-icons-react/round-outlined-radius-2-stroke-2/CentralIconBase"
|
|
4
4
|
import { IconBell as IconBellBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconBell"
|
|
5
|
+
import { IconCalendar1 as IconCalendar1Base } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconCalendar1"
|
|
5
6
|
import { IconChainLink1 as IconChainLink1Base } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconChainLink1"
|
|
6
7
|
import { IconCheckmark1 as IconCheckmark1Base } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconCheckmark1"
|
|
7
8
|
import { IconChevronBottom as IconChevronBottomBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconChevronBottom"
|
|
8
9
|
import { IconChevronDownSmall as IconChevronDownSmallBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconChevronDownSmall"
|
|
9
10
|
import { IconChevronRightSmall as IconChevronRightSmallBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconChevronRightSmall"
|
|
11
|
+
import { IconCircleCheck as IconCircleCheckBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconCircleCheck"
|
|
12
|
+
import { IconCircleInfo as IconCircleInfoBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconCircleInfo"
|
|
10
13
|
import { IconClipboard as IconClipboardBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconClipboard"
|
|
11
14
|
import { IconCrossSmall as IconCrossSmallBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconCrossSmall"
|
|
15
|
+
import { IconDotGrid1x3Horizontal as IconDotGrid1x3HorizontalBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconDotGrid1x3Horizontal"
|
|
16
|
+
import { IconExclamationCircle as IconExclamationCircleBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconExclamationCircle"
|
|
17
|
+
import { IconExclamationTriangle as IconExclamationTriangleBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconExclamationTriangle"
|
|
12
18
|
import { IconHome as IconHomeBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconHome"
|
|
13
19
|
import { IconMagnifyingGlass as IconMagnifyingGlassBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconMagnifyingGlass"
|
|
14
20
|
import { IconMinusMedium as IconMinusBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconMinusMedium"
|
|
@@ -17,6 +23,7 @@ import { IconPeople as IconPeopleBase } from "@central-icons-react/round-outline
|
|
|
17
23
|
import { IconPlusMedium as IconPlusBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconPlusMedium"
|
|
18
24
|
import { IconSettingsGear1 as IconSettingsGear1Base } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconSettingsGear1"
|
|
19
25
|
import { IconSquareBehindSquare6 as IconSquareBehindSquare6Base } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconSquareBehindSquare6"
|
|
26
|
+
import { IconStar as IconStarBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconStar"
|
|
20
27
|
import { IconSun as IconSunBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconSun"
|
|
21
28
|
import { IconX as IconXBase } from "@central-icons-react/round-outlined-radius-2-stroke-2/IconX"
|
|
22
29
|
import type { ComponentType } from "react"
|
|
@@ -43,6 +50,7 @@ export const withCentralIconDefaults = (
|
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
export const IconBell = withCentralIconDefaults(IconBellBase)
|
|
53
|
+
export const IconCalendar1 = withCentralIconDefaults(IconCalendar1Base)
|
|
46
54
|
export const IconChainLink1 = withCentralIconDefaults(IconChainLink1Base)
|
|
47
55
|
export const IconCheckmark1 = withCentralIconDefaults(IconCheckmark1Base)
|
|
48
56
|
export const IconChevronBottom = withCentralIconDefaults(IconChevronBottomBase)
|
|
@@ -52,8 +60,19 @@ export const IconChevronDownSmall = withCentralIconDefaults(
|
|
|
52
60
|
export const IconChevronRightSmall = withCentralIconDefaults(
|
|
53
61
|
IconChevronRightSmallBase,
|
|
54
62
|
)
|
|
63
|
+
export const IconCircleCheck = withCentralIconDefaults(IconCircleCheckBase)
|
|
64
|
+
export const IconCircleInfo = withCentralIconDefaults(IconCircleInfoBase)
|
|
55
65
|
export const IconClipboard = withCentralIconDefaults(IconClipboardBase)
|
|
56
66
|
export const IconCrossSmall = withCentralIconDefaults(IconCrossSmallBase)
|
|
67
|
+
export const IconDotGrid1x3Horizontal = withCentralIconDefaults(
|
|
68
|
+
IconDotGrid1x3HorizontalBase,
|
|
69
|
+
)
|
|
70
|
+
export const IconExclamationCircle = withCentralIconDefaults(
|
|
71
|
+
IconExclamationCircleBase,
|
|
72
|
+
)
|
|
73
|
+
export const IconExclamationTriangle = withCentralIconDefaults(
|
|
74
|
+
IconExclamationTriangleBase,
|
|
75
|
+
)
|
|
57
76
|
export const IconHome = withCentralIconDefaults(IconHomeBase)
|
|
58
77
|
export const IconMagnifyingGlass = withCentralIconDefaults(
|
|
59
78
|
IconMagnifyingGlassBase,
|
|
@@ -66,11 +85,13 @@ export const IconSettingsGear1 = withCentralIconDefaults(IconSettingsGear1Base)
|
|
|
66
85
|
export const IconSquareBehindSquare6 = withCentralIconDefaults(
|
|
67
86
|
IconSquareBehindSquare6Base,
|
|
68
87
|
)
|
|
88
|
+
export const IconStar = withCentralIconDefaults(IconStarBase)
|
|
69
89
|
export const IconSun = withCentralIconDefaults(IconSunBase)
|
|
70
90
|
export const IconX = withCentralIconDefaults(IconXBase)
|
|
71
91
|
|
|
72
92
|
export const iconGallery = [
|
|
73
93
|
{ name: "IconHome", Icon: IconHome },
|
|
94
|
+
{ name: "IconCalendar1", Icon: IconCalendar1 },
|
|
74
95
|
{ name: "IconMagnifyingGlass", Icon: IconMagnifyingGlass },
|
|
75
96
|
{ name: "IconSettingsGear1", Icon: IconSettingsGear1 },
|
|
76
97
|
{ name: "IconBell", Icon: IconBell },
|
|
@@ -85,7 +106,13 @@ export const iconGallery = [
|
|
|
85
106
|
{ name: "IconChevronBottom", Icon: IconChevronBottom },
|
|
86
107
|
{ name: "IconChevronDownSmall", Icon: IconChevronDownSmall },
|
|
87
108
|
{ name: "IconChevronRightSmall", Icon: IconChevronRightSmall },
|
|
109
|
+
{ name: "IconCircleCheck", Icon: IconCircleCheck },
|
|
110
|
+
{ name: "IconCircleInfo", Icon: IconCircleInfo },
|
|
88
111
|
{ name: "IconClipboard", Icon: IconClipboard },
|
|
112
|
+
{ name: "IconDotGrid1x3Horizontal", Icon: IconDotGrid1x3Horizontal },
|
|
89
113
|
{ name: "IconSquareBehindSquare6", Icon: IconSquareBehindSquare6 },
|
|
90
114
|
{ name: "IconChainLink1", Icon: IconChainLink1 },
|
|
115
|
+
{ name: "IconExclamationCircle", Icon: IconExclamationCircle },
|
|
116
|
+
{ name: "IconExclamationTriangle", Icon: IconExclamationTriangle },
|
|
117
|
+
{ name: "IconStar", Icon: IconStar },
|
|
91
118
|
] as const
|
package/src/index.ts
CHANGED
|
@@ -92,17 +92,27 @@ export {
|
|
|
92
92
|
type AvatarFallbackProps,
|
|
93
93
|
} from "./avatar";
|
|
94
94
|
export { Calendar, type CalendarProps } from "./calendar";
|
|
95
|
+
export {
|
|
96
|
+
DatePicker,
|
|
97
|
+
type DatePickerProps,
|
|
98
|
+
type DatePickerSingleProps,
|
|
99
|
+
type DatePickerRangeProps,
|
|
100
|
+
} from "./date-picker";
|
|
101
|
+
export type { DateRange } from "react-day-picker";
|
|
95
102
|
export {
|
|
96
103
|
Card,
|
|
97
104
|
CardHeader,
|
|
98
105
|
CardTitle,
|
|
99
106
|
CardDescription,
|
|
107
|
+
CardAction,
|
|
100
108
|
CardContent,
|
|
101
109
|
CardFooter,
|
|
110
|
+
cardVariants,
|
|
102
111
|
type CardProps,
|
|
103
112
|
type CardHeaderProps,
|
|
104
113
|
type CardTitleProps,
|
|
105
114
|
type CardDescriptionProps,
|
|
115
|
+
type CardActionProps,
|
|
106
116
|
type CardContentProps,
|
|
107
117
|
type CardFooterProps,
|
|
108
118
|
} from "./card";
|
|
@@ -650,6 +660,7 @@ export {
|
|
|
650
660
|
BreadcrumbLink,
|
|
651
661
|
BreadcrumbPage,
|
|
652
662
|
BreadcrumbSeparator,
|
|
663
|
+
breadcrumbSeparatorVariants,
|
|
653
664
|
type BreadcrumbProps,
|
|
654
665
|
type BreadcrumbListProps,
|
|
655
666
|
type BreadcrumbItemProps,
|
|
@@ -785,13 +796,19 @@ export {
|
|
|
785
796
|
withCentralIconDefaults,
|
|
786
797
|
iconGallery,
|
|
787
798
|
IconBell,
|
|
799
|
+
IconCalendar1,
|
|
788
800
|
IconChainLink1,
|
|
789
801
|
IconCheckmark1,
|
|
790
802
|
IconChevronBottom,
|
|
791
803
|
IconChevronDownSmall,
|
|
792
804
|
IconChevronRightSmall,
|
|
805
|
+
IconCircleCheck,
|
|
806
|
+
IconCircleInfo,
|
|
793
807
|
IconClipboard,
|
|
794
808
|
IconCrossSmall,
|
|
809
|
+
IconDotGrid1x3Horizontal,
|
|
810
|
+
IconExclamationCircle,
|
|
811
|
+
IconExclamationTriangle,
|
|
795
812
|
IconHome,
|
|
796
813
|
IconMagnifyingGlass,
|
|
797
814
|
IconMinus,
|
|
@@ -800,6 +817,7 @@ export {
|
|
|
800
817
|
IconPlus,
|
|
801
818
|
IconSettingsGear1,
|
|
802
819
|
IconSquareBehindSquare6,
|
|
820
|
+
IconStar,
|
|
803
821
|
IconSun,
|
|
804
822
|
IconX,
|
|
805
823
|
type CentralIconProps,
|
package/src/input.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import { forwardRef, type InputHTMLAttributes } from "react"
|
|
|
5
5
|
import { cn } from "./lib/cn"
|
|
6
6
|
|
|
7
7
|
const inputVariants = cva(
|
|
8
|
-
"text-sm flex w-full cursor-text rounded-md text-fg-primary transition-[color,box-shadow] duration-
|
|
8
|
+
"text-sm flex w-full cursor-text rounded-md text-fg-primary transition-[color,box-shadow] duration-[var(--duration-sm)] ease-enter placeholder:text-fg-quaternary outline-none aria-invalid:border-destructive disabled:cursor-not-allowed disabled:opacity-50",
|
|
9
9
|
{
|
|
10
10
|
variants: {
|
|
11
11
|
variant: {
|