@passui/react 0.1.46 → 0.2.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 (429) hide show
  1. package/README.md +29 -109
  2. package/THIRD_PARTY_NOTICES.md +29 -0
  3. package/dist/accordion.d.ts +15 -0
  4. package/dist/accordion.js +93 -0
  5. package/dist/alert-dialog.d.ts +26 -0
  6. package/dist/alert-dialog.js +142 -0
  7. package/dist/alert.d.ts +10 -0
  8. package/dist/alert.js +28 -0
  9. package/dist/{types/src/components/ambient/ambient.d.ts → ambient.d.ts} +4 -4
  10. package/dist/ambient.js +22 -0
  11. package/dist/{types/src/appearance → appearance}/platform.d.ts +3 -3
  12. package/dist/appearance/platform.js +43 -0
  13. package/dist/appearance/theme.d.ts +71 -0
  14. package/dist/appearance/theme.js +236 -0
  15. package/dist/appearance.d.ts +3 -0
  16. package/dist/appearance.js +3 -0
  17. package/dist/{types/src/components/aspect-ratio/aspect-ratio.d.ts → aspect-ratio.d.ts} +4 -4
  18. package/dist/aspect-ratio.js +17 -0
  19. package/dist/avatar.d.ts +5 -0
  20. package/dist/avatar.js +43 -0
  21. package/dist/badge.d.ts +8 -0
  22. package/dist/badge.js +21 -0
  23. package/dist/breadcrumb.d.ts +13 -0
  24. package/dist/breadcrumb.js +63 -0
  25. package/dist/button-group.d.ts +5 -0
  26. package/dist/button-group.js +14 -0
  27. package/dist/button.d.ts +21 -0
  28. package/dist/button.js +58 -0
  29. package/dist/calendar.d.ts +35 -0
  30. package/dist/calendar.js +225 -0
  31. package/dist/card.d.ts +9 -0
  32. package/dist/card.js +54 -0
  33. package/dist/chart.d.ts +30 -0
  34. package/dist/chart.js +226 -0
  35. package/dist/checkbox.d.ts +13 -0
  36. package/dist/checkbox.js +53 -0
  37. package/dist/{types/src/lib/clipboard.d.ts → clipboard.d.ts} +1 -1
  38. package/dist/clipboard.js +16 -0
  39. package/dist/cn.d.ts +2 -0
  40. package/dist/cn.js +10 -0
  41. package/dist/code-block.d.ts +34 -0
  42. package/dist/code-block.js +87 -0
  43. package/dist/collapsible.d.ts +13 -0
  44. package/dist/collapsible.js +49 -0
  45. package/dist/combobox.d.ts +25 -0
  46. package/dist/combobox.js +112 -0
  47. package/dist/command.d.ts +22 -0
  48. package/dist/command.js +129 -0
  49. package/dist/components/toast/toast-store.d.ts +60 -0
  50. package/dist/components/toast/toast-store.js +96 -0
  51. package/dist/{types/src/components → components}/toast/toaster.d.ts +4 -4
  52. package/dist/components/toast/toaster.js +345 -0
  53. package/dist/context-menu.d.ts +2 -0
  54. package/dist/context-menu.js +2 -0
  55. package/dist/conversation.d.ts +48 -0
  56. package/dist/conversation.js +202 -0
  57. package/dist/date-time-picker.d.ts +50 -0
  58. package/dist/date-time-picker.js +235 -0
  59. package/dist/date.d.ts +50 -0
  60. package/dist/date.js +77 -0
  61. package/dist/dialog.d.ts +21 -0
  62. package/dist/dialog.js +113 -0
  63. package/dist/drawer.d.ts +30 -0
  64. package/dist/drawer.js +140 -0
  65. package/dist/dropdown-menu.d.ts +56 -0
  66. package/dist/dropdown-menu.js +295 -0
  67. package/dist/empty.d.ts +11 -0
  68. package/dist/empty.js +51 -0
  69. package/dist/field.d.ts +16 -0
  70. package/dist/field.js +47 -0
  71. package/{src/hooks/scroll/minimize-decision.ts → dist/hooks/scroll/minimize-decision.js} +3 -5
  72. package/dist/{types/src/hooks → hooks}/use-anchored-placement.d.ts +2 -2
  73. package/dist/hooks/use-anchored-placement.js +33 -0
  74. package/dist/{types/src/hooks → hooks}/use-minimize-on-scroll.d.ts +1 -1
  75. package/dist/hooks/use-minimize-on-scroll.js +59 -0
  76. package/dist/{types/src/hooks → hooks}/use-visual-viewport.d.ts +2 -2
  77. package/{src/hooks/use-visual-viewport.ts → dist/hooks/use-visual-viewport.js} +20 -35
  78. package/dist/hooks/viewport/types.d.ts +7 -0
  79. package/dist/hooks/viewport/viewport-metrics.js +13 -0
  80. package/dist/index.d.ts +84 -0
  81. package/dist/index.js +80 -0
  82. package/dist/input-group.d.ts +17 -0
  83. package/dist/input-group.js +55 -0
  84. package/dist/input-otp.d.ts +13 -0
  85. package/dist/input-otp.js +36 -0
  86. package/dist/input.d.ts +4 -0
  87. package/dist/input.js +14 -0
  88. package/dist/item.d.ts +49 -0
  89. package/dist/item.js +142 -0
  90. package/dist/kbd.d.ts +4 -0
  91. package/dist/kbd.js +86 -0
  92. package/dist/label.d.ts +3 -0
  93. package/dist/label.js +12 -0
  94. package/dist/labeled-content.d.ts +24 -0
  95. package/dist/labeled-content.js +41 -0
  96. package/dist/{types/src/lib/language.d.ts → language.d.ts} +1 -1
  97. package/dist/language.js +11 -0
  98. package/dist/layout.d.ts +24 -0
  99. package/dist/layout.js +36 -0
  100. package/dist/{types/src/lib → lib}/anchored-placement.d.ts +27 -27
  101. package/dist/lib/anchored-placement.js +42 -0
  102. package/dist/lib/calendar-month.js +90 -0
  103. package/dist/lib/cx.js +6 -0
  104. package/dist/lib/drawer.math.js +29 -0
  105. package/dist/lib/floating-layers.d.ts +3 -0
  106. package/dist/lib/floating-layers.js +25 -0
  107. package/dist/{types/src/lib → lib}/haptics.d.ts +1 -1
  108. package/dist/lib/haptics.js +13 -0
  109. package/dist/lib/liquid-step.js +33 -0
  110. package/dist/lib/page-scale.js +58 -0
  111. package/dist/lib/portal.js +12 -0
  112. package/dist/lib/presence.js +53 -0
  113. package/dist/lib/range-value.js +25 -0
  114. package/dist/lib/render.d.ts +8 -0
  115. package/dist/lib/render.js +42 -0
  116. package/dist/lib/rolling-digit.js +83 -0
  117. package/dist/{types/src/lib → lib}/screen-edges.d.ts +5 -5
  118. package/dist/lib/screen-edges.js +30 -0
  119. package/dist/lib/swipe-touch-action.js +34 -0
  120. package/dist/lib/visual-viewport.js +27 -0
  121. package/dist/lib/water-drop.js +412 -0
  122. package/dist/lib/wheel.js +125 -0
  123. package/dist/list.d.ts +26 -0
  124. package/dist/list.js +80 -0
  125. package/dist/locales.d.ts +18 -0
  126. package/dist/locales.js +36 -0
  127. package/dist/marker.d.ts +13 -0
  128. package/dist/marker.js +33 -0
  129. package/dist/motion/transitions.d.ts +170 -0
  130. package/dist/motion/transitions.js +156 -0
  131. package/dist/pagination.d.ts +30 -0
  132. package/dist/pagination.js +117 -0
  133. package/dist/popover.d.ts +26 -0
  134. package/dist/popover.js +101 -0
  135. package/dist/progress.d.ts +9 -0
  136. package/dist/progress.js +24 -0
  137. package/dist/questionnaire.d.ts +46 -0
  138. package/dist/questionnaire.js +133 -0
  139. package/dist/radio-group.d.ts +21 -0
  140. package/dist/radio-group.js +67 -0
  141. package/dist/search-field.d.ts +18 -0
  142. package/dist/search-field.js +45 -0
  143. package/dist/segmented-control.d.ts +16 -0
  144. package/dist/segmented-control.js +25 -0
  145. package/dist/select.d.ts +24 -0
  146. package/dist/select.js +107 -0
  147. package/dist/separator.d.ts +9 -0
  148. package/dist/separator.js +17 -0
  149. package/dist/{types/src/lib/shapes.d.ts → shapes.d.ts} +2 -2
  150. package/dist/shapes.js +65 -0
  151. package/dist/sheet.d.ts +24 -0
  152. package/dist/sheet.js +141 -0
  153. package/dist/sidebar.d.ts +32 -0
  154. package/dist/sidebar.js +85 -0
  155. package/dist/skeleton.d.ts +3 -0
  156. package/dist/skeleton.js +13 -0
  157. package/dist/slider.d.ts +9 -0
  158. package/dist/slider.js +42 -0
  159. package/dist/slosh-slider.d.ts +21 -0
  160. package/dist/slosh-slider.js +205 -0
  161. package/dist/spinner.d.ts +3 -0
  162. package/dist/spinner.js +20 -0
  163. package/dist/stat-tile.d.ts +20 -0
  164. package/dist/stat-tile.js +53 -0
  165. package/dist/stepper.d.ts +22 -0
  166. package/dist/stepper.js +98 -0
  167. package/dist/swatch-picker.d.ts +22 -0
  168. package/dist/swatch-picker.js +70 -0
  169. package/dist/switch.d.ts +10 -0
  170. package/dist/switch.js +44 -0
  171. package/dist/tab-bar.d.ts +15 -0
  172. package/dist/tab-bar.js +34 -0
  173. package/dist/{types/src/components/table/table.d.ts → table.d.ts} +3 -3
  174. package/dist/table.js +93 -0
  175. package/dist/tabs.d.ts +32 -0
  176. package/dist/tabs.js +131 -0
  177. package/dist/text.d.ts +25 -0
  178. package/dist/text.js +44 -0
  179. package/dist/textarea.d.ts +3 -0
  180. package/dist/textarea.js +13 -0
  181. package/dist/toast.d.ts +3 -0
  182. package/dist/toast.js +3 -0
  183. package/dist/toggle-group.d.ts +20 -0
  184. package/dist/toggle-group.js +68 -0
  185. package/dist/toggle.d.ts +24 -0
  186. package/dist/toggle.js +37 -0
  187. package/dist/tokens.d.ts +1 -0
  188. package/dist/tooltip.d.ts +21 -0
  189. package/dist/tooltip.js +61 -0
  190. package/dist/trace.d.ts +14 -0
  191. package/dist/trace.js +54 -0
  192. package/dist/{types/src/hooks/use-dismiss.d.ts → use-dismiss.d.ts} +3 -3
  193. package/dist/use-dismiss.js +38 -0
  194. package/dist/{types/src/hooks/use-media-query.d.ts → use-media-query.d.ts} +12 -12
  195. package/dist/use-media-query.js +56 -0
  196. package/dist/use-os.d.ts +12 -0
  197. package/dist/use-os.js +17 -0
  198. package/dist/wake-slider.d.ts +15 -0
  199. package/dist/wake-slider.js +174 -0
  200. package/package.json +122 -253
  201. package/src/styles/code-block.css +4 -0
  202. package/src/styles/globals.css +5 -0
  203. package/src/styles/motion-controls.css +10 -0
  204. package/src/styles/page-scale.css +27 -0
  205. package/src/styles/styles.css +4 -2
  206. package/dist/types/src/appearance/index.d.ts +0 -2
  207. package/dist/types/src/appearance/theme.d.ts +0 -71
  208. package/dist/types/src/components/accordion/accordion.d.ts +0 -23
  209. package/dist/types/src/components/ambient/index.d.ts +0 -1
  210. package/dist/types/src/components/breadcrumb/breadcrumb.d.ts +0 -19
  211. package/dist/types/src/components/button/button-styles.d.ts +0 -12
  212. package/dist/types/src/components/button/button.d.ts +0 -32
  213. package/dist/types/src/components/button/icon-button.d.ts +0 -10
  214. package/dist/types/src/components/button/pending-spinner.d.ts +0 -5
  215. package/dist/types/src/components/button/use-pending-indicator.d.ts +0 -2
  216. package/dist/types/src/components/chip/chip.d.ts +0 -10
  217. package/dist/types/src/components/code-block/code-block.d.ts +0 -13
  218. package/dist/types/src/components/combo-box/combo-box.d.ts +0 -9
  219. package/dist/types/src/components/command/command.d.ts +0 -18
  220. package/dist/types/src/components/compact-date-picker/calendar-month.d.ts +0 -25
  221. package/dist/types/src/components/compact-date-picker/compact-date-picker.d.ts +0 -30
  222. package/dist/types/src/components/compact-time-picker/compact-time-picker.d.ts +0 -29
  223. package/dist/types/src/components/compact-time-picker/time-value.d.ts +0 -18
  224. package/dist/types/src/components/content-unavailable-view/content-unavailable-view.d.ts +0 -12
  225. package/dist/types/src/components/content-view/content-view.d.ts +0 -51
  226. package/dist/types/src/components/content-view/index.d.ts +0 -1
  227. package/dist/types/src/components/context-menu/conceal-menu-source.d.ts +0 -2
  228. package/dist/types/src/components/context-menu/context-menu-host.d.ts +0 -2
  229. package/dist/types/src/components/context-menu/context-menu-store.d.ts +0 -62
  230. package/dist/types/src/components/context-menu/menu-navigation.d.ts +0 -6
  231. package/dist/types/src/components/context-menu/menu-position.d.ts +0 -21
  232. package/dist/types/src/components/context-menu/menu-reveal.d.ts +0 -26
  233. package/dist/types/src/components/context-menu/use-context-menu.d.ts +0 -14
  234. package/dist/types/src/components/conversation/conversation.d.ts +0 -48
  235. package/dist/types/src/components/conversation/index.d.ts +0 -1
  236. package/dist/types/src/components/date-picker/date-picker.d.ts +0 -19
  237. package/dist/types/src/components/date-picker/date-value.d.ts +0 -2
  238. package/dist/types/src/components/dialog/dialog-host.d.ts +0 -6
  239. package/dist/types/src/components/dialog/dialog-store.d.ts +0 -23
  240. package/dist/types/src/components/dialog/dialog.d.ts +0 -33
  241. package/dist/types/src/components/dialog/index.d.ts +0 -1
  242. package/dist/types/src/components/disclosure-group/disclosure-group.d.ts +0 -18
  243. package/dist/types/src/components/divider/divider.d.ts +0 -9
  244. package/dist/types/src/components/inline-disclosure/inline-disclosure.d.ts +0 -15
  245. package/dist/types/src/components/keyboard-shortcut/keyboard-shortcut.d.ts +0 -8
  246. package/dist/types/src/components/labeled-content/labeled-content.d.ts +0 -22
  247. package/dist/types/src/components/locale-switcher/index.d.ts +0 -1
  248. package/dist/types/src/components/locale-switcher/locale-switcher.d.ts +0 -13
  249. package/dist/types/src/components/menu/menu.d.ts +0 -16
  250. package/dist/types/src/components/morph/index.d.ts +0 -2
  251. package/dist/types/src/components/morph/morph.d.ts +0 -32
  252. package/dist/types/src/components/morph/use-morph-disclosure.d.ts +0 -13
  253. package/dist/types/src/components/one-time-code/one-time-code.d.ts +0 -26
  254. package/dist/types/src/components/picker/picker-trigger.d.ts +0 -3
  255. package/dist/types/src/components/picker/picker.d.ts +0 -46
  256. package/dist/types/src/components/popover/anchored-surface.d.ts +0 -17
  257. package/dist/types/src/components/popover/index.d.ts +0 -41
  258. package/dist/types/src/components/popover/popover-content.d.ts +0 -32
  259. package/dist/types/src/components/popover/popover-fit.d.ts +0 -21
  260. package/dist/types/src/components/popover/popover-root.d.ts +0 -22
  261. package/dist/types/src/components/popover/popover-trigger.d.ts +0 -23
  262. package/dist/types/src/components/profile-image/profile-image.d.ts +0 -9
  263. package/dist/types/src/components/progress-view/progress-view.d.ts +0 -13
  264. package/dist/types/src/components/progress-view/use-liquid-progress.d.ts +0 -3
  265. package/dist/types/src/components/radio-group/radio-group.d.ts +0 -20
  266. package/dist/types/src/components/search-field/expanding-search-field.d.ts +0 -5
  267. package/dist/types/src/components/search-field/search-field.d.ts +0 -9
  268. package/dist/types/src/components/search-list/search-list.d.ts +0 -22
  269. package/dist/types/src/components/section/section.d.ts +0 -18
  270. package/dist/types/src/components/secure-field/secure-field.d.ts +0 -4
  271. package/dist/types/src/components/segmented-control/segmented-control.d.ts +0 -25
  272. package/dist/types/src/components/sheet/modal-environment.d.ts +0 -2
  273. package/dist/types/src/components/sheet/sheet-portal.d.ts +0 -5
  274. package/dist/types/src/components/sheet/sheet.d.ts +0 -26
  275. package/dist/types/src/components/sheet/use-sheet-focus.d.ts +0 -3
  276. package/dist/types/src/components/sidebar/sidebar.d.ts +0 -24
  277. package/dist/types/src/components/skeleton/skeleton.d.ts +0 -9
  278. package/dist/types/src/components/slider/slider.d.ts +0 -17
  279. package/dist/types/src/components/slosh-slider/liquid-step.d.ts +0 -6
  280. package/dist/types/src/components/slosh-slider/slosh-slider.d.ts +0 -21
  281. package/dist/types/src/components/stat-tile/index.d.ts +0 -1
  282. package/dist/types/src/components/stat-tile/stat-tile.d.ts +0 -20
  283. package/dist/types/src/components/status-indicator/status-indicator.d.ts +0 -17
  284. package/dist/types/src/components/stepper/rolling-digit.d.ts +0 -11
  285. package/dist/types/src/components/stepper/stepper.d.ts +0 -22
  286. package/dist/types/src/components/swatch-picker/swatch-picker.d.ts +0 -22
  287. package/dist/types/src/components/tab-bar/tab-bar.d.ts +0 -43
  288. package/dist/types/src/components/tab-view/tab-view.d.ts +0 -27
  289. package/dist/types/src/components/text-editor/text-editor.d.ts +0 -9
  290. package/dist/types/src/components/text-field/text-field.d.ts +0 -33
  291. package/dist/types/src/components/toast/toast-store.d.ts +0 -52
  292. package/dist/types/src/components/toggle/toggle.d.ts +0 -22
  293. package/dist/types/src/components/tooltip/tooltip-host.d.ts +0 -7
  294. package/dist/types/src/components/view-controller/index.d.ts +0 -1
  295. package/dist/types/src/components/view-controller/view-controller.d.ts +0 -21
  296. package/dist/types/src/components/wake-slider/wake-slider.d.ts +0 -15
  297. package/dist/types/src/hooks/scroll/minimize-decision.d.ts +0 -2
  298. package/dist/types/src/hooks/use-anchored-disclosure.d.ts +0 -9
  299. package/dist/types/src/hooks/use-floating-dismiss.d.ts +0 -3
  300. package/dist/types/src/hooks/viewport/types.d.ts +0 -19
  301. package/dist/types/src/hooks/viewport/viewport-metrics.d.ts +0 -3
  302. package/dist/types/src/icons/icons.d.ts +0 -616
  303. package/dist/types/src/index.d.ts +0 -73
  304. package/dist/types/src/lib/class-names.d.ts +0 -2
  305. package/dist/types/src/lib/date.d.ts +0 -50
  306. package/dist/types/src/lib/floating-layers.d.ts +0 -8
  307. package/dist/types/src/lib/range-value.d.ts +0 -4
  308. package/dist/types/src/machines/popover.machine.d.ts +0 -30
  309. package/dist/types/src/motion/transitions.d.ts +0 -170
  310. package/src/appearance/index.ts +0 -2
  311. package/src/appearance/platform.tsx +0 -102
  312. package/src/appearance/theme.tsx +0 -467
  313. package/src/components/accordion/accordion.tsx +0 -70
  314. package/src/components/ambient/ambient.tsx +0 -35
  315. package/src/components/ambient/index.ts +0 -1
  316. package/src/components/aspect-ratio/aspect-ratio.tsx +0 -27
  317. package/src/components/breadcrumb/breadcrumb.tsx +0 -73
  318. package/src/components/button/button-styles.ts +0 -49
  319. package/src/components/button/button.tsx +0 -107
  320. package/src/components/button/icon-button.tsx +0 -33
  321. package/src/components/button/pending-spinner.tsx +0 -14
  322. package/src/components/button/use-pending-indicator.ts +0 -22
  323. package/src/components/chip/chip.tsx +0 -45
  324. package/src/components/code-block/code-block.tsx +0 -48
  325. package/src/components/combo-box/combo-box.tsx +0 -13
  326. package/src/components/command/command.tsx +0 -149
  327. package/src/components/compact-date-picker/calendar-month.ts +0 -109
  328. package/src/components/compact-date-picker/compact-date-picker.tsx +0 -337
  329. package/src/components/compact-time-picker/compact-time-picker.tsx +0 -321
  330. package/src/components/compact-time-picker/time-value.ts +0 -58
  331. package/src/components/content-unavailable-view/content-unavailable-view.tsx +0 -78
  332. package/src/components/content-view/content-view.tsx +0 -215
  333. package/src/components/content-view/index.ts +0 -1
  334. package/src/components/context-menu/conceal-menu-source.ts +0 -30
  335. package/src/components/context-menu/context-menu-host.tsx +0 -459
  336. package/src/components/context-menu/context-menu-store.ts +0 -167
  337. package/src/components/context-menu/menu-navigation.ts +0 -36
  338. package/src/components/context-menu/menu-position.ts +0 -38
  339. package/src/components/context-menu/menu-reveal.ts +0 -42
  340. package/src/components/context-menu/use-context-menu.ts +0 -73
  341. package/src/components/conversation/conversation.tsx +0 -309
  342. package/src/components/conversation/index.ts +0 -1
  343. package/src/components/date-picker/date-picker.tsx +0 -106
  344. package/src/components/date-picker/date-value.ts +0 -22
  345. package/src/components/dialog/dialog-host.tsx +0 -119
  346. package/src/components/dialog/dialog-store.ts +0 -66
  347. package/src/components/dialog/dialog.tsx +0 -211
  348. package/src/components/dialog/index.ts +0 -1
  349. package/src/components/disclosure-group/disclosure-group.tsx +0 -108
  350. package/src/components/divider/divider.tsx +0 -33
  351. package/src/components/inline-disclosure/inline-disclosure.tsx +0 -53
  352. package/src/components/keyboard-shortcut/keyboard-shortcut.tsx +0 -32
  353. package/src/components/labeled-content/labeled-content.tsx +0 -84
  354. package/src/components/locale-switcher/index.ts +0 -1
  355. package/src/components/locale-switcher/locale-switcher.tsx +0 -311
  356. package/src/components/menu/menu.tsx +0 -85
  357. package/src/components/morph/index.ts +0 -2
  358. package/src/components/morph/morph.tsx +0 -258
  359. package/src/components/morph/use-morph-disclosure.ts +0 -27
  360. package/src/components/one-time-code/one-time-code.tsx +0 -234
  361. package/src/components/picker/picker-trigger.ts +0 -22
  362. package/src/components/picker/picker.tsx +0 -404
  363. package/src/components/popover/anchored-surface.tsx +0 -264
  364. package/src/components/popover/index.ts +0 -50
  365. package/src/components/popover/popover-content.tsx +0 -334
  366. package/src/components/popover/popover-fit.ts +0 -74
  367. package/src/components/popover/popover-root.tsx +0 -97
  368. package/src/components/popover/popover-trigger.tsx +0 -71
  369. package/src/components/profile-image/profile-image.tsx +0 -96
  370. package/src/components/progress-view/progress-view.tsx +0 -72
  371. package/src/components/progress-view/use-liquid-progress.ts +0 -43
  372. package/src/components/radio-group/radio-group.tsx +0 -86
  373. package/src/components/search-field/expanding-search-field.tsx +0 -197
  374. package/src/components/search-field/search-field.tsx +0 -66
  375. package/src/components/search-list/search-list.tsx +0 -276
  376. package/src/components/section/section.tsx +0 -75
  377. package/src/components/secure-field/secure-field.tsx +0 -8
  378. package/src/components/segmented-control/segmented-control.tsx +0 -157
  379. package/src/components/sheet/modal-environment.ts +0 -82
  380. package/src/components/sheet/sheet-portal.tsx +0 -62
  381. package/src/components/sheet/sheet.tsx +0 -165
  382. package/src/components/sheet/use-sheet-focus.ts +0 -109
  383. package/src/components/sidebar/sidebar.tsx +0 -102
  384. package/src/components/skeleton/skeleton.tsx +0 -38
  385. package/src/components/slider/slider.tsx +0 -134
  386. package/src/components/slosh-slider/liquid-step.ts +0 -43
  387. package/src/components/slosh-slider/slosh-slider.tsx +0 -294
  388. package/src/components/stat-tile/index.ts +0 -1
  389. package/src/components/stat-tile/stat-tile.tsx +0 -90
  390. package/src/components/status-indicator/status-indicator.tsx +0 -54
  391. package/src/components/stepper/rolling-digit.tsx +0 -91
  392. package/src/components/stepper/stepper.tsx +0 -136
  393. package/src/components/swatch-picker/swatch-picker.tsx +0 -138
  394. package/src/components/tab-bar/tab-bar.tsx +0 -182
  395. package/src/components/tab-view/tab-view.tsx +0 -155
  396. package/src/components/table/table.tsx +0 -151
  397. package/src/components/text-editor/text-editor.tsx +0 -42
  398. package/src/components/text-field/text-field.tsx +0 -200
  399. package/src/components/toast/toast-store.ts +0 -164
  400. package/src/components/toast/toaster.tsx +0 -407
  401. package/src/components/toggle/toggle.tsx +0 -320
  402. package/src/components/tooltip/tooltip-host.tsx +0 -178
  403. package/src/components/view-controller/index.ts +0 -1
  404. package/src/components/view-controller/view-controller.tsx +0 -75
  405. package/src/components/wake-slider/wake-slider.tsx +0 -260
  406. package/src/hooks/use-anchored-disclosure.ts +0 -23
  407. package/src/hooks/use-anchored-placement.ts +0 -40
  408. package/src/hooks/use-dismiss.ts +0 -44
  409. package/src/hooks/use-floating-dismiss.ts +0 -30
  410. package/src/hooks/use-media-query.ts +0 -94
  411. package/src/hooks/use-minimize-on-scroll.ts +0 -77
  412. package/src/hooks/viewport/types.ts +0 -19
  413. package/src/hooks/viewport/viewport-metrics.ts +0 -19
  414. package/src/icons/icons.tsx +0 -458
  415. package/src/index.ts +0 -107
  416. package/src/lib/anchored-placement.ts +0 -91
  417. package/src/lib/class-names.ts +0 -21
  418. package/src/lib/clipboard.ts +0 -15
  419. package/src/lib/date.ts +0 -86
  420. package/src/lib/floating-layers.ts +0 -53
  421. package/src/lib/haptics.ts +0 -23
  422. package/src/lib/language.ts +0 -16
  423. package/src/lib/range-value.ts +0 -38
  424. package/src/lib/screen-edges.ts +0 -44
  425. package/src/lib/shapes.ts +0 -59
  426. package/src/machines/popover.machine.ts +0 -51
  427. package/src/motion/transitions.ts +0 -97
  428. package/src/tokens.ts +0 -1
  429. /package/dist/{types/src/tokens.d.ts → tokens.js} +0 -0
@@ -1,157 +0,0 @@
1
- import { motion, useReducedMotion } from "motion/react";
2
- import { useId, useLayoutEffect, useRef, useState } from "react";
3
- import { cn } from "../../lib/class-names";
4
- import { haptic } from "../../lib/haptics";
5
- import { spring } from "../../motion/transitions";
6
- import { Picker } from "../picker/picker";
7
-
8
- export type SegmentedControlSize = "sm" | "md" | "lg";
9
-
10
- const segmentPaddings: Record<SegmentedControlSize, string> = {
11
- sm: "p-[2px]",
12
- md: "p-[3px]",
13
- lg: "p-[4px]",
14
- };
15
- const segmentLabelClasses: Record<SegmentedControlSize, string> = {
16
- sm: "min-w-[52px] px-2 py-0.5 text-caption2 whitespace-nowrap",
17
- md: "min-w-[64px] px-3 py-1 text-footnote whitespace-nowrap",
18
- lg: "min-w-[80px] px-4 py-1.5 text-subheadline whitespace-nowrap",
19
- };
20
- const segmentRadius: Record<SegmentedControlSize, string> = {
21
- sm: "rounded-sm",
22
- md: "rounded-md",
23
- lg: "rounded-lg",
24
- };
25
- const fallbackPickerSizes: Record<SegmentedControlSize, string> = {
26
- sm: "rounded-md py-1 text-caption2 font-semibold",
27
- md: "rounded-lg py-1.5 text-footnote font-semibold",
28
- lg: "rounded-lg py-2 text-subheadline font-semibold",
29
- };
30
-
31
- export interface SegmentedControlProps<T extends string> {
32
- /** Value of the selected segment. */
33
- value: T;
34
- /** The choices, in display order. */
35
- options: ReadonlyArray<{ value: T; label: string }>;
36
- /** Called with the selected segment's value. */
37
- onChange: (value: NoInfer<T>) => void;
38
- /** Accessible name for the group and its compact picker. */
39
- label: string;
40
- /** Custom classes for the control container. */
41
- className?: string;
42
- /** Segment padding, label text scale and min-width. @default "md" */
43
- size?: SegmentedControlSize;
44
- }
45
-
46
- /**
47
- * Mutually exclusive choices with a sliding selection, as on Apple
48
- * platforms. When the labels can't all fit the space it is given (a long
49
- * translation, a narrow pane) it becomes a pop-up button instead of
50
- * squeezing or spilling its text.
51
- */
52
- export function SegmentedControl<T extends string>({
53
- value,
54
- options,
55
- onChange,
56
- label,
57
- className,
58
- size = "md",
59
- }: SegmentedControlProps<T>) {
60
- const id = useId();
61
- const reducedMotion = useReducedMotion();
62
- const frame = useRef<HTMLDivElement>(null);
63
- const measure = useRef<HTMLDivElement>(null);
64
- const [fits, setFits] = useState(true);
65
-
66
- useLayoutEffect(() => {
67
- const box = frame.current;
68
- const natural = measure.current;
69
- if (!box || !natural) return;
70
- const check = () => setFits(natural.offsetWidth <= box.clientWidth + 0.5);
71
- check();
72
- const observer = new ResizeObserver(check);
73
- observer.observe(box);
74
- observer.observe(natural);
75
- return () => observer.disconnect();
76
- }, []);
77
-
78
- return (
79
- <div ref={frame} className={cn("relative w-full min-w-0", className)}>
80
- {/* The control at its natural size, to know whether it fits. */}
81
- <div
82
- ref={measure}
83
- aria-hidden="true"
84
- className={cn(
85
- "pointer-events-none invisible absolute top-0 flex w-max font-semibold",
86
- segmentPaddings[size],
87
- segmentLabelClasses[size].replace(/min-w-\[[^\]]+\]\s*/, ""),
88
- )}
89
- >
90
- {options.map((option) => (
91
- <span key={option.value} className={segmentLabelClasses[size]}>
92
- {option.label}
93
- </span>
94
- ))}
95
- </div>
96
- {fits ? (
97
- <fieldset
98
- className={cn(
99
- "bg-fill flex w-full rounded-lg shadow-[inset_0_1px_2px_rgb(40_30_0/0.06)]",
100
- segmentPaddings[size],
101
- )}
102
- >
103
- <legend className="sr-only">{label}</legend>
104
- {options.map((option) => {
105
- const selected = option.value === value;
106
- return (
107
- <label
108
- key={option.value}
109
- className={cn(
110
- "has-[:focus-visible]:ring-accent/60 relative isolate flex-1 cursor-pointer text-center whitespace-nowrap transition-colors has-[:focus-visible]:ring-2",
111
- segmentLabelClasses[size].replace("whitespace-nowrap", ""),
112
- segmentRadius[size],
113
- selected
114
- ? "text-label font-semibold"
115
- : "text-label-secondary hover:text-label font-medium",
116
- )}
117
- >
118
- <input
119
- type="radio"
120
- name={id}
121
- value={option.value}
122
- checked={selected}
123
- onChange={() => {
124
- haptic("selection");
125
- onChange(option.value);
126
- }}
127
- className="sr-only"
128
- />
129
- {selected && (
130
- <motion.span
131
- layoutId={`segment-${id}`}
132
- className={cn(
133
- "bg-elevated absolute inset-0 -z-10 shadow-[0_0_0_0.5px_rgb(0_0_0/0.06),0_1px_2px_rgb(0_0_0/0.08),0_3px_8px_-2px_rgb(0_0_0/0.10)]",
134
- segmentRadius[size],
135
- )}
136
- transition={reducedMotion ? { duration: 0 } : spring.snappy}
137
- />
138
- )}
139
- {option.label}
140
- </label>
141
- );
142
- })}
143
- </fieldset>
144
- ) : (
145
- <Picker<T>
146
- label={label}
147
- value={value}
148
- options={options}
149
- onChange={onChange}
150
- searchable={false}
151
- className={fallbackPickerSizes[size]}
152
- size={size === "sm" ? "sm" : size === "lg" ? "lg" : "md"}
153
- />
154
- )}
155
- </div>
156
- );
157
- }
@@ -1,82 +0,0 @@
1
- import { FLOATING_LAYER, ownsFloatingLayer } from "../../lib/floating-layers";
2
-
3
- const surfaces: HTMLElement[] = [];
4
- const isolated = new Map<HTMLElement, boolean>();
5
- let overflow = "";
6
- let overflowPriority = "";
7
-
8
- function restoreBackground() {
9
- for (const [element, inert] of isolated) element.inert = inert;
10
- isolated.clear();
11
- }
12
-
13
- function isolateBackground() {
14
- restoreBackground();
15
- const surface = surfaces.at(-1);
16
- if (!surface) return;
17
- const roots = [surface.parentElement ?? surface];
18
- for (const layer of document.querySelectorAll<HTMLElement>(
19
- `[${FLOATING_LAYER}]`,
20
- )) {
21
- if (ownsFloatingLayer(surface, layer)) roots.push(layer);
22
- }
23
- const visit = (parent: HTMLElement) => {
24
- for (const child of parent.children) {
25
- if (!(child instanceof HTMLElement)) continue;
26
- if (roots.includes(child)) continue;
27
- if (roots.some((root) => child.contains(root))) {
28
- visit(child);
29
- } else if (!child.matches("script, style, link")) {
30
- isolated.set(child, child.inert);
31
- child.inert = true;
32
- }
33
- }
34
- };
35
- visit(document.body);
36
- }
37
-
38
- /** Keeps nested sheets and their portaled controls above an inactive background. */
39
- export function enterModalEnvironment(surface: HTMLElement): () => void {
40
- if (!surfaces.length) {
41
- overflow = document.body.style.getPropertyValue("overflow");
42
- overflowPriority = document.body.style.getPropertyPriority("overflow");
43
- document.body.style.setProperty("overflow", "hidden");
44
- }
45
- surfaces.push(surface);
46
- isolateBackground();
47
- const preventBackgroundScroll = (event: WheelEvent | TouchEvent) => {
48
- if (surfaces.at(-1) !== surface) return;
49
- const target = event.target;
50
- if (
51
- target instanceof Element &&
52
- (surface.contains(target) || ownsFloatingLayer(surface, target))
53
- )
54
- return;
55
- event.preventDefault();
56
- };
57
- document.addEventListener("wheel", preventBackgroundScroll, {
58
- passive: false,
59
- });
60
- document.addEventListener("touchmove", preventBackgroundScroll, {
61
- passive: false,
62
- });
63
- const observer = new MutationObserver(() => {
64
- if (surfaces.at(-1) === surface) isolateBackground();
65
- });
66
- observer.observe(document.body, {
67
- childList: true,
68
- subtree: true,
69
- });
70
- return () => {
71
- observer.disconnect();
72
- document.removeEventListener("wheel", preventBackgroundScroll);
73
- document.removeEventListener("touchmove", preventBackgroundScroll);
74
- surfaces.splice(surfaces.indexOf(surface), 1);
75
- isolateBackground();
76
- if (!surfaces.length) {
77
- if (overflow)
78
- document.body.style.setProperty("overflow", overflow, overflowPriority);
79
- else document.body.style.removeProperty("overflow");
80
- }
81
- };
82
- }
@@ -1,62 +0,0 @@
1
- import { type ReactNode, useLayoutEffect, useRef, useState } from "react";
2
- import { createPortal } from "react-dom";
3
-
4
- /** Escape transformed page layers while retaining the source's scoped appearance. */
5
- export function SheetPortal({ children }: { children: ReactNode }) {
6
- const source = useRef<HTMLSpanElement>(null);
7
- const [host, setHost] = useState<HTMLDivElement | null>(null);
8
- useLayoutEffect(() => {
9
- const marker = source.current;
10
- if (!marker) return;
11
- const document = marker.ownerDocument;
12
- const layer = document.createElement("div");
13
- layer.dataset.passuiOverlay = "";
14
- layer.style.display = "contents";
15
- const attributes = ["data-theme", "data-accent", "data-os", "dir"];
16
- let properties = new Set<string>();
17
- const inherit = () => {
18
- for (const name of attributes) {
19
- const value = marker.closest(`[${name}]`)?.getAttribute(name);
20
- if (value === null || value === undefined) layer.removeAttribute(name);
21
- else layer.setAttribute(name, value);
22
- }
23
- const computed = getComputedStyle(marker);
24
- const next = new Set<string>();
25
- for (const name of computed) {
26
- if (!name.startsWith("--")) continue;
27
- next.add(name);
28
- layer.style.setProperty(name, computed.getPropertyValue(name));
29
- }
30
- for (const name of properties)
31
- if (!next.has(name)) layer.style.removeProperty(name);
32
- properties = next;
33
- layer.style.colorScheme = computed.colorScheme;
34
- layer.style.fontFamily = computed.fontFamily;
35
- layer.style.direction = computed.direction;
36
- };
37
- inherit();
38
- document.body.appendChild(layer);
39
- setHost(layer);
40
- const observer = new MutationObserver(inherit);
41
- for (
42
- let ancestor = marker.parentElement;
43
- ancestor;
44
- ancestor = ancestor.parentElement
45
- ) {
46
- observer.observe(ancestor, {
47
- attributes: true,
48
- attributeFilter: [...attributes, "style", "class"],
49
- });
50
- }
51
- return () => {
52
- observer.disconnect();
53
- layer.remove();
54
- };
55
- }, []);
56
- return (
57
- <>
58
- <span ref={source} hidden aria-hidden="true" />
59
- {host && createPortal(children, host)}
60
- </>
61
- );
62
- }
@@ -1,165 +0,0 @@
1
- import { AnimatePresence, motion, useReducedMotion } from "motion/react";
2
- import { type ReactNode, useRef } from "react";
3
- import { useVisualViewport } from "../../hooks/use-visual-viewport";
4
- import { cn } from "../../lib/class-names";
5
- import { contentCrossfade, spring, zoomReveal } from "../../motion/transitions";
6
- import { SheetPortal } from "./sheet-portal";
7
- import { useSheetFocus } from "./use-sheet-focus";
8
-
9
- export type SheetPlacement = "adaptive" | "center";
10
- export type SheetSize = "sm" | "md" | "lg";
11
-
12
- const outerPaddings: Record<SheetSize, string> = {
13
- sm: "p-4",
14
- md: "p-6",
15
- lg: "p-8",
16
- };
17
- const panelMaxWidths: Record<SheetSize, string> = {
18
- sm: "max-w-sm",
19
- md: "max-w-[560px]",
20
- lg: "max-w-2xl",
21
- };
22
-
23
- export interface SheetProps {
24
- /** Controls whether the sheet is presented. */
25
- open: boolean;
26
- /** Called on Escape or an outside press. */
27
- onClose: () => void;
28
- /** Allow tapping the backdrop to close. Escape still calls onClose. @default true */
29
- dismissOnOutsidePress?: boolean;
30
- /** Read out by screen readers as the sheet's name. */
31
- label: string;
32
- /** ID of a visible heading to use instead of label for the accessible name. */
33
- labelledBy?: string;
34
- /** `adaptive` rises from the bottom on phones; `center` always floats. @default "adaptive" */
35
- placement?: SheetPlacement;
36
- /** Outer padding and panel max-width. @default "md" */
37
- size?: SheetSize;
38
- className?: string;
39
- children: ReactNode;
40
- }
41
-
42
- /**
43
- * A modal card: rises from the bottom edge on phones and floats in the
44
- * middle on larger screens. Escape or a tap outside closes it.
45
- */
46
- export function Sheet({ open, ...props }: SheetProps) {
47
- return (
48
- <AnimatePresence>
49
- {open && (
50
- <SheetPortal>
51
- <OpenSheet {...props} />
52
- </SheetPortal>
53
- )}
54
- </AnimatePresence>
55
- );
56
- }
57
-
58
- function OpenSheet({
59
- onClose,
60
- dismissOnOutsidePress = true,
61
- label,
62
- labelledBy,
63
- placement = "adaptive",
64
- size = "md",
65
- className,
66
- children,
67
- }: Omit<SheetProps, "open">) {
68
- const panel = useRef<HTMLDivElement>(null);
69
- const reducedMotion = useReducedMotion();
70
- const viewport = useVisualViewport();
71
- useSheetFocus(panel, onClose);
72
-
73
- return (
74
- <div
75
- className={cn(
76
- "fixed inset-0 z-[65] flex justify-center",
77
- placement === "center"
78
- ? cn("items-center", outerPaddings[size])
79
- : cn("items-end sm:items-center", `sm:${outerPaddings[size]}`),
80
- )}
81
- style={
82
- viewport
83
- ? {
84
- top: viewport.top,
85
- left: viewport.left,
86
- width: viewport.width,
87
- height: viewport.height,
88
- bottom: "auto",
89
- right: "auto",
90
- }
91
- : undefined
92
- }
93
- >
94
- <motion.div
95
- aria-hidden="true"
96
- className="absolute inset-0 bg-black/30 backdrop-blur-md"
97
- initial={{ opacity: 0 }}
98
- animate={{ opacity: 1 }}
99
- exit={{ opacity: 0 }}
100
- onClick={dismissOnOutsidePress ? onClose : undefined}
101
- />
102
- <motion.div
103
- ref={panel}
104
- role="dialog"
105
- aria-modal="true"
106
- aria-label={labelledBy ? undefined : label}
107
- aria-labelledby={labelledBy}
108
- tabIndex={-1}
109
- className={cn(
110
- "glass-menu relative flex w-full flex-col overflow-hidden",
111
- "max-h-[92%]",
112
- panelMaxWidths[size],
113
- placement === "center"
114
- ? "rounded-sheet"
115
- : "rounded-t-sheet sm:rounded-sheet",
116
- className,
117
- )}
118
- style={{
119
- transformOrigin:
120
- placement === "center" ? "center center" : "bottom center",
121
- }}
122
- initial={
123
- reducedMotion
124
- ? { opacity: 0 }
125
- : placement === "center"
126
- ? zoomReveal.initial
127
- : { y: 40, opacity: 0, scale: 0.96 }
128
- }
129
- animate={
130
- reducedMotion
131
- ? { opacity: 1 }
132
- : placement === "center"
133
- ? zoomReveal.animate
134
- : { y: 0, opacity: 1, scale: 1 }
135
- }
136
- exit={
137
- reducedMotion
138
- ? { opacity: 0 }
139
- : placement === "center"
140
- ? zoomReveal.exit
141
- : { y: 30, opacity: 0, scale: 0.98 }
142
- }
143
- transition={
144
- reducedMotion
145
- ? { duration: 0 }
146
- : placement === "center"
147
- ? zoomReveal.transition
148
- : { ...spring.bouncy, opacity: { duration: 0.18 } }
149
- }
150
- >
151
- <motion.div
152
- className="flex min-h-0 flex-1 flex-col overflow-y-auto"
153
- initial={reducedMotion ? false : contentCrossfade.initial}
154
- animate={reducedMotion ? undefined : contentCrossfade.animate}
155
- exit={reducedMotion ? undefined : contentCrossfade.exit}
156
- transition={
157
- reducedMotion ? { duration: 0 } : contentCrossfade.transition
158
- }
159
- >
160
- {children}
161
- </motion.div>
162
- </motion.div>
163
- </div>
164
- );
165
- }
@@ -1,109 +0,0 @@
1
- import {
2
- type RefObject,
3
- useEffect,
4
- useLayoutEffect,
5
- useRef,
6
- useState,
7
- } from "react";
8
- import { ownsFloatingLayer } from "../../lib/floating-layers";
9
- import { enterModalEnvironment } from "./modal-environment";
10
-
11
- const sheets: HTMLElement[] = [];
12
- const focusableSelector = [
13
- "a[href]",
14
- "button",
15
- "input:not([type=hidden])",
16
- "select",
17
- "textarea",
18
- "[tabindex]",
19
- "[contenteditable=true]",
20
- ].join(",");
21
-
22
- function focusableElements(panel: HTMLElement): HTMLElement[] {
23
- return Array.from(
24
- panel.querySelectorAll<HTMLElement>(focusableSelector),
25
- ).filter(
26
- (element) =>
27
- element.tabIndex >= 0 &&
28
- !element.matches(":disabled") &&
29
- !element.closest("[inert]") &&
30
- element.getClientRects().length > 0 &&
31
- getComputedStyle(element).visibility !== "hidden",
32
- );
33
- }
34
-
35
- /** Keeps keyboard focus in the foremost sheet, including its floating pickers. */
36
- export function useSheetFocus(
37
- panel: RefObject<HTMLDivElement | null>,
38
- onClose: () => void,
39
- ) {
40
- // Capture before children mount, since a child may use autoFocus.
41
- const [opener] = useState(() =>
42
- typeof document === "undefined" ? null : document.activeElement,
43
- );
44
- const close = useRef(onClose);
45
- useEffect(() => {
46
- close.current = onClose;
47
- }, [onClose]);
48
-
49
- useLayoutEffect(() => {
50
- const surface = panel.current;
51
- if (!surface) return;
52
- sheets.push(surface);
53
- const foremost = () => sheets.at(-1) === surface;
54
- const focusFirst = () => (focusableElements(surface)[0] ?? surface).focus();
55
- const inFloatingLayer = (element: Element | null) =>
56
- ownsFloatingLayer(surface, element);
57
- const belongsToSheet = (element: Element | null) =>
58
- surface.contains(element) || inFloatingLayer(element);
59
-
60
- if (!surface.contains(document.activeElement))
61
- surface.focus({ preventScroll: true });
62
- const leaveModalEnvironment = enterModalEnvironment(surface);
63
-
64
- const onFocus = (event: FocusEvent) => {
65
- if (foremost() && !belongsToSheet(event.target as Element | null))
66
- focusFirst();
67
- };
68
- const onKey = (event: KeyboardEvent) => {
69
- if (!foremost() || event.defaultPrevented) return;
70
- if (event.key === "Escape") {
71
- // Floating controls handle their own Escape before the sheet.
72
- if (inFloatingLayer(document.activeElement)) return;
73
- event.preventDefault();
74
- event.stopPropagation();
75
- close.current();
76
- }
77
- if (event.key !== "Tab") return;
78
- const controls = focusableElements(surface);
79
- const first = controls[0] ?? surface;
80
- const last = controls.at(-1) ?? surface;
81
- const active = document.activeElement;
82
- if (
83
- event.shiftKey &&
84
- (active === surface || active === first || !surface.contains(active))
85
- ) {
86
- event.preventDefault();
87
- last.focus();
88
- } else if (
89
- !event.shiftKey &&
90
- (active === last || !surface.contains(active) || active === surface)
91
- ) {
92
- event.preventDefault();
93
- first.focus();
94
- }
95
- };
96
-
97
- document.addEventListener("focusin", onFocus);
98
- window.addEventListener("keydown", onKey);
99
- return () => {
100
- const wasForemost = foremost();
101
- sheets.splice(sheets.indexOf(surface), 1);
102
- document.removeEventListener("focusin", onFocus);
103
- window.removeEventListener("keydown", onKey);
104
- leaveModalEnvironment();
105
- if (wasForemost && opener instanceof HTMLElement && opener.isConnected)
106
- opener.focus();
107
- };
108
- }, [panel, opener]);
109
- }
@@ -1,102 +0,0 @@
1
- import { useId, type ReactNode } from "react";
2
- import { cn } from "../../lib/class-names";
3
-
4
- export interface SidebarSectionProps {
5
- /** Visible heading for this group of navigation rows. */
6
- title: string;
7
- children: ReactNode;
8
- }
9
-
10
- export interface SidebarItemContentProps {
11
- icon?: ReactNode;
12
- /** Optional trailing count. */
13
- count?: number;
14
- /** Matches the router link's active state. */
15
- active?: boolean;
16
- children: ReactNode;
17
- }
18
-
19
- export function SidebarSection({
20
- title,
21
- children,
22
- size = "md",
23
- }: SidebarSectionProps & { size?: SidebarSize }) {
24
- const headingId = useId();
25
- return (
26
- <section aria-labelledby={headingId} className="flex flex-col gap-0.5">
27
- <h2 id={headingId} className={sidebarHeadingSizes[size]}>
28
- {title}
29
- </h2>
30
- {children}
31
- </section>
32
- );
33
- }
34
-
35
- /** Classes for a sidebar row; apply to the app's router link. */
36
- export type SidebarDensity = "regular" | "compact";
37
- export type SidebarSize = "sm" | "md" | "lg";
38
-
39
- const sidebarItemSizes: Record<SidebarSize, string> = {
40
- sm: "min-h-8 rounded-lg px-2 py-1 text-footnote [@media(pointer:coarse)]:min-h-10",
41
- md: "rounded-2xl px-2.5 py-[7px] text-subheadline",
42
- lg: "rounded-2xl px-3 py-2.5 text-body [@media(pointer:coarse)]:min-h-13",
43
- };
44
- const sidebarHeadingSizes: Record<SidebarSize, string> = {
45
- sm: "px-2 pb-1 text-caption2 font-semibold text-label-tertiary",
46
- md: "px-2.5 pb-1.5 text-caption font-semibold text-label-tertiary",
47
- lg: "px-3 pb-2 text-subheadline font-semibold text-label-tertiary",
48
- };
49
- const sidebarCountSizes: Record<SidebarSize, string> = {
50
- sm: "text-caption2 tabular-nums",
51
- md: "text-footnote tabular-nums",
52
- lg: "text-subheadline tabular-nums",
53
- };
54
-
55
- export function sidebarItemClass(
56
- active?: boolean,
57
- density: SidebarDensity = "regular",
58
- size?: SidebarSize,
59
- ): string {
60
- const resolved = size ?? (density === "compact" ? "sm" : "md");
61
- return cn(
62
- "group text-label duration-fast focus-visible:outline-accent-text flex w-full items-center gap-2.5 no-underline transition-colors focus-visible:outline-2 focus-visible:outline-offset-2",
63
- sidebarItemSizes[resolved],
64
- active
65
- ? "bg-fill font-medium"
66
- : "text-label-secondary hover:bg-fill/70 hover:text-label font-normal",
67
- );
68
- }
69
-
70
- export function SidebarItemContent({
71
- icon,
72
- count,
73
- active,
74
- size = "md",
75
- children,
76
- }: SidebarItemContentProps & { size?: SidebarSize }) {
77
- return (
78
- <>
79
- {icon && (
80
- <span
81
- className={cn(
82
- "flex transition-colors",
83
- active ? "text-accent-text" : "text-label-secondary",
84
- )}
85
- >
86
- {icon}
87
- </span>
88
- )}
89
- <span className="grow truncate">{children}</span>
90
- {count !== undefined && (
91
- <span
92
- className={cn(
93
- sidebarCountSizes[size],
94
- active ? "text-accent-text" : "text-label-tertiary",
95
- )}
96
- >
97
- {count}
98
- </span>
99
- )}
100
- </>
101
- );
102
- }