@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,91 +0,0 @@
1
- import { useEffect, useRef } from "react";
2
- import { useMediaQuery } from "../../hooks/use-media-query";
3
-
4
- /** Counts at a place retain carries: the tens column of 1284 targets 128. */
5
- export function digitAt(count: number) {
6
- return ((Math.floor(count) % 10) + 10) % 10;
7
- }
8
-
9
- export function advanceDigit(
10
- position: number,
11
- velocity: number,
12
- target: number,
13
- frames: number,
14
- ) {
15
- const nextVelocity =
16
- (velocity + (target - position) * 0.16 * frames) * 0.7 ** frames;
17
- return { position: position + nextVelocity * frames, velocity: nextVelocity };
18
- }
19
-
20
- /** Three recycled cells keep the strip continuous through either side of zero. */
21
- export function RollingDigit({
22
- count,
23
- place,
24
- }: {
25
- count: number;
26
- place: number;
27
- }) {
28
- const strip = useRef<HTMLSpanElement>(null);
29
- const state = useRef({ position: count, velocity: 0 });
30
- const reduced = useMediaQuery("(prefers-reduced-motion: reduce)");
31
- useEffect(() => {
32
- let frame = 0;
33
- let previous = 0;
34
- let due = 0;
35
- const paint = (position: number, velocity: number) => {
36
- const node = strip.current;
37
- if (!node) return;
38
- const base = Math.floor(position);
39
- for (let index = 0; index < node.children.length; index++) {
40
- (node.children[index] as HTMLElement).textContent = String(
41
- digitAt(base + index - 1),
42
- );
43
- }
44
- node.style.transform = `translateY(${(-(position - base + 1) * 100) / 3}%)`;
45
- node.style.filter = `blur(${Math.min(2, Math.abs(velocity) * 1.4)}px)`;
46
- };
47
- if (reduced) {
48
- state.current = { position: count, velocity: 0 };
49
- paint(count, 0);
50
- return;
51
- }
52
- const tick = (now: number) => {
53
- if (!due) due = now + place * 28;
54
- const frames = previous ? Math.min((now - previous) / (1000 / 60), 2) : 1;
55
- previous = now;
56
- if (now >= due) {
57
- state.current = advanceDigit(
58
- state.current.position,
59
- state.current.velocity,
60
- count,
61
- frames,
62
- );
63
- if (
64
- Math.abs(count - state.current.position) < 0.002 &&
65
- Math.abs(state.current.velocity) < 0.002
66
- ) {
67
- state.current = { position: count, velocity: 0 };
68
- paint(count, 0);
69
- return;
70
- }
71
- paint(state.current.position, state.current.velocity);
72
- }
73
- frame = requestAnimationFrame(tick);
74
- };
75
- frame = requestAnimationFrame(tick);
76
- return () => cancelAnimationFrame(frame);
77
- }, [count, place, reduced]);
78
- return (
79
- <span className="relative inline-block h-[1.5em] w-[1ch] overflow-hidden align-middle">
80
- <span
81
- ref={strip}
82
- className="absolute inset-x-0 top-0 flex flex-col leading-[1.5em]"
83
- style={{ transform: "translateY(-33.333333%)" }}
84
- >
85
- <span>{digitAt(count - 1)}</span>
86
- <span>{digitAt(count)}</span>
87
- <span>{digitAt(count + 1)}</span>
88
- </span>
89
- </span>
90
- );
91
- }
@@ -1,136 +0,0 @@
1
- import { useId } from "react";
2
- import { Button, type ButtonSize } from "../button/button";
3
- import { cn } from "../../lib/class-names";
4
- import { clampRange, stepRange } from "../../lib/range-value";
5
- import { RollingDigit } from "./rolling-digit";
6
-
7
- export type StepperSize = "sm" | "md" | "lg";
8
-
9
- const labelText: Record<StepperSize, string> = {
10
- sm: "min-w-0 text-footnote text-label",
11
- md: "min-w-0 text-subheadline text-label",
12
- lg: "min-w-0 text-body text-label",
13
- };
14
- const outputText: Record<StepperSize, string> = {
15
- sm: "text-footnote tabular-nums text-label",
16
- md: "text-subheadline tabular-nums text-label",
17
- lg: "text-body tabular-nums text-label",
18
- };
19
- const buttonSizes: Record<StepperSize, { size: ButtonSize; cls: string }> = {
20
- sm: {
21
- size: "icon-sm",
22
- cls: "size-7 rounded-none text-subheadline text-accent-text [@media(pointer:coarse)]:size-10",
23
- },
24
- md: {
25
- size: "icon",
26
- cls: "size-8 rounded-none text-title3 text-accent-text [@media(pointer:coarse)]:size-11",
27
- },
28
- lg: {
29
- size: "icon-lg",
30
- cls: "size-9 rounded-none text-title2 text-accent-text [@media(pointer:coarse)]:size-12",
31
- },
32
- };
33
-
34
- export interface StepperProps {
35
- value: number;
36
- onChange: (value: number) => void;
37
- label: string;
38
- /** Localized accessible names for each action. */
39
- labels: { decrement: string; increment: string };
40
- min?: number;
41
- max?: number;
42
- step?: number;
43
- disabled?: boolean;
44
- className?: string;
45
- /** Formats the displayed value. */
46
- formatValue?: (value: number) => string;
47
- /** Label, output and +/- button scale. @default "md" */
48
- size?: StepperSize;
49
- }
50
-
51
- /** Discrete increments with disabled boundary actions and a spoken value. */
52
- export function Stepper({
53
- value,
54
- onChange,
55
- label,
56
- labels,
57
- min = 0,
58
- max = 100,
59
- step = 1,
60
- disabled = false,
61
- className,
62
- formatValue,
63
- size = "md",
64
- }: StepperProps) {
65
- const id = useId();
66
- const upper = Math.max(min, max);
67
- const current = clampRange(value, min, upper);
68
- const decrement = stepRange(current, -1, min, upper, step > 0 ? step : 1);
69
- const increment = stepRange(current, 1, min, upper, step > 0 ? step : 1);
70
- const displayed = formatValue?.(current) ?? String(current);
71
- const digits = displayed.replace(/[^0-9]/g, "");
72
- let digitIndex = 0;
73
-
74
- return (
75
- <div
76
- className={cn(
77
- "flex min-w-0 items-center justify-between gap-3",
78
- className,
79
- )}
80
- >
81
- <span id={id} className={labelText[size]}>
82
- {label}
83
- </span>
84
- <div className="flex shrink-0 items-center gap-3">
85
- <output
86
- aria-live="polite"
87
- aria-labelledby={id}
88
- className={outputText[size]}
89
- >
90
- <span aria-hidden="true" className="inline-flex items-center">
91
- {Array.from(displayed).map((character) => {
92
- if (!/[0-9]/.test(character))
93
- return <span key={`sep-${character}`}>{character}</span>;
94
- const prefix = digits.slice(0, ++digitIndex);
95
- const place = digits.length - digitIndex;
96
- return (
97
- <RollingDigit
98
- key={`place-${place}`}
99
- count={Number(prefix)}
100
- place={place}
101
- />
102
- );
103
- })}
104
- </span>
105
- <span className="sr-only">{displayed}</span>
106
- </output>
107
- <div className="divide-separator bg-fill flex items-center divide-x overflow-hidden rounded-lg">
108
- <Button
109
- type="button"
110
- variant="ghost"
111
- size={buttonSizes[size].size}
112
- aria-label={labels.decrement}
113
- aria-describedby={id}
114
- disabled={disabled || decrement === current}
115
- onClick={() => onChange(decrement)}
116
- className={buttonSizes[size].cls}
117
- >
118
- −
119
- </Button>
120
- <Button
121
- type="button"
122
- variant="ghost"
123
- size={buttonSizes[size].size}
124
- aria-label={labels.increment}
125
- aria-describedby={id}
126
- disabled={disabled || increment === current}
127
- onClick={() => onChange(increment)}
128
- className={buttonSizes[size].cls}
129
- >
130
- +
131
- </Button>
132
- </div>
133
- </div>
134
- </div>
135
- );
136
- }
@@ -1,138 +0,0 @@
1
- import { motion } from "motion/react";
2
- import { useId } from "react";
3
- import { CheckIcon } from "../../icons/icons";
4
- import { cn } from "../../lib/class-names";
5
- import { haptic } from "../../lib/haptics";
6
- import { spring } from "../../motion/transitions";
7
-
8
- export interface SwatchPickerOption<T extends string> {
9
- value: T;
10
- label: string;
11
- /** Swatch background color. */
12
- color: string;
13
- /** Color of the selected checkmark. */
14
- ink: string;
15
- }
16
-
17
- export type SwatchPickerSize = "sm" | "md" | "lg";
18
-
19
- const swatchSizes: Record<SwatchPickerSize, string> = {
20
- sm: "size-6",
21
- md: "size-8",
22
- lg: "size-10",
23
- };
24
- const checkSizes: Record<SwatchPickerSize, number> = {
25
- sm: 13,
26
- md: 16,
27
- lg: 19,
28
- };
29
- const captionText: Record<SwatchPickerSize, string> = {
30
- sm: "text-caption2",
31
- md: "text-caption2",
32
- lg: "text-caption",
33
- };
34
- const fieldsetGaps: Record<SwatchPickerSize, string> = {
35
- sm: "gap-2",
36
- md: "gap-3",
37
- lg: "gap-4",
38
- };
39
- const labelGaps: Record<SwatchPickerSize, string> = {
40
- sm: "gap-1",
41
- md: "gap-1.5",
42
- lg: "gap-2",
43
- };
44
-
45
- export interface SwatchPickerProps<T extends string> {
46
- value: T;
47
- options: ReadonlyArray<SwatchPickerOption<T>>;
48
- onChange: (value: T) => void;
49
- /** Accessible name for the group. */
50
- label: string;
51
- /** Custom classes for the swatch container. */
52
- className?: string;
53
- /** Swatch diameter, check icon and caption scale. @default "md" */
54
- size?: SwatchPickerSize;
55
- }
56
-
57
- /** Colour swatches with a check on the chosen one. */
58
- export function SwatchPicker<T extends string>({
59
- value,
60
- options,
61
- onChange,
62
- label,
63
- className,
64
- size = "md",
65
- }: SwatchPickerProps<T>) {
66
- const name = useId();
67
- return (
68
- <fieldset className={cn("flex flex-wrap", fieldsetGaps[size], className)}>
69
- <legend className="sr-only">{label}</legend>
70
- {options.map((option) => {
71
- const selected = option.value === value;
72
- return (
73
- <label
74
- key={option.value}
75
- className={cn(
76
- "group flex cursor-pointer flex-col items-center",
77
- labelGaps[size],
78
- )}
79
- >
80
- <input
81
- type="radio"
82
- name={name}
83
- value={option.value}
84
- checked={selected}
85
- onChange={() => {
86
- haptic("selection");
87
- onChange(option.value);
88
- }}
89
- className="peer sr-only"
90
- />
91
- <span
92
- className={cn(
93
- "ring-offset-elevated duration-fast peer-focus-visible:ring-accent flex items-center justify-center rounded-full ring-offset-1 transition-[box-shadow,transform] group-active:scale-95 peer-focus-visible:ring-2",
94
- swatchSizes[size],
95
- selected
96
- ? "ring-label/70 ring-[1.5px]"
97
- : "group-hover:ring-separator ring-0 group-hover:ring-[1.5px]",
98
- )}
99
- style={{
100
- background: option.color,
101
- }}
102
- >
103
- {selected && (
104
- <motion.span
105
- initial={{
106
- scale: 0.4,
107
- opacity: 0,
108
- }}
109
- animate={{
110
- scale: 1,
111
- opacity: 1,
112
- }}
113
- transition={spring.bouncy}
114
- >
115
- <CheckIcon
116
- size={checkSizes[size]}
117
- strokeWidth={2.6}
118
- style={{
119
- color: option.ink,
120
- }}
121
- />
122
- </motion.span>
123
- )}
124
- </span>
125
- <span
126
- className={cn(
127
- captionText[size],
128
- selected ? "text-label font-semibold" : "text-label-tertiary",
129
- )}
130
- >
131
- {option.label}
132
- </span>
133
- </label>
134
- );
135
- })}
136
- </fieldset>
137
- );
138
- }
@@ -1,182 +0,0 @@
1
- import { motion, useReducedMotion } from "motion/react";
2
- import { Fragment, type ReactNode, useId } from "react";
3
- import { useMinimizeOnScroll } from "../../hooks/use-minimize-on-scroll";
4
- import { SearchIcon } from "../../icons/icons";
5
- import { cn } from "../../lib/class-names";
6
- import { spring } from "../../motion/transitions";
7
-
8
- export interface TabBarTab<Id extends string = string> {
9
- id: Id;
10
- label: string;
11
- icon: ReactNode;
12
- }
13
-
14
- /** What a tab's link receives; spread it onto the router's own link. */
15
- export interface TabBarLinkProps {
16
- className: string;
17
- "aria-current": "page" | undefined;
18
- onClick: () => void;
19
- children: ReactNode;
20
- }
21
-
22
- export type TabBarMinimizeBehavior = "platform" | "scroll" | "never";
23
- export type TabBarSize = "sm" | "md" | "lg";
24
-
25
- const tabHeights: Record<TabBarSize, string> = {
26
- sm: "h-9",
27
- md: "h-11",
28
- lg: "h-13",
29
- };
30
- const tabMinimizedWidths: Record<TabBarSize, string> = {
31
- sm: "w-9",
32
- md: "w-11",
33
- lg: "w-13",
34
- };
35
- const tabText: Record<TabBarSize, string> = {
36
- sm: "text-caption",
37
- md: "text-caption2",
38
- lg: "text-subheadline",
39
- };
40
- const searchButtonSizes: Record<TabBarSize, string> = {
41
- sm: "size-10",
42
- md: "size-12",
43
- lg: "size-14",
44
- };
45
- const searchIconSizes: Record<TabBarSize, number> = {
46
- sm: 17,
47
- md: 19,
48
- lg: 21,
49
- };
50
-
51
- export interface TabBarProps<Tab extends TabBarTab> {
52
- /** `platform` follows the platform, `scroll` always minimizes, `never` stays expanded. @default "platform" */
53
- minimizeBehavior?: TabBarMinimizeBehavior;
54
- tabs: readonly Tab[];
55
- /** Active tab ID, or null for a destination outside the bar. */
56
- active: Tab["id"] | null;
57
- /** Renders your router's link with the supplied appearance and accessibility props. */
58
- renderLink: (tab: Tab, props: TabBarLinkProps) => ReactNode;
59
- search?: { label: string; onPress: () => void };
60
- /** Accessible name for the navigation. */
61
- label: string;
62
- /** Tab height, label text, minimized width and search button diameter. @default "md" */
63
- size?: TabBarSize;
64
- className?: string;
65
- }
66
-
67
- /**
68
- * The app's main places a thumb's reach away, drawn as iOS 26 draws them: a
69
- * floating glass capsule of tabs, with Search as its own round button at the
70
- * trailing end. Scrolling down through content shrinks the capsule to the
71
- * current tab; scrolling back up, or a tap, restores it. Android shares the
72
- * glass, but its bar stays full size, as Android's own bars do.
73
- *
74
- * Links stay the app's own (`renderLink`), so the bar works with any router.
75
- */
76
- export function TabBar<Tab extends TabBarTab>({
77
- tabs,
78
- active,
79
- renderLink,
80
- search,
81
- label,
82
- className,
83
- size = "md",
84
- minimizeBehavior = "platform",
85
- }: TabBarProps<Tab>) {
86
- // Scopes the sliding selection to this bar, so two bars on one
87
- // screen (a docs page, a split view) never trade their highlight.
88
- const selectionId = `${useId()}-tab-selection`;
89
- const reducedMotion = useReducedMotion();
90
- const [scrolledAway, setScrolledAway] = useMinimizeOnScroll();
91
- // Platform behavior keeps Android expanded; apps can opt into scroll minimization.
92
- const minimized =
93
- scrolledAway &&
94
- active !== null &&
95
- minimizeBehavior !== "never" &&
96
- (minimizeBehavior === "scroll" || !onAndroid());
97
- return (
98
- <nav
99
- aria-label={label}
100
- className={cn(
101
- "fixed inset-x-4 bottom-[max(14px,env(safe-area-inset-bottom))] z-30 flex items-center gap-3",
102
- className,
103
- )}
104
- >
105
- <motion.div
106
- layout={!reducedMotion}
107
- transition={reducedMotion ? { duration: 0 } : spring.smooth}
108
- // A tap on the shrunken capsule brings every tab back.
109
- onClickCapture={(event) => {
110
- if (!minimized) return;
111
- event.preventDefault();
112
- event.stopPropagation();
113
- setScrolledAway(false);
114
- }}
115
- className={cn(
116
- "glass flex min-w-0 items-center rounded-full p-0.5",
117
- minimized ? "grow-0" : "grow",
118
- )}
119
- >
120
- {tabs.map((tab) => {
121
- const current = tab.id === active;
122
- if (minimized && !current) return null;
123
- return (
124
- <Fragment key={tab.id}>
125
- {renderLink(tab, {
126
- "aria-current": current ? "page" : undefined,
127
- // Switching tabs is silent, as on Apple and Android: no haptic.
128
- onClick: () => {},
129
- className: cn(
130
- "duration-fast relative isolate flex min-w-0 flex-col items-center justify-center gap-0.5 rounded-full font-semibold tracking-[0.01em] no-underline transition-[color,transform] active:scale-[0.94]",
131
- tabHeights[size],
132
- tabText[size],
133
- minimized ? tabMinimizedWidths[size] : "flex-1 px-1",
134
- current ? "text-accent-text" : "text-label-secondary",
135
- ),
136
- children: (
137
- <>
138
- {current && (
139
- <motion.span
140
- layoutId={selectionId}
141
- className="glass-lens absolute inset-0 -z-10 rounded-full"
142
- transition={
143
- reducedMotion ? { duration: 0 } : spring.snappy
144
- }
145
- />
146
- )}
147
- {tab.icon}
148
- <span
149
- className={minimized ? "sr-only" : "max-w-full truncate"}
150
- >
151
- {tab.label}
152
- </span>
153
- </>
154
- ),
155
- })}
156
- </Fragment>
157
- );
158
- })}
159
- </motion.div>
160
- {search && (
161
- <button
162
- type="button"
163
- aria-label={search.label}
164
- onClick={search.onPress}
165
- className={cn(
166
- "glass text-label duration-fast ms-auto flex shrink-0 items-center justify-center rounded-full transition-transform active:scale-[0.92]",
167
- searchButtonSizes[size],
168
- )}
169
- >
170
- <SearchIcon size={searchIconSizes[size]} strokeWidth={2} />
171
- </button>
172
- )}
173
- </nav>
174
- );
175
- }
176
-
177
- function onAndroid() {
178
- return (
179
- typeof document !== "undefined" &&
180
- document.documentElement.dataset.os === "android"
181
- );
182
- }
@@ -1,155 +0,0 @@
1
- import { useId, useRef, useState, type ReactNode } from "react";
2
- import { cn } from "../../lib/class-names";
3
-
4
- export type TabViewAlign = "start" | "center";
5
- export type TabViewSize = "sm" | "md" | "lg";
6
-
7
- const containerGaps: Record<TabViewSize, string> = {
8
- sm: "gap-4",
9
- md: "gap-5",
10
- lg: "gap-6",
11
- };
12
- const tablistClasses: Record<TabViewSize, string> = {
13
- sm: "inline-flex h-7 w-fit max-w-full items-center gap-4 p-[2px]",
14
- md: "inline-flex h-8 w-fit max-w-full items-center gap-5 p-[3px]",
15
- lg: "inline-flex h-10 w-fit max-w-full items-center gap-6 p-[4px]",
16
- };
17
- const tabText: Record<TabViewSize, string> = {
18
- sm: "text-footnote",
19
- md: "text-subheadline",
20
- lg: "text-body",
21
- };
22
- const underlineOffset: Record<TabViewSize, string> = {
23
- sm: "after:bottom-[-4px] after:h-0.5",
24
- md: "after:bottom-[-5px] after:h-0.5",
25
- lg: "after:bottom-[-6px] after:h-1",
26
- };
27
-
28
- export interface TabViewProps<Value extends string> {
29
- /** Available tabs, in keyboard navigation order. */
30
- options: readonly { value: Value; label: string; disabled?: boolean }[];
31
- /** Initial selection when value is not controlled. */
32
- defaultValue: Value;
33
- /** Controlled selection; omit to keep selection inside TabView. */
34
- value?: Value;
35
- onValueChange?: (value: Value) => void;
36
- /** Tab alignment: `start` or `center`. @default "center" */
37
- align?: TabViewAlign;
38
- /** Accessible name for the tab list. */
39
- label: string;
40
- /** Renders the selected tab's panel. */
41
- children: (value: Value) => ReactNode;
42
- /** Tablist height, tab text scale and underline offset. @default "md" */
43
- size?: TabViewSize;
44
- className?: string;
45
- }
46
-
47
- /** Content tabs with native buttons, roving focus and automatic keyboard activation. */
48
- export function TabView<Value extends string>({
49
- options,
50
- defaultValue,
51
- value: controlledValue,
52
- onValueChange,
53
- align = "center",
54
- label,
55
- children,
56
- size = "md",
57
- className,
58
- }: TabViewProps<Value>) {
59
- const id = useId();
60
- const buttons = useRef<(HTMLButtonElement | null)[]>([]);
61
- const [selected, setSelected] = useState(defaultValue);
62
- const current = controlledValue ?? selected;
63
- function select(next: Value) {
64
- if (controlledValue === undefined) setSelected(next);
65
- onValueChange?.(next);
66
- }
67
- const enabled = options.filter((option) => !option.disabled);
68
- const value = enabled.some((option) => option.value === current)
69
- ? current
70
- : enabled[0]?.value;
71
- if (value === undefined) return null;
72
-
73
- return (
74
- <div className={cn("flex w-full flex-col", containerGaps[size], className)}>
75
- <div
76
- role="tablist"
77
- aria-label={label}
78
- className={cn(
79
- tablistClasses[size],
80
- align === "start" ? "self-start" : "mx-auto justify-center",
81
- )}
82
- >
83
- {options.map((option, index) => (
84
- <button
85
- key={option.value}
86
- type="button"
87
- role="tab"
88
- id={`${id}-tab-${index}`}
89
- aria-controls={`${id}-panel-${index}`}
90
- aria-selected={option.value === value}
91
- aria-disabled={option.disabled || undefined}
92
- disabled={option.disabled}
93
- tabIndex={option.value === value ? 0 : -1}
94
- ref={(element) => {
95
- buttons.current[index] = element;
96
- }}
97
- onClick={() => select(option.value)}
98
- onKeyDown={(event) => {
99
- const rtl =
100
- getComputedStyle(event.currentTarget).direction === "rtl";
101
- let next: number;
102
- let step: number;
103
- if (event.key === "Home") {
104
- next = -1;
105
- step = 1;
106
- } else if (event.key === "End") {
107
- next = options.length;
108
- step = -1;
109
- } else if (event.key === "ArrowRight") {
110
- step = rtl ? -1 : 1;
111
- next = index;
112
- } else if (event.key === "ArrowLeft") {
113
- step = rtl ? 1 : -1;
114
- next = index;
115
- } else return;
116
- event.preventDefault();
117
- for (let offset = 0; offset < options.length; offset++) {
118
- next = (next + step + options.length) % options.length;
119
- const option = options[next];
120
- if (!option || option.disabled) continue;
121
- select(option.value);
122
- buttons.current[next]?.focus();
123
- break;
124
- }
125
- }}
126
- className={cn(
127
- "relative inline-flex h-[calc(100%-1px)] shrink-0 items-center justify-center border border-transparent p-0 font-medium whitespace-nowrap",
128
- tabText[size],
129
- "focus-visible:outline-2 focus-visible:outline-offset-2",
130
- "after:absolute after:inset-x-0 after:bg-current",
131
- underlineOffset[size],
132
- option.value === value
133
- ? "after:opacity-100"
134
- : "opacity-60 after:opacity-0 hover:opacity-100",
135
- )}
136
- >
137
- {option.label}
138
- </button>
139
- ))}
140
- </div>
141
- {options.map((option, index) => (
142
- <div
143
- key={option.value}
144
- role="tabpanel"
145
- id={`${id}-panel-${index}`}
146
- aria-labelledby={`${id}-tab-${index}`}
147
- hidden={option.value !== value}
148
- className="w-full outline-offset-4"
149
- >
150
- {option.value === value && children(option.value)}
151
- </div>
152
- ))}
153
- </div>
154
- );
155
- }