sparkdesign 0.4.6 → 0.4.8

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 (276) hide show
  1. package/AI_README.md +60 -0
  2. package/README.md +1 -1
  3. package/cli/dist/commands/add.js +1 -1
  4. package/cli/dist/commands/init.js +1 -1
  5. package/cli/registry/AGENTS.md +9 -2
  6. package/cli/registry/agent-manifest.json +794 -0
  7. package/cli/registry/basic/alert-dialog.tsx +3 -6
  8. package/cli/registry/basic/alert.tsx +76 -0
  9. package/cli/registry/basic/aspect-ratio.tsx +8 -0
  10. package/cli/registry/basic/breadcrumb.tsx +117 -0
  11. package/cli/registry/basic/button-group.tsx +79 -0
  12. package/cli/registry/basic/button.tsx +19 -6
  13. package/cli/registry/basic/calendar.tsx +221 -0
  14. package/cli/registry/basic/card.tsx +115 -0
  15. package/cli/registry/basic/carousel.tsx +241 -0
  16. package/cli/registry/basic/chart.tsx +372 -0
  17. package/cli/registry/basic/checkbox.tsx +42 -0
  18. package/cli/registry/basic/collapsible-card.tsx +4 -6
  19. package/cli/registry/basic/combobox.tsx +133 -0
  20. package/cli/registry/basic/command.tsx +184 -0
  21. package/cli/registry/basic/context-menu.tsx +238 -0
  22. package/cli/registry/basic/data-table.tsx +73 -0
  23. package/cli/registry/basic/date-picker.tsx +84 -0
  24. package/cli/registry/basic/dialog.tsx +164 -0
  25. package/cli/registry/basic/direction.tsx +25 -0
  26. package/cli/registry/basic/drawer.tsx +162 -0
  27. package/cli/registry/basic/dropdown-menu.tsx +2 -7
  28. package/cli/registry/basic/empty.tsx +104 -0
  29. package/cli/registry/basic/field.tsx +248 -0
  30. package/cli/registry/basic/hover-card.tsx +57 -0
  31. package/cli/registry/basic/icon-button.tsx +18 -11
  32. package/cli/registry/basic/input-group.tsx +168 -0
  33. package/cli/registry/basic/input-otp.tsx +75 -0
  34. package/cli/registry/basic/input.tsx +43 -0
  35. package/cli/registry/basic/item.tsx +204 -0
  36. package/cli/registry/basic/label.tsx +24 -0
  37. package/cli/registry/basic/menubar.tsx +274 -0
  38. package/cli/registry/basic/native-select.tsx +62 -0
  39. package/cli/registry/basic/navigation-menu.tsx +168 -0
  40. package/cli/registry/basic/popover.tsx +58 -0
  41. package/cli/registry/basic/scroll-area.tsx +58 -0
  42. package/cli/registry/basic/select.tsx +24 -3
  43. package/cli/registry/basic/separator.tsx +26 -0
  44. package/cli/registry/basic/sheet.tsx +18 -0
  45. package/cli/registry/basic/spinner.tsx +20 -5
  46. package/cli/registry/basic/textarea.tsx +43 -0
  47. package/cli/registry/basic/toggle.tsx +1 -1
  48. package/cli/registry/basic/tooltip.tsx +2 -1
  49. package/cli/registry/basic/typography.tsx +1 -1
  50. package/cli/registry/chat/chat-input/chat-input-textarea.tsx +1 -1
  51. package/cli/registry/chat/chat-input/compound.tsx +4 -3
  52. package/cli/registry/chat/chat-input/context.tsx +4 -1
  53. package/cli/registry/chat/code-block-part.tsx +1 -1
  54. package/cli/registry/chat/conversation-anchor-nav.tsx +349 -0
  55. package/cli/registry/chat/file-attachment.tsx +2 -1
  56. package/cli/registry/chat/file-review-part.tsx +21 -21
  57. package/cli/registry/chat/markdown.tsx +2 -2
  58. package/cli/registry/chat/queue-indicator.tsx +1 -0
  59. package/cli/registry/chat/streaming-markdown-block.tsx +12 -8
  60. package/cli/registry/chat/tool-invocation-card.tsx +4 -1
  61. package/cli/registry/lib/file-icon-maps.ts +22 -22
  62. package/cli/registry/meta.json +600 -15
  63. package/cli/registry/tokens/ontology.json +404 -0
  64. package/cli/registry/tokens/scale/presets/compact.css +16 -5
  65. package/cli/registry/tokens/scale/presets/dense.css +13 -2
  66. package/cli/registry/tokens/scale/presets/sharp.css +18 -6
  67. package/cli/registry/tokens/scale/presets/soft.css +23 -1
  68. package/dist/registry/basic/alert-dialog.d.ts +1 -1
  69. package/dist/registry/basic/alert.d.ts +24 -0
  70. package/dist/registry/basic/aspect-ratio.d.ts +16 -0
  71. package/dist/registry/basic/avatar.d.ts +1 -1
  72. package/dist/registry/basic/breadcrumb.d.ts +24 -0
  73. package/dist/registry/basic/button-group.d.ts +26 -0
  74. package/dist/registry/basic/button.d.ts +3 -1
  75. package/dist/registry/basic/calendar.d.ts +22 -0
  76. package/dist/registry/basic/card.d.ts +32 -0
  77. package/dist/registry/basic/carousel.d.ts +19 -0
  78. package/dist/registry/basic/chart.d.ts +55 -0
  79. package/dist/registry/basic/checkbox.d.ts +21 -0
  80. package/dist/registry/basic/combobox.d.ts +37 -0
  81. package/dist/registry/basic/command.d.ts +18 -0
  82. package/dist/registry/basic/context-menu.d.ts +44 -0
  83. package/dist/registry/basic/data-table.d.ts +26 -0
  84. package/dist/registry/basic/date-picker.d.ts +27 -0
  85. package/dist/registry/basic/dialog.d.ts +39 -0
  86. package/dist/registry/basic/direction.d.ts +19 -0
  87. package/dist/registry/basic/drawer.d.ts +37 -0
  88. package/dist/registry/basic/empty.d.ts +22 -0
  89. package/dist/registry/basic/field.d.ts +24 -0
  90. package/dist/registry/basic/hover-card.d.ts +22 -0
  91. package/dist/registry/basic/icon-button.d.ts +2 -1
  92. package/dist/registry/basic/input-group.d.ts +29 -0
  93. package/dist/registry/basic/input-otp.d.ts +22 -0
  94. package/dist/registry/basic/input.d.ts +20 -0
  95. package/dist/registry/basic/item.d.ts +34 -0
  96. package/dist/registry/basic/label.d.ts +16 -0
  97. package/dist/registry/basic/menubar.d.ts +37 -0
  98. package/dist/registry/basic/native-select.d.ts +18 -0
  99. package/dist/registry/basic/navigation-menu.d.ts +25 -0
  100. package/dist/registry/basic/popover.d.ts +23 -0
  101. package/dist/registry/basic/resizable.d.ts +48 -48
  102. package/dist/registry/basic/scroll-area.d.ts +5 -0
  103. package/dist/registry/basic/select.d.ts +7 -2
  104. package/dist/registry/basic/separator.d.ts +16 -0
  105. package/dist/registry/basic/sheet.d.ts +13 -0
  106. package/dist/registry/basic/spinner.d.ts +6 -2
  107. package/dist/registry/basic/tag.d.ts +1 -1
  108. package/dist/registry/basic/textarea.d.ts +21 -0
  109. package/dist/registry/chat/chat-input/context.d.ts +3 -1
  110. package/dist/registry/chat/conversation-anchor-nav.d.ts +72 -0
  111. package/dist/registry/chat/tool-invocation-card.d.ts +2 -0
  112. package/dist/scale/computed.css +11 -0
  113. package/dist/scale/config.css +11 -0
  114. package/dist/scale/presets/compact.css +23 -5
  115. package/dist/scale/presets/dense.css +20 -2
  116. package/dist/scale/presets/sharp.css +25 -6
  117. package/dist/scale/presets/soft.css +30 -1
  118. package/dist/spark-design.cjs.js +37 -33
  119. package/dist/spark-design.es.js +10324 -8950
  120. package/dist/sparkdesign.css +1 -1
  121. package/dist/src/components/basic/Alert/index.d.ts +13 -0
  122. package/dist/src/components/basic/AspectRatio/index.d.ts +13 -0
  123. package/dist/src/components/basic/Breadcrumb/index.d.ts +12 -0
  124. package/dist/src/components/basic/ButtonGroup/index.d.ts +13 -0
  125. package/dist/src/components/basic/Calendar/index.d.ts +13 -0
  126. package/dist/src/components/basic/Card/index.d.ts +13 -0
  127. package/dist/src/components/basic/Carousel/index.d.ts +12 -0
  128. package/dist/src/components/basic/Chart/index.d.ts +13 -0
  129. package/dist/src/components/basic/Checkbox/index.d.ts +13 -0
  130. package/dist/src/components/basic/Combobox/index.d.ts +13 -0
  131. package/dist/src/components/basic/Command/index.d.ts +12 -0
  132. package/dist/src/components/basic/ContextMenu/index.d.ts +19 -0
  133. package/dist/src/components/basic/DataTable/index.d.ts +13 -0
  134. package/dist/src/components/basic/DatePicker/index.d.ts +13 -0
  135. package/dist/src/components/basic/Dialog/index.d.ts +16 -0
  136. package/dist/src/components/basic/Direction/index.d.ts +13 -0
  137. package/dist/src/components/basic/Drawer/index.d.ts +16 -0
  138. package/dist/src/components/basic/Empty/index.d.ts +12 -0
  139. package/dist/src/components/basic/Field/index.d.ts +12 -0
  140. package/dist/src/components/basic/HoverCard/index.d.ts +16 -0
  141. package/dist/src/components/basic/Input/index.d.ts +13 -0
  142. package/dist/src/components/basic/InputGroup/index.d.ts +12 -0
  143. package/dist/src/components/basic/InputOTP/index.d.ts +12 -0
  144. package/dist/src/components/basic/Item/index.d.ts +12 -0
  145. package/dist/src/components/basic/Label/index.d.ts +13 -0
  146. package/dist/src/components/basic/Menubar/index.d.ts +12 -0
  147. package/dist/src/components/basic/NativeSelect/index.d.ts +12 -0
  148. package/dist/src/components/basic/NavigationMenu/index.d.ts +12 -0
  149. package/dist/src/components/basic/Popover/index.d.ts +16 -0
  150. package/dist/src/components/basic/ScrollArea/index.d.ts +12 -0
  151. package/dist/src/components/basic/Separator/index.d.ts +13 -0
  152. package/dist/src/components/basic/Sheet/index.d.ts +13 -0
  153. package/dist/src/components/basic/Textarea/index.d.ts +13 -0
  154. package/dist/src/components/chat/ConversationAnchorNav/index.d.ts +13 -0
  155. package/dist/src/components/chat/StreamingMarkdownBlock/index.d.ts +13 -0
  156. package/dist/src/components/index.d.ts +58 -1
  157. package/dist/src/lib/index.d.ts +1 -1
  158. package/dist/src/lib/motion.d.ts +79 -0
  159. package/dist/theme-base.css +22 -0
  160. package/dist/themes/dark-mint.css +6 -0
  161. package/dist/themes/dark-parchment.css +6 -0
  162. package/dist/themes/light-parchment.css +6 -0
  163. package/dist/tokens/AGENTS.md +1 -0
  164. package/dist/tokens/scale/computed.css +11 -0
  165. package/dist/tokens/scale/config.css +11 -0
  166. package/dist/tokens/scale/presets/compact.css +23 -5
  167. package/dist/tokens/scale/presets/dense.css +20 -2
  168. package/dist/tokens/scale/presets/sharp.css +25 -6
  169. package/dist/tokens/scale/presets/soft.css +30 -1
  170. package/dist/tokens/theme-base.css +22 -0
  171. package/dist/tokens/themes/dark-mint.css +6 -0
  172. package/dist/tokens/themes/dark-parchment.css +6 -0
  173. package/dist/tokens/themes/light-parchment.css +6 -0
  174. package/docs/agent/component-selection.md +60 -0
  175. package/docs/agent/token-ontology.md +37 -0
  176. package/package.json +31 -5
  177. package/registry/agent-manifest.json +794 -0
  178. package/registry/tokens/ontology.json +404 -0
  179. package/dist/_basePickBy-DnQN8w3y.js +0 -151
  180. package/dist/_basePickBy-a-kPMlkg.cjs +0 -1
  181. package/dist/_baseUniq-B-N2NQ50.js +0 -614
  182. package/dist/_baseUniq-Cc_zbSif.cjs +0 -1
  183. package/dist/arc-BQBhijZ6.js +0 -83
  184. package/dist/arc-mWQt0Yph.cjs +0 -1
  185. package/dist/architectureDiagram-VXUJARFQ-BMZEucno.cjs +0 -36
  186. package/dist/architectureDiagram-VXUJARFQ-DTdjD3Bp.js +0 -4661
  187. package/dist/blockDiagram-VD42YOAC-CzHn0yob.js +0 -2256
  188. package/dist/blockDiagram-VD42YOAC-DDxdHAlz.cjs +0 -122
  189. package/dist/c4Diagram-YG6GDRKO-4Gz0I4gj.cjs +0 -10
  190. package/dist/c4Diagram-YG6GDRKO-BIy--yVN.js +0 -1580
  191. package/dist/channel-BQn0o8bs.js +0 -5
  192. package/dist/channel-DaN7XniJ.cjs +0 -1
  193. package/dist/chunk-4BX2VUAB-BlQFTQqz.cjs +0 -1
  194. package/dist/chunk-4BX2VUAB-Czitj3Kc.js +0 -8
  195. package/dist/chunk-55IACEB6-DXacNZbO.js +0 -8
  196. package/dist/chunk-55IACEB6-DnDxpye9.cjs +0 -1
  197. package/dist/chunk-B4BG7PRW-CBdN0q_V.js +0 -1375
  198. package/dist/chunk-B4BG7PRW-DbGvUkGO.cjs +0 -165
  199. package/dist/chunk-DI55MBZ5-D1YJMs6x.cjs +0 -220
  200. package/dist/chunk-DI55MBZ5-NCQTvayw.js +0 -1370
  201. package/dist/chunk-FMBD7UC4-CsGMbrtr.js +0 -19
  202. package/dist/chunk-FMBD7UC4-Di7cUUh5.cjs +0 -15
  203. package/dist/chunk-QN33PNHL-0j5LC8Lm.cjs +0 -1
  204. package/dist/chunk-QN33PNHL-3GERZBRm.js +0 -19
  205. package/dist/chunk-QZHKN3VN-AVEY9ImQ.js +0 -15
  206. package/dist/chunk-QZHKN3VN-s8Z0a8mc.cjs +0 -1
  207. package/dist/chunk-TZMSLE5B-CAf87HPt.cjs +0 -1
  208. package/dist/chunk-TZMSLE5B-sbiflal0.js +0 -64
  209. package/dist/classDiagram-2ON5EDUG-Ct9JLIN2.cjs +0 -1
  210. package/dist/classDiagram-2ON5EDUG-Dzfrft3a.js +0 -16
  211. package/dist/classDiagram-v2-WZHVMYZB-Ct9JLIN2.cjs +0 -1
  212. package/dist/classDiagram-v2-WZHVMYZB-Dzfrft3a.js +0 -16
  213. package/dist/clone-Cde_NQ8V.js +0 -8
  214. package/dist/clone-DCNjWuM2.cjs +0 -1
  215. package/dist/cose-bilkent-S5V4N54A-0uLijMro.cjs +0 -1
  216. package/dist/cose-bilkent-S5V4N54A-Bb08N431.js +0 -2608
  217. package/dist/cytoscape.esm-CNUX3VTg.cjs +0 -321
  218. package/dist/cytoscape.esm-Cvf3sx9F.js +0 -18704
  219. package/dist/dagre-6UL2VRFP-CY_Wz5Zd.js +0 -444
  220. package/dist/dagre-6UL2VRFP-Dxe7_qZc.cjs +0 -4
  221. package/dist/defaultLocale-BgPVtth8.js +0 -171
  222. package/dist/defaultLocale-C4wbwF1n.cjs +0 -1
  223. package/dist/diagram-PSM6KHXK-D2bdb7MT.js +0 -531
  224. package/dist/diagram-PSM6KHXK-YF69SUjY.cjs +0 -24
  225. package/dist/diagram-QEK2KX5R-BpUSoh0-.js +0 -217
  226. package/dist/diagram-QEK2KX5R-DZPGteon.cjs +0 -43
  227. package/dist/diagram-S2PKOQOG-ht-zdvFG.cjs +0 -24
  228. package/dist/diagram-S2PKOQOG-zFeLJ50Z.js +0 -142
  229. package/dist/erDiagram-Q2GNP2WA-B38iJ6ts.js +0 -841
  230. package/dist/erDiagram-Q2GNP2WA-RgS80DDU.cjs +0 -60
  231. package/dist/flowDiagram-NV44I4VS-BHilOs2p.cjs +0 -162
  232. package/dist/flowDiagram-NV44I4VS-BrBJcoce.js +0 -1620
  233. package/dist/ganttDiagram-JELNMOA3-pZiJeFio.cjs +0 -267
  234. package/dist/ganttDiagram-JELNMOA3-tw6FhkWJ.js +0 -2670
  235. package/dist/gitGraphDiagram-V2S2FVAM-BWn5uIK5.js +0 -699
  236. package/dist/gitGraphDiagram-V2S2FVAM-DKKeG-9R.cjs +0 -65
  237. package/dist/graph-DIbblrZP.cjs +0 -1
  238. package/dist/graph-DPcK91G3.js +0 -247
  239. package/dist/infoDiagram-HS3SLOUP-B8gwwhct.cjs +0 -2
  240. package/dist/infoDiagram-HS3SLOUP-D47PNcP_.js +0 -24
  241. package/dist/init-CHZsXQcr.cjs +0 -1
  242. package/dist/init-DjUOC4st.js +0 -16
  243. package/dist/journeyDiagram-XKPGCS4Q-BG3cfhyU.js +0 -834
  244. package/dist/journeyDiagram-XKPGCS4Q-D8DVLJof.cjs +0 -139
  245. package/dist/kanban-definition-3W4ZIXB7-4OCnEouP.cjs +0 -89
  246. package/dist/kanban-definition-3W4ZIXB7-CWi_ssF9.js +0 -719
  247. package/dist/layout-Byuh8f-J.cjs +0 -1
  248. package/dist/layout-CdLdvj1j.js +0 -1335
  249. package/dist/linear-C2Q_PI9B.js +0 -259
  250. package/dist/linear-C69aPBW1.cjs +0 -1
  251. package/dist/mermaid.core-DBwAx_jp.cjs +0 -249
  252. package/dist/mermaid.core-gFR0XUlD.js +0 -15300
  253. package/dist/mindmap-definition-VGOIOE7T-8P7obVV4.cjs +0 -68
  254. package/dist/mindmap-definition-VGOIOE7T-DnOa7WJ9.js +0 -784
  255. package/dist/ordinal-B6-f3MAq.js +0 -61
  256. package/dist/ordinal-CagbB1m8.cjs +0 -1
  257. package/dist/pieDiagram-ADFJNKIX-5NAlvhMo.js +0 -161
  258. package/dist/pieDiagram-ADFJNKIX-CQBG4yR9.cjs +0 -30
  259. package/dist/quadrantDiagram-AYHSOK5B-Oe4y7RZ0.cjs +0 -7
  260. package/dist/quadrantDiagram-AYHSOK5B-rh2DPEP1.js +0 -1022
  261. package/dist/requirementDiagram-UZGBJVZJ-DcWaCuXr.js +0 -850
  262. package/dist/requirementDiagram-UZGBJVZJ-gfdlrFiq.cjs +0 -64
  263. package/dist/sankeyDiagram-TZEHDZUN-CQIKFwD0.js +0 -810
  264. package/dist/sankeyDiagram-TZEHDZUN-DvPtzQvC.cjs +0 -10
  265. package/dist/sequenceDiagram-WL72ISMW-BNrsMagL.cjs +0 -145
  266. package/dist/sequenceDiagram-WL72ISMW-iCX3ckKx.js +0 -2511
  267. package/dist/stateDiagram-FKZM4ZOC-DBvJ_eeL.cjs +0 -1
  268. package/dist/stateDiagram-FKZM4ZOC-ZVsJlaHJ.js +0 -263
  269. package/dist/stateDiagram-v2-4FDKWEC3-CB_nTHcE.js +0 -16
  270. package/dist/stateDiagram-v2-4FDKWEC3-Xkx17v6T.cjs +0 -1
  271. package/dist/timeline-definition-IT6M3QCI-BmGkYQiz.cjs +0 -61
  272. package/dist/timeline-definition-IT6M3QCI-Ck8zTt6w.js +0 -795
  273. package/dist/treemap-GDKQZRPO-B9sfERx8.js +0 -17922
  274. package/dist/treemap-GDKQZRPO-BVfJRs0Z.cjs +0 -160
  275. package/dist/xychartDiagram-PRI3JC2R-By_S8NzN.js +0 -1340
  276. package/dist/xychartDiagram-PRI3JC2R-CNfDrGxM.cjs +0 -7
@@ -0,0 +1,164 @@
1
+ import * as React from 'react'
2
+ import { motion } from 'framer-motion'
3
+ import * as DialogPrimitive from '@radix-ui/react-dialog'
4
+ import { cva, type VariantProps } from 'class-variance-authority'
5
+ import { cn } from '@/lib/utils'
6
+ import { MOTION_FADE, MOTION_SLIDE_UP } from '@/lib/motion'
7
+ import { CloseLine } from './icons-inline'
8
+ import { getThemeFromDocument } from './theme-from-document'
9
+
10
+ const Dialog = DialogPrimitive.Root
11
+ const DialogTrigger = DialogPrimitive.Trigger
12
+ const DialogPortal = DialogPrimitive.Portal
13
+ const DialogClose = DialogPrimitive.Close
14
+
15
+ const DialogOverlay = React.forwardRef<
16
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
17
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
18
+ >(({ className, ...props }, ref) => (
19
+ <DialogPrimitive.Overlay ref={ref} asChild {...props}>
20
+ <motion.div
21
+ className={cn('fixed inset-0 z-50 bg-bg-mask/60', className)}
22
+ {...MOTION_FADE}
23
+ />
24
+ </DialogPrimitive.Overlay>
25
+ ))
26
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
27
+
28
+ const contentVariants = cva(
29
+ 'font-sans fixed left-1/2 top-1/2 z-50 w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 rounded-xl border border-border bg-bg-base text-text shadow-lg p-6 outline-none',
30
+ {
31
+ variants: {
32
+ size: {
33
+ sm: 'max-w-sm',
34
+ default: 'max-w-lg',
35
+ lg: 'max-w-2xl',
36
+ xl: 'max-w-4xl',
37
+ },
38
+ },
39
+ defaultVariants: { size: 'default' },
40
+ },
41
+ )
42
+
43
+ export interface DialogContentProps
44
+ extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>,
45
+ VariantProps<typeof contentVariants> {
46
+ size?: 'sm' | 'default' | 'lg' | 'xl'
47
+ /** Hide the built-in top-right close button. */
48
+ hideCloseButton?: boolean
49
+ /** When provided (e.g. from ThemeStyleProvider), used for portal wrapper */
50
+ dataStyle?: string
51
+ dataTheme?: string
52
+ }
53
+
54
+ const DialogContent = React.forwardRef<
55
+ React.ElementRef<typeof DialogPrimitive.Content>,
56
+ DialogContentProps
57
+ >(
58
+ (
59
+ {
60
+ className,
61
+ children,
62
+ size = 'default',
63
+ hideCloseButton = false,
64
+ dataStyle,
65
+ dataTheme,
66
+ ...props
67
+ },
68
+ ref,
69
+ ) => {
70
+ const fromDoc = getThemeFromDocument()
71
+ const dataProps =
72
+ dataStyle !== undefined
73
+ ? { 'data-style': dataStyle, 'data-theme': dataTheme ?? fromDoc['data-theme'] ?? '' }
74
+ : fromDoc
75
+ return (
76
+ <DialogPortal>
77
+ <div style={{ display: 'contents' }} {...dataProps}>
78
+ <DialogOverlay />
79
+ <DialogPrimitive.Content ref={ref} asChild {...props}>
80
+ <motion.div
81
+ className={cn(contentVariants({ size }), className)}
82
+ {...MOTION_SLIDE_UP}
83
+ >
84
+ {children}
85
+ {!hideCloseButton && (
86
+ <DialogPrimitive.Close
87
+ className={cn(
88
+ 'absolute right-4 top-4 inline-flex size-7 items-center justify-center rounded-md text-text-tertiary opacity-70 transition-colors',
89
+ 'hover:bg-fill-secondary hover:text-text hover:opacity-100',
90
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-border',
91
+ 'disabled:pointer-events-none',
92
+ )}
93
+ >
94
+ <CloseLine className="size-4" />
95
+ <span className="sr-only">Close</span>
96
+ </DialogPrimitive.Close>
97
+ )}
98
+ </motion.div>
99
+ </DialogPrimitive.Content>
100
+ </div>
101
+ </DialogPortal>
102
+ )
103
+ },
104
+ )
105
+ DialogContent.displayName = DialogPrimitive.Content.displayName
106
+
107
+ const DialogHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
108
+ ({ className, ...props }, ref) => (
109
+ <div ref={ref} className={cn('flex flex-col gap-2 text-left', className)} {...props} />
110
+ ),
111
+ )
112
+ DialogHeader.displayName = 'DialogHeader'
113
+
114
+ const DialogFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
115
+ ({ className, ...props }, ref) => (
116
+ <div
117
+ ref={ref}
118
+ className={cn('mt-6 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
119
+ {...props}
120
+ />
121
+ ),
122
+ )
123
+ DialogFooter.displayName = 'DialogFooter'
124
+
125
+ const DialogTitle = React.forwardRef<
126
+ React.ElementRef<typeof DialogPrimitive.Title>,
127
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
128
+ >(({ className, ...props }, ref) => (
129
+ <DialogPrimitive.Title
130
+ ref={ref}
131
+ className={cn('font-sans text-base font-medium leading-6 text-text', className)}
132
+ {...props}
133
+ />
134
+ ))
135
+ DialogTitle.displayName = DialogPrimitive.Title.displayName
136
+
137
+ const DialogDescription = React.forwardRef<
138
+ React.ElementRef<typeof DialogPrimitive.Description>,
139
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
140
+ >(({ className, ...props }, ref) => (
141
+ <DialogPrimitive.Description
142
+ ref={ref}
143
+ className={cn('text-sm leading-6 text-text-tertiary', className)}
144
+ {...props}
145
+ />
146
+ ))
147
+ DialogDescription.displayName = DialogPrimitive.Description.displayName
148
+
149
+ export type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement>
150
+ export type DialogFooterProps = React.HTMLAttributes<HTMLDivElement>
151
+
152
+ export {
153
+ Dialog,
154
+ DialogTrigger,
155
+ DialogPortal,
156
+ DialogOverlay,
157
+ DialogClose,
158
+ DialogContent,
159
+ DialogHeader,
160
+ DialogFooter,
161
+ DialogTitle,
162
+ DialogDescription,
163
+ contentVariants as dialogContentVariants,
164
+ }
@@ -0,0 +1,25 @@
1
+ import * as React from 'react'
2
+
3
+ export type Direction = 'ltr' | 'rtl'
4
+
5
+ const DirectionContext = React.createContext<Direction>('ltr')
6
+
7
+ export interface DirectionProviderProps extends React.HTMLAttributes<HTMLDivElement> {
8
+ dir?: Direction
9
+ }
10
+
11
+ function DirectionProvider({ dir = 'ltr', children, ...props }: DirectionProviderProps) {
12
+ return (
13
+ <DirectionContext.Provider value={dir}>
14
+ <div dir={dir} {...props}>
15
+ {children}
16
+ </div>
17
+ </DirectionContext.Provider>
18
+ )
19
+ }
20
+
21
+ function useDirection() {
22
+ return React.useContext(DirectionContext)
23
+ }
24
+
25
+ export { DirectionProvider, useDirection }
@@ -0,0 +1,162 @@
1
+ import * as React from 'react'
2
+ import { motion } from 'framer-motion'
3
+ import * as DialogPrimitive from '@radix-ui/react-dialog'
4
+ import { cva, type VariantProps } from 'class-variance-authority'
5
+ import { cn } from '@/lib/utils'
6
+ import { MOTION_FADE, MOTION_DURATION, MOTION_EASE } from '@/lib/motion'
7
+ import { CloseLine } from './icons-inline'
8
+ import { getThemeFromDocument } from './theme-from-document'
9
+
10
+ const Drawer = DialogPrimitive.Root
11
+ const DrawerTrigger = DialogPrimitive.Trigger
12
+ const DrawerClose = DialogPrimitive.Close
13
+ const DrawerPortal = DialogPrimitive.Portal
14
+
15
+ const DrawerOverlay = React.forwardRef<
16
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
17
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
18
+ >(({ className, ...props }, ref) => (
19
+ <DialogPrimitive.Overlay ref={ref} asChild {...props}>
20
+ <motion.div
21
+ className={cn('fixed inset-0 z-50 bg-bg-mask/60', className)}
22
+ {...MOTION_FADE}
23
+ />
24
+ </DialogPrimitive.Overlay>
25
+ ))
26
+ DrawerOverlay.displayName = DialogPrimitive.Overlay.displayName
27
+
28
+ const drawerVariants = cva(
29
+ 'fixed z-50 gap-4 bg-bg-base text-text shadow-lg border-border p-6 outline-none flex flex-col',
30
+ {
31
+ variants: {
32
+ side: {
33
+ top: 'inset-x-0 top-0 border-b',
34
+ bottom: 'inset-x-0 bottom-0 border-t',
35
+ left: 'inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
36
+ right: 'inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
37
+ },
38
+ },
39
+ defaultVariants: { side: 'right' },
40
+ },
41
+ )
42
+
43
+ const sideOffsetMap = {
44
+ top: { initial: { y: '-100%' }, animate: { y: 0 }, exit: { y: '-100%' } },
45
+ bottom: { initial: { y: '100%' }, animate: { y: 0 }, exit: { y: '100%' } },
46
+ left: { initial: { x: '-100%' }, animate: { x: 0 }, exit: { x: '-100%' } },
47
+ right: { initial: { x: '100%' }, animate: { x: 0 }, exit: { x: '100%' } },
48
+ } as const
49
+
50
+ export interface DrawerContentProps
51
+ extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>,
52
+ VariantProps<typeof drawerVariants> {
53
+ side?: 'top' | 'right' | 'bottom' | 'left'
54
+ showCloseButton?: boolean
55
+ /** When provided (e.g. from ThemeStyleProvider), used for portal wrapper */
56
+ dataStyle?: string
57
+ dataTheme?: string
58
+ }
59
+
60
+ const DrawerContent = React.forwardRef<
61
+ React.ElementRef<typeof DialogPrimitive.Content>,
62
+ DrawerContentProps
63
+ >(
64
+ (
65
+ { side = 'right', className, children, showCloseButton = true, dataStyle, dataTheme, ...props },
66
+ ref,
67
+ ) => {
68
+ const fromDoc = getThemeFromDocument()
69
+ const dataProps =
70
+ dataStyle !== undefined
71
+ ? { 'data-style': dataStyle, 'data-theme': dataTheme ?? fromDoc['data-theme'] ?? '' }
72
+ : fromDoc
73
+ const motionProps = sideOffsetMap[side]
74
+ return (
75
+ <DrawerPortal>
76
+ <div style={{ display: 'contents' }} {...dataProps}>
77
+ <DrawerOverlay />
78
+ <DialogPrimitive.Content ref={ref} asChild {...props}>
79
+ <motion.div
80
+ className={cn(drawerVariants({ side }), className)}
81
+ initial={motionProps.initial}
82
+ animate={motionProps.animate}
83
+ exit={motionProps.exit}
84
+ transition={{ duration: MOTION_DURATION.slow, ease: MOTION_EASE.standard }}
85
+ >
86
+ {children}
87
+ {showCloseButton && (
88
+ <DialogPrimitive.Close
89
+ className={cn(
90
+ 'absolute right-4 top-4 inline-flex size-7 items-center justify-center rounded-md text-text-tertiary opacity-70 transition-colors',
91
+ 'hover:bg-fill-secondary hover:text-text hover:opacity-100',
92
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-border',
93
+ 'disabled:pointer-events-none',
94
+ )}
95
+ >
96
+ <CloseLine className="size-4" />
97
+ <span className="sr-only">Close</span>
98
+ </DialogPrimitive.Close>
99
+ )}
100
+ </motion.div>
101
+ </DialogPrimitive.Content>
102
+ </div>
103
+ </DrawerPortal>
104
+ )
105
+ },
106
+ )
107
+ DrawerContent.displayName = DialogPrimitive.Content.displayName
108
+
109
+ const DrawerHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
110
+ ({ className, ...props }, ref) => (
111
+ <div ref={ref} className={cn('flex flex-col gap-1.5', className)} {...props} />
112
+ ),
113
+ )
114
+ DrawerHeader.displayName = 'DrawerHeader'
115
+
116
+ const DrawerFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
117
+ ({ className, ...props }, ref) => (
118
+ <div ref={ref} className={cn('mt-auto flex flex-col gap-2', className)} {...props} />
119
+ ),
120
+ )
121
+ DrawerFooter.displayName = 'DrawerFooter'
122
+
123
+ const DrawerTitle = React.forwardRef<
124
+ React.ElementRef<typeof DialogPrimitive.Title>,
125
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
126
+ >(({ className, ...props }, ref) => (
127
+ <DialogPrimitive.Title
128
+ ref={ref}
129
+ className={cn('text-base font-medium leading-6 text-text', className)}
130
+ {...props}
131
+ />
132
+ ))
133
+ DrawerTitle.displayName = DialogPrimitive.Title.displayName
134
+
135
+ const DrawerDescription = React.forwardRef<
136
+ React.ElementRef<typeof DialogPrimitive.Description>,
137
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
138
+ >(({ className, ...props }, ref) => (
139
+ <DialogPrimitive.Description
140
+ ref={ref}
141
+ className={cn('text-sm leading-6 text-text-tertiary', className)}
142
+ {...props}
143
+ />
144
+ ))
145
+ DrawerDescription.displayName = DialogPrimitive.Description.displayName
146
+
147
+ export type DrawerHeaderProps = React.HTMLAttributes<HTMLDivElement>
148
+ export type DrawerFooterProps = React.HTMLAttributes<HTMLDivElement>
149
+
150
+ export {
151
+ Drawer,
152
+ DrawerTrigger,
153
+ DrawerClose,
154
+ DrawerPortal,
155
+ DrawerOverlay,
156
+ DrawerContent,
157
+ DrawerHeader,
158
+ DrawerFooter,
159
+ DrawerTitle,
160
+ DrawerDescription,
161
+ drawerVariants,
162
+ }
@@ -3,13 +3,10 @@ import { motion } from 'framer-motion'
3
3
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'
4
4
  import { cva, type VariantProps } from 'class-variance-authority'
5
5
  import { cn } from '@/lib/utils'
6
+ import { MOTION_SCALE_IN } from '@/lib/motion'
6
7
  import { ArrowRightLine, CheckLine } from './icons-inline'
7
8
  import { getThemeFromDocument } from './theme-from-document'
8
9
 
9
- /** 取消 outline/ring,避免与全局 *:focus-visible 冲突产生偶现 focus 环 */
10
- const FOCUS_RESET =
11
- 'outline-none focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:!outline-none focus-visible:!ring-0 focus-visible:outline-offset-0 focus-visible:!outline-offset-0 focus-visible:ring-offset-0 focus-visible:!ring-offset-0'
12
-
13
10
  const DropdownMenu = DropdownMenuPrimitive.Root
14
11
  const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
15
12
  const DropdownMenuGroup = DropdownMenuPrimitive.Group
@@ -46,9 +43,7 @@ const DropdownMenuContent = React.forwardRef<
46
43
  {...props}
47
44
  >
48
45
  <motion.div
49
- initial={{ opacity: 0 }}
50
- animate={{ opacity: 1 }}
51
- transition={{ duration: 0.15, ease: [0.4, 0, 0.2, 1] }}
46
+ {...MOTION_SCALE_IN}
52
47
  >
53
48
  {children}
54
49
  </motion.div>
@@ -0,0 +1,104 @@
1
+ import { cva, type VariantProps } from "class-variance-authority"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ function Empty({ className, ...props }: React.ComponentProps<"div">) {
6
+ return (
7
+ <div
8
+ data-slot="empty"
9
+ className={cn(
10
+ "flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) {
19
+ return (
20
+ <div
21
+ data-slot="empty-header"
22
+ className={cn(
23
+ "flex max-w-sm flex-col items-center gap-2 text-center",
24
+ className
25
+ )}
26
+ {...props}
27
+ />
28
+ )
29
+ }
30
+
31
+ const emptyMediaVariants = cva(
32
+ "mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
33
+ {
34
+ variants: {
35
+ variant: {
36
+ default: "bg-transparent",
37
+ icon: "flex size-10 shrink-0 items-center justify-center rounded-lg bg-fill-tertiary text-text [&_svg:not([class*='size-'])]:size-6",
38
+ },
39
+ },
40
+ defaultVariants: {
41
+ variant: "default",
42
+ },
43
+ }
44
+ )
45
+
46
+ function EmptyMedia({
47
+ className,
48
+ variant = "default",
49
+ ...props
50
+ }: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) {
51
+ return (
52
+ <div
53
+ data-slot="empty-icon"
54
+ data-variant={variant}
55
+ className={cn(emptyMediaVariants({ variant, className }))}
56
+ {...props}
57
+ />
58
+ )
59
+ }
60
+
61
+ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
62
+ return (
63
+ <div
64
+ data-slot="empty-title"
65
+ className={cn("text-lg font-medium tracking-tight", className)}
66
+ {...props}
67
+ />
68
+ )
69
+ }
70
+
71
+ function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
72
+ return (
73
+ <div
74
+ data-slot="empty-description"
75
+ className={cn(
76
+ "text-sm/relaxed text-text-tertiary [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
77
+ className
78
+ )}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ function EmptyContent({ className, ...props }: React.ComponentProps<"div">) {
85
+ return (
86
+ <div
87
+ data-slot="empty-content"
88
+ className={cn(
89
+ "flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance",
90
+ className
91
+ )}
92
+ {...props}
93
+ />
94
+ )
95
+ }
96
+
97
+ export {
98
+ Empty,
99
+ EmptyHeader,
100
+ EmptyTitle,
101
+ EmptyDescription,
102
+ EmptyContent,
103
+ EmptyMedia,
104
+ }