@passui/react 0.1.16 → 0.1.19

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 (366) hide show
  1. package/README.md +102 -1
  2. package/dist/types/src/appearance/index.d.ts +2 -0
  3. package/dist/types/src/appearance/platform.d.ts +9 -0
  4. package/dist/types/src/appearance/theme.d.ts +71 -0
  5. package/dist/types/src/components/ambient/ambient.d.ts +12 -0
  6. package/dist/types/src/components/ambient/index.d.ts +1 -0
  7. package/dist/types/src/components/button/button-styles.d.ts +12 -0
  8. package/dist/types/src/components/button/button.d.ts +30 -0
  9. package/dist/types/src/components/button/icon-button.d.ts +10 -0
  10. package/dist/types/src/components/button/pending-spinner.d.ts +5 -0
  11. package/dist/types/src/components/button/use-pending-indicator.d.ts +2 -0
  12. package/dist/types/src/components/chip/chip.d.ts +7 -0
  13. package/dist/types/src/components/compact-date-picker/calendar-month.d.ts +25 -0
  14. package/dist/types/src/components/compact-date-picker/compact-date-picker.d.ts +27 -0
  15. package/dist/types/src/components/compact-time-picker/compact-time-picker.d.ts +26 -0
  16. package/dist/types/src/components/compact-time-picker/time-value.d.ts +18 -0
  17. package/dist/types/src/components/content-view/content-view.d.ts +48 -0
  18. package/dist/types/src/components/content-view/index.d.ts +1 -0
  19. package/dist/types/src/components/context-menu/conceal-menu-source.d.ts +2 -0
  20. package/dist/types/src/components/context-menu/context-menu-host.d.ts +2 -0
  21. package/dist/types/src/components/context-menu/context-menu-store.d.ts +57 -0
  22. package/dist/types/src/components/context-menu/menu-navigation.d.ts +6 -0
  23. package/dist/types/src/components/context-menu/menu-position.d.ts +21 -0
  24. package/dist/types/src/components/context-menu/menu-reveal.d.ts +22 -0
  25. package/dist/types/src/components/context-menu/use-context-menu.d.ts +14 -0
  26. package/dist/types/src/components/conversation/conversation.d.ts +43 -0
  27. package/dist/types/src/components/conversation/index.d.ts +1 -0
  28. package/dist/types/src/components/date-picker/date-picker.d.ts +16 -0
  29. package/dist/types/src/components/date-picker/date-value.d.ts +2 -0
  30. package/dist/types/src/components/dialog/dialog-host.d.ts +6 -0
  31. package/dist/types/src/components/dialog/dialog-store.d.ts +21 -0
  32. package/dist/types/src/components/dialog/dialog.d.ts +30 -0
  33. package/dist/types/src/components/dialog/index.d.ts +1 -0
  34. package/dist/types/src/components/disclosure-group/disclosure-group.d.ts +13 -0
  35. package/dist/types/src/components/divider/divider.d.ts +9 -0
  36. package/dist/types/src/components/inline-disclosure/inline-disclosure.d.ts +15 -0
  37. package/dist/types/src/components/labeled-content/labeled-content.d.ts +19 -0
  38. package/dist/types/src/components/locale-switcher/index.d.ts +1 -0
  39. package/dist/types/src/components/locale-switcher/locale-switcher.d.ts +10 -0
  40. package/dist/types/src/components/menu/menu.d.ts +16 -0
  41. package/dist/types/src/components/picker/picker-trigger.d.ts +2 -0
  42. package/dist/types/src/components/picker/picker.d.ts +37 -0
  43. package/dist/types/src/components/popover/popover-fit.d.ts +21 -0
  44. package/dist/types/src/components/popover/popover.d.ts +14 -0
  45. package/dist/types/src/components/profile-image/profile-image.d.ts +4 -0
  46. package/dist/types/src/components/progress-view/progress-view.d.ts +13 -0
  47. package/dist/types/src/components/search-field/search-field.d.ts +2 -0
  48. package/dist/types/src/components/search-list/search-list.d.ts +19 -0
  49. package/dist/types/src/components/section/section.d.ts +15 -0
  50. package/dist/types/src/components/secure-field/secure-field.d.ts +4 -0
  51. package/dist/types/src/components/segmented-control/segmented-control.d.ts +20 -0
  52. package/dist/types/src/components/sheet/modal-environment.d.ts +2 -0
  53. package/dist/types/src/components/sheet/sheet-portal.d.ts +5 -0
  54. package/dist/types/src/components/sheet/sheet.d.ts +21 -0
  55. package/dist/types/src/components/sheet/use-sheet-focus.d.ts +3 -0
  56. package/dist/types/src/components/sidebar/sidebar.d.ts +18 -0
  57. package/dist/types/src/components/slider/slider.d.ts +14 -0
  58. package/dist/types/src/components/stat-tile/index.d.ts +1 -0
  59. package/dist/types/src/components/stat-tile/stat-tile.d.ts +15 -0
  60. package/dist/types/src/components/status-indicator/status-indicator.d.ts +14 -0
  61. package/dist/types/src/components/stepper/stepper.d.ts +19 -0
  62. package/dist/types/src/components/swatch-picker/swatch-picker.d.ts +17 -0
  63. package/dist/types/src/components/tab-bar/tab-bar.d.ts +40 -0
  64. package/dist/types/src/components/tab-view/tab-view.d.ts +24 -0
  65. package/dist/types/src/components/table/table.d.ts +10 -0
  66. package/dist/types/src/components/text-editor/text-editor.d.ts +2 -0
  67. package/dist/types/src/components/text-field/text-field.d.ts +18 -0
  68. package/dist/types/src/components/toast/toast-store.d.ts +47 -0
  69. package/dist/types/src/components/toast/toaster.d.ts +10 -0
  70. package/dist/types/src/components/toggle/toggle.d.ts +17 -0
  71. package/dist/types/src/components/tooltip/tooltip-host.d.ts +6 -0
  72. package/dist/types/src/components/view-controller/index.d.ts +1 -0
  73. package/dist/types/src/components/view-controller/view-controller.d.ts +21 -0
  74. package/dist/types/src/hooks/scroll/minimize-decision.d.ts +2 -0
  75. package/dist/types/src/hooks/use-anchored-placement.d.ts +7 -0
  76. package/dist/types/src/hooks/use-dismiss.d.ts +9 -0
  77. package/dist/types/src/hooks/use-floating-dismiss.d.ts +3 -0
  78. package/dist/types/src/hooks/use-media-query.d.ts +21 -0
  79. package/dist/types/src/hooks/use-minimize-on-scroll.d.ts +6 -0
  80. package/dist/types/src/hooks/use-visual-viewport.d.ts +4 -0
  81. package/dist/types/src/hooks/viewport/types.d.ts +19 -0
  82. package/dist/types/src/hooks/viewport/viewport-metrics.d.ts +3 -0
  83. package/dist/types/src/icons/icons.d.ts +612 -0
  84. package/dist/types/src/index.d.ts +58 -0
  85. package/dist/types/src/lib/anchored-placement.d.ts +39 -0
  86. package/dist/types/src/lib/class-names.d.ts +2 -0
  87. package/dist/types/src/lib/clipboard.d.ts +6 -0
  88. package/dist/types/src/lib/date.d.ts +50 -0
  89. package/dist/types/src/lib/floating-layers.d.ts +8 -0
  90. package/dist/types/src/lib/haptics.d.ts +8 -0
  91. package/dist/types/src/lib/language.d.ts +4 -0
  92. package/dist/types/src/lib/range-value.d.ts +4 -0
  93. package/dist/types/src/lib/screen-edges.d.ts +12 -0
  94. package/dist/types/src/lib/shapes.d.ts +17 -0
  95. package/dist/types/src/motion/transitions.d.ts +97 -0
  96. package/dist/types/src/tokens.d.ts +1 -0
  97. package/package.json +192 -40
  98. package/src/appearance/platform.tsx +10 -47
  99. package/src/appearance/theme.tsx +42 -142
  100. package/src/components/ambient/ambient.tsx +2 -10
  101. package/src/components/button/button-styles.ts +13 -31
  102. package/src/components/button/button.tsx +19 -14
  103. package/src/components/button/icon-button.tsx +14 -56
  104. package/src/components/button/use-pending-indicator.ts +2 -7
  105. package/src/components/chip/chip.tsx +8 -13
  106. package/src/components/compact-date-picker/calendar-month.ts +13 -57
  107. package/src/components/compact-date-picker/compact-date-picker.tsx +44 -123
  108. package/src/components/compact-time-picker/compact-time-picker.tsx +46 -130
  109. package/src/components/compact-time-picker/time-value.ts +4 -16
  110. package/src/components/content-view/content-view.tsx +13 -56
  111. package/src/components/context-menu/conceal-menu-source.ts +1 -4
  112. package/src/components/context-menu/context-menu-host.tsx +125 -195
  113. package/src/components/context-menu/context-menu-store.ts +3 -11
  114. package/src/components/context-menu/menu-navigation.ts +29 -0
  115. package/src/components/context-menu/menu-position.ts +6 -27
  116. package/src/components/context-menu/menu-reveal.ts +13 -54
  117. package/src/components/context-menu/use-context-menu.ts +6 -30
  118. package/src/components/conversation/conversation.tsx +26 -72
  119. package/src/components/date-picker/date-picker.tsx +8 -37
  120. package/src/components/date-picker/date-value.ts +5 -30
  121. package/src/components/dialog/dialog-host.tsx +31 -76
  122. package/src/components/dialog/dialog-store.ts +1 -3
  123. package/src/components/dialog/dialog.tsx +23 -80
  124. package/src/components/disclosure-group/disclosure-group.tsx +70 -0
  125. package/src/components/divider/divider.tsx +31 -0
  126. package/src/components/inline-disclosure/inline-disclosure.tsx +49 -0
  127. package/src/components/labeled-content/labeled-content.tsx +24 -18
  128. package/src/components/locale-switcher/locale-switcher.tsx +20 -70
  129. package/src/components/menu/menu.tsx +68 -0
  130. package/src/components/picker/picker-trigger.ts +10 -0
  131. package/src/components/picker/picker.tsx +72 -203
  132. package/src/components/popover/popover-fit.ts +69 -0
  133. package/src/components/popover/popover.tsx +94 -77
  134. package/src/components/profile-image/profile-image.tsx +6 -28
  135. package/src/components/progress-view/progress-view.tsx +65 -0
  136. package/src/components/search-field/search-field.tsx +27 -25
  137. package/src/components/search-list/search-list.tsx +43 -69
  138. package/src/components/section/section.tsx +18 -17
  139. package/src/components/secure-field/secure-field.tsx +5 -7
  140. package/src/components/segmented-control/segmented-control.tsx +20 -29
  141. package/src/components/sheet/modal-environment.ts +16 -54
  142. package/src/components/sheet/sheet-portal.tsx +10 -42
  143. package/src/components/sheet/sheet.tsx +17 -25
  144. package/src/components/sheet/use-sheet-focus.ts +15 -51
  145. package/src/components/sidebar/sidebar.tsx +27 -30
  146. package/src/components/slider/slider.tsx +76 -0
  147. package/src/components/stat-tile/stat-tile.tsx +9 -30
  148. package/src/components/status-indicator/status-indicator.tsx +12 -19
  149. package/src/components/stepper/stepper.tsx +80 -0
  150. package/src/components/swatch-picker/swatch-picker.tsx +19 -15
  151. package/src/components/tab-bar/tab-bar.tsx +59 -59
  152. package/src/components/tab-view/tab-view.tsx +52 -57
  153. package/src/components/table/table.tsx +14 -62
  154. package/src/components/text-editor/text-editor.tsx +2 -12
  155. package/src/components/text-field/text-field.tsx +11 -40
  156. package/src/components/toast/toast-store.ts +9 -30
  157. package/src/components/toast/toaster.tsx +90 -104
  158. package/src/components/toggle/toggle.tsx +28 -24
  159. package/src/components/tooltip/tooltip-host.tsx +71 -69
  160. package/src/components/view-controller/view-controller.tsx +4 -21
  161. package/src/hooks/scroll/minimize-decision.ts +1 -5
  162. package/src/hooks/use-anchored-placement.ts +4 -14
  163. package/src/hooks/use-dismiss.ts +5 -23
  164. package/src/hooks/use-floating-dismiss.ts +28 -0
  165. package/src/hooks/use-media-query.ts +12 -31
  166. package/src/hooks/use-minimize-on-scroll.ts +10 -34
  167. package/src/hooks/use-visual-viewport.ts +5 -14
  168. package/src/hooks/viewport/viewport-metrics.ts +4 -16
  169. package/src/icons/icons.tsx +167 -121
  170. package/src/index.ts +9 -1
  171. package/src/lib/anchored-placement.ts +5 -15
  172. package/src/lib/class-names.ts +1 -2
  173. package/src/lib/clipboard.ts +14 -0
  174. package/src/lib/date.ts +4 -15
  175. package/src/lib/floating-layers.ts +18 -8
  176. package/src/lib/haptics.ts +1 -3
  177. package/src/lib/language.ts +2 -7
  178. package/src/lib/range-value.ts +32 -0
  179. package/src/lib/screen-edges.ts +2 -6
  180. package/src/lib/shapes.ts +5 -20
  181. package/src/motion/transitions.ts +18 -12
  182. package/src/components/ambient/ambient.docs.tsx +0 -68
  183. package/src/components/ambient/examples/ambient-images.tsx +0 -30
  184. package/src/components/ambient/examples/ambient-now-playing.tsx +0 -55
  185. package/src/components/ambient/examples/ambient-showcase.tsx +0 -33
  186. package/src/components/ambient/examples/ambient-usage.tsx +0 -19
  187. package/src/components/button/button.docs.tsx +0 -116
  188. package/src/components/button/examples/button-disabled.tsx +0 -19
  189. package/src/components/button/examples/button-icon.tsx +0 -39
  190. package/src/components/button/examples/button-link.tsx +0 -12
  191. package/src/components/button/examples/button-pending.tsx +0 -27
  192. package/src/components/button/examples/button-showcase.tsx +0 -115
  193. package/src/components/button/examples/button-sizes.tsx +0 -12
  194. package/src/components/button/examples/button-usage.tsx +0 -12
  195. package/src/components/button/examples/button-variants.tsx +0 -15
  196. package/src/components/button/examples/button-with-icon.tsx +0 -32
  197. package/src/components/button/examples/icon-button-player.tsx +0 -38
  198. package/src/components/button/examples/icon-button-showcase.tsx +0 -83
  199. package/src/components/button/examples/icon-button-usage.tsx +0 -11
  200. package/src/components/button/examples/icon-button-variants.tsx +0 -39
  201. package/src/components/button/icon-button.docs.tsx +0 -68
  202. package/src/components/chip/chip.docs.tsx +0 -37
  203. package/src/components/chip/examples/chip-in-rows.tsx +0 -19
  204. package/src/components/chip/examples/chip-showcase.tsx +0 -51
  205. package/src/components/chip/examples/chip-tones.tsx +0 -13
  206. package/src/components/chip/examples/chip-usage.tsx +0 -5
  207. package/src/components/compact-date-picker/compact-date-picker.docs.tsx +0 -81
  208. package/src/components/compact-date-picker/examples/compact-date-picker-showcase.tsx +0 -35
  209. package/src/components/compact-date-picker/examples/compact-date-picker-usage.tsx +0 -22
  210. package/src/components/compact-time-picker/compact-time-picker.docs.tsx +0 -80
  211. package/src/components/compact-time-picker/examples/compact-time-picker-showcase.tsx +0 -31
  212. package/src/components/compact-time-picker/examples/compact-time-picker-usage.tsx +0 -21
  213. package/src/components/content-view/content-view.docs.tsx +0 -61
  214. package/src/components/content-view/examples/content-view-header-action.tsx +0 -33
  215. package/src/components/content-view/examples/content-view-showcase.tsx +0 -65
  216. package/src/components/content-view/examples/content-view-stats.tsx +0 -35
  217. package/src/components/content-view/examples/content-view-usage.tsx +0 -14
  218. package/src/components/context-menu/context-menu.docs.tsx +0 -92
  219. package/src/components/context-menu/examples/context-menu-checked.tsx +0 -37
  220. package/src/components/context-menu/examples/context-menu-list.tsx +0 -85
  221. package/src/components/context-menu/examples/context-menu-showcase.tsx +0 -56
  222. package/src/components/context-menu/examples/context-menu-toolbar.tsx +0 -63
  223. package/src/components/context-menu/examples/context-menu-usage.tsx +0 -24
  224. package/src/components/conversation/conversation.docs.tsx +0 -88
  225. package/src/components/conversation/examples/conversation-composer.tsx +0 -36
  226. package/src/components/conversation/examples/conversation-days.tsx +0 -48
  227. package/src/components/conversation/examples/conversation-showcase.tsx +0 -71
  228. package/src/components/conversation/examples/conversation-usage.tsx +0 -28
  229. package/src/components/date-picker/date-picker.docs.tsx +0 -88
  230. package/src/components/date-picker/examples/date-picker-locales.tsx +0 -41
  231. package/src/components/date-picker/examples/date-picker-past-only.tsx +0 -29
  232. package/src/components/date-picker/examples/date-picker-showcase.tsx +0 -49
  233. package/src/components/date-picker/examples/date-picker-usage.tsx +0 -22
  234. package/src/components/dialog/dialog.docs.tsx +0 -114
  235. package/src/components/dialog/examples/dialog-confirm.tsx +0 -24
  236. package/src/components/dialog/examples/dialog-form.tsx +0 -46
  237. package/src/components/dialog/examples/dialog-inline.tsx +0 -48
  238. package/src/components/dialog/examples/dialog-showcase.tsx +0 -53
  239. package/src/components/dialog/examples/dialog-usage.tsx +0 -31
  240. package/src/components/labeled-content/examples/labeled-content-descriptions.tsx +0 -37
  241. package/src/components/labeled-content/examples/labeled-content-showcase.tsx +0 -54
  242. package/src/components/labeled-content/examples/labeled-content-usage.tsx +0 -22
  243. package/src/components/labeled-content/examples/labeled-content-values.tsx +0 -26
  244. package/src/components/labeled-content/examples/labeled-content-wide.tsx +0 -46
  245. package/src/components/labeled-content/labeled-content.docs.tsx +0 -69
  246. package/src/components/locale-switcher/examples/locale-switcher-native-names.tsx +0 -30
  247. package/src/components/locale-switcher/examples/locale-switcher-showcase.tsx +0 -46
  248. package/src/components/locale-switcher/examples/locale-switcher-translated-page.tsx +0 -35
  249. package/src/components/locale-switcher/examples/locale-switcher-usage.tsx +0 -20
  250. package/src/components/locale-switcher/locale-switcher.docs.tsx +0 -91
  251. package/src/components/picker/examples/picker-details.tsx +0 -44
  252. package/src/components/picker/examples/picker-searchable.tsx +0 -48
  253. package/src/components/picker/examples/picker-showcase.tsx +0 -66
  254. package/src/components/picker/examples/picker-usage.tsx +0 -20
  255. package/src/components/picker/picker.docs.tsx +0 -68
  256. package/src/components/popover/examples/popover-help.tsx +0 -57
  257. package/src/components/popover/examples/popover-menu.tsx +0 -51
  258. package/src/components/popover/examples/popover-showcase.tsx +0 -61
  259. package/src/components/popover/examples/popover-usage.tsx +0 -31
  260. package/src/components/popover/popover.docs.tsx +0 -84
  261. package/src/components/profile-image/examples/profile-image-fallbacks.tsx +0 -29
  262. package/src/components/profile-image/examples/profile-image-group.tsx +0 -34
  263. package/src/components/profile-image/examples/profile-image-showcase.tsx +0 -30
  264. package/src/components/profile-image/examples/profile-image-usage.tsx +0 -14
  265. package/src/components/profile-image/profile-image.docs.tsx +0 -81
  266. package/src/components/search-field/examples/search-field-filter.tsx +0 -53
  267. package/src/components/search-field/examples/search-field-showcase.tsx +0 -56
  268. package/src/components/search-field/examples/search-field-toolbar.tsx +0 -27
  269. package/src/components/search-field/examples/search-field-usage.tsx +0 -18
  270. package/src/components/search-field/search-field.docs.tsx +0 -58
  271. package/src/components/search-list/examples/search-list-dropdown.tsx +0 -53
  272. package/src/components/search-list/examples/search-list-groups.tsx +0 -64
  273. package/src/components/search-list/examples/search-list-showcase.tsx +0 -67
  274. package/src/components/search-list/examples/search-list-usage.tsx +0 -27
  275. package/src/components/search-list/search-list.docs.tsx +0 -87
  276. package/src/components/section/examples/section-actions.tsx +0 -35
  277. package/src/components/section/examples/section-groups.tsx +0 -41
  278. package/src/components/section/examples/section-showcase.tsx +0 -63
  279. package/src/components/section/examples/section-usage.tsx +0 -19
  280. package/src/components/section/section.docs.tsx +0 -51
  281. package/src/components/secure-field/examples/secure-field-new-password.tsx +0 -56
  282. package/src/components/secure-field/examples/secure-field-reveal.tsx +0 -20
  283. package/src/components/secure-field/examples/secure-field-showcase.tsx +0 -62
  284. package/src/components/secure-field/examples/secure-field-usage.tsx +0 -19
  285. package/src/components/secure-field/secure-field.docs.tsx +0 -72
  286. package/src/components/segmented-control/examples/segmented-control-overflow.tsx +0 -28
  287. package/src/components/segmented-control/examples/segmented-control-showcase.tsx +0 -59
  288. package/src/components/segmented-control/examples/segmented-control-usage.tsx +0 -20
  289. package/src/components/segmented-control/examples/segmented-control-views.tsx +0 -32
  290. package/src/components/segmented-control/segmented-control.docs.tsx +0 -61
  291. package/src/components/sheet/examples/sheet-choices.tsx +0 -58
  292. package/src/components/sheet/examples/sheet-share.tsx +0 -51
  293. package/src/components/sheet/examples/sheet-showcase.tsx +0 -74
  294. package/src/components/sheet/examples/sheet-usage.tsx +0 -32
  295. package/src/components/sheet/sheet.docs.tsx +0 -75
  296. package/src/components/sidebar/examples/sidebar-groups.tsx +0 -133
  297. package/src/components/sidebar/examples/sidebar-showcase.tsx +0 -123
  298. package/src/components/sidebar/examples/sidebar-unread.tsx +0 -66
  299. package/src/components/sidebar/examples/sidebar-usage.tsx +0 -52
  300. package/src/components/sidebar/sidebar.docs.tsx +0 -135
  301. package/src/components/stat-tile/examples/stat-tile-filters.tsx +0 -32
  302. package/src/components/stat-tile/examples/stat-tile-grid.tsx +0 -21
  303. package/src/components/stat-tile/examples/stat-tile-showcase.tsx +0 -52
  304. package/src/components/stat-tile/examples/stat-tile-usage.tsx +0 -13
  305. package/src/components/stat-tile/stat-tile.docs.tsx +0 -60
  306. package/src/components/status-indicator/examples/status-indicator-live.tsx +0 -34
  307. package/src/components/status-indicator/examples/status-indicator-showcase.tsx +0 -39
  308. package/src/components/status-indicator/examples/status-indicator-states.tsx +0 -17
  309. package/src/components/status-indicator/examples/status-indicator-usage.tsx +0 -9
  310. package/src/components/status-indicator/status-indicator.docs.tsx +0 -43
  311. package/src/components/swatch-picker/examples/swatch-picker-accents.tsx +0 -42
  312. package/src/components/swatch-picker/examples/swatch-picker-labels.tsx +0 -45
  313. package/src/components/swatch-picker/examples/swatch-picker-showcase.tsx +0 -70
  314. package/src/components/swatch-picker/examples/swatch-picker-usage.tsx +0 -39
  315. package/src/components/swatch-picker/swatch-picker.docs.tsx +0 -60
  316. package/src/components/tab-bar/examples/tab-bar-five-tabs.tsx +0 -66
  317. package/src/components/tab-bar/examples/tab-bar-minimize.tsx +0 -71
  318. package/src/components/tab-bar/examples/tab-bar-showcase.tsx +0 -82
  319. package/src/components/tab-bar/examples/tab-bar-usage.tsx +0 -54
  320. package/src/components/tab-bar/tab-bar.docs.tsx +0 -136
  321. package/src/components/tab-view/examples/tab-view-keyboard.tsx +0 -39
  322. package/src/components/tab-view/examples/tab-view-settings.tsx +0 -56
  323. package/src/components/tab-view/examples/tab-view-showcase.tsx +0 -53
  324. package/src/components/tab-view/examples/tab-view-usage.tsx +0 -23
  325. package/src/components/tab-view/tab-view.docs.tsx +0 -77
  326. package/src/components/table/examples/table-empty.tsx +0 -53
  327. package/src/components/table/examples/table-invoices.tsx +0 -102
  328. package/src/components/table/examples/table-selection.tsx +0 -150
  329. package/src/components/table/examples/table-showcase.tsx +0 -115
  330. package/src/components/table/examples/table-usage.tsx +0 -67
  331. package/src/components/table/examples/table-wide.tsx +0 -75
  332. package/src/components/table/table.docs.tsx +0 -131
  333. package/src/components/text-editor/examples/text-editor-comment.tsx +0 -48
  334. package/src/components/text-editor/examples/text-editor-count.tsx +0 -38
  335. package/src/components/text-editor/examples/text-editor-showcase.tsx +0 -58
  336. package/src/components/text-editor/examples/text-editor-usage.tsx +0 -25
  337. package/src/components/text-editor/text-editor.docs.tsx +0 -61
  338. package/src/components/text-field/examples/text-field-icons.tsx +0 -72
  339. package/src/components/text-field/examples/text-field-showcase.tsx +0 -50
  340. package/src/components/text-field/examples/text-field-usage.tsx +0 -18
  341. package/src/components/text-field/examples/text-field-validation.tsx +0 -27
  342. package/src/components/text-field/text-field.docs.tsx +0 -118
  343. package/src/components/toast/examples/toast-action.tsx +0 -32
  344. package/src/components/toast/examples/toast-promise.tsx +0 -45
  345. package/src/components/toast/examples/toast-showcase.tsx +0 -49
  346. package/src/components/toast/examples/toast-usage.tsx +0 -13
  347. package/src/components/toast/toast.docs.tsx +0 -79
  348. package/src/components/toggle/examples/toggle-checkboxes.tsx +0 -43
  349. package/src/components/toggle/examples/toggle-settings.tsx +0 -31
  350. package/src/components/toggle/examples/toggle-showcase.tsx +0 -59
  351. package/src/components/toggle/examples/toggle-usage.tsx +0 -13
  352. package/src/components/toggle/toggle.docs.tsx +0 -69
  353. package/src/components/tooltip/examples/tooltip-icon-buttons.tsx +0 -27
  354. package/src/components/tooltip/examples/tooltip-shortcuts.tsx +0 -38
  355. package/src/components/tooltip/examples/tooltip-showcase.tsx +0 -44
  356. package/src/components/tooltip/examples/tooltip-usage.tsx +0 -13
  357. package/src/components/tooltip/tooltip.docs.tsx +0 -56
  358. package/src/components/view-controller/examples/view-controller-action.tsx +0 -27
  359. package/src/components/view-controller/examples/view-controller-settings.tsx +0 -31
  360. package/src/components/view-controller/examples/view-controller-showcase.tsx +0 -45
  361. package/src/components/view-controller/examples/view-controller-usage.tsx +0 -19
  362. package/src/components/view-controller/view-controller.docs.tsx +0 -71
  363. package/src/docs/index.ts +0 -3
  364. package/src/docs/registry.ts +0 -113
  365. package/src/docs/snippet.ts +0 -17
  366. package/src/docs/types.ts +0 -180
@@ -1,27 +1,30 @@
1
- import type { ReactNode } from "react"
1
+ import { useId, type HTMLAttributes, type ReactNode } from "react"
2
+ import { cn } from "../../lib/class-names"
3
+
4
+ export interface SectionProps extends HTMLAttributes<HTMLElement> {
5
+ /** Optional group heading and accessible name. */
6
+ title?: string
7
+ /** Supporting text below the grouped rows. */
8
+ footer?: ReactNode
9
+ /** Rows, typically LabeledContent. */
10
+ children?: ReactNode
11
+ }
2
12
 
3
13
  /**
4
14
  * A titled, inset group of rows with an optional footer, as in iOS Settings
5
15
  * and SwiftUI's grouped `List` with `Section(header:footer:)`. Rows are
6
16
  * usually `LabeledContent`; dividers between them come for free.
7
17
  */
8
- export function Section({
9
- title,
10
- footer,
11
- children,
12
- }: {
13
- /** iOS groups can stand without a header. */
14
- title?: string
15
- footer?: ReactNode
16
- children?: ReactNode
17
- }) {
18
+ export function Section({ title, footer, children, className, ...props }: SectionProps) {
19
+ const headingId = useId()
18
20
  return (
19
21
  <section
20
- aria-label={title}
21
- className="flex flex-col gap-2"
22
+ aria-labelledby={title ? headingId : undefined}
23
+ className={cn("flex flex-col gap-2", className)}
24
+ {...props}
22
25
  >
23
26
  {title && (
24
- <h2 className="px-4 text-footnote font-medium text-label-tertiary">
27
+ <h2 id={headingId} className="px-4 text-footnote font-medium text-label-tertiary">
25
28
  {title}
26
29
  </h2>
27
30
  )}
@@ -32,9 +35,7 @@ export function Section({
32
35
  </div>
33
36
  ) : null}
34
37
  {footer && (
35
- <p className="px-4 text-caption leading-snug text-label-tertiary">
36
- {footer}
37
- </p>
38
+ <div className="px-4 text-caption leading-snug text-label-tertiary">{footer}</div>
38
39
  )}
39
40
  </section>
40
41
  )
@@ -1,10 +1,8 @@
1
- import {
2
- TextField,
3
- type TextFieldProps,
4
- } from "../text-field/text-field"
1
+ import { TextField, type TextFieldProps } from "../text-field/text-field"
5
2
 
6
- export function SecureField(
7
- props: Omit<TextFieldProps, "type">
8
- ) {
3
+ /** TextField's native input props, with the password type managed by SecureField. */
4
+ export type SecureFieldProps = Omit<TextFieldProps, "type">
5
+
6
+ export function SecureField(props: SecureFieldProps) {
9
7
  return <TextField {...props} type="password" />
10
8
  }
@@ -1,15 +1,21 @@
1
- import { motion } from "motion/react"
2
- import {
3
- useId,
4
- useLayoutEffect,
5
- useRef,
6
- useState,
7
- } from "react"
1
+ import { motion, useReducedMotion } from "motion/react"
2
+ import { useId, useLayoutEffect, useRef, useState } from "react"
8
3
  import { cn } from "../../lib/class-names"
9
4
  import { haptic } from "../../lib/haptics"
10
5
  import { spring } from "../../motion/transitions"
11
6
  import { Picker } from "../picker/picker"
12
7
 
8
+ export interface SegmentedControlProps<T extends string> {
9
+ /** Value of the selected segment. */
10
+ value: T
11
+ /** The choices, in display order. */
12
+ options: ReadonlyArray<{ value: T; label: string }>
13
+ /** Called with the selected segment's value. */
14
+ onChange: (value: NoInfer<T>) => void
15
+ /** Accessible name for the group and its compact picker. */
16
+ label: string
17
+ }
18
+
13
19
  /**
14
20
  * Mutually exclusive choices with a sliding selection, as on Apple
15
21
  * platforms. When the labels can't all fit the space it is given (a long
@@ -21,13 +27,9 @@ export function SegmentedControl<T extends string>({
21
27
  options,
22
28
  onChange,
23
29
  label,
24
- }: {
25
- value: T
26
- options: Array<{ value: T; label: string }>
27
- onChange: (value: T) => void
28
- label: string
29
- }) {
30
+ }: SegmentedControlProps<T>) {
30
31
  const id = useId()
32
+ const reducedMotion = useReducedMotion()
31
33
  const frame = useRef<HTMLDivElement>(null)
32
34
  const measure = useRef<HTMLDivElement>(null)
33
35
  const [fits, setFits] = useState(true)
@@ -36,10 +38,7 @@ export function SegmentedControl<T extends string>({
36
38
  const box = frame.current
37
39
  const natural = measure.current
38
40
  if (!box || !natural) return
39
- const check = () =>
40
- setFits(
41
- natural.offsetWidth <= box.clientWidth + 0.5
42
- )
41
+ const check = () => setFits(natural.offsetWidth <= box.clientWidth + 0.5)
43
42
  check()
44
43
  const observer = new ResizeObserver(check)
45
44
  observer.observe(box)
@@ -56,22 +55,16 @@ export function SegmentedControl<T extends string>({
56
55
  className="pointer-events-none invisible absolute top-0 flex w-max p-[3px] text-footnote font-semibold"
57
56
  >
58
57
  {options.map((option) => (
59
- <span
60
- key={option.value}
61
- className="min-w-[64px] px-3 py-1 whitespace-nowrap"
62
- >
58
+ <span key={option.value} className="min-w-[64px] px-3 py-1 whitespace-nowrap">
63
59
  {option.label}
64
60
  </span>
65
61
  ))}
66
62
  </div>
67
63
  {fits ? (
68
64
  <fieldset className="flex w-full rounded-lg bg-fill p-[3px] shadow-[inset_0_1px_2px_rgb(40_30_0/0.06)]">
69
- <legend className="sr-only">
70
- {label}
71
- </legend>
65
+ <legend className="sr-only">{label}</legend>
72
66
  {options.map((option) => {
73
- const selected =
74
- option.value === value
67
+ const selected = option.value === value
75
68
  return (
76
69
  <label
77
70
  key={option.value}
@@ -97,9 +90,7 @@ export function SegmentedControl<T extends string>({
97
90
  <motion.span
98
91
  layoutId={`segment-${id}`}
99
92
  className="absolute inset-0 -z-10 rounded-md bg-elevated 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)]"
100
- transition={
101
- spring.snappy
102
- }
93
+ transition={reducedMotion ? { duration: 0 } : spring.snappy}
103
94
  />
104
95
  )}
105
96
  {option.label}
@@ -1,7 +1,4 @@
1
- import {
2
- FLOATING_LAYER,
3
- ownsFloatingLayer,
4
- } from "../../lib/floating-layers"
1
+ import { FLOATING_LAYER, ownsFloatingLayer } from "../../lib/floating-layers"
5
2
 
6
3
  const surfaces: HTMLElement[] = []
7
4
  const isolated = new Map<HTMLElement, boolean>()
@@ -9,8 +6,7 @@ let overflow = ""
9
6
  let overflowPriority = ""
10
7
 
11
8
  function restoreBackground() {
12
- for (const [element, inert] of isolated)
13
- element.inert = inert
9
+ for (const [element, inert] of isolated) element.inert = inert
14
10
  isolated.clear()
15
11
  }
16
12
 
@@ -19,11 +15,8 @@ function isolateBackground() {
19
15
  const surface = surfaces.at(-1)
20
16
  if (!surface) return
21
17
  const roots = [surface.parentElement ?? surface]
22
- for (const layer of document.querySelectorAll<HTMLElement>(
23
- `[${FLOATING_LAYER}]`
24
- )) {
25
- if (ownsFloatingLayer(surface, layer))
26
- roots.push(layer)
18
+ for (const layer of document.querySelectorAll<HTMLElement>(`[${FLOATING_LAYER}]`)) {
19
+ if (ownsFloatingLayer(surface, layer)) roots.push(layer)
27
20
  }
28
21
  const visit = (parent: HTMLElement) => {
29
22
  for (const child of parent.children) {
@@ -31,9 +24,7 @@ function isolateBackground() {
31
24
  if (roots.includes(child)) continue
32
25
  if (roots.some((root) => child.contains(root))) {
33
26
  visit(child)
34
- } else if (
35
- !child.matches("script, style, link")
36
- ) {
27
+ } else if (!child.matches("script, style, link")) {
37
28
  isolated.set(child, child.inert)
38
29
  child.inert = true
39
30
  }
@@ -43,43 +34,26 @@ function isolateBackground() {
43
34
  }
44
35
 
45
36
  /** Keeps nested sheets and their portaled controls above an inactive background. */
46
- export function enterModalEnvironment(
47
- surface: HTMLElement
48
- ): () => void {
37
+ export function enterModalEnvironment(surface: HTMLElement): () => void {
49
38
  if (!surfaces.length) {
50
- overflow =
51
- document.body.style.getPropertyValue("overflow")
52
- overflowPriority =
53
- document.body.style.getPropertyPriority(
54
- "overflow"
55
- )
39
+ overflow = document.body.style.getPropertyValue("overflow")
40
+ overflowPriority = document.body.style.getPropertyPriority("overflow")
56
41
  document.body.style.setProperty("overflow", "hidden")
57
42
  }
58
43
  surfaces.push(surface)
59
44
  isolateBackground()
60
- const preventBackgroundScroll = (
61
- event: WheelEvent | TouchEvent
62
- ) => {
45
+ const preventBackgroundScroll = (event: WheelEvent | TouchEvent) => {
63
46
  if (surfaces.at(-1) !== surface) return
64
47
  const target = event.target
65
48
  if (
66
49
  target instanceof Element &&
67
- (surface.contains(target) ||
68
- ownsFloatingLayer(surface, target))
50
+ (surface.contains(target) || ownsFloatingLayer(surface, target))
69
51
  )
70
52
  return
71
53
  event.preventDefault()
72
54
  }
73
- document.addEventListener(
74
- "wheel",
75
- preventBackgroundScroll,
76
- { passive: false }
77
- )
78
- document.addEventListener(
79
- "touchmove",
80
- preventBackgroundScroll,
81
- { passive: false }
82
- )
55
+ document.addEventListener("wheel", preventBackgroundScroll, { passive: false })
56
+ document.addEventListener("touchmove", preventBackgroundScroll, { passive: false })
83
57
  const observer = new MutationObserver(() => {
84
58
  if (surfaces.at(-1) === surface) isolateBackground()
85
59
  })
@@ -89,25 +63,13 @@ export function enterModalEnvironment(
89
63
  })
90
64
  return () => {
91
65
  observer.disconnect()
92
- document.removeEventListener(
93
- "wheel",
94
- preventBackgroundScroll
95
- )
96
- document.removeEventListener(
97
- "touchmove",
98
- preventBackgroundScroll
99
- )
66
+ document.removeEventListener("wheel", preventBackgroundScroll)
67
+ document.removeEventListener("touchmove", preventBackgroundScroll)
100
68
  surfaces.splice(surfaces.indexOf(surface), 1)
101
69
  isolateBackground()
102
70
  if (!surfaces.length) {
103
- if (overflow)
104
- document.body.style.setProperty(
105
- "overflow",
106
- overflow,
107
- overflowPriority
108
- )
109
- else
110
- document.body.style.removeProperty("overflow")
71
+ if (overflow) document.body.style.setProperty("overflow", overflow, overflowPriority)
72
+ else document.body.style.removeProperty("overflow")
111
73
  }
112
74
  }
113
75
  }
@@ -1,21 +1,10 @@
1
- import {
2
- type ReactNode,
3
- useLayoutEffect,
4
- useRef,
5
- useState,
6
- } from "react"
1
+ import { type ReactNode, useLayoutEffect, useRef, useState } from "react"
7
2
  import { createPortal } from "react-dom"
8
3
 
9
4
  /** Escape transformed page layers while retaining the source's scoped appearance. */
10
- export function SheetPortal({
11
- children,
12
- }: {
13
- children: ReactNode
14
- }) {
5
+ export function SheetPortal({ children }: { children: ReactNode }) {
15
6
  const source = useRef<HTMLSpanElement>(null)
16
- const [host, setHost] = useState<HTMLDivElement | null>(
17
- null
18
- )
7
+ const [host, setHost] = useState<HTMLDivElement | null>(null)
19
8
  useLayoutEffect(() => {
20
9
  const marker = source.current
21
10
  if (!marker) return
@@ -23,20 +12,12 @@ export function SheetPortal({
23
12
  const layer = document.createElement("div")
24
13
  layer.dataset.passuiOverlay = ""
25
14
  layer.style.display = "contents"
26
- const attributes = [
27
- "data-theme",
28
- "data-accent",
29
- "data-os",
30
- "dir",
31
- ]
15
+ const attributes = ["data-theme", "data-accent", "data-os", "dir"]
32
16
  let properties = new Set<string>()
33
17
  const inherit = () => {
34
18
  for (const name of attributes) {
35
- const value = marker
36
- .closest(`[${name}]`)
37
- ?.getAttribute(name)
38
- if (value === null || value === undefined)
39
- layer.removeAttribute(name)
19
+ const value = marker.closest(`[${name}]`)?.getAttribute(name)
20
+ if (value === null || value === undefined) layer.removeAttribute(name)
40
21
  else layer.setAttribute(name, value)
41
22
  }
42
23
  const computed = getComputedStyle(marker)
@@ -44,14 +25,9 @@ export function SheetPortal({
44
25
  for (const name of computed) {
45
26
  if (!name.startsWith("--")) continue
46
27
  next.add(name)
47
- layer.style.setProperty(
48
- name,
49
- computed.getPropertyValue(name)
50
- )
28
+ layer.style.setProperty(name, computed.getPropertyValue(name))
51
29
  }
52
- for (const name of properties)
53
- if (!next.has(name))
54
- layer.style.removeProperty(name)
30
+ for (const name of properties) if (!next.has(name)) layer.style.removeProperty(name)
55
31
  properties = next
56
32
  layer.style.colorScheme = computed.colorScheme
57
33
  layer.style.fontFamily = computed.fontFamily
@@ -61,18 +37,10 @@ export function SheetPortal({
61
37
  document.body.appendChild(layer)
62
38
  setHost(layer)
63
39
  const observer = new MutationObserver(inherit)
64
- for (
65
- let ancestor = marker.parentElement;
66
- ancestor;
67
- ancestor = ancestor.parentElement
68
- ) {
40
+ for (let ancestor = marker.parentElement; ancestor; ancestor = ancestor.parentElement) {
69
41
  observer.observe(ancestor, {
70
42
  attributes: true,
71
- attributeFilter: [
72
- ...attributes,
73
- "style",
74
- "class",
75
- ],
43
+ attributeFilter: [...attributes, "style", "class"],
76
44
  })
77
45
  }
78
46
  return () => {
@@ -1,8 +1,4 @@
1
- import {
2
- AnimatePresence,
3
- motion,
4
- useReducedMotion,
5
- } from "motion/react"
1
+ import { AnimatePresence, motion, useReducedMotion } from "motion/react"
6
2
  import { type ReactNode, useRef } from "react"
7
3
  import { useVisualViewport } from "../../hooks/use-visual-viewport"
8
4
  import { cn } from "../../lib/class-names"
@@ -10,12 +6,19 @@ import { spring } from "../../motion/transitions"
10
6
  import { SheetPortal } from "./sheet-portal"
11
7
  import { useSheetFocus } from "./use-sheet-focus"
12
8
 
13
- interface SheetProps {
9
+ export type SheetPlacement = "adaptive" | "center"
10
+
11
+ export interface SheetProps {
12
+ /** Controls whether the sheet is presented. */
14
13
  open: boolean
14
+ /** Called on Escape or an outside press. */
15
15
  onClose: () => void
16
16
  /** Read out by screen readers as the sheet's name. */
17
17
  label: string
18
+ /** ID of a visible heading to use instead of label for the accessible name. */
18
19
  labelledBy?: string
20
+ /** `adaptive` rises from the bottom on phones; `center` always floats. @default "adaptive" */
21
+ placement?: SheetPlacement
19
22
  className?: string
20
23
  children: ReactNode
21
24
  }
@@ -40,6 +43,7 @@ function OpenSheet({
40
43
  onClose,
41
44
  label,
42
45
  labelledBy,
46
+ placement = "adaptive",
43
47
  className,
44
48
  children,
45
49
  }: Omit<SheetProps, "open">) {
@@ -51,8 +55,8 @@ function OpenSheet({
51
55
  return (
52
56
  <div
53
57
  className={cn(
54
- "fixed inset-0 z-[65] flex items-end justify-center",
55
- "sm:items-center sm:p-6"
58
+ "fixed inset-0 z-[65] flex justify-center",
59
+ placement === "center" ? "items-center p-6" : "items-end sm:items-center sm:p-6"
56
60
  )}
57
61
  style={
58
62
  viewport
@@ -85,25 +89,13 @@ function OpenSheet({
85
89
  className={cn(
86
90
  "glass-menu relative flex w-full flex-col overflow-hidden",
87
91
  "max-h-[92%] max-w-[560px]",
88
- "rounded-t-sheet sm:rounded-sheet",
92
+ placement === "center" ? "rounded-sheet" : "rounded-t-sheet sm:rounded-sheet",
89
93
  className
90
94
  )}
91
- initial={
92
- reducedMotion
93
- ? { opacity: 0 }
94
- : { y: 40, opacity: 0, scale: 0.98 }
95
- }
96
- animate={{ y: 0, opacity: 1, scale: 1 }}
97
- exit={
98
- reducedMotion
99
- ? { opacity: 0 }
100
- : { y: 30, opacity: 0 }
101
- }
102
- transition={
103
- reducedMotion
104
- ? { duration: 0 }
105
- : spring.smooth
106
- }
95
+ initial={reducedMotion ? { opacity: 0 } : { y: 40, opacity: 0 }}
96
+ animate={{ y: 0, opacity: 1 }}
97
+ exit={reducedMotion ? { opacity: 0 } : { y: 30, opacity: 0 }}
98
+ transition={reducedMotion ? { duration: 0 } : spring.smooth}
107
99
  >
108
100
  {children}
109
101
  </motion.div>
@@ -1,10 +1,4 @@
1
- import {
2
- type RefObject,
3
- useEffect,
4
- useLayoutEffect,
5
- useRef,
6
- useState,
7
- } from "react"
1
+ import { type RefObject, useEffect, useLayoutEffect, useRef, useState } from "react"
8
2
  import { ownsFloatingLayer } from "../../lib/floating-layers"
9
3
  import { enterModalEnvironment } from "./modal-environment"
10
4
 
@@ -19,12 +13,8 @@ const focusableSelector = [
19
13
  "[contenteditable=true]",
20
14
  ].join(",")
21
15
 
22
- function focusableElements(
23
- panel: HTMLElement
24
- ): HTMLElement[] {
25
- return Array.from(
26
- panel.querySelectorAll<HTMLElement>(focusableSelector)
27
- ).filter(
16
+ function focusableElements(panel: HTMLElement): HTMLElement[] {
17
+ return Array.from(panel.querySelectorAll<HTMLElement>(focusableSelector)).filter(
28
18
  (element) =>
29
19
  element.tabIndex >= 0 &&
30
20
  !element.matches(":disabled") &&
@@ -35,15 +25,10 @@ function focusableElements(
35
25
  }
36
26
 
37
27
  /** Keeps keyboard focus in the foremost sheet, including its floating pickers. */
38
- export function useSheetFocus(
39
- panel: RefObject<HTMLDivElement | null>,
40
- onClose: () => void
41
- ) {
28
+ export function useSheetFocus(panel: RefObject<HTMLDivElement | null>, onClose: () => void) {
42
29
  // Capture before children mount, since a child may use autoFocus.
43
30
  const [opener] = useState(() =>
44
- typeof document === "undefined"
45
- ? null
46
- : document.activeElement
31
+ typeof document === "undefined" ? null : document.activeElement
47
32
  )
48
33
  const close = useRef(onClose)
49
34
  useEffect(() => {
@@ -55,34 +40,22 @@ export function useSheetFocus(
55
40
  if (!surface) return
56
41
  sheets.push(surface)
57
42
  const foremost = () => sheets.at(-1) === surface
58
- const focusFirst = () =>
59
- (focusableElements(surface)[0] ?? surface).focus()
60
- const inFloatingLayer = (element: Element | null) =>
61
- ownsFloatingLayer(surface, element)
43
+ const focusFirst = () => (focusableElements(surface)[0] ?? surface).focus()
44
+ const inFloatingLayer = (element: Element | null) => ownsFloatingLayer(surface, element)
62
45
  const belongsToSheet = (element: Element | null) =>
63
- surface.contains(element) ||
64
- inFloatingLayer(element)
46
+ surface.contains(element) || inFloatingLayer(element)
65
47
 
66
- if (!surface.contains(document.activeElement))
67
- surface.focus({ preventScroll: true })
68
- const leaveModalEnvironment =
69
- enterModalEnvironment(surface)
48
+ if (!surface.contains(document.activeElement)) surface.focus({ preventScroll: true })
49
+ const leaveModalEnvironment = enterModalEnvironment(surface)
70
50
 
71
51
  const onFocus = (event: FocusEvent) => {
72
- if (
73
- foremost() &&
74
- !belongsToSheet(
75
- event.target as Element | null
76
- )
77
- )
78
- focusFirst()
52
+ if (foremost() && !belongsToSheet(event.target as Element | null)) focusFirst()
79
53
  }
80
54
  const onKey = (event: KeyboardEvent) => {
81
55
  if (!foremost() || event.defaultPrevented) return
82
56
  if (event.key === "Escape") {
83
57
  // Floating controls handle their own Escape before the sheet.
84
- if (inFloatingLayer(document.activeElement))
85
- return
58
+ if (inFloatingLayer(document.activeElement)) return
86
59
  event.preventDefault()
87
60
  event.stopPropagation()
88
61
  close.current()
@@ -94,17 +67,13 @@ export function useSheetFocus(
94
67
  const active = document.activeElement
95
68
  if (
96
69
  event.shiftKey &&
97
- (active === surface ||
98
- active === first ||
99
- !surface.contains(active))
70
+ (active === surface || active === first || !surface.contains(active))
100
71
  ) {
101
72
  event.preventDefault()
102
73
  last.focus()
103
74
  } else if (
104
75
  !event.shiftKey &&
105
- (active === last ||
106
- !surface.contains(active) ||
107
- active === surface)
76
+ (active === last || !surface.contains(active) || active === surface)
108
77
  ) {
109
78
  event.preventDefault()
110
79
  first.focus()
@@ -119,12 +88,7 @@ export function useSheetFocus(
119
88
  document.removeEventListener("focusin", onFocus)
120
89
  window.removeEventListener("keydown", onKey)
121
90
  leaveModalEnvironment()
122
- if (
123
- wasForemost &&
124
- opener instanceof HTMLElement &&
125
- opener.isConnected
126
- )
127
- opener.focus()
91
+ if (wasForemost && opener instanceof HTMLElement && opener.isConnected) opener.focus()
128
92
  }
129
93
  }, [panel, opener])
130
94
  }
@@ -1,20 +1,33 @@
1
- import type { ReactNode } from "react"
1
+ import { useId, type ReactNode } from "react"
2
2
  import { cn } from "../../lib/class-names"
3
3
 
4
- export function SidebarSection({
5
- title,
6
- children,
7
- }: {
4
+ export interface SidebarSectionProps {
5
+ /** Visible heading for this group of navigation rows. */
8
6
  title: string
9
7
  children: ReactNode
10
- }) {
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({ title, children }: SidebarSectionProps) {
20
+ const headingId = useId()
11
21
  return (
12
- <div className="flex flex-col gap-0.5">
13
- <span className="px-2.5 pb-1.5 text-caption font-semibold text-label-tertiary">
22
+ <section aria-labelledby={headingId} className="flex flex-col gap-0.5">
23
+ <h2
24
+ id={headingId}
25
+ className="px-2.5 pb-1.5 text-caption font-semibold text-label-tertiary"
26
+ >
14
27
  {title}
15
- </span>
28
+ </h2>
16
29
  {children}
17
- </div>
30
+ </section>
18
31
  )
19
32
  }
20
33
 
@@ -22,31 +35,17 @@ export function SidebarSection({
22
35
  export function sidebarItemClass(active?: boolean): string {
23
36
  return cn(
24
37
  "group flex items-center gap-2.5 rounded-2xl px-2.5 py-[7px] text-subheadline text-label no-underline transition-colors duration-fast",
25
- active
26
- ? "bg-accent-soft font-medium text-label"
27
- : "hover:bg-fill/70"
38
+ active ? "bg-accent-soft font-medium text-label" : "hover:bg-fill/70"
28
39
  )
29
40
  }
30
41
 
31
- export function SidebarItemContent({
32
- icon,
33
- count,
34
- active,
35
- children,
36
- }: {
37
- icon: ReactNode
38
- count?: number
39
- active?: boolean
40
- children: ReactNode
41
- }) {
42
+ export function SidebarItemContent({ icon, count, active, children }: SidebarItemContentProps) {
42
43
  return (
43
44
  <>
44
45
  <span
45
46
  className={cn(
46
47
  "flex transition-colors",
47
- active
48
- ? "text-accent-text"
49
- : "text-label-secondary"
48
+ active ? "text-accent-text" : "text-label-secondary"
50
49
  )}
51
50
  >
52
51
  {icon}
@@ -56,9 +55,7 @@ export function SidebarItemContent({
56
55
  <span
57
56
  className={cn(
58
57
  "text-footnote tabular-nums",
59
- active
60
- ? "text-accent-text"
61
- : "text-label-tertiary"
58
+ active ? "text-accent-text" : "text-label-tertiary"
62
59
  )}
63
60
  >
64
61
  {count}