@adea-ai/ui 0.22.2 → 0.23.1

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 (92) hide show
  1. package/README.md +6 -3
  2. package/dist/components/account-drawer.d.ts +3 -3
  3. package/dist/components/account-drawer.js +119 -19
  4. package/dist/components/on-screen-controls.d.ts +2 -1
  5. package/dist/components/on-screen-controls.js +158 -46
  6. package/dist/components/scene-settings.d.ts +3 -3
  7. package/dist/components/scene-settings.js +247 -28
  8. package/dist/components/theme-provider.d.ts +27 -5
  9. package/dist/components/theme-provider.js +96 -7
  10. package/dist/components/theme-toggle.d.ts +4 -4
  11. package/dist/components/theme-toggle.js +62 -18
  12. package/dist/components/ui/badge.d.ts +4 -3
  13. package/dist/components/ui/badge.js +31 -30
  14. package/dist/components/ui/button.d.ts +4 -3
  15. package/dist/components/ui/button.js +49 -32
  16. package/dist/components/ui/card.d.ts +3 -3
  17. package/dist/components/ui/card.js +25 -6
  18. package/dist/components/ui/dialog.d.ts +13 -13
  19. package/dist/components/ui/dialog.js +94 -26
  20. package/dist/components/ui/drawer.d.ts +23 -15
  21. package/dist/components/ui/drawer.js +109 -64
  22. package/dist/components/ui/dropdown-menu.d.ts +28 -22
  23. package/dist/components/ui/dropdown-menu.js +165 -36
  24. package/dist/components/ui/empty.d.ts +7 -6
  25. package/dist/components/ui/empty.js +78 -26
  26. package/dist/components/ui/field.d.ts +15 -14
  27. package/dist/components/ui/field.js +177 -55
  28. package/dist/components/ui/input.d.ts +2 -2
  29. package/dist/components/ui/input.js +20 -5
  30. package/dist/components/ui/label.d.ts +2 -2
  31. package/dist/components/ui/label.js +15 -5
  32. package/dist/components/ui/radio-group.d.ts +4 -4
  33. package/dist/components/ui/radio-group.js +36 -9
  34. package/dist/components/ui/separator.d.ts +6 -2
  35. package/dist/components/ui/separator.js +18 -6
  36. package/dist/components/ui/skeleton.d.ts +2 -1
  37. package/dist/components/ui/skeleton.js +15 -4
  38. package/dist/components/ui/spinner.d.ts +4 -3
  39. package/dist/components/ui/spinner.js +15 -5
  40. package/dist/components/ui/switch.d.ts +6 -3
  41. package/dist/components/ui/switch.js +57 -6
  42. package/dist/components/ui/tabs.d.ts +6 -5
  43. package/dist/components/ui/tabs.js +52 -24
  44. package/dist/components/ui/toggle-group.d.ts +10 -8
  45. package/dist/components/ui/toggle-group.js +91 -20
  46. package/dist/components/ui/toggle.d.ts +4 -2
  47. package/dist/components/ui/toggle.js +38 -23
  48. package/dist/components/ui/tooltip.d.ts +13 -6
  49. package/dist/components/ui/tooltip.js +51 -14
  50. package/dist/components/version-dialog.d.ts +2 -2
  51. package/dist/components/version-dialog.js +322 -129
  52. package/dist/components/workspace-brand.d.ts +1 -1
  53. package/dist/components/workspace-brand.js +12 -3
  54. package/dist/components/workspace-logo.d.ts +2 -2
  55. package/dist/components/workspace-logo.js +15 -3
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.js +20 -19
  58. package/dist/lib/utils.js +7 -4
  59. package/dist/lib/version-notes.js +14 -29
  60. package/package.json +18 -16
  61. package/src/components/account-drawer.tsx +48 -67
  62. package/src/components/on-screen-controls.tsx +55 -62
  63. package/src/components/scene-settings.tsx +97 -100
  64. package/src/components/theme-provider.tsx +122 -22
  65. package/src/components/theme-toggle.tsx +29 -54
  66. package/src/components/ui/badge.tsx +14 -23
  67. package/src/components/ui/button.tsx +9 -11
  68. package/src/components/ui/card.tsx +9 -6
  69. package/src/components/ui/dialog.tsx +58 -55
  70. package/src/components/ui/drawer.tsx +84 -125
  71. package/src/components/ui/dropdown-menu.tsx +130 -153
  72. package/src/components/ui/empty.tsx +29 -26
  73. package/src/components/ui/field.tsx +83 -87
  74. package/src/components/ui/input.tsx +8 -8
  75. package/src/components/ui/label.tsx +6 -7
  76. package/src/components/ui/radio-group.tsx +22 -19
  77. package/src/components/ui/separator.tsx +16 -9
  78. package/src/components/ui/skeleton.tsx +6 -3
  79. package/src/components/ui/spinner.tsx +9 -5
  80. package/src/components/ui/switch.tsx +47 -20
  81. package/src/components/ui/tabs.tsx +31 -30
  82. package/src/components/ui/toggle-group.tsx +65 -54
  83. package/src/components/ui/toggle.tsx +9 -12
  84. package/src/components/ui/tooltip.tsx +41 -36
  85. package/src/components/version-dialog.tsx +144 -144
  86. package/src/components/workspace-brand.tsx +5 -5
  87. package/src/components/workspace-logo.tsx +9 -8
  88. package/src/index.tsx +7 -1
  89. package/src/styles/base.css +637 -0
  90. package/src/styles/globals.css +1 -1
  91. package/tsconfig.json +2 -1
  92. package/components.json +0 -19
@@ -1,116 +1,119 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
- import { Dialog as DialogPrimitive } from '@base-ui/react/dialog'
5
- import { X } from 'lucide-react'
1
+ import { Dialog as DialogPrimitive } from '@kobalte/core/dialog'
2
+ import { X } from 'lucide-solid'
3
+ import { splitProps, type ComponentProps } from 'solid-js'
6
4
 
7
5
  import { cn } from '#lib/utils'
8
6
 
9
- function Dialog({ ...props }: DialogPrimitive.Root.Props) {
10
- return <DialogPrimitive.Root data-slot="dialog" {...props} />
7
+ function Dialog(props: ComponentProps<typeof DialogPrimitive>) {
8
+ // Background inertness is owned by `ModalDialog` (see
9
+ // packages/workspace-ui), which marks the rest of the document `inert` while
10
+ // a dialog is open. Kobalte's own modal layer hides the document with
11
+ // `aria-hidden` and can leave that attribute behind when a dialog closes as
12
+ // a side effect of an async action, which would hide the whole workspace
13
+ // from assistive technology.
14
+ return <DialogPrimitive data-slot="dialog" modal={false} {...props} />
11
15
  }
12
16
 
13
- function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
17
+ function DialogTrigger(props: ComponentProps<typeof DialogPrimitive.Trigger>) {
14
18
  return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
15
19
  }
16
20
 
17
- function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {
21
+ function DialogPortal(props: ComponentProps<typeof DialogPrimitive.Portal>) {
18
22
  return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
19
23
  }
20
24
 
21
- function DialogClose({ ...props }: DialogPrimitive.Close.Props) {
22
- return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
25
+ function DialogClose(props: ComponentProps<typeof DialogPrimitive.CloseButton>) {
26
+ return <DialogPrimitive.CloseButton data-slot="dialog-close" {...props} />
23
27
  }
24
28
 
25
- function DialogOverlay({ className, ...props }: DialogPrimitive.Backdrop.Props) {
29
+ function DialogOverlay(props: ComponentProps<typeof DialogPrimitive.Overlay>) {
30
+ const [local, rest] = splitProps(props, ['class'])
26
31
  return (
27
- <DialogPrimitive.Backdrop
32
+ <DialogPrimitive.Overlay
28
33
  data-slot="dialog-overlay"
29
- className={cn(
30
- 'fixed inset-0 z-[120] bg-slate-950/55 backdrop-blur-[2px] transition-opacity duration-200 data-ending-style:opacity-0 data-starting-style:opacity-0',
31
- className
32
- )}
33
- {...props}
34
+ class={cn('fixed inset-0 z-[120] bg-slate-950/55 backdrop-blur-[2px]', local.class)}
35
+ {...rest}
34
36
  />
35
37
  )
36
38
  }
37
39
 
38
- function DialogContent({
39
- className,
40
- children,
41
- showCloseButton = true,
42
- ...props
43
- }: DialogPrimitive.Popup.Props & { showCloseButton?: boolean }) {
40
+ function DialogContent(
41
+ props: ComponentProps<typeof DialogPrimitive.Content> & { showCloseButton?: boolean }
42
+ ) {
43
+ const [local, rest] = splitProps(props, ['class', 'children', 'showCloseButton'])
44
44
  return (
45
45
  <DialogPortal>
46
46
  <DialogOverlay />
47
- <DialogPrimitive.Viewport
48
- data-slot="dialog-viewport"
49
- className="fixed inset-0 z-[120] flex items-center justify-center p-4"
50
- >
51
- <DialogPrimitive.Popup
47
+ {/* Flex centering keeps the dialog on whole pixels; a translate-based
48
+ center can land on a half pixel and shift every edge. */}
49
+ <div class="fixed inset-0 z-[120] flex items-center justify-center p-4">
50
+ <DialogPrimitive.Content
52
51
  data-slot="dialog-content"
53
- className={cn(
54
- 'relative grid max-h-[min(44rem,calc(100dvh-2rem))] w-full max-w-2xl gap-0 overflow-hidden rounded-2xl border bg-card text-card-foreground shadow-2xl outline-none transition-[opacity,transform] duration-200 data-ending-style:scale-[0.98] data-ending-style:opacity-0 data-starting-style:scale-[0.98] data-starting-style:opacity-0',
55
- className
52
+ class={cn(
53
+ 'relative grid max-h-[min(44rem,calc(100dvh-2rem))] w-full max-w-2xl gap-0 overflow-hidden rounded-2xl border bg-card text-card-foreground shadow-2xl outline-none',
54
+ local.class
56
55
  )}
57
- {...props}
56
+ {...rest}
58
57
  >
59
- {children}
60
- {showCloseButton && (
61
- <DialogPrimitive.Close
58
+ {local.children}
59
+ {(local.showCloseButton ?? true) ? (
60
+ <DialogPrimitive.CloseButton
62
61
  data-slot="dialog-close"
63
- className="absolute right-4 top-4 inline-flex size-8 items-center justify-center rounded-lg text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-3 focus-visible:ring-ring/50"
62
+ class="absolute right-4 top-4 inline-flex size-8 items-center justify-center rounded-lg text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-3 focus-visible:ring-ring/50"
64
63
  aria-label="Close dialog"
65
64
  >
66
- <X className="size-4" aria-hidden="true" />
67
- </DialogPrimitive.Close>
68
- )}
69
- </DialogPrimitive.Popup>
70
- </DialogPrimitive.Viewport>
65
+ <X class="size-4" aria-hidden="true" />
66
+ </DialogPrimitive.CloseButton>
67
+ ) : null}
68
+ </DialogPrimitive.Content>
69
+ </div>
71
70
  </DialogPortal>
72
71
  )
73
72
  }
74
73
 
75
- function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
74
+ function DialogHeader(props: ComponentProps<'div'>) {
75
+ const [local, rest] = splitProps(props, ['class'])
76
76
  return (
77
77
  <div
78
78
  data-slot="dialog-header"
79
- className={cn('flex flex-col gap-1.5 border-b px-6 py-5 pr-14', className)}
80
- {...props}
79
+ class={cn('flex flex-col gap-1.5 border-b px-6 py-5 pr-14', local.class)}
80
+ {...rest}
81
81
  />
82
82
  )
83
83
  }
84
84
 
85
- function DialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
85
+ function DialogFooter(props: ComponentProps<'div'>) {
86
+ const [local, rest] = splitProps(props, ['class'])
86
87
  return (
87
88
  <div
88
89
  data-slot="dialog-footer"
89
- className={cn(
90
+ class={cn(
90
91
  'flex flex-col-reverse gap-2 border-t px-6 py-4 sm:flex-row sm:justify-end',
91
- className
92
+ local.class
92
93
  )}
93
- {...props}
94
+ {...rest}
94
95
  />
95
96
  )
96
97
  }
97
98
 
98
- function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
99
+ function DialogTitle(props: ComponentProps<typeof DialogPrimitive.Title>) {
100
+ const [local, rest] = splitProps(props, ['class'])
99
101
  return (
100
102
  <DialogPrimitive.Title
101
103
  data-slot="dialog-title"
102
- className={cn('text-base font-semibold tracking-tight', className)}
103
- {...props}
104
+ class={cn('text-base font-semibold tracking-tight', local.class)}
105
+ {...rest}
104
106
  />
105
107
  )
106
108
  }
107
109
 
108
- function DialogDescription({ className, ...props }: DialogPrimitive.Description.Props) {
110
+ function DialogDescription(props: ComponentProps<typeof DialogPrimitive.Description>) {
111
+ const [local, rest] = splitProps(props, ['class'])
109
112
  return (
110
113
  <DialogPrimitive.Description
111
114
  data-slot="dialog-description"
112
- className={cn('text-sm leading-5 text-muted-foreground', className)}
113
- {...props}
115
+ class={cn('text-sm leading-5 text-muted-foreground', local.class)}
116
+ {...rest}
114
117
  />
115
118
  )
116
119
  }
@@ -1,195 +1,153 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
- import { Drawer as DrawerPrimitive } from '@base-ui/react/drawer'
1
+ import DrawerPrimitive from '@corvu/drawer'
2
+ import type { Side } from '@corvu/drawer'
3
+ import { Show, splitProps, type ComponentProps } from 'solid-js'
5
4
 
6
5
  import { cn } from '#lib/utils'
7
6
 
8
- type DrawerContextProps = {
9
- hasSnapPoints: boolean
10
- modal: DrawerPrimitive.Root.Props['modal']
11
- showSwipeHandle: boolean
12
- swipeDirection: NonNullable<DrawerPrimitive.Root.Props['swipeDirection']>
13
- }
14
-
15
- const DrawerContext = React.createContext<DrawerContextProps | null>(null)
16
-
17
- function useDrawer() {
18
- const context = React.useContext(DrawerContext)
7
+ type DrawerSide = Side
19
8
 
20
- if (!context) {
21
- throw new Error('useDrawer must be used within a Drawer.')
22
- }
23
-
24
- return context
9
+ type DrawerProps = ComponentProps<typeof DrawerPrimitive> & {
10
+ /** Base UI spoke of swipe directions; corvu speaks of the side the drawer attaches to. */
11
+ swipeDirection?: DrawerSide
12
+ showSwipeHandle?: boolean
25
13
  }
26
14
 
27
- function Drawer({
28
- modal = true,
29
- showSwipeHandle = false,
30
- snapPoints,
31
- swipeDirection = 'down',
32
- ...props
33
- }: DrawerPrimitive.Root.Props & {
34
- showSwipeHandle?: boolean
35
- }) {
36
- const hasSnapPoints = snapPoints != null && snapPoints.length > 0
37
- const contextValue = React.useMemo(
38
- () => ({ hasSnapPoints, modal, showSwipeHandle, swipeDirection }),
39
- [hasSnapPoints, modal, showSwipeHandle, swipeDirection]
40
- )
15
+ // Side drawers honor `--drawer-content-width` (the contract the pre-Solid
16
+ // drawer exposed) and fall back to the default width. Task detail sets the
17
+ // variable to `min(29rem, 94vw)`; without the variable here the class below
18
+ // would win and the panel would render narrower than its committed baseline.
19
+ const SIDE_DRAWER_WIDTH = 'w-[var(--drawer-content-width,min(24rem,90vw))]'
20
+
21
+ const SIDE_CLASSES: Record<DrawerSide, string> = {
22
+ bottom: 'inset-x-0 bottom-0 max-h-[calc(100dvh-2rem)] rounded-t-xl border-t',
23
+ top: 'inset-x-0 top-0 max-h-[calc(100dvh-2rem)] rounded-b-xl border-b',
24
+ left: `inset-y-0 left-0 h-full ${SIDE_DRAWER_WIDTH} rounded-r-xl border-r`,
25
+ right: `inset-y-0 right-0 h-full ${SIDE_DRAWER_WIDTH} rounded-l-xl border-l`,
26
+ }
41
27
 
28
+ function Drawer(props: DrawerProps) {
29
+ const [local, rest] = splitProps(props, ['swipeDirection', 'side'])
42
30
  return (
43
- <DrawerContext.Provider value={contextValue}>
44
- <DrawerPrimitive.Root
45
- data-slot="drawer"
46
- modal={modal}
47
- snapPoints={snapPoints}
48
- swipeDirection={swipeDirection}
49
- {...props}
50
- />
51
- </DrawerContext.Provider>
31
+ <DrawerPrimitive
32
+ data-slot="drawer"
33
+ side={local.side ?? local.swipeDirection ?? 'bottom'}
34
+ {...rest}
35
+ />
52
36
  )
53
37
  }
54
38
 
55
- function DrawerTrigger({ ...props }: DrawerPrimitive.Trigger.Props) {
39
+ function DrawerTrigger(props: ComponentProps<typeof DrawerPrimitive.Trigger>) {
56
40
  return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
57
41
  }
58
42
 
59
- function DrawerPortal({ ...props }: DrawerPrimitive.Portal.Props) {
43
+ function DrawerPortal(props: ComponentProps<typeof DrawerPrimitive.Portal>) {
60
44
  return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />
61
45
  }
62
46
 
63
- function DrawerClose({ ...props }: DrawerPrimitive.Close.Props) {
47
+ function DrawerClose(props: ComponentProps<typeof DrawerPrimitive.Close>) {
64
48
  return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />
65
49
  }
66
50
 
67
- function DrawerOverlay({ className, ...props }: DrawerPrimitive.Backdrop.Props) {
51
+ function DrawerOverlay(props: ComponentProps<typeof DrawerPrimitive.Overlay>) {
52
+ const [local, rest] = splitProps(props, ['class'])
68
53
  return (
69
- <DrawerPrimitive.Backdrop
54
+ <DrawerPrimitive.Overlay
70
55
  data-slot="drawer-overlay"
71
- className={cn(
72
- 'fixed inset-0 z-[110] min-h-dvh bg-black/10 opacity-[max(var(--drawer-overlay-min-opacity,0),calc(1-var(--drawer-swipe-progress)))] transition-opacity duration-450 ease-[cubic-bezier(0.32,0.72,0,1)] select-none data-ending-style:pointer-events-none data-ending-style:opacity-0 data-ending-style:duration-[calc(var(--drawer-swipe-strength)*400ms)] data-snap-points:[--drawer-overlay-min-opacity:0.5] data-starting-style:opacity-0 data-swiping:duration-0 supports-backdrop-filter:backdrop-blur-xs supports-[-webkit-touch-callout:none]:absolute',
73
- className
56
+ // The scrim keeps the pre-Solid 10% black the committed screenshots
57
+ // were taken against; 25% dimmed the page behind every drawer.
58
+ class={cn(
59
+ 'fixed inset-0 z-[110] bg-black/10 backdrop-blur-xs transition-opacity duration-300 data-closed:opacity-0',
60
+ local.class
74
61
  )}
75
- {...props}
62
+ {...rest}
76
63
  />
77
64
  )
78
65
  }
79
66
 
80
- function DrawerSwipeHandle({ className, ...props }: React.ComponentProps<'div'>) {
67
+ function DrawerSwipeHandle(props: ComponentProps<'div'>) {
68
+ const [local, rest] = splitProps(props, ['class'])
81
69
  return (
82
70
  <div
83
71
  data-slot="drawer-swipe-handle"
84
72
  aria-hidden="true"
85
- className={cn(
86
- 'relative z-10 flex shrink-0 cursor-grab transition-opacity duration-200 group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-drawer-swiping/drawer-popup:opacity-100 group-data-[swipe-axis=x]/drawer-popup:h-full group-data-[swipe-axis=x]/drawer-popup:w-3 group-data-[swipe-axis=x]/drawer-popup:items-center group-data-[swipe-axis=y]/drawer-popup:h-3 group-data-[swipe-axis=y]/drawer-popup:w-full group-data-[swipe-axis=y]/drawer-popup:justify-center group-data-[swipe-direction=down]/drawer-popup:items-end group-data-[swipe-direction=left]/drawer-popup:order-last group-data-[swipe-direction=left]/drawer-popup:justify-start group-data-[swipe-direction=right]/drawer-popup:justify-end group-data-[swipe-direction=up]/drawer-popup:order-last group-data-[swipe-direction=up]/drawer-popup:items-start after:block after:shrink-0 after:rounded-full after:bg-muted group-data-[swipe-axis=x]/drawer-popup:after:h-24 group-data-[swipe-axis=x]/drawer-popup:after:w-1 group-data-[swipe-axis=y]/drawer-popup:after:h-1 group-data-[swipe-axis=y]/drawer-popup:after:w-24 active:cursor-grabbing',
87
- className
73
+ class={cn(
74
+ 'relative z-10 flex shrink-0 cursor-grab items-center justify-center py-2 active:cursor-grabbing after:block after:h-1 after:w-24 after:shrink-0 after:rounded-full after:bg-muted',
75
+ local.class
88
76
  )}
89
- {...props}
77
+ {...rest}
90
78
  />
91
79
  )
92
80
  }
93
81
 
94
- function DrawerContent({ className, children, ...props }: DrawerPrimitive.Popup.Props) {
95
- const { hasSnapPoints, modal, showSwipeHandle, swipeDirection } = useDrawer()
96
- const swipeAxis = swipeDirection === 'down' || swipeDirection === 'up' ? 'y' : 'x'
82
+ type DrawerContentProps = ComponentProps<typeof DrawerPrimitive.Content> & {
83
+ showSwipeHandle?: boolean
84
+ }
85
+
86
+ function DrawerContent(props: DrawerContentProps) {
87
+ const [local, rest] = splitProps(props, ['class', 'children', 'showSwipeHandle'])
88
+ const side = DrawerPrimitive.useContext().side
97
89
 
98
90
  return (
99
91
  <DrawerPortal data-slot="drawer-portal">
100
- {modal === true && <DrawerOverlay data-snap-points={hasSnapPoints ? '' : undefined} />}
101
- <DrawerPrimitive.Viewport
102
- data-slot="drawer-viewport"
103
- data-modal={modal}
104
- className="pointer-events-none fixed inset-0 z-[110] select-none data-[modal=true]:pointer-events-auto"
92
+ <DrawerOverlay />
93
+ <DrawerPrimitive.Content
94
+ data-slot="drawer-content"
95
+ class={cn(
96
+ 'group/drawer-content fixed z-[110] flex flex-col overflow-hidden bg-popover text-sm text-popover-foreground shadow-lg outline-none transition-transform duration-300 ease-out will-change-transform',
97
+ SIDE_CLASSES[side()],
98
+ local.class
99
+ )}
100
+ {...rest}
105
101
  >
106
- <DrawerPrimitive.Popup
107
- data-slot="drawer-popup"
108
- data-swipe-axis={swipeAxis}
109
- data-snap-points={hasSnapPoints ? '' : undefined}
110
- className={cn(
111
- // Base.
112
- 'group/drawer-popup pointer-events-auto fixed z-[110] m-(--drawer-inset,0px) flex h-(--drawer-content-height) max-h-(--drawer-content-max-height,none) min-h-0 w-(--drawer-content-width,auto) transform-[translate3d(var(--translate-x,0px),var(--translate-y,0px),0)_scale(var(--stack-scale))] flex-col bg-popover text-sm text-popover-foreground transition-[transform,height,opacity,filter] duration-450 ease-[cubic-bezier(0.22,1,0.36,1)] will-change-transform outline-none select-none [interpolate-size:allow-keywords] data-[swipe-direction=down]:rounded-t-xl data-[swipe-direction=down]:border-t data-[swipe-direction=left]:rounded-r-xl data-[swipe-direction=left]:border-r data-[swipe-direction=right]:rounded-l-xl data-[swipe-direction=right]:border-l data-[swipe-direction=up]:rounded-b-xl data-[swipe-direction=up]:border-b',
113
- // Nested.
114
- 'data-nested-drawer-open:overflow-hidden data-nested-drawer-open:brightness-95',
115
- // Bleed.
116
- 'after:pointer-events-none after:absolute after:bg-(--drawer-bleed-background,var(--color-popover)) data-[swipe-axis=x]:after:inset-y-0 data-[swipe-axis=x]:after:w-(--bleed) data-[swipe-axis=y]:after:inset-x-0 data-[swipe-axis=y]:after:h-(--bleed) data-[swipe-direction=down]:after:top-full data-[swipe-direction=left]:after:right-full data-[swipe-direction=right]:after:left-full data-[swipe-direction=up]:after:bottom-full',
117
- // Sizing.
118
- '[--drawer-content-height:var(--drawer-height,auto)] data-[swipe-axis=x]:[--drawer-content-width:75%] data-[swipe-axis=y]:[--drawer-content-max-height:calc(100dvh-6rem)] data-[swipe-axis=y]:data-snap-points:[--drawer-content-height:100dvh] data-[swipe-axis=x]:sm:[--drawer-content-width:24rem]',
119
- // Stack.
120
- '[--bleed:3rem] [--peek:1rem] [--stack-height:var(--drawer-frontmost-height,var(--drawer-height,0px))] [--stack-peek-offset:max(0px,calc((var(--nested-drawers)-var(--stack-progress))*var(--peek)))] [--stack-progress:clamp(0,var(--drawer-swipe-progress),1)] [--stack-scale-base:max(0,calc(1-(var(--nested-drawers)*var(--stack-step))))] [--stack-scale:clamp(0,calc(var(--stack-scale-base)+(var(--stack-step)*var(--stack-progress))),1)] [--stack-shrink:calc(1-var(--stack-scale))] [--stack-step:0.05]',
121
- // Transitions.
122
- 'data-ending-style:transform-(--closed-transform) data-ending-style:opacity-[0.9999] data-ending-style:duration-[calc(var(--drawer-swipe-strength)*400ms)] data-nested-drawer-swiping:duration-0 data-ending-style:data-nested-drawer-swiping:duration-[calc(var(--drawer-swipe-strength)*400ms)] data-starting-style:transform-(--closed-transform) data-swiping:duration-0 data-ending-style:data-swiping:duration-[calc(var(--drawer-swipe-strength)*400ms)]',
123
- // Axis: y.
124
- 'data-[swipe-axis=y]:inset-x-0 data-[swipe-axis=y]:data-nested-drawer-open:h-(--stack-height)',
125
- // Axis: x.
126
- 'data-[swipe-axis=x]:inset-y-0 data-[swipe-axis=x]:flex-row',
127
- // Direction: down.
128
- 'data-[swipe-direction=down]:bottom-0 data-[swipe-direction=down]:origin-bottom data-[swipe-direction=down]:[--closed-transform:translate3d(0,calc(100%+var(--drawer-inset,0px)+2px),0)] data-[swipe-direction=down]:[--translate-y:calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-y)-var(--stack-peek-offset)-(var(--stack-shrink)*var(--stack-height)))]',
129
- // Direction: up.
130
- 'data-[swipe-direction=up]:top-0 data-[swipe-direction=up]:origin-top data-[swipe-direction=up]:[--closed-transform:translate3d(0,calc(-100%-var(--drawer-inset,0px)-2px),0)] data-[swipe-direction=up]:[--translate-y:calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-y)+var(--stack-peek-offset)+(var(--stack-shrink)*var(--stack-height)))]',
131
- // Direction: left.
132
- 'data-[swipe-direction=left]:left-0 data-[swipe-direction=left]:origin-left data-[swipe-direction=left]:[--closed-transform:translate3d(calc(-100%-var(--drawer-inset,0px)-2px),0,0)] data-[swipe-direction=left]:[--translate-x:calc(var(--drawer-swipe-movement-x)+var(--stack-peek-offset)+(var(--stack-shrink)*100%))]',
133
- // Direction: right.
134
- 'data-[swipe-direction=right]:right-0 data-[swipe-direction=right]:origin-right data-[swipe-direction=right]:[--closed-transform:translate3d(calc(100%+var(--drawer-inset,0px)+2px),0,0)] data-[swipe-direction=right]:[--translate-x:calc(var(--drawer-swipe-movement-x)-var(--stack-peek-offset)-(var(--stack-shrink)*100%))]',
135
- className
136
- )}
137
- {...props}
138
- >
139
- {showSwipeHandle && <DrawerSwipeHandle />}
140
- <DrawerPrimitive.Content
141
- data-slot="drawer-content"
142
- className={cn(
143
- 'flex min-h-0 flex-1 flex-col overflow-hidden overscroll-contain rounded-[inherit] transition-opacity duration-300 ease-[cubic-bezier(0.45,1.005,0,1.005)] select-text group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-drawer-swiping/drawer-popup:opacity-100 group-data-swiping/drawer-popup:select-none'
144
- )}
145
- >
146
- {children}
147
- </DrawerPrimitive.Content>
148
- </DrawerPrimitive.Popup>
149
- </DrawerPrimitive.Viewport>
102
+ <Show when={local.showSwipeHandle}>
103
+ <DrawerSwipeHandle />
104
+ </Show>
105
+ {local.children}
106
+ </DrawerPrimitive.Content>
150
107
  </DrawerPortal>
151
108
  )
152
109
  }
153
110
 
154
- function DrawerHeader({ className, ...props }: React.ComponentProps<'div'>) {
111
+ function DrawerHeader(props: ComponentProps<'div'>) {
112
+ const [local, rest] = splitProps(props, ['class'])
155
113
  return (
156
114
  <div
157
115
  data-slot="drawer-header"
158
- className={cn(
159
- 'flex shrink-0 flex-col gap-0.5 p-4 pb-0 group-data-[swipe-axis=y]/drawer-popup:text-center md:gap-0.5 md:text-left',
160
- className
161
- )}
162
- {...props}
116
+ class={cn('flex shrink-0 flex-col gap-0.5 p-4 pb-0 text-center md:text-left', local.class)}
117
+ {...rest}
163
118
  />
164
119
  )
165
120
  }
166
121
 
167
- function DrawerFooter({ className, ...props }: React.ComponentProps<'div'>) {
122
+ function DrawerFooter(props: ComponentProps<'div'>) {
123
+ const [local, rest] = splitProps(props, ['class'])
168
124
  return (
169
125
  <div
170
126
  data-slot="drawer-footer"
171
- className={cn('mt-auto flex shrink-0 flex-col gap-2 p-4 pt-0', className)}
172
- {...props}
127
+ class={cn('mt-auto flex shrink-0 flex-col gap-2 p-4 pt-0', local.class)}
128
+ {...rest}
173
129
  />
174
130
  )
175
131
  }
176
132
 
177
- function DrawerTitle({ className, ...props }: DrawerPrimitive.Title.Props) {
133
+ function DrawerTitle(props: ComponentProps<typeof DrawerPrimitive.Label>) {
134
+ const [local, rest] = splitProps(props, ['class'])
178
135
  return (
179
- <DrawerPrimitive.Title
136
+ <DrawerPrimitive.Label
180
137
  data-slot="drawer-title"
181
- className={cn('text-base font-medium text-foreground', className)}
182
- {...props}
138
+ class={cn('text-base font-medium text-foreground', local.class)}
139
+ {...rest}
183
140
  />
184
141
  )
185
142
  }
186
143
 
187
- function DrawerDescription({ className, ...props }: DrawerPrimitive.Description.Props) {
144
+ function DrawerDescription(props: ComponentProps<typeof DrawerPrimitive.Description>) {
145
+ const [local, rest] = splitProps(props, ['class'])
188
146
  return (
189
147
  <DrawerPrimitive.Description
190
148
  data-slot="drawer-description"
191
- className={cn('text-sm text-balance text-muted-foreground', className)}
192
- {...props}
149
+ class={cn('text-sm text-balance text-muted-foreground', local.class)}
150
+ {...rest}
193
151
  />
194
152
  )
195
153
  }
@@ -206,4 +164,5 @@ export {
206
164
  DrawerFooter,
207
165
  DrawerTitle,
208
166
  DrawerDescription,
167
+ type DrawerProps,
209
168
  }