@glyphui/ui 0.3.0 → 0.5.0

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 (563) hide show
  1. package/README.md +68 -12
  2. package/dist/chart.d.ts +14 -202
  3. package/dist/chart.js +14 -456
  4. package/dist/components/accordion/accordion.d.ts +15 -0
  5. package/dist/components/accordion/accordion.js +69 -0
  6. package/dist/components/accordion/accordion.styles.d.ts +65 -0
  7. package/dist/components/accordion/accordion.styles.js +30 -0
  8. package/dist/components/accordion/index.d.ts +3 -0
  9. package/dist/components/alert/alert-icons.js +62 -0
  10. package/dist/components/alert/alert.d.ts +19 -0
  11. package/dist/components/alert/alert.js +64 -0
  12. package/dist/components/alert/alert.styles.d.ts +107 -0
  13. package/dist/components/alert/alert.styles.js +86 -0
  14. package/dist/components/alert/index.d.ts +3 -0
  15. package/dist/components/alert-dialog/alert-dialog.d.ts +29 -0
  16. package/dist/components/alert-dialog/alert-dialog.js +89 -0
  17. package/dist/components/alert-dialog/alert-dialog.styles.d.ts +63 -0
  18. package/dist/components/alert-dialog/alert-dialog.styles.js +19 -0
  19. package/dist/components/alert-dialog/confirm-dialog.js +22 -0
  20. package/dist/components/alert-dialog/confirm.d.ts +30 -0
  21. package/dist/components/alert-dialog/confirm.js +62 -0
  22. package/dist/components/alert-dialog/index.d.ts +4 -0
  23. package/dist/components/aspect-ratio/aspect-ratio.d.ts +55 -0
  24. package/dist/components/aspect-ratio/aspect-ratio.js +28 -0
  25. package/dist/components/aspect-ratio/index.d.ts +2 -0
  26. package/dist/components/avatar/avatar.d.ts +13 -0
  27. package/dist/components/avatar/avatar.js +50 -0
  28. package/dist/components/avatar/avatar.styles.d.ts +77 -0
  29. package/dist/components/avatar/avatar.styles.js +32 -0
  30. package/dist/components/avatar/index.d.ts +3 -0
  31. package/dist/components/badge/badge.d.ts +10 -0
  32. package/dist/components/badge/badge.js +28 -0
  33. package/dist/components/badge/badge.styles.d.ts +62 -0
  34. package/dist/components/badge/badge.styles.js +72 -0
  35. package/dist/components/badge/index.d.ts +3 -0
  36. package/dist/components/banner/banner.d.ts +17 -0
  37. package/dist/components/banner/banner.js +71 -0
  38. package/dist/components/banner/banner.styles.d.ts +98 -0
  39. package/dist/components/banner/banner.styles.js +27 -0
  40. package/dist/components/banner/index.d.ts +3 -0
  41. package/dist/components/blockquote/blockquote.d.ts +72 -0
  42. package/dist/components/blockquote/blockquote.js +47 -0
  43. package/dist/components/blockquote/index.d.ts +2 -0
  44. package/dist/components/breadcrumb/breadcrumb.d.ts +28 -0
  45. package/dist/components/breadcrumb/breadcrumb.js +85 -0
  46. package/dist/components/breadcrumb/breadcrumb.styles.d.ts +63 -0
  47. package/dist/components/breadcrumb/breadcrumb.styles.js +18 -0
  48. package/dist/components/breadcrumb/index.d.ts +3 -0
  49. package/dist/components/button/button.d.ts +20 -0
  50. package/dist/components/button/button.js +52 -0
  51. package/dist/components/button/button.styles.d.ts +146 -0
  52. package/dist/components/button/button.styles.js +64 -0
  53. package/dist/components/button/index.d.ts +3 -0
  54. package/dist/components/calendar/calendar.d.ts +9 -0
  55. package/dist/components/calendar/calendar.js +75 -0
  56. package/dist/components/calendar/calendar.styles.d.ts +171 -0
  57. package/dist/components/calendar/calendar.styles.js +42 -0
  58. package/dist/components/calendar/index.d.ts +4 -0
  59. package/dist/components/card/card.d.ts +17 -0
  60. package/dist/components/card/card.js +79 -0
  61. package/dist/components/card/card.styles.d.ts +113 -0
  62. package/dist/components/card/card.styles.js +38 -0
  63. package/dist/components/card/index.d.ts +3 -0
  64. package/dist/components/carousel/carousel.d.ts +37 -0
  65. package/dist/components/carousel/carousel.js +190 -0
  66. package/dist/components/carousel/carousel.styles.d.ts +74 -0
  67. package/dist/components/carousel/carousel.styles.js +35 -0
  68. package/dist/components/carousel/index.d.ts +3 -0
  69. package/dist/components/checkbox/checkbox.d.ts +37 -0
  70. package/dist/components/checkbox/checkbox.js +44 -0
  71. package/dist/components/checkbox/index.d.ts +2 -0
  72. package/dist/components/code/code.d.ts +18 -0
  73. package/dist/components/code/code.js +75 -0
  74. package/dist/components/code/code.styles.d.ts +76 -0
  75. package/dist/components/code/code.styles.js +18 -0
  76. package/dist/components/code/index.d.ts +3 -0
  77. package/dist/components/collapsible/collapsible.d.ts +56 -0
  78. package/dist/components/collapsible/collapsible.js +43 -0
  79. package/dist/components/collapsible/index.d.ts +2 -0
  80. package/dist/components/combobox/combobox.d.ts +50 -0
  81. package/dist/components/combobox/combobox.js +141 -0
  82. package/dist/components/combobox/combobox.styles.d.ts +110 -0
  83. package/dist/components/combobox/combobox.styles.js +42 -0
  84. package/dist/components/combobox/index.d.ts +3 -0
  85. package/dist/components/command-menu/command-menu.d.ts +40 -0
  86. package/dist/components/command-menu/command-menu.js +148 -0
  87. package/dist/components/command-menu/command-menu.styles.d.ts +105 -0
  88. package/dist/components/command-menu/command-menu.styles.js +30 -0
  89. package/dist/components/command-menu/index.d.ts +3 -0
  90. package/dist/components/container/container.d.ts +34 -0
  91. package/dist/components/container/container.js +30 -0
  92. package/dist/components/container/index.d.ts +2 -0
  93. package/dist/components/context-menu/context-menu.d.ts +34 -0
  94. package/dist/components/context-menu/context-menu.js +157 -0
  95. package/dist/components/context-menu/context-menu.styles.d.ts +135 -0
  96. package/dist/components/context-menu/context-menu.styles.js +14 -0
  97. package/dist/components/context-menu/index.d.ts +3 -0
  98. package/dist/components/copy-button/copy-button.d.ts +61 -0
  99. package/dist/components/copy-button/copy-button.js +79 -0
  100. package/dist/components/copy-button/index.d.ts +2 -0
  101. package/dist/components/date-picker/date-picker.d.ts +51 -0
  102. package/dist/components/date-picker/date-picker.js +235 -0
  103. package/dist/components/date-picker/date-picker.styles.d.ts +77 -0
  104. package/dist/components/date-picker/date-picker.styles.js +31 -0
  105. package/dist/components/date-picker/index.d.ts +3 -0
  106. package/dist/components/description-list/description-list.d.ts +15 -0
  107. package/dist/components/description-list/description-list.js +51 -0
  108. package/dist/components/description-list/description-list.styles.d.ts +74 -0
  109. package/dist/components/description-list/description-list.styles.js +35 -0
  110. package/dist/components/description-list/index.d.ts +3 -0
  111. package/dist/components/dialog/close-icon.js +22 -0
  112. package/dist/components/dialog/dialog.d.ts +21 -0
  113. package/dist/components/dialog/dialog.js +79 -0
  114. package/dist/components/dialog/dialog.styles.d.ts +83 -0
  115. package/dist/components/dialog/dialog.styles.js +34 -0
  116. package/dist/components/dialog/index.d.ts +3 -0
  117. package/dist/components/dropdown-menu/dropdown-menu.d.ts +34 -0
  118. package/dist/components/dropdown-menu/dropdown-menu.js +160 -0
  119. package/dist/components/dropdown-menu/dropdown-menu.styles.d.ts +83 -0
  120. package/dist/components/dropdown-menu/dropdown-menu.styles.js +38 -0
  121. package/dist/components/dropdown-menu/index.d.ts +3 -0
  122. package/dist/components/eyebrow/eyebrow.d.ts +9 -0
  123. package/dist/components/eyebrow/eyebrow.js +20 -0
  124. package/dist/components/eyebrow/eyebrow.styles.d.ts +38 -0
  125. package/dist/components/eyebrow/eyebrow.styles.js +13 -0
  126. package/dist/components/eyebrow/index.d.ts +3 -0
  127. package/dist/components/field/field-context.d.ts +25 -0
  128. package/dist/components/field/field-context.js +27 -0
  129. package/dist/components/field/field.d.ts +28 -0
  130. package/dist/{field-CWZ_FdkD.js → components/field/field.js} +20 -34
  131. package/dist/components/field/field.styles.d.ts +53 -0
  132. package/dist/components/field/field.styles.js +22 -0
  133. package/dist/components/field/index.d.ts +4 -0
  134. package/dist/components/file-upload/file-upload.d.ts +52 -0
  135. package/dist/components/file-upload/file-upload.js +266 -0
  136. package/dist/components/file-upload/file-upload.styles.d.ts +123 -0
  137. package/dist/components/file-upload/file-upload.styles.js +32 -0
  138. package/dist/components/file-upload/index.d.ts +3 -0
  139. package/dist/components/grid/grid.d.ts +168 -0
  140. package/dist/components/grid/grid.js +126 -0
  141. package/dist/components/grid/index.d.ts +2 -0
  142. package/dist/components/heading/heading.d.ts +12 -0
  143. package/dist/components/heading/heading.js +28 -0
  144. package/dist/components/heading/heading.styles.d.ts +65 -0
  145. package/dist/components/heading/heading.styles.js +15 -0
  146. package/dist/components/heading/index.d.ts +3 -0
  147. package/dist/components/hover-card/hover-card.d.ts +43 -0
  148. package/dist/components/hover-card/hover-card.js +27 -0
  149. package/dist/components/hover-card/index.d.ts +2 -0
  150. package/dist/components/input/index.d.ts +3 -0
  151. package/dist/components/input/input.d.ts +13 -0
  152. package/dist/components/input/input.js +33 -0
  153. package/dist/components/input/input.styles.d.ts +55 -0
  154. package/dist/components/input/input.styles.js +33 -0
  155. package/dist/components/input-otp/index.d.ts +4 -0
  156. package/dist/components/input-otp/index.js +5 -0
  157. package/dist/components/input-otp/input-otp.d.ts +23 -0
  158. package/dist/components/input-otp/input-otp.js +86 -0
  159. package/dist/components/input-otp/input-otp.styles.d.ts +71 -0
  160. package/dist/components/input-otp/input-otp.styles.js +30 -0
  161. package/dist/components/kbd/index.d.ts +2 -0
  162. package/dist/components/kbd/kbd.d.ts +30 -0
  163. package/dist/components/kbd/kbd.js +17 -0
  164. package/dist/components/label/index.d.ts +2 -0
  165. package/dist/components/label/label.d.ts +31 -0
  166. package/dist/components/label/label.js +17 -0
  167. package/dist/components/link/index.d.ts +3 -0
  168. package/dist/components/link/link.d.ts +14 -0
  169. package/dist/components/link/link.js +57 -0
  170. package/dist/components/link/link.styles.d.ts +89 -0
  171. package/dist/components/link/link.styles.js +33 -0
  172. package/dist/components/modal/index.d.ts +3 -0
  173. package/dist/components/modal/modal.d.ts +33 -0
  174. package/dist/components/modal/modal.js +56 -0
  175. package/dist/components/modal/modal.styles.d.ts +61 -0
  176. package/dist/components/modal/modal.styles.js +14 -0
  177. package/dist/components/navigation-menu/index.d.ts +3 -0
  178. package/dist/components/navigation-menu/navigation-menu.d.ts +37 -0
  179. package/dist/components/navigation-menu/navigation-menu.js +138 -0
  180. package/dist/components/navigation-menu/navigation-menu.styles.d.ts +111 -0
  181. package/dist/components/navigation-menu/navigation-menu.styles.js +39 -0
  182. package/dist/components/number-input/index.d.ts +3 -0
  183. package/dist/components/number-input/number-input.d.ts +30 -0
  184. package/dist/components/number-input/number-input.js +151 -0
  185. package/dist/components/number-input/number-input.styles.d.ts +68 -0
  186. package/dist/components/number-input/number-input.styles.js +35 -0
  187. package/dist/components/pagination/index.d.ts +4 -0
  188. package/dist/components/pagination/pagination-range.d.ts +11 -0
  189. package/dist/components/pagination/pagination-range.js +42 -0
  190. package/dist/components/pagination/pagination.d.ts +18 -0
  191. package/dist/components/pagination/pagination.js +94 -0
  192. package/dist/components/pagination/pagination.styles.d.ts +65 -0
  193. package/dist/components/pagination/pagination.styles.js +35 -0
  194. package/dist/components/password-input/index.d.ts +3 -0
  195. package/dist/components/password-input/password-input.d.ts +20 -0
  196. package/dist/components/password-input/password-input.js +106 -0
  197. package/dist/components/password-input/password-input.styles.d.ts +66 -0
  198. package/dist/components/password-input/password-input.styles.js +21 -0
  199. package/dist/components/popover/index.d.ts +2 -0
  200. package/dist/components/popover/popover.d.ts +52 -0
  201. package/dist/components/popover/popover.js +35 -0
  202. package/dist/components/progress/index.d.ts +3 -0
  203. package/dist/components/progress/progress.d.ts +29 -0
  204. package/dist/components/progress/progress.js +108 -0
  205. package/dist/components/progress/progress.styles.d.ts +236 -0
  206. package/dist/components/progress/progress.styles.js +69 -0
  207. package/dist/components/prose/index.d.ts +2 -0
  208. package/dist/components/prose/prose.d.ts +90 -0
  209. package/dist/components/prose/prose.js +67 -0
  210. package/dist/components/radio-group/index.d.ts +3 -0
  211. package/dist/components/radio-group/radio-group.d.ts +26 -0
  212. package/dist/components/radio-group/radio-group.js +102 -0
  213. package/dist/components/radio-group/radio-group.styles.d.ts +80 -0
  214. package/dist/components/radio-group/radio-group.styles.js +56 -0
  215. package/dist/components/resizable/index.d.ts +3 -0
  216. package/dist/components/resizable/resizable.d.ts +17 -0
  217. package/dist/components/resizable/resizable.js +81 -0
  218. package/dist/components/resizable/resizable.styles.d.ts +53 -0
  219. package/dist/components/resizable/resizable.styles.js +19 -0
  220. package/dist/components/scroll-area/index.d.ts +2 -0
  221. package/dist/components/scroll-area/scroll-area.d.ts +70 -0
  222. package/dist/components/scroll-area/scroll-area.js +70 -0
  223. package/dist/components/section/index.d.ts +2 -0
  224. package/dist/components/section/section.d.ts +52 -0
  225. package/dist/components/section/section.js +41 -0
  226. package/dist/components/segmented-control/index.d.ts +2 -0
  227. package/dist/components/segmented-control/segmented-control.d.ts +92 -0
  228. package/dist/components/segmented-control/segmented-control.js +86 -0
  229. package/dist/components/select/index.d.ts +2 -0
  230. package/dist/components/select/select.d.ts +85 -0
  231. package/dist/components/select/select.js +81 -0
  232. package/dist/components/separator/index.d.ts +2 -0
  233. package/dist/components/separator/separator.d.ts +40 -0
  234. package/dist/components/separator/separator.js +27 -0
  235. package/dist/components/sheet/index.d.ts +3 -0
  236. package/dist/components/sheet/sheet.d.ts +20 -0
  237. package/dist/components/sheet/sheet.js +83 -0
  238. package/dist/components/sheet/sheet.styles.d.ts +101 -0
  239. package/dist/components/sheet/sheet.styles.js +62 -0
  240. package/dist/components/skeleton/index.d.ts +2 -0
  241. package/dist/components/skeleton/skeleton.d.ts +30 -0
  242. package/dist/components/skeleton/skeleton.js +18 -0
  243. package/dist/components/slider/index.d.ts +3 -0
  244. package/dist/components/slider/slider.d.ts +38 -0
  245. package/dist/components/slider/slider.js +68 -0
  246. package/dist/components/slider/slider.styles.d.ts +56 -0
  247. package/dist/components/slider/slider.styles.js +23 -0
  248. package/dist/components/spinner/index.d.ts +3 -0
  249. package/dist/components/spinner/spinner.d.ts +9 -0
  250. package/dist/components/spinner/spinner.js +36 -0
  251. package/dist/components/spinner/spinner.styles.d.ts +53 -0
  252. package/dist/components/spinner/spinner.styles.js +18 -0
  253. package/dist/components/stack/index.d.ts +2 -0
  254. package/dist/components/stack/stack.d.ts +109 -0
  255. package/dist/components/stack/stack.js +62 -0
  256. package/dist/components/stat-card/index.d.ts +3 -0
  257. package/dist/components/stat-card/stat-card.d.ts +22 -0
  258. package/dist/components/stat-card/stat-card.js +82 -0
  259. package/dist/components/stat-card/stat-card.styles.d.ts +83 -0
  260. package/dist/components/stat-card/stat-card.styles.js +16 -0
  261. package/dist/components/stepper/index.d.ts +3 -0
  262. package/dist/components/stepper/stepper.d.ts +20 -0
  263. package/dist/components/stepper/stepper.js +100 -0
  264. package/dist/components/stepper/stepper.styles.d.ts +170 -0
  265. package/dist/components/stepper/stepper.styles.js +67 -0
  266. package/dist/components/switch/index.d.ts +2 -0
  267. package/dist/components/switch/switch.d.ts +51 -0
  268. package/dist/components/switch/switch.js +43 -0
  269. package/dist/components/table/index.d.ts +2 -0
  270. package/dist/components/table/table.d.ts +78 -0
  271. package/dist/components/table/table.js +82 -0
  272. package/dist/components/tabs/index.d.ts +2 -0
  273. package/dist/components/tabs/tabs.d.ts +73 -0
  274. package/dist/components/tabs/tabs.js +103 -0
  275. package/dist/components/tag-input/index.d.ts +3 -0
  276. package/dist/components/tag-input/tag-input.d.ts +30 -0
  277. package/dist/components/tag-input/tag-input.js +149 -0
  278. package/dist/components/tag-input/tag-input.styles.d.ts +71 -0
  279. package/dist/components/tag-input/tag-input.styles.js +29 -0
  280. package/dist/components/text/index.d.ts +3 -0
  281. package/dist/components/text/text.d.ts +9 -0
  282. package/dist/components/text/text.js +25 -0
  283. package/dist/components/text/text.styles.d.ts +188 -0
  284. package/dist/components/text/text.styles.js +36 -0
  285. package/dist/components/textarea/index.d.ts +2 -0
  286. package/dist/components/textarea/textarea.d.ts +29 -0
  287. package/dist/components/textarea/textarea.js +23 -0
  288. package/dist/components/timeline/index.d.ts +3 -0
  289. package/dist/components/timeline/timeline.d.ts +28 -0
  290. package/dist/components/timeline/timeline.js +61 -0
  291. package/dist/components/timeline/timeline.styles.d.ts +110 -0
  292. package/dist/components/timeline/timeline.styles.js +30 -0
  293. package/dist/components/toast/index.d.ts +2 -0
  294. package/dist/components/toast/toast.d.ts +119 -0
  295. package/dist/components/toast/toast.js +75 -0
  296. package/dist/components/toggle/index.d.ts +3 -0
  297. package/dist/components/toggle/toggle.d.ts +20 -0
  298. package/dist/components/toggle/toggle.js +58 -0
  299. package/dist/components/toggle/toggle.styles.d.ts +80 -0
  300. package/dist/components/toggle/toggle.styles.js +34 -0
  301. package/dist/components/tooltip/index.d.ts +2 -0
  302. package/dist/components/tooltip/tooltip.d.ts +39 -0
  303. package/dist/components/tooltip/tooltip.js +29 -0
  304. package/dist/components/tree-view/index.d.ts +3 -0
  305. package/dist/components/tree-view/tree-view.d.ts +31 -0
  306. package/dist/components/tree-view/tree-view.js +192 -0
  307. package/dist/components/tree-view/tree-view.styles.d.ts +59 -0
  308. package/dist/components/tree-view/tree-view.styles.js +32 -0
  309. package/dist/components/visually-hidden/index.d.ts +2 -0
  310. package/dist/components/visually-hidden/visually-hidden.d.ts +10 -0
  311. package/dist/components/visually-hidden/visually-hidden.js +16 -0
  312. package/dist/data-table.d.ts +3 -110
  313. package/dist/data-table.js +2 -224
  314. package/dist/form.d.ts +2 -79
  315. package/dist/form.js +1 -83
  316. package/dist/hooks/index.d.ts +5 -0
  317. package/dist/hooks/use-component-config.d.ts +13 -0
  318. package/dist/hooks/use-component-config.js +22 -0
  319. package/dist/hooks/use-controllable-state.d.ts +9 -0
  320. package/dist/hooks/use-controllable-state.js +18 -0
  321. package/dist/hooks/use-media-query.d.ts +4 -0
  322. package/dist/hooks/use-media-query.js +13 -0
  323. package/dist/hooks/use-scrolled.d.ts +4 -0
  324. package/dist/hooks/use-scrolled.js +17 -0
  325. package/dist/index.d.ts +223 -6849
  326. package/dist/index.js +148 -6718
  327. package/dist/internal/dev.js +12 -0
  328. package/dist/internal/icons.js +91 -0
  329. package/dist/motion/active-indicator.d.ts +12 -0
  330. package/dist/motion/active-indicator.js +26 -0
  331. package/dist/motion/animated-number.d.ts +21 -0
  332. package/dist/motion/animated-number.js +88 -0
  333. package/dist/motion/features.js +10 -0
  334. package/dist/motion/index.d.ts +10 -0
  335. package/dist/motion/index.js +10 -0
  336. package/dist/motion/motion-root.js +48 -0
  337. package/dist/motion/page-transition.d.ts +16 -0
  338. package/dist/motion/page-transition.js +23 -0
  339. package/dist/motion/presence-list.js +46 -0
  340. package/dist/motion/presence.d.ts +11 -0
  341. package/dist/motion/presence.js +17 -0
  342. package/dist/motion/reveal.d.ts +18 -0
  343. package/dist/motion/reveal.js +37 -0
  344. package/dist/motion/stagger.d.ts +29 -0
  345. package/dist/motion/stagger.js +52 -0
  346. package/dist/motion/use-motion-settings.d.ts +25 -0
  347. package/dist/motion/use-motion-settings.js +47 -0
  348. package/dist/motion/use-reveal.d.ts +11 -0
  349. package/dist/motion/use-reveal.js +41 -0
  350. package/dist/patterns/app-shell/app-shell-context.d.ts +14 -0
  351. package/dist/patterns/app-shell/app-shell-context.js +16 -0
  352. package/dist/patterns/app-shell/app-shell.d.ts +21 -0
  353. package/dist/patterns/app-shell/app-shell.js +82 -0
  354. package/dist/patterns/app-shell/app-shell.styles.d.ts +302 -0
  355. package/dist/patterns/app-shell/app-shell.styles.js +106 -0
  356. package/dist/patterns/app-shell/index.d.ts +7 -0
  357. package/dist/patterns/app-shell/navbar.d.ts +29 -0
  358. package/dist/patterns/app-shell/navbar.js +116 -0
  359. package/dist/patterns/app-shell/page-header.d.ts +12 -0
  360. package/dist/patterns/app-shell/page-header.js +38 -0
  361. package/dist/patterns/app-shell/sidebar.d.ts +31 -0
  362. package/dist/patterns/app-shell/sidebar.js +141 -0
  363. package/dist/patterns/async/async.d.ts +40 -0
  364. package/dist/patterns/async/async.js +61 -0
  365. package/dist/patterns/async/index.d.ts +3 -0
  366. package/dist/patterns/async/states.d.ts +68 -0
  367. package/dist/patterns/async/states.js +116 -0
  368. package/dist/patterns/chart/cartesian.d.ts +128 -0
  369. package/dist/patterns/chart/cartesian.js +552 -0
  370. package/dist/patterns/chart/chart-card.d.ts +39 -0
  371. package/dist/patterns/chart/chart-card.js +103 -0
  372. package/dist/patterns/chart/chart-parts.d.ts +53 -0
  373. package/dist/patterns/chart/chart-parts.js +282 -0
  374. package/dist/patterns/chart/chart.styles.d.ts +200 -0
  375. package/dist/patterns/chart/chart.styles.js +43 -0
  376. package/dist/patterns/chart/export.d.ts +45 -0
  377. package/dist/patterns/chart/export.js +293 -0
  378. package/dist/patterns/chart/funnel.d.ts +23 -0
  379. package/dist/patterns/chart/funnel.js +129 -0
  380. package/dist/patterns/chart/heatmap.d.ts +37 -0
  381. package/dist/patterns/chart/heatmap.js +258 -0
  382. package/dist/patterns/chart/icons.js +39 -0
  383. package/dist/patterns/chart/pie.d.ts +36 -0
  384. package/dist/patterns/chart/pie.js +120 -0
  385. package/dist/patterns/chart/radial.d.ts +75 -0
  386. package/dist/patterns/chart/radial.js +282 -0
  387. package/dist/patterns/chart/sankey.d.ts +29 -0
  388. package/dist/patterns/chart/sankey.js +136 -0
  389. package/dist/patterns/chart/scatter.d.ts +42 -0
  390. package/dist/patterns/chart/scatter.js +203 -0
  391. package/dist/patterns/chart/sparkline.d.ts +20 -0
  392. package/dist/patterns/chart/sparkline.js +102 -0
  393. package/dist/patterns/chart/treemap.d.ts +25 -0
  394. package/dist/patterns/chart/treemap.js +128 -0
  395. package/dist/patterns/chart/use-element-width.js +23 -0
  396. package/dist/patterns/data-table/data-table.d.ts +109 -0
  397. package/dist/patterns/data-table/data-table.js +233 -0
  398. package/dist/patterns/form/form.d.ts +89 -0
  399. package/dist/patterns/form/form.js +111 -0
  400. package/dist/provider/color-mode-script.d.ts +15 -0
  401. package/dist/provider/color-mode-script.js +13 -0
  402. package/dist/provider/color-mode.d.ts +24 -0
  403. package/dist/provider/color-mode.js +87 -0
  404. package/dist/provider/glyph-context.d.ts +51 -0
  405. package/dist/provider/glyph-context.js +28 -0
  406. package/dist/provider/glyph-provider.d.ts +37 -0
  407. package/dist/provider/glyph-provider.js +48 -0
  408. package/dist/provider/index.d.ts +6 -0
  409. package/dist/provider/theme-scope.d.ts +12 -0
  410. package/dist/provider/theme-scope.js +42 -0
  411. package/dist/provider/theme-style.js +15 -0
  412. package/dist/react-router.d.ts +18 -0
  413. package/dist/react-router.js +44 -0
  414. package/dist/register.d.ts +57 -0
  415. package/dist/themes.d.ts +22 -0
  416. package/dist/themes.js +49 -0
  417. package/dist/utils/cn.d.ts +6 -0
  418. package/dist/utils/cn.js +12 -0
  419. package/dist/utils/compose-refs.js +11 -0
  420. package/dist/{registry-BGSJoiLq.d.ts → utils/registry.d.ts} +2 -3
  421. package/dist/utils/styles.js +20 -0
  422. package/dist/{tv-DuMh7UH2.d.ts → utils/tv.d.ts} +2 -2
  423. package/dist/utils/tv.js +8 -0
  424. package/dist/utils/tw-merge-config.js +13 -0
  425. package/dist/vite.d.ts +27 -0
  426. package/dist/vite.js +29 -0
  427. package/fonts.css +10 -0
  428. package/package.json +33 -5
  429. package/src/components/accordion/accordion.styles.ts +1 -1
  430. package/src/components/alert/alert.styles.ts +1 -1
  431. package/src/components/alert-dialog/alert-dialog.styles.ts +5 -4
  432. package/src/components/alert-dialog/confirm-dialog.tsx +42 -0
  433. package/src/components/alert-dialog/confirm.tsx +12 -31
  434. package/src/components/aspect-ratio/aspect-ratio.tsx +1 -1
  435. package/src/components/avatar/avatar.styles.ts +1 -1
  436. package/src/components/badge/badge.styles.ts +12 -17
  437. package/src/components/banner/banner.styles.ts +5 -5
  438. package/src/components/blockquote/blockquote.tsx +1 -1
  439. package/src/components/breadcrumb/breadcrumb.styles.ts +1 -1
  440. package/src/components/button/button.styles.ts +6 -2
  441. package/src/components/calendar/calendar.styles.ts +4 -3
  442. package/src/components/card/card.styles.ts +1 -1
  443. package/src/components/carousel/carousel.styles.ts +1 -1
  444. package/src/components/checkbox/checkbox.tsx +20 -5
  445. package/src/components/code/code.styles.ts +2 -2
  446. package/src/components/collapsible/collapsible.tsx +1 -1
  447. package/src/components/combobox/combobox.styles.ts +5 -2
  448. package/src/components/command-menu/command-menu.styles.ts +6 -4
  449. package/src/components/container/container.tsx +1 -1
  450. package/src/components/context-menu/context-menu.styles.ts +4 -2
  451. package/src/components/copy-button/copy-button.tsx +1 -1
  452. package/src/components/date-picker/date-picker.styles.ts +2 -2
  453. package/src/components/description-list/description-list.styles.ts +1 -1
  454. package/src/components/dialog/dialog.styles.ts +11 -4
  455. package/src/components/dropdown-menu/dropdown-menu.styles.ts +5 -5
  456. package/src/components/eyebrow/eyebrow.styles.ts +2 -2
  457. package/src/components/field/field-context.ts +2 -0
  458. package/src/components/field/field.styles.ts +5 -3
  459. package/src/components/field/field.tsx +25 -4
  460. package/src/components/file-upload/file-upload.styles.ts +4 -4
  461. package/src/components/file-upload/file-upload.tsx +51 -48
  462. package/src/components/grid/grid.tsx +1 -1
  463. package/src/components/heading/heading.styles.ts +1 -1
  464. package/src/components/hover-card/hover-card.tsx +5 -2
  465. package/src/components/input/input.styles.ts +1 -1
  466. package/src/components/input-otp/input-otp.styles.ts +1 -1
  467. package/src/components/kbd/kbd.tsx +1 -1
  468. package/src/components/label/label.tsx +1 -1
  469. package/src/components/link/link.styles.ts +2 -2
  470. package/src/components/modal/modal.styles.ts +3 -1
  471. package/src/components/modal/modal.tsx +30 -5
  472. package/src/components/navigation-menu/navigation-menu.styles.ts +2 -2
  473. package/src/components/navigation-menu/navigation-menu.tsx +14 -4
  474. package/src/components/number-input/number-input.styles.ts +1 -1
  475. package/src/components/pagination/pagination.styles.ts +6 -4
  476. package/src/components/pagination/pagination.tsx +14 -1
  477. package/src/components/password-input/password-input.styles.ts +4 -4
  478. package/src/components/popover/popover.tsx +1 -1
  479. package/src/components/progress/progress.styles.ts +2 -2
  480. package/src/components/prose/prose.tsx +2 -2
  481. package/src/components/radio-group/radio-group.styles.ts +1 -1
  482. package/src/components/resizable/resizable.styles.ts +1 -1
  483. package/src/components/scroll-area/scroll-area.tsx +24 -2
  484. package/src/components/section/section.tsx +1 -1
  485. package/src/components/segmented-control/segmented-control.tsx +40 -9
  486. package/src/components/select/select.tsx +2 -2
  487. package/src/components/separator/separator.tsx +1 -1
  488. package/src/components/sheet/sheet.styles.ts +1 -1
  489. package/src/components/skeleton/skeleton.tsx +1 -1
  490. package/src/components/slider/slider.styles.ts +1 -1
  491. package/src/components/slider/slider.tsx +9 -2
  492. package/src/components/spinner/spinner.styles.ts +1 -1
  493. package/src/components/stack/stack.tsx +1 -1
  494. package/src/components/stat-card/stat-card.styles.ts +1 -1
  495. package/src/components/stepper/stepper.styles.ts +3 -3
  496. package/src/components/switch/switch.tsx +2 -2
  497. package/src/components/table/table.tsx +1 -1
  498. package/src/components/tabs/tabs.tsx +46 -15
  499. package/src/components/tag-input/tag-input.styles.ts +2 -2
  500. package/src/components/tag-input/tag-input.tsx +27 -18
  501. package/src/components/text/text.styles.ts +5 -5
  502. package/src/components/textarea/textarea.tsx +1 -1
  503. package/src/components/timeline/timeline.styles.ts +1 -1
  504. package/src/components/toast/toast.tsx +1 -1
  505. package/src/components/toggle/toggle.styles.ts +1 -1
  506. package/src/components/tooltip/tooltip.tsx +6 -3
  507. package/src/components/tree-view/tree-view.styles.ts +1 -1
  508. package/src/index.ts +3 -0
  509. package/src/integrations/react-router.tsx +39 -0
  510. package/src/integrations/vite.test-d.ts +6 -0
  511. package/src/integrations/vite.test.ts +28 -0
  512. package/src/integrations/vite.ts +33 -0
  513. package/src/internal/dev.ts +12 -0
  514. package/src/motion/active-indicator.tsx +26 -0
  515. package/src/motion/animated-number.tsx +113 -0
  516. package/src/motion/features.ts +7 -0
  517. package/src/motion/index.ts +9 -0
  518. package/src/motion/motion-root.tsx +46 -0
  519. package/src/motion/page-transition.tsx +30 -0
  520. package/src/motion/presence-list.tsx +42 -0
  521. package/src/motion/presence.tsx +13 -0
  522. package/src/motion/reveal.tsx +50 -0
  523. package/src/motion/stagger.tsx +81 -0
  524. package/src/motion/use-motion-settings.ts +52 -0
  525. package/src/motion/use-reveal.ts +54 -0
  526. package/src/patterns/app-shell/app-shell.styles.ts +19 -12
  527. package/src/patterns/app-shell/navbar.tsx +34 -16
  528. package/src/patterns/app-shell/sidebar.tsx +35 -9
  529. package/src/patterns/async/states.tsx +1 -1
  530. package/src/patterns/chart/cartesian.tsx +755 -0
  531. package/src/patterns/chart/chart-card.tsx +148 -0
  532. package/src/patterns/chart/chart-parts.tsx +330 -57
  533. package/src/patterns/chart/chart.styles.ts +29 -3
  534. package/src/patterns/chart/export.ts +334 -0
  535. package/src/patterns/chart/funnel.tsx +171 -0
  536. package/src/patterns/chart/heatmap.tsx +339 -0
  537. package/src/patterns/chart/icons.tsx +44 -0
  538. package/src/patterns/chart/index.ts +52 -7
  539. package/src/patterns/chart/pie.tsx +169 -0
  540. package/src/patterns/chart/radial.tsx +361 -0
  541. package/src/patterns/chart/sankey.tsx +197 -0
  542. package/src/patterns/chart/scatter.tsx +254 -0
  543. package/src/patterns/chart/sparkline.tsx +111 -0
  544. package/src/patterns/chart/test-utils.tsx +35 -0
  545. package/src/patterns/chart/treemap.tsx +198 -0
  546. package/src/patterns/chart/use-element-width.ts +20 -0
  547. package/src/patterns/data-table/data-table.tsx +1 -1
  548. package/src/patterns/form/form.tsx +49 -7
  549. package/src/patterns/form/index.ts +1 -0
  550. package/src/provider/color-mode-script.ts +28 -0
  551. package/src/provider/color-mode.tsx +14 -20
  552. package/src/provider/glyph-context.ts +41 -1
  553. package/src/provider/glyph-provider.tsx +45 -14
  554. package/src/provider/index.ts +4 -0
  555. package/src/provider/theme-scope.tsx +20 -11
  556. package/src/themes.ts +3 -3
  557. package/src/utils/styles.ts +17 -3
  558. package/styles.css +194 -3
  559. package/dist/field-context-anGPYXbW.js +0 -267
  560. package/dist/index-BWK4czIG.d.ts +0 -233
  561. package/dist/states-DR-OoDT-.js +0 -288
  562. package/dist/tv-DBAGlgXJ.js +0 -58
  563. package/src/patterns/chart/chart.tsx +0 -369
@@ -0,0 +1,113 @@
1
+ import { springEasing, springPosition } from '@glyphui/tokens'
2
+ import { type ComponentProps, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
3
+ import { cn } from '../utils/cn'
4
+ import { useMotionSettings } from './use-motion-settings'
5
+
6
+ const useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect
7
+
8
+ export interface AnimatedNumberProps extends Omit<ComponentProps<'span'>, 'children'> {
9
+ value: number
10
+ /** Intl number formatting, e.g. `{ style: 'currency', currency: 'USD' }`. */
11
+ format?: Intl.NumberFormatOptions
12
+ locale?: string
13
+ /** Full control over the text, e.g. your own price formatter. Overrides `format`. */
14
+ formatValue?: (value: number) => string
15
+ /**
16
+ * Where the first count starts. Defaults to 0, counting up once the number scrolls into
17
+ * view. Set it to `value` to skip the first count.
18
+ */
19
+ from?: number
20
+ }
21
+
22
+ /**
23
+ * A number that springs to each new value: stats, prices, counters. Screen readers get the
24
+ * final value once, not every frame. Shows the final value immediately when motion is off.
25
+ */
26
+ export function AnimatedNumber({
27
+ value,
28
+ format,
29
+ locale,
30
+ formatValue,
31
+ from = 0,
32
+ className,
33
+ ref,
34
+ ...props
35
+ }: AnimatedNumberProps) {
36
+ const { animate, spring } = useMotionSettings()
37
+ const formatter = useMemo(() => new Intl.NumberFormat(locale, format), [locale, format])
38
+ const text = (n: number) => (formatValue ? formatValue(n) : formatter.format(n))
39
+ // Render the real value first: server HTML, tests and no-JS visitors see the right number.
40
+ const [shown, setShown] = useState(value)
41
+ const current = useRef(value)
42
+ const el = useRef<HTMLSpanElement>(null)
43
+ const [armed, setArmed] = useState(false)
44
+ const [inView, setInView] = useState(false)
45
+
46
+ // Before the first paint, rewind to `from` and wait until the number is on screen.
47
+ useIsomorphicLayoutEffect(() => {
48
+ const node = el.current
49
+ if (!node || !animate || typeof IntersectionObserver === 'undefined') return
50
+ current.current = from
51
+ setShown(from)
52
+ setArmed(true)
53
+ const observer = new IntersectionObserver(([entry]) => {
54
+ if (entry?.isIntersecting) {
55
+ setInView(true)
56
+ observer.disconnect()
57
+ }
58
+ })
59
+ observer.observe(node)
60
+ return () => observer.disconnect()
61
+ // Only on mount and when motion turns on: later changes to `from` don't restart it.
62
+ }, [animate])
63
+
64
+ useEffect(() => {
65
+ if (!animate || !armed) {
66
+ current.current = value
67
+ setShown(value)
68
+ return
69
+ }
70
+ if (!inView) return
71
+ const start = current.current
72
+ if (start === value) return
73
+ const { duration } = springEasing(spring)
74
+ const begin = performance.now()
75
+ let frame = 0
76
+ const tick = (now: number) => {
77
+ const elapsed = Math.min(now - begin, duration)
78
+ const next = start + (value - start) * springPosition(spring, elapsed / 1000)
79
+ current.current = next
80
+ setShown(next)
81
+ if (elapsed < duration) frame = requestAnimationFrame(tick)
82
+ else {
83
+ current.current = value
84
+ setShown(value)
85
+ }
86
+ }
87
+ frame = requestAnimationFrame(tick)
88
+ return () => cancelAnimationFrame(frame)
89
+ }, [value, animate, armed, inView, spring])
90
+
91
+ return (
92
+ <span
93
+ data-slot="animated-number"
94
+ ref={(node) => {
95
+ el.current = node
96
+ if (typeof ref === 'function') ref(node)
97
+ else if (ref) ref.current = node
98
+ }}
99
+ className={cn('tabular-nums', className)}
100
+ {...props}
101
+ >
102
+ {shown === value ? (
103
+ text(value)
104
+ ) : (
105
+ // While counting, screen readers get the final value once, not every frame.
106
+ <>
107
+ <span aria-hidden="true">{text(shown)}</span>
108
+ <span className="sr-only">{text(value)}</span>
109
+ </>
110
+ )}
111
+ </span>
112
+ )
113
+ }
@@ -0,0 +1,7 @@
1
+ import { domMax } from 'motion/react'
2
+
3
+ /**
4
+ * Animation features, loaded on demand by `LazyMotion` so they stay out of the initial
5
+ * bundle. `domMax` because shared `layoutId` indicators need layout animations.
6
+ */
7
+ export default domMax
@@ -0,0 +1,9 @@
1
+ export { m } from 'motion/react'
2
+ export { ActiveIndicator } from './active-indicator'
3
+ export { AnimatedNumber, type AnimatedNumberProps } from './animated-number'
4
+ export { PageTransition, type PageTransitionProps } from './page-transition'
5
+ export { Presence, type PresenceProps } from './presence'
6
+ export { Reveal, type RevealProps } from './reveal'
7
+ export { Stagger, StaggerItem, type StaggerItemProps, type StaggerProps } from './stagger'
8
+ export { type MotionSettings, useMotionSettings } from './use-motion-settings'
9
+ export type { RevealOptions } from './use-reveal'
@@ -0,0 +1,46 @@
1
+ import { LazyMotion, MotionConfig } from 'motion/react'
2
+ import { type ReactNode, useEffect } from 'react'
3
+ import { useMotionSettings } from './use-motion-settings'
4
+
5
+ const loadFeatures = () => import('./features').then((mod) => mod.default)
6
+ const instant = { duration: 0 } as const
7
+
8
+ /**
9
+ * Connects the `motion` library to the theme: one lazily loaded feature bundle, the theme's
10
+ * spring as the default transition, and instant transitions when motion is off.
11
+ */
12
+ export function MotionScope({ children }: { children: ReactNode }) {
13
+ const { animate, spring } = useMotionSettings()
14
+ return (
15
+ <LazyMotion features={loadFeatures}>
16
+ <MotionConfig reducedMotion="user" transition={animate ? spring : instant}>
17
+ {children}
18
+ </MotionConfig>
19
+ </LazyMotion>
20
+ )
21
+ }
22
+
23
+ /** Mirrors the effective motion level onto `<html data-motion>` so CSS animations follow it. */
24
+ export function MotionRootAttribute() {
25
+ const { level } = useMotionSettings()
26
+ useEffect(() => {
27
+ const root = document.documentElement
28
+ const previous = root.getAttribute('data-motion')
29
+ root.setAttribute('data-motion', level)
30
+ return () => {
31
+ if (previous === null) root.removeAttribute('data-motion')
32
+ else root.setAttribute('data-motion', previous)
33
+ }
34
+ }, [level])
35
+ return null
36
+ }
37
+
38
+ /** Inside a `ThemeScope`: `motion` transitions use that theme's spring and level. */
39
+ export function ScopedMotionConfig({ children }: { children: ReactNode }) {
40
+ const { animate, spring } = useMotionSettings()
41
+ return (
42
+ <MotionConfig reducedMotion="user" transition={animate ? spring : instant}>
43
+ {children}
44
+ </MotionConfig>
45
+ )
46
+ }
@@ -0,0 +1,30 @@
1
+ import { type ComponentProps, useEffect, useRef } from 'react'
2
+ import { cn } from '../utils/cn'
3
+
4
+ export interface PageTransitionProps extends ComponentProps<'div'> {
5
+ /**
6
+ * Changes when the page changes, e.g. `location.pathname`. Each new value replays the
7
+ * entrance; the first page renders without one.
8
+ */
9
+ transitionKey: string
10
+ }
11
+
12
+ /**
13
+ * Fades and lifts each new page in on route changes. Wrap your router outlet:
14
+ * `<PageTransition transitionKey={useLocation().pathname}><Outlet /></PageTransition>`.
15
+ * Enter-only by design: the old page leaves immediately, so nothing ever overlaps or flickers.
16
+ */
17
+ export function PageTransition({ transitionKey, className, ...props }: PageTransitionProps) {
18
+ const mounted = useRef(false)
19
+ useEffect(() => {
20
+ mounted.current = true
21
+ }, [])
22
+ return (
23
+ <div
24
+ key={transitionKey}
25
+ data-slot="page-transition"
26
+ className={cn(mounted.current && 'animate-page-in', className)}
27
+ {...props}
28
+ />
29
+ )
30
+ }
@@ -0,0 +1,42 @@
1
+ import { AnimatePresence, m } from 'motion/react'
2
+ import type { ComponentProps, ReactNode } from 'react'
3
+ import { useMotionSettings } from './use-motion-settings'
4
+
5
+ /**
6
+ * Animates items of a list in and out, and slides the rest into place. Children must be
7
+ * keyed `PresenceItem`s. Renders the list statically when motion is off.
8
+ */
9
+ export function PresenceList({ children }: { children: ReactNode }) {
10
+ const { animate } = useMotionSettings()
11
+ if (!animate) return children
12
+ return <AnimatePresence initial={false}>{children}</AnimatePresence>
13
+ }
14
+
15
+ type PresenceItemProps<T extends 'li' | 'span'> = ComponentProps<T> & { as?: T }
16
+
17
+ const enter = { opacity: 0, scale: 0.96 }
18
+ const shown = { opacity: 1, scale: 1 }
19
+ const leave = { opacity: 0, scale: 0.96, transition: { duration: 0.12 } }
20
+
21
+ /** One item of a `PresenceList`: fades and scales in, out, and between positions. */
22
+ export function PresenceItem<T extends 'li' | 'span' = 'li'>({
23
+ as,
24
+ ...props
25
+ }: PresenceItemProps<T>) {
26
+ const { animate } = useMotionSettings()
27
+ const tag = (as ?? 'li') as 'li' | 'span'
28
+ if (!animate) {
29
+ const Static = tag
30
+ return <Static {...(props as ComponentProps<'li'>)} />
31
+ }
32
+ const Animated = (tag === 'li' ? m.li : m.span) as typeof m.li
33
+ return (
34
+ <Animated
35
+ layout="position"
36
+ initial={enter}
37
+ animate={shown}
38
+ exit={leave}
39
+ {...(props as ComponentProps<typeof m.li>)}
40
+ />
41
+ )
42
+ }
@@ -0,0 +1,13 @@
1
+ import { AnimatePresence } from 'motion/react'
2
+ import type { ComponentProps } from 'react'
3
+
4
+ export type PresenceProps = ComponentProps<typeof AnimatePresence>
5
+
6
+ /**
7
+ * `motion`'s AnimatePresence with Glyph's defaults: children already on screen when the
8
+ * page loads don't animate in (`initial={false}`). Use it with `m.*` elements for custom
9
+ * enter and exit animations; transitions follow the theme's spring.
10
+ */
11
+ export function Presence({ initial = false, ...props }: PresenceProps) {
12
+ return <AnimatePresence initial={initial} {...props} />
13
+ }
@@ -0,0 +1,50 @@
1
+ import { Slot } from 'radix-ui'
2
+ import { type ComponentProps, type CSSProperties, useRef } from 'react'
3
+ import { composeRefs } from '../utils/compose-refs'
4
+ import { type RevealOptions, useReveal } from './use-reveal'
5
+
6
+ export interface RevealProps extends ComponentProps<'div'>, RevealOptions {
7
+ /** Delay before the entrance starts, in milliseconds. */
8
+ delay?: number
9
+ /** Distance it rises from, in px or any CSS length. Defaults to the motion level's. */
10
+ y?: number | string
11
+ /** Start slightly smaller, for cards and media. */
12
+ scale?: boolean
13
+ asChild?: boolean
14
+ }
15
+
16
+ const length = (value: number | string) => (typeof value === 'number' ? `${value}px` : value)
17
+
18
+ /**
19
+ * Fades and rises its content in when it scrolls into view. Uses the theme's spring, follows
20
+ * the motion level, and leaves content visible when motion is off or JavaScript hasn't run.
21
+ */
22
+ export function Reveal({
23
+ delay,
24
+ y,
25
+ scale,
26
+ once,
27
+ amount,
28
+ enabled,
29
+ asChild,
30
+ style,
31
+ ref,
32
+ ...props
33
+ }: RevealProps) {
34
+ const local = useRef<HTMLDivElement>(null)
35
+ useReveal(local, 'reveal', { once, amount, enabled })
36
+ const Comp = asChild ? Slot.Root : 'div'
37
+ const vars = {
38
+ ...(delay !== undefined && { '--glyph-reveal-delay': `${delay}ms` }),
39
+ ...(y !== undefined && { '--glyph-reveal-y': length(y) }),
40
+ ...(scale && { '--glyph-reveal-scale': 'var(--glyph-motion-scale)' }),
41
+ } as CSSProperties
42
+ return (
43
+ <Comp
44
+ data-slot="reveal"
45
+ ref={composeRefs(local, ref)}
46
+ style={{ ...vars, ...style }}
47
+ {...props}
48
+ />
49
+ )
50
+ }
@@ -0,0 +1,81 @@
1
+ import { Slot } from 'radix-ui'
2
+ import {
3
+ Children,
4
+ type ComponentProps,
5
+ type CSSProperties,
6
+ isValidElement,
7
+ type ReactNode,
8
+ useRef,
9
+ } from 'react'
10
+ import { composeRefs } from '../utils/compose-refs'
11
+ import { type RevealOptions, useReveal } from './use-reveal'
12
+
13
+ type StaggerElement = 'div' | 'ul' | 'ol' | 'dl' | 'section'
14
+
15
+ export interface StaggerProps extends ComponentProps<'div'>, RevealOptions {
16
+ /** The element to render, e.g. `ul` for a list whose `li` items cascade in. Default `div`. */
17
+ as?: StaggerElement
18
+ /** Milliseconds between one child and the next. Defaults to the motion level's step. */
19
+ step?: number
20
+ /** Milliseconds before the first child. */
21
+ delay?: number
22
+ asChild?: boolean
23
+ }
24
+
25
+ /**
26
+ * Reveals its children one after another when the group scrolls into view: feature grids,
27
+ * pricing tiers, card lists. Each direct child becomes a `StaggerItem` without a wrapper.
28
+ */
29
+ export function Stagger({
30
+ step,
31
+ delay,
32
+ once,
33
+ amount,
34
+ enabled,
35
+ as = 'div',
36
+ asChild,
37
+ style,
38
+ children,
39
+ ref,
40
+ ...props
41
+ }: StaggerProps) {
42
+ const local = useRef<HTMLDivElement>(null)
43
+ useReveal(local, 'stagger', { once, amount, enabled })
44
+ const Comp = (asChild ? Slot.Root : as) as 'div'
45
+ const vars = {
46
+ ...(step !== undefined && { '--glyph-stagger-step': `${step}ms` }),
47
+ ...(delay !== undefined && { '--glyph-stagger-delay': `${delay}ms` }),
48
+ } as CSSProperties
49
+ let index = 0
50
+ const items = Children.map(children, (child) =>
51
+ isValidElement(child) ? <StaggerItem index={index++}>{child}</StaggerItem> : child,
52
+ )
53
+ return (
54
+ <Comp
55
+ data-slot="stagger"
56
+ ref={composeRefs(local, ref)}
57
+ style={{ ...vars, ...style }}
58
+ {...props}
59
+ >
60
+ {asChild ? children : items}
61
+ </Comp>
62
+ )
63
+ }
64
+
65
+ export interface StaggerItemProps {
66
+ /** Position in the cascade, starting at 0. */
67
+ index: number
68
+ children: ReactNode
69
+ }
70
+
71
+ /**
72
+ * One step of a `Stagger`, for children that are not direct (e.g. inside a fragment or a
73
+ * mapped list with wrappers). Merges onto its child; renders no element of its own.
74
+ */
75
+ export function StaggerItem({ index, children }: StaggerItemProps) {
76
+ return (
77
+ <Slot.Root data-stagger-item="" style={{ '--glyph-stagger-index': index } as CSSProperties}>
78
+ {children}
79
+ </Slot.Root>
80
+ )
81
+ }
@@ -0,0 +1,52 @@
1
+ import type { MotionLevel, SpringConfig } from '@glyphui/tokens'
2
+ import { useContext, useMemo } from 'react'
3
+ import { useMediaQuery } from '../hooks/use-media-query'
4
+ import { GlyphContext } from '../provider/glyph-context'
5
+
6
+ export interface MotionSettings {
7
+ /** The effective level: the theme's, overridden by the provider, forced to `none` by reduced motion. */
8
+ level: MotionLevel
9
+ /** `false` when level is `none`. Components render static markup then. */
10
+ animate: boolean
11
+ /** The theme's spring for overlays, indicators and layout animations. */
12
+ spring: SpringConfig & { type: 'spring' }
13
+ /** Theme durations in seconds, for tween animations. */
14
+ duration: { fast: number; base: number; slow: number }
15
+ }
16
+
17
+ const defaultSpring: SpringConfig = { stiffness: 420, damping: 34 }
18
+
19
+ function seconds(value: string | undefined, fallback: number): number {
20
+ if (!value) return fallback
21
+ const n = Number.parseFloat(value)
22
+ if (Number.isNaN(n)) return fallback
23
+ return value.trim().endsWith('ms') ? n / 1000 : n
24
+ }
25
+
26
+ /**
27
+ * How Glyph components should animate right now. Every animated component reads this, so a
28
+ * theme's `motion.level`, the provider's `motion` prop and the visitor's reduced-motion
29
+ * setting control all motion in one place.
30
+ */
31
+ export function useMotionSettings(): MotionSettings {
32
+ const context = useContext(GlyphContext)
33
+ const reduced = useMediaQuery('(prefers-reduced-motion: reduce)')
34
+ const motion = context?.theme.motion
35
+ const level: MotionLevel = reduced ? 'none' : (context?.motion ?? motion?.level ?? 'subtle')
36
+ const spring = motion?.spring ?? defaultSpring
37
+ const durations = motion?.duration
38
+ // Stable identity per theme, so components can depend on these in effects.
39
+ return useMemo(
40
+ () => ({
41
+ level,
42
+ animate: level !== 'none',
43
+ spring: { type: 'spring' as const, ...spring },
44
+ duration: {
45
+ fast: seconds(durations?.fast, 0.12),
46
+ base: seconds(durations?.base, 0.18),
47
+ slow: seconds(durations?.slow, 0.28),
48
+ },
49
+ }),
50
+ [level, spring, durations],
51
+ )
52
+ }
@@ -0,0 +1,54 @@
1
+ import { type RefObject, useEffect, useLayoutEffect } from 'react'
2
+ import { useMotionSettings } from './use-motion-settings'
3
+
4
+ const useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect
5
+
6
+ export interface RevealOptions {
7
+ /** Animate only the first time it scrolls into view. Default true. */
8
+ once?: boolean | undefined
9
+ /** Share of the element that must be visible, 0–1. Default 0.15. */
10
+ amount?: number | undefined
11
+ /** Set false to show the content without animating. */
12
+ enabled?: boolean | undefined
13
+ }
14
+
15
+ /**
16
+ * Drives a `data-<attribute>="hidden|shown"` attribute from an IntersectionObserver.
17
+ *
18
+ * Content stays visible unless everything needed to reveal it is available: motion is on,
19
+ * the browser has IntersectionObserver, and JavaScript ran. Server HTML, tests and
20
+ * reduced-motion visitors always get visible content.
21
+ */
22
+ export function useReveal(
23
+ ref: RefObject<HTMLElement | null>,
24
+ attribute: 'reveal' | 'stagger',
25
+ { once = true, amount = 0.15, enabled = true }: RevealOptions = {},
26
+ ): void {
27
+ const { animate } = useMotionSettings()
28
+ const active = enabled && animate
29
+
30
+ // Hide before the first paint, so in-view content animates in instead of flashing.
31
+ useIsomorphicLayoutEffect(() => {
32
+ const el = ref.current
33
+ if (!el || !active || typeof IntersectionObserver === 'undefined') return
34
+ const key = `data-${attribute}`
35
+ el.setAttribute(key, 'hidden')
36
+ const observer = new IntersectionObserver(
37
+ ([entry]) => {
38
+ if (!entry) return
39
+ if (entry.isIntersecting) {
40
+ el.setAttribute(key, 'shown')
41
+ if (once) observer.disconnect()
42
+ } else if (!once) {
43
+ el.setAttribute(key, 'hidden')
44
+ }
45
+ },
46
+ { threshold: amount },
47
+ )
48
+ observer.observe(el)
49
+ return () => {
50
+ observer.disconnect()
51
+ el.removeAttribute(key)
52
+ }
53
+ }, [active, attribute, once, amount])
54
+ }
@@ -1,7 +1,7 @@
1
1
  import { focusRing, transition } from '../../utils/styles'
2
2
  import { tv, type VariantProps } from '../../utils/tv'
3
3
 
4
- export const appShellStyles = tv({
4
+ export const appShellStyles = /* @__PURE__ */ tv({
5
5
  slots: {
6
6
  root: 'flex w-full bg-background',
7
7
  sidebar: 'hidden shrink-0 md:flex',
@@ -10,9 +10,10 @@ export const appShellStyles = tv({
10
10
  'flex h-14 shrink-0 items-center gap-2 border-b-border px-3 md:hidden',
11
11
  'border-b-(length:--glyph-border-width)',
12
12
  ],
13
- overlay: 'fixed inset-0 z-50 animate-fade-in bg-overlay',
13
+ overlay:
14
+ 'fixed inset-0 z-50 bg-overlay data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out',
14
15
  drawer:
15
- 'fixed inset-y-0 left-0 z-50 flex w-72 max-w-[85vw] animate-slide-in-left shadow-lg outline-none [&>[data-slot=sidebar]]:w-full',
16
+ 'fixed inset-y-0 left-0 z-50 flex w-72 max-w-[85vw] shadow-lg data-[state=open]:animate-sheet-in-left data-[state=closed]:animate-sheet-out-left outline-none [&>[data-slot=sidebar]]:w-full',
16
17
  },
17
18
  variants: {
18
19
  layout: {
@@ -33,10 +34,11 @@ export const appShellStyles = tv({
33
34
 
34
35
  export type AppShellVariants = VariantProps<typeof appShellStyles>
35
36
 
36
- export const sidebarStyles = tv({
37
+ export const sidebarStyles = /* @__PURE__ */ tv({
37
38
  slots: {
38
39
  root: [
39
- 'group/sidebar flex h-full w-60 flex-col overflow-hidden border-r-border bg-subtle',
40
+ // Isolated so the active item's sliding highlight stays under every item's label.
41
+ 'group/sidebar isolate flex h-full w-60 flex-col overflow-hidden border-r-border bg-subtle',
40
42
  'border-r-(length:--glyph-border-width)',
41
43
  'transition-[width] duration-(--glyph-duration-base) ease-standard data-[collapsed=true]:w-15',
42
44
  ],
@@ -50,12 +52,16 @@ export const sidebarStyles = tv({
50
52
  transition,
51
53
  focusRing,
52
54
  'hover:bg-muted hover:text-foreground',
53
- 'aria-[current=page]:bg-muted aria-[current=page]:text-foreground',
54
- 'before:absolute before:inset-y-1.5 before:-left-3 before:w-0.5 before:rounded-r-pill before:bg-transparent aria-[current=page]:before:bg-primary',
55
+ 'aria-[current=page]:text-foreground',
55
56
  'group-data-[collapsed=true]/sidebar:justify-center group-data-[collapsed=true]/sidebar:px-0',
56
57
  ],
58
+ /** The active item's background and accent bar. Slides between items on navigation. */
59
+ itemIndicator: [
60
+ 'pointer-events-none absolute inset-0 -z-10 rounded-[inherit] bg-muted',
61
+ 'before:absolute before:inset-y-1.5 before:-left-3 before:w-0.5 before:rounded-r-pill before:bg-primary',
62
+ ],
57
63
  itemIcon: 'flex size-4 shrink-0 items-center justify-center [&>svg]:size-4',
58
- itemLabel: 'min-w-0 flex-1 truncate text-left group-data-[collapsed=true]/sidebar:hidden',
64
+ itemLabel: 'min-w-0 flex-1 truncate text-left group-data-[collapsed=true]/sidebar:sr-only',
59
65
  itemBadge:
60
66
  'ml-auto font-mono text-caption text-faint-foreground tabular-nums group-data-[collapsed=true]/sidebar:hidden',
61
67
  footer: [
@@ -65,7 +71,7 @@ export const sidebarStyles = tv({
65
71
  },
66
72
  })
67
73
 
68
- export const navbarStyles = tv({
74
+ export const navbarStyles = /* @__PURE__ */ tv({
69
75
  slots: {
70
76
  root: [
71
77
  'top-0 z-40 w-full border-b-transparent',
@@ -83,9 +89,10 @@ export const navbarStyles = tv({
83
89
  ],
84
90
  actions: 'ml-auto hidden items-center gap-2 md:flex',
85
91
  menuButton: 'ml-auto md:hidden',
86
- overlay: 'fixed inset-0 z-50 animate-fade-in bg-overlay',
92
+ overlay:
93
+ 'fixed inset-0 z-50 bg-overlay data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out',
87
94
  panel: [
88
- 'fixed inset-x-0 top-0 z-50 max-h-dvh overflow-y-auto border-b-border bg-background px-4 pb-6 shadow-lg outline-none animate-slide-in-top',
95
+ 'fixed inset-x-0 top-0 z-50 max-h-dvh overflow-y-auto border-b-border bg-background px-4 pb-6 shadow-lg outline-none animate-slide-in-top data-[state=closed]:animate-pop-out',
89
96
  'border-b-(length:--glyph-border-width)',
90
97
  ],
91
98
  panelHeader: 'flex h-16 items-center justify-between',
@@ -112,7 +119,7 @@ export const navbarStyles = tv({
112
119
  defaultVariants: { sticky: true, blur: true },
113
120
  })
114
121
 
115
- export const pageHeaderStyles = tv({
122
+ export const pageHeaderStyles = /* @__PURE__ */ tv({
116
123
  slots: {
117
124
  root: [
118
125
  'flex flex-col gap-4 border-b-border pb-5 sm:flex-row sm:items-end sm:justify-between',
@@ -5,13 +5,42 @@ import { Container, type ContainerProps } from '../../components/container'
5
5
  import { useComponentConfig } from '../../hooks/use-component-config'
6
6
  import { useScrolled } from '../../hooks/use-scrolled'
7
7
  import { MenuIcon, XIcon } from '../../internal/icons'
8
- import { useLinkComponent } from '../../provider/glyph-context'
8
+ import { useIsActive, useLinkComponent } from '../../provider/glyph-context'
9
9
  import { navbarStyles } from './app-shell.styles'
10
10
 
11
11
  export interface NavLink {
12
12
  label: ReactNode
13
13
  href: string
14
+ /** Marks the current page. Computed from the provider's `router` when not set. */
14
15
  active?: boolean
16
+ /** With automatic matching, only the exact path is active (not its children). */
17
+ end?: boolean
18
+ }
19
+
20
+ function NavbarLink({
21
+ link,
22
+ className,
23
+ onClick,
24
+ }: {
25
+ link: NavLink
26
+ className: string
27
+ onClick?: () => void
28
+ }) {
29
+ const Link = useLinkComponent()
30
+ const active = useIsActive(link.href, {
31
+ explicit: link.active,
32
+ ...(link.end !== undefined && { end: link.end }),
33
+ })
34
+ return (
35
+ <Link
36
+ href={link.href}
37
+ aria-current={active ? 'page' : undefined}
38
+ className={className}
39
+ {...(onClick && { onClick })}
40
+ >
41
+ {link.label}
42
+ </Link>
43
+ )
15
44
  }
16
45
 
17
46
  export interface NavbarProps extends Omit<ComponentProps<'header'>, 'children'> {
@@ -44,7 +73,6 @@ export function Navbar(inProps: NavbarProps) {
44
73
  } = props
45
74
  const [open, setOpen] = useState(false)
46
75
  const scrolled = useScrolled(8, blurOnScroll)
47
- const Link = useLinkComponent()
48
76
  const s = navbarStyles({ sticky, blur: blurOnScroll })
49
77
 
50
78
  return (
@@ -59,14 +87,7 @@ export function Navbar(inProps: NavbarProps) {
59
87
  {links.length > 0 && (
60
88
  <nav aria-label="Main" className={s.links({ class: slots.links })}>
61
89
  {links.map((link) => (
62
- <Link
63
- key={link.href}
64
- href={link.href}
65
- aria-current={link.active ? 'page' : undefined}
66
- className={s.link({ class: slots.link })}
67
- >
68
- {link.label}
69
- </Link>
90
+ <NavbarLink key={link.href} link={link} className={s.link({ class: slots.link })} />
70
91
  ))}
71
92
  </nav>
72
93
  )}
@@ -96,15 +117,12 @@ export function Navbar(inProps: NavbarProps) {
96
117
  </div>
97
118
  <nav aria-label="Main" className={s.panelLinks({ class: slots.panelLinks })}>
98
119
  {links.map((link) => (
99
- <Link
120
+ <NavbarLink
100
121
  key={link.href}
101
- href={link.href}
102
- aria-current={link.active ? 'page' : undefined}
122
+ link={link}
103
123
  className={s.panelLink({ class: slots.panelLink })}
104
124
  onClick={() => setOpen(false)}
105
- >
106
- {link.label}
107
- </Link>
125
+ />
108
126
  ))}
109
127
  </nav>
110
128
  {actions && (