@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/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
- className={cn("relative", className)}
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 ref={carouselRef} className="overflow-hidden" data-slot="carousel-viewport">
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 = "outline",
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 = "outline",
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-150 ease-out 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",
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-300 ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:transition-none",
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-150 ease-out placeholder:text-fg-quaternary",
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-150 ease-out placeholder:text-fg-quaternary outline-none aria-invalid:border-destructive disabled:cursor-not-allowed disabled:opacity-50",
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: {