@a-type/ui 1.3.0 → 1.3.2

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 (233) hide show
  1. package/dist/cjs/components/actions/ActionButton.d.ts +1 -1
  2. package/dist/cjs/components/actions/ActionButton.js +4 -4
  3. package/dist/cjs/components/actions/ActionButton.js.map +1 -1
  4. package/dist/cjs/components/box/Box.d.ts +4 -2
  5. package/dist/cjs/components/box/Box.js +9 -6
  6. package/dist/cjs/components/box/Box.js.map +1 -1
  7. package/dist/cjs/components/box/Box.stories.d.ts +1 -1
  8. package/dist/cjs/components/button/Button.d.ts +3 -2
  9. package/dist/cjs/components/button/Button.js +4 -4
  10. package/dist/cjs/components/button/Button.js.map +1 -1
  11. package/dist/cjs/components/button/Button.stories.d.ts +1 -1
  12. package/dist/cjs/components/camera/Camera.d.ts +7 -5
  13. package/dist/cjs/components/camera/Camera.js +12 -10
  14. package/dist/cjs/components/camera/Camera.js.map +1 -1
  15. package/dist/cjs/components/camera/Camera.stories.d.ts +2 -2
  16. package/dist/cjs/components/card/Card.d.ts +10 -18
  17. package/dist/cjs/components/card/Card.js +11 -10
  18. package/dist/cjs/components/card/Card.js.map +1 -1
  19. package/dist/cjs/components/checkbox/Checkbox.d.ts +2 -1
  20. package/dist/cjs/components/checkbox/Checkbox.js +3 -3
  21. package/dist/cjs/components/checkbox/Checkbox.js.map +1 -1
  22. package/dist/cjs/components/chip/Chip.d.ts +3 -2
  23. package/dist/cjs/components/chip/Chip.js +4 -5
  24. package/dist/cjs/components/chip/Chip.js.map +1 -1
  25. package/dist/cjs/components/collapsible/Collapsible.d.ts +7 -4
  26. package/dist/cjs/components/collapsible/Collapsible.js +5 -5
  27. package/dist/cjs/components/collapsible/Collapsible.js.map +1 -1
  28. package/dist/cjs/components/contextMenu/contextMenu.d.ts +7 -2
  29. package/dist/cjs/components/contextMenu/contextMenu.js +5 -5
  30. package/dist/cjs/components/contextMenu/contextMenu.js.map +1 -1
  31. package/dist/cjs/components/dialog/Dialog.d.ts +37 -19
  32. package/dist/cjs/components/dialog/Dialog.js +20 -15
  33. package/dist/cjs/components/dialog/Dialog.js.map +1 -1
  34. package/dist/cjs/components/dialog/Dialog.stories.d.ts +14 -7
  35. package/dist/cjs/components/divider/Divider.d.ts +3 -1
  36. package/dist/cjs/components/divider/Divider.js +5 -5
  37. package/dist/cjs/components/divider/Divider.js.map +1 -1
  38. package/dist/cjs/components/dropdownMenu/DropdownMenu.d.ts +6 -2
  39. package/dist/cjs/components/dropdownMenu/DropdownMenu.js +3 -4
  40. package/dist/cjs/components/dropdownMenu/DropdownMenu.js.map +1 -1
  41. package/dist/cjs/components/dropdownMenu/DropdownMenu.stories.d.ts +3 -1
  42. package/dist/cjs/components/forms/TextField.d.ts +3 -1
  43. package/dist/cjs/components/forms/TextField.js +6 -5
  44. package/dist/cjs/components/forms/TextField.js.map +1 -1
  45. package/dist/cjs/components/icon/Icon.d.ts +3 -1
  46. package/dist/cjs/components/icon/Icon.js +4 -4
  47. package/dist/cjs/components/icon/Icon.js.map +1 -1
  48. package/dist/cjs/components/infiniteLoadTrigger/InfiniteLoadTrigger.d.ts +3 -1
  49. package/dist/cjs/components/infiniteLoadTrigger/InfiniteLoadTrigger.js +6 -5
  50. package/dist/cjs/components/infiniteLoadTrigger/InfiniteLoadTrigger.js.map +1 -1
  51. package/dist/cjs/components/input/Input.d.ts +3 -1
  52. package/dist/cjs/components/input/Input.js +4 -3
  53. package/dist/cjs/components/input/Input.js.map +1 -1
  54. package/dist/cjs/components/input/Input.stories.d.ts +3 -1
  55. package/dist/cjs/components/liveUpdateTextField/LiveUpdateTextField.d.ts +3 -2
  56. package/dist/cjs/components/liveUpdateTextField/LiveUpdateTextField.js +5 -4
  57. package/dist/cjs/components/liveUpdateTextField/LiveUpdateTextField.js.map +1 -1
  58. package/dist/cjs/components/marquee/marquee.d.ts +1 -1
  59. package/dist/cjs/components/navBar/NavBar.d.ts +10 -5
  60. package/dist/cjs/components/navBar/NavBar.js +8 -7
  61. package/dist/cjs/components/navBar/NavBar.js.map +1 -1
  62. package/dist/cjs/components/popover/Popover.d.ts +13 -8
  63. package/dist/cjs/components/popover/Popover.js +5 -5
  64. package/dist/cjs/components/popover/Popover.js.map +1 -1
  65. package/dist/cjs/components/progress/Progress.d.ts +4 -3
  66. package/dist/cjs/components/progress/Progress.js +3 -4
  67. package/dist/cjs/components/progress/Progress.js.map +1 -1
  68. package/dist/cjs/components/progress/Progress.stories.d.ts +4 -3
  69. package/dist/cjs/components/scrollArea/ScrollArea.d.ts +12 -5
  70. package/dist/cjs/components/scrollArea/ScrollArea.js +12 -9
  71. package/dist/cjs/components/scrollArea/ScrollArea.js.map +1 -1
  72. package/dist/cjs/components/select/Select.d.ts +23 -13
  73. package/dist/cjs/components/select/Select.js +18 -15
  74. package/dist/cjs/components/select/Select.js.map +1 -1
  75. package/dist/cjs/components/select/Select.stories.d.ts +10 -6
  76. package/dist/cjs/components/slider/Slider.d.ts +3 -1
  77. package/dist/cjs/components/slider/Slider.js +3 -4
  78. package/dist/cjs/components/slider/Slider.js.map +1 -1
  79. package/dist/cjs/components/slider/Slider.stories.d.ts +3 -1
  80. package/dist/cjs/components/spinner/Spinner.d.ts +6 -2
  81. package/dist/cjs/components/spinner/Spinner.js +8 -6
  82. package/dist/cjs/components/spinner/Spinner.js.map +1 -1
  83. package/dist/cjs/components/switch/Switch.d.ts +3 -1
  84. package/dist/cjs/components/switch/Switch.js +15 -4
  85. package/dist/cjs/components/switch/Switch.js.map +1 -1
  86. package/dist/cjs/components/textArea/TextArea.d.ts +3 -1
  87. package/dist/cjs/components/textArea/TextArea.js +4 -3
  88. package/dist/cjs/components/textArea/TextArea.js.map +1 -1
  89. package/dist/cjs/components/textArea/TextArea.stories.d.ts +3 -1
  90. package/dist/cjs/components/tooltip/Tooltip.d.ts +3 -1
  91. package/dist/cjs/components/tooltip/Tooltip.js +3 -4
  92. package/dist/cjs/components/tooltip/Tooltip.js.map +1 -1
  93. package/dist/cjs/components/tooltip/Tooltip.stories.d.ts +3 -1
  94. package/dist/cjs/components/utility/HideWhileKeyboardOpen.d.ts +3 -1
  95. package/dist/cjs/components/utility/HideWhileKeyboardOpen.js +5 -5
  96. package/dist/cjs/components/utility/HideWhileKeyboardOpen.js.map +1 -1
  97. package/dist/cjs/components/utility/SlotDiv.d.ts +1 -1
  98. package/dist/cjs/components/utility/SlotDiv.js +4 -4
  99. package/dist/cjs/components/utility/SlotDiv.js.map +1 -1
  100. package/dist/cjs/hooks/useMergedRef.d.ts +1 -1
  101. package/dist/cjs/hooks/useMergedRef.js.map +1 -1
  102. package/dist/esm/components/actions/ActionButton.d.ts +1 -1
  103. package/dist/esm/components/actions/ActionButton.js +4 -4
  104. package/dist/esm/components/actions/ActionButton.js.map +1 -1
  105. package/dist/esm/components/box/Box.d.ts +4 -2
  106. package/dist/esm/components/box/Box.js +9 -6
  107. package/dist/esm/components/box/Box.js.map +1 -1
  108. package/dist/esm/components/box/Box.stories.d.ts +1 -1
  109. package/dist/esm/components/button/Button.d.ts +3 -2
  110. package/dist/esm/components/button/Button.js +4 -4
  111. package/dist/esm/components/button/Button.js.map +1 -1
  112. package/dist/esm/components/button/Button.stories.d.ts +1 -1
  113. package/dist/esm/components/camera/Camera.d.ts +7 -5
  114. package/dist/esm/components/camera/Camera.js +7 -7
  115. package/dist/esm/components/camera/Camera.js.map +1 -1
  116. package/dist/esm/components/camera/Camera.stories.d.ts +2 -2
  117. package/dist/esm/components/card/Card.d.ts +10 -18
  118. package/dist/esm/components/card/Card.js +6 -7
  119. package/dist/esm/components/card/Card.js.map +1 -1
  120. package/dist/esm/components/checkbox/Checkbox.d.ts +2 -1
  121. package/dist/esm/components/checkbox/Checkbox.js +3 -3
  122. package/dist/esm/components/checkbox/Checkbox.js.map +1 -1
  123. package/dist/esm/components/chip/Chip.d.ts +3 -2
  124. package/dist/esm/components/chip/Chip.js +3 -4
  125. package/dist/esm/components/chip/Chip.js.map +1 -1
  126. package/dist/esm/components/collapsible/Collapsible.d.ts +7 -4
  127. package/dist/esm/components/collapsible/Collapsible.js +4 -5
  128. package/dist/esm/components/collapsible/Collapsible.js.map +1 -1
  129. package/dist/esm/components/contextMenu/contextMenu.d.ts +7 -2
  130. package/dist/esm/components/contextMenu/contextMenu.js +4 -5
  131. package/dist/esm/components/contextMenu/contextMenu.js.map +1 -1
  132. package/dist/esm/components/dialog/Dialog.d.ts +37 -19
  133. package/dist/esm/components/dialog/Dialog.js +16 -16
  134. package/dist/esm/components/dialog/Dialog.js.map +1 -1
  135. package/dist/esm/components/dialog/Dialog.stories.d.ts +14 -7
  136. package/dist/esm/components/divider/Divider.d.ts +3 -1
  137. package/dist/esm/components/divider/Divider.js +4 -5
  138. package/dist/esm/components/divider/Divider.js.map +1 -1
  139. package/dist/esm/components/dropdownMenu/DropdownMenu.d.ts +6 -2
  140. package/dist/esm/components/dropdownMenu/DropdownMenu.js +3 -4
  141. package/dist/esm/components/dropdownMenu/DropdownMenu.js.map +1 -1
  142. package/dist/esm/components/dropdownMenu/DropdownMenu.stories.d.ts +3 -1
  143. package/dist/esm/components/forms/TextField.d.ts +3 -1
  144. package/dist/esm/components/forms/TextField.js +6 -6
  145. package/dist/esm/components/forms/TextField.js.map +1 -1
  146. package/dist/esm/components/icon/Icon.d.ts +3 -1
  147. package/dist/esm/components/icon/Icon.js +3 -4
  148. package/dist/esm/components/icon/Icon.js.map +1 -1
  149. package/dist/esm/components/infiniteLoadTrigger/InfiniteLoadTrigger.d.ts +3 -1
  150. package/dist/esm/components/infiniteLoadTrigger/InfiniteLoadTrigger.js +5 -5
  151. package/dist/esm/components/infiniteLoadTrigger/InfiniteLoadTrigger.js.map +1 -1
  152. package/dist/esm/components/input/Input.d.ts +3 -1
  153. package/dist/esm/components/input/Input.js +4 -4
  154. package/dist/esm/components/input/Input.js.map +1 -1
  155. package/dist/esm/components/input/Input.stories.d.ts +3 -1
  156. package/dist/esm/components/liveUpdateTextField/LiveUpdateTextField.d.ts +3 -2
  157. package/dist/esm/components/liveUpdateTextField/LiveUpdateTextField.js +4 -4
  158. package/dist/esm/components/liveUpdateTextField/LiveUpdateTextField.js.map +1 -1
  159. package/dist/esm/components/marquee/marquee.d.ts +1 -1
  160. package/dist/esm/components/navBar/NavBar.d.ts +10 -5
  161. package/dist/esm/components/navBar/NavBar.js +6 -7
  162. package/dist/esm/components/navBar/NavBar.js.map +1 -1
  163. package/dist/esm/components/popover/Popover.d.ts +13 -8
  164. package/dist/esm/components/popover/Popover.js +4 -5
  165. package/dist/esm/components/popover/Popover.js.map +1 -1
  166. package/dist/esm/components/progress/Progress.d.ts +4 -3
  167. package/dist/esm/components/progress/Progress.js +3 -4
  168. package/dist/esm/components/progress/Progress.js.map +1 -1
  169. package/dist/esm/components/progress/Progress.stories.d.ts +4 -3
  170. package/dist/esm/components/scrollArea/ScrollArea.d.ts +12 -5
  171. package/dist/esm/components/scrollArea/ScrollArea.js +10 -9
  172. package/dist/esm/components/scrollArea/ScrollArea.js.map +1 -1
  173. package/dist/esm/components/select/Select.d.ts +23 -13
  174. package/dist/esm/components/select/Select.js +16 -16
  175. package/dist/esm/components/select/Select.js.map +1 -1
  176. package/dist/esm/components/select/Select.stories.d.ts +10 -6
  177. package/dist/esm/components/slider/Slider.d.ts +3 -1
  178. package/dist/esm/components/slider/Slider.js +3 -4
  179. package/dist/esm/components/slider/Slider.js.map +1 -1
  180. package/dist/esm/components/slider/Slider.stories.d.ts +3 -1
  181. package/dist/esm/components/spinner/Spinner.d.ts +6 -2
  182. package/dist/esm/components/spinner/Spinner.js +6 -6
  183. package/dist/esm/components/spinner/Spinner.js.map +1 -1
  184. package/dist/esm/components/switch/Switch.d.ts +3 -1
  185. package/dist/esm/components/switch/Switch.js +15 -4
  186. package/dist/esm/components/switch/Switch.js.map +1 -1
  187. package/dist/esm/components/textArea/TextArea.d.ts +3 -1
  188. package/dist/esm/components/textArea/TextArea.js +4 -4
  189. package/dist/esm/components/textArea/TextArea.js.map +1 -1
  190. package/dist/esm/components/textArea/TextArea.stories.d.ts +3 -1
  191. package/dist/esm/components/tooltip/Tooltip.d.ts +3 -1
  192. package/dist/esm/components/tooltip/Tooltip.js +3 -4
  193. package/dist/esm/components/tooltip/Tooltip.js.map +1 -1
  194. package/dist/esm/components/tooltip/Tooltip.stories.d.ts +3 -1
  195. package/dist/esm/components/utility/HideWhileKeyboardOpen.d.ts +3 -1
  196. package/dist/esm/components/utility/HideWhileKeyboardOpen.js +4 -5
  197. package/dist/esm/components/utility/HideWhileKeyboardOpen.js.map +1 -1
  198. package/dist/esm/components/utility/SlotDiv.d.ts +1 -1
  199. package/dist/esm/components/utility/SlotDiv.js +3 -4
  200. package/dist/esm/components/utility/SlotDiv.js.map +1 -1
  201. package/dist/esm/hooks/useMergedRef.d.ts +1 -1
  202. package/dist/esm/hooks/useMergedRef.js.map +1 -1
  203. package/package.json +1 -1
  204. package/src/components/actions/ActionButton.tsx +45 -45
  205. package/src/components/box/Box.tsx +27 -24
  206. package/src/components/button/Button.tsx +54 -57
  207. package/src/components/camera/Camera.tsx +133 -133
  208. package/src/components/card/Card.tsx +24 -23
  209. package/src/components/checkbox/Checkbox.tsx +9 -10
  210. package/src/components/chip/Chip.tsx +9 -5
  211. package/src/components/collapsible/Collapsible.tsx +56 -54
  212. package/src/components/contextMenu/contextMenu.tsx +60 -56
  213. package/src/components/dialog/Dialog.tsx +328 -312
  214. package/src/components/divider/Divider.tsx +32 -26
  215. package/src/components/dropdownMenu/DropdownMenu.tsx +126 -123
  216. package/src/components/forms/TextField.tsx +137 -140
  217. package/src/components/icon/Icon.tsx +33 -28
  218. package/src/components/infiniteLoadTrigger/InfiniteLoadTrigger.tsx +42 -38
  219. package/src/components/input/Input.tsx +75 -81
  220. package/src/components/liveUpdateTextField/LiveUpdateTextField.tsx +134 -138
  221. package/src/components/navBar/NavBar.tsx +105 -96
  222. package/src/components/popover/Popover.tsx +84 -87
  223. package/src/components/progress/Progress.tsx +40 -34
  224. package/src/components/scrollArea/ScrollArea.tsx +102 -94
  225. package/src/components/select/Select.tsx +294 -283
  226. package/src/components/slider/Slider.tsx +58 -55
  227. package/src/components/spinner/Spinner.tsx +66 -59
  228. package/src/components/switch/Switch.tsx +31 -27
  229. package/src/components/textArea/TextArea.tsx +114 -117
  230. package/src/components/tooltip/Tooltip.tsx +68 -63
  231. package/src/components/utility/HideWhileKeyboardOpen.tsx +30 -26
  232. package/src/components/utility/SlotDiv.tsx +16 -15
  233. package/src/hooks/useMergedRef.ts +3 -1
@@ -1,312 +1,328 @@
1
- 'use client';
2
-
3
- import * as DialogPrimitive from '@radix-ui/react-dialog';
4
- import { CheckIcon, ChevronDownIcon } from '@radix-ui/react-icons';
5
- import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
6
- import { useDrag } from '@use-gesture/react';
7
- import classNames from 'clsx';
8
- import {
9
- ComponentPropsWithoutRef,
10
- createContext,
11
- forwardRef,
12
- useCallback,
13
- useContext,
14
- useRef,
15
- useState,
16
- } from 'react';
17
- import useMergedRef from '../../hooks/useMergedRef.js';
18
- import { withClassName } from '../../hooks/withClassName.js';
19
- import { Button } from '../button/index.js';
20
- import { useParticles } from '../particles/index.js';
21
- import { useConfig } from '../provider/Provider.js';
22
- import { selectTriggerClassName } from '../select/index.js';
23
-
24
- const StyledOverlay = withClassName(
25
- DialogPrimitive.Overlay,
26
- 'layer-components:(fixed inset-0 z-dialog-backdrop animate-fade-in animate-duration-200 bg-overlay [box-shadow:inset_0_30px_60px_0px_var(--color-overlay)] border-top-1 border-top-solid border-top-gray-5)',
27
- 'layer-components:[&[data-state=closed]]:animate-fade-out',
28
- 'motion-reduce:animate-none',
29
- );
30
-
31
- const StyledContent = withClassName(
32
- DialogPrimitive.Content,
33
- 'layer-components:(z-dialog fixed shadow-xl-up bg-white overflow-y-auto flex flex-col border-top-1 border-top-solid border-top-gray-5)',
34
- 'layer-components:sm:(shadow-xl)',
35
- 'transform-gpu !motion-reduce:animate-none',
36
- 'layer-components:(left-50% top-50% translate-[-50%] w-90vw max-w-450px max-h-85vh p-6 pt-8 rounded-lg border-b-1 pt-6)',
37
- 'layer-components:(animate-dialog-in [&[data-state=closed]]:animate-dialog-out motion-reduce:animate-none)',
38
- );
39
- const sheetClassNames = classNames(
40
- 'layer-variants:lt-sm:(translate-0 left-0 right-0 top-auto h-min-content rounded-tl-xl rounded-tr-xl rounded-b-0 p-6 pt-8 w-full max-w-none pb-[calc(3rem+env(safe-area-inset-bottom,0px))] border-b-0)',
41
- 'layer-variants:lt-sm:(animate-ease-in animate-fade-in-up [&[data-state=closed]]:animate-fade-out-down)',
42
- );
43
- const sheetClassNameWithOverlayKeyboard = classNames(
44
- 'layer-variants:lt-sm:(bottom-[calc(var(--mock-virtual-keyboard-height,env(keyboard-inset-height,0px))+var(--gesture-y,0px))] max-h-[calc(95vh-var(--mock-virtual-keyboard-height,env(keyboard-inset-height,0px)))])',
45
- );
46
- const sheetClassNameWithDisplaceKeyboard = classNames(
47
- 'layer-variants:lt-sm:(bottom-[calc(var(--viewport-bottom-offset,0px)+var(--gesture-y,0px))] max-h-[calc(0.85*var(--viewport-height,100vh))])',
48
- );
49
-
50
- export const Content = forwardRef<
51
- HTMLDivElement,
52
- ComponentPropsWithoutRef<typeof StyledContent> & {
53
- outerClassName?: string;
54
- width?: 'lg' | 'md' | 'sm';
55
- disableSheet?: boolean;
56
- }
57
- >(function Content(
58
- { children, width, outerClassName, className, disableSheet, ...props },
59
- ref,
60
- ) {
61
- const particles = useParticles();
62
- const wasOpenRef = useRef(false);
63
- const openRef = useCallback(
64
- (element: HTMLDivElement | null) => {
65
- if (
66
- !wasOpenRef.current &&
67
- element?.getAttribute('data-state') === 'open'
68
- ) {
69
- wasOpenRef.current = true;
70
-
71
- const matchesSmall =
72
- !disableSheet &&
73
- typeof window !== 'undefined' &&
74
- !window.matchMedia('(min-width:600px)').matches;
75
- if (!matchesSmall) return;
76
-
77
- setTimeout(() => {
78
- particles?.addParticles(
79
- particles.elementExplosion({
80
- count: 20,
81
- margin: 40,
82
- borders: ['top'],
83
- color: [
84
- {
85
- space: 'rgb',
86
- values: [0, 0, 0],
87
- opacity: 0.02,
88
- },
89
- {
90
- space: 'rgb',
91
- values: [0, 0, 0],
92
- opacity: 0,
93
- },
94
- ],
95
- element,
96
- startRadius: 15,
97
- endRadius: 0,
98
- lifespan: 1000,
99
- force: 0.5,
100
- drag: 0.01,
101
- forceFuzz: 0.5,
102
- angleFuzz: 0.1,
103
- }),
104
- );
105
- }, 180);
106
- } else if (element?.getAttribute('data-state') === 'closed') {
107
- wasOpenRef.current = false;
108
- }
109
- },
110
- [particles, disableSheet],
111
- );
112
-
113
- const gestureRef = useRef<HTMLDivElement>(null);
114
-
115
- const finalRef = useMergedRef(ref, openRef, gestureRef);
116
-
117
- const { virtualKeyboardBehavior } = useConfig();
118
-
119
- return (
120
- <DialogPrimitive.Portal>
121
- <StyledOverlay />
122
- <StyledContent
123
- data-dialog-content
124
- ref={finalRef}
125
- {...props}
126
- className={classNames(
127
- {
128
- 'md:max-w-800px': width === 'lg',
129
- 'max-w-600px': width === 'md',
130
- 'max-w-300px': width === 'sm',
131
- },
132
- !disableSheet && sheetClassNames,
133
- !disableSheet &&
134
- virtualKeyboardBehavior === 'overlay' &&
135
- sheetClassNameWithOverlayKeyboard,
136
- !disableSheet &&
137
- virtualKeyboardBehavior === 'displace' &&
138
- sheetClassNameWithDisplaceKeyboard,
139
- outerClassName || className,
140
- )}
141
- >
142
- {!disableSheet && <DialogSwipeHandle />}
143
- {children}
144
- </StyledContent>
145
- </DialogPrimitive.Portal>
146
- );
147
- });
148
-
149
- export const DialogSwipeHandle = forwardRef<
150
- HTMLDivElement,
151
- ComponentPropsWithoutRef<'div'>
152
- >(function DialogSwipeHandle({ className, ...props }, ref) {
153
- const close = useContext(DialogCloseContext);
154
- const innerRef = useRef<HTMLDivElement>(null);
155
- useDrag(
156
- ({ swipe: [, swipeY], movement: [, dy], velocity: [, vy], last }) => {
157
- const content = findParentDialogContent(innerRef.current);
158
- if (!content) return;
159
-
160
- const contentHeight = content.clientHeight;
161
-
162
- const shouldClose = last && (swipeY === 1 || dy > contentHeight / 2);
163
- if (shouldClose) {
164
- close();
165
- }
166
- const gestureY = last ? (shouldClose ? -1000 : 0) : -Math.max(0, dy);
167
- console.log(gestureY, dy, vy, swipeY);
168
- content.style.setProperty('--gesture-y', `${gestureY}px`);
169
- content.style.setProperty('transition', last ? 'bottom 0.2s' : '');
170
- },
171
- {
172
- target: innerRef,
173
- axis: 'y',
174
- },
175
- );
176
- const finalRef = useMergedRef(ref, innerRef);
177
- return (
178
- <div
179
- ref={finalRef}
180
- {...props}
181
- className={classNames(
182
- 'absolute top-0 left-50% transform-gpu -translate-x-1/2 w-20% py-2 rounded-full cursor-grab sm:hidden touch-none',
183
- className,
184
- )}
185
- >
186
- <div className="w-full h-[4px] bg-gray-4 rounded-full" />
187
- </div>
188
- );
189
- });
190
-
191
- function findParentDialogContent(
192
- element: HTMLElement | null,
193
- ): HTMLElement | null {
194
- if (!element) return null;
195
- if (element.getAttribute('data-dialog-content')) return element;
196
- return findParentDialogContent(element.parentElement);
197
- }
198
-
199
- const DialogCloseContext = createContext<() => void>(() => {});
200
-
201
- const StyledTitle = withClassName(
202
- DialogPrimitive.Title,
203
- 'font-title color-black text-3xl mb-4 mt-0',
204
- );
205
-
206
- const StyledDescription = withClassName(
207
- DialogPrimitive.Description,
208
- 'mt-3 mb-6 color-gray8 text-md leading-6',
209
- );
210
-
211
- // Exports
212
- const DialogRoot = (props: DialogPrimitive.DialogProps) => {
213
- const [innerOpen, innerOnOpenChange] = useState(props.defaultOpen);
214
- const open = props.open ?? innerOpen;
215
- const onOpenChange = useCallback(
216
- (open: boolean) => {
217
- innerOnOpenChange(open);
218
- props.onOpenChange?.(open);
219
- },
220
- [props.onOpenChange],
221
- );
222
-
223
- const close = useCallback(() => {
224
- onOpenChange(false);
225
- }, [onOpenChange]);
226
-
227
- return (
228
- <DialogCloseContext.Provider value={close}>
229
- <DialogPrimitive.Root
230
- {...props}
231
- open={open}
232
- onOpenChange={onOpenChange}
233
- />
234
- </DialogCloseContext.Provider>
235
- );
236
- };
237
-
238
- export const DialogTrigger = DialogPrimitive.Trigger;
239
- export const DialogContent = Content;
240
- export const DialogTitle = StyledTitle;
241
- export const DialogDescription = StyledDescription;
242
- export const DialogClose = forwardRef<
243
- HTMLButtonElement,
244
- DialogPrimitive.DialogCloseProps
245
- >(function DialogClose({ asChild, children, ...props }, ref) {
246
- return (
247
- <DialogPrimitive.DialogClose asChild ref={ref} {...props}>
248
- {asChild === true ? children : <Button>{children ?? 'Close'}</Button>}
249
- </DialogPrimitive.DialogClose>
250
- );
251
- });
252
-
253
- export type { DialogProps } from '@radix-ui/react-dialog';
254
-
255
- export const DialogActions = withClassName(
256
- 'div',
257
- 'flex justify-end sticky w-full gap-3 items-center bg-white py-4 translate-y-6 flex-wrap',
258
- 'bottom--6',
259
- 'sm:(bottom-0)',
260
- );
261
-
262
- export const DialogSelectTrigger = forwardRef<
263
- HTMLButtonElement,
264
- DialogPrimitive.DialogTriggerProps
265
- >(function DialogSelectTrigger({ children, className, ...props }, ref) {
266
- return (
267
- <DialogPrimitive.Trigger
268
- className={classNames(selectTriggerClassName, className)}
269
- {...props}
270
- >
271
- <span>{children}</span>
272
- <ChevronDownIcon />
273
- </DialogPrimitive.Trigger>
274
- );
275
- });
276
-
277
- export const DialogSelectList = withClassName(
278
- RadioGroupPrimitive.Root,
279
- 'flex flex-col gap-2 overflow-y-auto p-2',
280
- );
281
-
282
- export const DialogSelectItemRoot = withClassName(
283
- RadioGroupPrimitive.Item,
284
- 'flex items-center gap-3 w-full py-3 px-4 text-left border-none rounded-lg font-normal bg-transparent [&:nth-child(2n+1)]:bg-gray-blend cursor-pointer transition-all',
285
- '[&[data-state=checked]]:(bg-primary-wash text-primary-dark)',
286
- );
287
-
288
- export const DialogSelectItem = forwardRef<
289
- HTMLButtonElement,
290
- ComponentPropsWithoutRef<typeof DialogSelectItemRoot>
291
- >(function DialogSelectItem({ children, ...props }, ref) {
292
- return (
293
- <DialogSelectItemRoot {...props}>
294
- <span className="flex-1">{children}</span>
295
- <RadioGroupPrimitive.Indicator className="flex-0-0-auto">
296
- <CheckIcon />
297
- </RadioGroupPrimitive.Indicator>
298
- </DialogSelectItemRoot>
299
- );
300
- });
301
-
302
- export const Dialog = Object.assign(DialogRoot, {
303
- Trigger: DialogTrigger,
304
- Content,
305
- Title: StyledTitle,
306
- Description: StyledDescription,
307
- Close: DialogClose,
308
- Actions: DialogActions,
309
- SelectTrigger: DialogSelectTrigger,
310
- SelectList: DialogSelectList,
311
- SelectItem: DialogSelectItem,
312
- });
1
+ 'use client';
2
+
3
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
4
+ import { CheckIcon, ChevronDownIcon } from '@radix-ui/react-icons';
5
+ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
6
+ import { useDrag } from '@use-gesture/react';
7
+ import classNames from 'clsx';
8
+ import {
9
+ ComponentPropsWithoutRef,
10
+ createContext,
11
+ useCallback,
12
+ useContext,
13
+ useRef,
14
+ useState,
15
+ } from 'react';
16
+ import useMergedRef from '../../hooks/useMergedRef.js';
17
+ import { withClassName } from '../../hooks/withClassName.js';
18
+ import { Button } from '../button/index.js';
19
+ import { useParticles } from '../particles/index.js';
20
+ import { useConfig } from '../provider/Provider.js';
21
+ import { selectTriggerClassName } from '../select/index.js';
22
+
23
+ const StyledOverlay = withClassName(
24
+ DialogPrimitive.Overlay,
25
+ 'layer-components:(fixed inset-0 z-dialog-backdrop animate-fade-in animate-duration-200 bg-overlay [box-shadow:inset_0_30px_60px_0px_var(--color-overlay)] border-top-1 border-top-solid border-top-gray-5)',
26
+ 'layer-components:[&[data-state=closed]]:animate-fade-out',
27
+ 'motion-reduce:animate-none',
28
+ );
29
+
30
+ const StyledContent = withClassName(
31
+ DialogPrimitive.Content,
32
+ 'layer-components:(z-dialog fixed shadow-xl-up bg-white overflow-y-auto flex flex-col border-top-1 border-top-solid border-top-gray-5)',
33
+ 'layer-components:sm:(shadow-xl)',
34
+ 'transform-gpu !motion-reduce:animate-none',
35
+ 'layer-components:(left-50% top-50% translate-[-50%] w-90vw max-w-450px max-h-85vh p-6 pt-8 rounded-lg border-b-1 pt-6)',
36
+ 'layer-components:(animate-dialog-in [&[data-state=closed]]:animate-dialog-out motion-reduce:animate-none)',
37
+ );
38
+ const sheetClassNames = classNames(
39
+ 'layer-variants:lt-sm:(translate-0 left-0 right-0 top-auto h-min-content rounded-tl-xl rounded-tr-xl rounded-b-0 p-6 pt-8 w-full max-w-none pb-[calc(3rem+env(safe-area-inset-bottom,0px))] border-b-0)',
40
+ 'layer-variants:lt-sm:(animate-ease-in animate-fade-in-up [&[data-state=closed]]:animate-fade-out-down)',
41
+ );
42
+ const sheetClassNameWithOverlayKeyboard = classNames(
43
+ 'layer-variants:lt-sm:(bottom-[calc(var(--mock-virtual-keyboard-height,env(keyboard-inset-height,0px))+var(--gesture-y,0px))] max-h-[calc(95vh-var(--mock-virtual-keyboard-height,env(keyboard-inset-height,0px)))])',
44
+ );
45
+ const sheetClassNameWithDisplaceKeyboard = classNames(
46
+ 'layer-variants:lt-sm:(bottom-[calc(var(--viewport-bottom-offset,0px)+var(--gesture-y,0px))] max-h-[calc(0.85*var(--viewport-height,100vh))])',
47
+ );
48
+
49
+ export const Content = function Content({
50
+ ref,
51
+ children,
52
+ width,
53
+ outerClassName,
54
+ className,
55
+ disableSheet,
56
+ ...props
57
+ }: ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
58
+ width?: 'sm' | 'md' | 'lg';
59
+ disableSheet?: boolean;
60
+ outerClassName?: string;
61
+ ref?: React.Ref<HTMLDivElement>;
62
+ }) {
63
+ const particles = useParticles();
64
+ const wasOpenRef = useRef(false);
65
+ const openRef = useCallback(
66
+ (element: HTMLDivElement | null) => {
67
+ if (
68
+ !wasOpenRef.current &&
69
+ element?.getAttribute('data-state') === 'open'
70
+ ) {
71
+ wasOpenRef.current = true;
72
+
73
+ const matchesSmall =
74
+ !disableSheet &&
75
+ typeof window !== 'undefined' &&
76
+ !window.matchMedia('(min-width:600px)').matches;
77
+ if (!matchesSmall) return;
78
+
79
+ setTimeout(() => {
80
+ particles?.addParticles(
81
+ particles.elementExplosion({
82
+ count: 20,
83
+ margin: 40,
84
+ borders: ['top'],
85
+ color: [
86
+ {
87
+ space: 'rgb',
88
+ values: [0, 0, 0],
89
+ opacity: 0.02,
90
+ },
91
+ {
92
+ space: 'rgb',
93
+ values: [0, 0, 0],
94
+ opacity: 0,
95
+ },
96
+ ],
97
+ element,
98
+ startRadius: 15,
99
+ endRadius: 0,
100
+ lifespan: 1000,
101
+ force: 0.5,
102
+ drag: 0.01,
103
+ forceFuzz: 0.5,
104
+ angleFuzz: 0.1,
105
+ }),
106
+ );
107
+ }, 180);
108
+ } else if (element?.getAttribute('data-state') === 'closed') {
109
+ wasOpenRef.current = false;
110
+ }
111
+ },
112
+ [particles, disableSheet],
113
+ );
114
+
115
+ const gestureRef = useRef<HTMLDivElement>(null);
116
+
117
+ const finalRef = useMergedRef(ref, openRef, gestureRef);
118
+
119
+ const { virtualKeyboardBehavior } = useConfig();
120
+
121
+ return (
122
+ <DialogPrimitive.Portal>
123
+ <StyledOverlay />
124
+ <StyledContent
125
+ data-dialog-content
126
+ ref={finalRef}
127
+ {...props}
128
+ className={classNames(
129
+ {
130
+ 'md:max-w-800px': width === 'lg',
131
+ 'max-w-600px': width === 'md',
132
+ 'max-w-300px': width === 'sm',
133
+ },
134
+ !disableSheet && sheetClassNames,
135
+ !disableSheet &&
136
+ virtualKeyboardBehavior === 'overlay' &&
137
+ sheetClassNameWithOverlayKeyboard,
138
+ !disableSheet &&
139
+ virtualKeyboardBehavior === 'displace' &&
140
+ sheetClassNameWithDisplaceKeyboard,
141
+ outerClassName || className,
142
+ )}
143
+ >
144
+ {!disableSheet && <DialogSwipeHandle />}
145
+ {children}
146
+ </StyledContent>
147
+ </DialogPrimitive.Portal>
148
+ );
149
+ };
150
+
151
+ export const DialogSwipeHandle = function DialogSwipeHandle({
152
+ ref,
153
+ className,
154
+ ...props
155
+ }: ComponentPropsWithoutRef<'div'> & {
156
+ ref?: React.Ref<HTMLDivElement>;
157
+ }) {
158
+ const close = useContext(DialogCloseContext);
159
+ const innerRef = useRef<HTMLDivElement>(null);
160
+ useDrag(
161
+ ({ swipe: [, swipeY], movement: [, dy], velocity: [, vy], last }) => {
162
+ const content = findParentDialogContent(innerRef.current);
163
+ if (!content) return;
164
+
165
+ const contentHeight = content.clientHeight;
166
+
167
+ const shouldClose = last && (swipeY === 1 || dy > contentHeight / 2);
168
+ if (shouldClose) {
169
+ close();
170
+ }
171
+ const gestureY = last ? (shouldClose ? -1000 : 0) : -Math.max(0, dy);
172
+ console.log(gestureY, dy, vy, swipeY);
173
+ content.style.setProperty('--gesture-y', `${gestureY}px`);
174
+ content.style.setProperty('transition', last ? 'bottom 0.2s' : '');
175
+ },
176
+ {
177
+ target: innerRef,
178
+ axis: 'y',
179
+ },
180
+ );
181
+ const finalRef = useMergedRef(ref, innerRef);
182
+ return (
183
+ <div
184
+ ref={finalRef}
185
+ {...props}
186
+ className={classNames(
187
+ 'absolute top-0 left-50% transform-gpu -translate-x-1/2 w-20% py-2 rounded-full cursor-grab sm:hidden touch-none',
188
+ className,
189
+ )}
190
+ >
191
+ <div className="w-full h-[4px] bg-gray-4 rounded-full" />
192
+ </div>
193
+ );
194
+ };
195
+
196
+ function findParentDialogContent(
197
+ element: HTMLElement | null,
198
+ ): HTMLElement | null {
199
+ if (!element) return null;
200
+ if (element.getAttribute('data-dialog-content')) return element;
201
+ return findParentDialogContent(element.parentElement);
202
+ }
203
+
204
+ const DialogCloseContext = createContext<() => void>(() => {});
205
+
206
+ const StyledTitle = withClassName(
207
+ DialogPrimitive.Title,
208
+ 'font-title color-black text-3xl mb-4 mt-0',
209
+ );
210
+
211
+ const StyledDescription = withClassName(
212
+ DialogPrimitive.Description,
213
+ 'mt-3 mb-6 color-gray8 text-md leading-6',
214
+ );
215
+
216
+ // Exports
217
+ const DialogRoot = (props: DialogPrimitive.DialogProps) => {
218
+ const [innerOpen, innerOnOpenChange] = useState(props.defaultOpen);
219
+ const open = props.open ?? innerOpen;
220
+ const onOpenChange = useCallback(
221
+ (open: boolean) => {
222
+ innerOnOpenChange(open);
223
+ props.onOpenChange?.(open);
224
+ },
225
+ [props.onOpenChange],
226
+ );
227
+
228
+ const close = useCallback(() => {
229
+ onOpenChange(false);
230
+ }, [onOpenChange]);
231
+
232
+ return (
233
+ <DialogCloseContext.Provider value={close}>
234
+ <DialogPrimitive.Root
235
+ {...props}
236
+ open={open}
237
+ onOpenChange={onOpenChange}
238
+ />
239
+ </DialogCloseContext.Provider>
240
+ );
241
+ };
242
+
243
+ export const DialogTrigger = DialogPrimitive.Trigger;
244
+ export const DialogContent = Content;
245
+ export const DialogTitle = StyledTitle;
246
+ export const DialogDescription = StyledDescription;
247
+ export const DialogClose = function DialogClose({
248
+ ref,
249
+ asChild,
250
+ children,
251
+ ...props
252
+ }: DialogPrimitive.DialogCloseProps & {
253
+ ref?: React.Ref<HTMLButtonElement>;
254
+ }) {
255
+ return (
256
+ <DialogPrimitive.DialogClose asChild ref={ref} {...props}>
257
+ {asChild === true ? children : <Button>{children ?? 'Close'}</Button>}
258
+ </DialogPrimitive.DialogClose>
259
+ );
260
+ };
261
+
262
+ export type { DialogProps } from '@radix-ui/react-dialog';
263
+
264
+ export const DialogActions = withClassName(
265
+ 'div',
266
+ 'flex justify-end sticky w-full gap-3 items-center bg-white py-4 translate-y-6 flex-wrap',
267
+ 'bottom--6',
268
+ 'sm:(bottom-0)',
269
+ );
270
+
271
+ export const DialogSelectTrigger = function DialogSelectTrigger({
272
+ ref,
273
+ children,
274
+ className,
275
+ ...props
276
+ }: DialogPrimitive.DialogTriggerProps & {
277
+ ref?: React.Ref<HTMLButtonElement>;
278
+ }) {
279
+ return (
280
+ <DialogPrimitive.Trigger
281
+ className={classNames(selectTriggerClassName, className)}
282
+ {...props}
283
+ >
284
+ <span>{children}</span>
285
+ <ChevronDownIcon />
286
+ </DialogPrimitive.Trigger>
287
+ );
288
+ };
289
+
290
+ export const DialogSelectList = withClassName(
291
+ RadioGroupPrimitive.Root,
292
+ 'flex flex-col gap-2 overflow-y-auto p-2',
293
+ );
294
+
295
+ export const DialogSelectItemRoot = withClassName(
296
+ RadioGroupPrimitive.Item,
297
+ 'flex items-center gap-3 w-full py-3 px-4 text-left border-none rounded-lg font-normal bg-transparent [&:nth-child(2n+1)]:bg-gray-blend cursor-pointer transition-all',
298
+ '[&[data-state=checked]]:(bg-primary-wash text-primary-dark)',
299
+ );
300
+
301
+ export const DialogSelectItem = function DialogSelectItem({
302
+ ref,
303
+ children,
304
+ ...props
305
+ }: ComponentPropsWithoutRef<typeof DialogSelectItemRoot> & {
306
+ ref?: React.Ref<HTMLButtonElement>;
307
+ }) {
308
+ return (
309
+ <DialogSelectItemRoot {...props}>
310
+ <span className="flex-1">{children}</span>
311
+ <RadioGroupPrimitive.Indicator className="flex-0-0-auto">
312
+ <CheckIcon />
313
+ </RadioGroupPrimitive.Indicator>
314
+ </DialogSelectItemRoot>
315
+ );
316
+ };
317
+
318
+ export const Dialog = Object.assign(DialogRoot, {
319
+ Trigger: DialogTrigger,
320
+ Content,
321
+ Title: StyledTitle,
322
+ Description: StyledDescription,
323
+ Close: DialogClose,
324
+ Actions: DialogActions,
325
+ SelectTrigger: DialogSelectTrigger,
326
+ SelectList: DialogSelectList,
327
+ SelectItem: DialogSelectItem,
328
+ });