@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,459 +0,0 @@
1
- import {
2
- AnimatePresence,
3
- motion,
4
- useIsPresent,
5
- useReducedMotion,
6
- } from "motion/react";
7
- import {
8
- useEffect,
9
- useLayoutEffect,
10
- useRef,
11
- useState,
12
- useSyncExternalStore,
13
- } from "react";
14
- import { FLOATING_LAYER } from "../../hooks/use-dismiss";
15
- import { CheckIcon } from "../../icons/icons";
16
- import { cn } from "../../lib/class-names";
17
- import {
18
- belongsToFloatingSurface,
19
- registerFloatingLayer,
20
- } from "../../lib/floating-layers";
21
- import { screenEdges } from "../../lib/screen-edges";
22
- import { fluidOvershoot } from "../../motion/transitions";
23
- import { concealMenuSource } from "./conceal-menu-source";
24
- import {
25
- findMenuTypeaheadIndex,
26
- isMenuNavigationKey,
27
- nextMenuIndex,
28
- } from "./menu-navigation";
29
- import { menuPosition } from "./menu-position";
30
- import { menuSurfaceExit, menuSurfaceReveal } from "./menu-reveal";
31
- import {
32
- closeContextMenu,
33
- getContextMenu,
34
- type ContextMenuSize,
35
- subscribeContextMenu,
36
- } from "./context-menu-store";
37
- import type { OpenMenu } from "./context-menu-store";
38
-
39
- const surfaceSizes: Record<ContextMenuSize, string> = {
40
- sm: "min-w-44 max-w-[min(240px,calc(100vw-24px))] rounded-2xl p-1",
41
- md: "min-w-50 max-w-[min(280px,calc(100vw-24px))] rounded-3xl p-1.5",
42
- lg: "min-w-56 max-w-[min(320px,calc(100vw-24px))] rounded-3xl p-2",
43
- };
44
- const itemSizes: Record<ContextMenuSize, string> = {
45
- sm: "flex items-center gap-2 rounded-md px-2 py-1 text-start text-caption transition-colors disabled:opacity-40",
46
- md: "flex items-center gap-2.5 rounded-lg px-2.5 text-start text-subheadline transition-colors disabled:opacity-40",
47
- lg: "flex items-center gap-3 rounded-lg px-3 py-2 text-start text-body transition-colors disabled:opacity-40",
48
- };
49
- const headingSizes: Record<ContextMenuSize, string> = {
50
- sm: "px-2 pt-1 pb-0.5 text-caption2 font-semibold text-label-tertiary",
51
- md: "px-2.5 pt-1.5 pb-0.5 text-caption2 font-semibold text-label-tertiary",
52
- lg: "px-3 pt-2 pb-1 text-caption font-semibold text-label-tertiary",
53
- };
54
- const dividerSizes: Record<ContextMenuSize, string> = {
55
- sm: "mx-1.5 my-0.5 h-px bg-separator/80",
56
- md: "mx-2 my-1 h-px bg-separator/80",
57
- lg: "mx-2.5 my-1.5 h-px bg-separator/80",
58
- };
59
- const iconSlotSizes: Record<ContextMenuSize, string> = {
60
- sm: "flex w-3.5 shrink-0 justify-center text-label-secondary",
61
- md: "flex w-4 shrink-0 justify-center text-label-secondary",
62
- lg: "flex w-5 shrink-0 justify-center text-label-secondary",
63
- };
64
- const checkIconSizes: Record<ContextMenuSize, number> = {
65
- sm: 13,
66
- md: 15,
67
- lg: 17,
68
- };
69
-
70
- /** Renders the open context menu. Mount once, near the app root. */
71
- export function ContextMenuHost() {
72
- const menu = useSyncExternalStore(
73
- subscribeContextMenu,
74
- getContextMenu,
75
- () => null,
76
- );
77
- return (
78
- <AnimatePresence>
79
- {menu && <Menu key={menu.id} menu={menu} />}
80
- </AnimatePresence>
81
- );
82
- }
83
-
84
- function Menu({ menu }: { menu: OpenMenu }) {
85
- const present = useIsPresent();
86
- const reducedMotion = useReducedMotion();
87
- const ref = useRef<HTMLDivElement>(null);
88
- const content = useRef<HTMLDivElement>(null);
89
- const [position, setPosition] = useState({
90
- left: menu.x,
91
- top: menu.y,
92
- originX: 0,
93
- originY: 0,
94
- maxHeight: undefined as number | undefined,
95
- width: 0,
96
- height: 0,
97
- radius: 0,
98
- ready: false,
99
- });
100
- const [focused, setFocused] = useState(-1);
101
- const typeahead = useRef({ query: "", at: 0 });
102
-
103
- useLayoutEffect(() => {
104
- if (
105
- !present ||
106
- (!menu.source && !menu.toolbar) ||
107
- !position.ready ||
108
- !(menu.anchor instanceof HTMLElement)
109
- )
110
- return;
111
- const anchor = menu.toolbar ?? menu.anchor;
112
- const surface = ref.current;
113
- const restore = concealMenuSource(anchor, Boolean(menu.toolbar));
114
- return () => {
115
- const restored = restore();
116
- if (
117
- restored &&
118
- menu.toolbar &&
119
- menu.restoreFocus &&
120
- menu.anchor instanceof HTMLElement &&
121
- (document.activeElement === document.body ||
122
- surface?.contains(document.activeElement))
123
- )
124
- menu.anchor.focus({ preventScroll: true });
125
- };
126
- }, [menu, position.ready, present]);
127
-
128
- useLayoutEffect(() => {
129
- const surface = ref.current;
130
- if (!surface || !present || !position.ready) return;
131
- const unregister = menu.anchor
132
- ? registerFloatingLayer(surface, menu.anchor)
133
- : undefined;
134
- surface.focus();
135
- return unregister;
136
- }, [menu.anchor, present, position.ready]);
137
-
138
- // Keep the whole menu on screen, opening up or left when near an edge. The
139
- // layout size, not the on-screen one: the menu is still mid-scale here.
140
- useLayoutEffect(() => {
141
- if (!ref.current || !present) return;
142
- const viewport = window.visualViewport;
143
- let frame = 0;
144
- const refit = () => {
145
- const element = ref.current;
146
- if (!element) return;
147
- const edges = screenEdges();
148
- const left = viewport?.offsetLeft ?? 0;
149
- const top = viewport?.offsetTop ?? 0;
150
- const next = {
151
- ...menuPosition(
152
- menu,
153
- {
154
- width: element.offsetWidth,
155
- height: Math.max(
156
- element.offsetHeight,
157
- (content.current?.scrollHeight ?? 0) + 12,
158
- ),
159
- },
160
- {
161
- left: left + edges.left,
162
- top: top + edges.top,
163
- right: left + (viewport?.width ?? window.innerWidth) - edges.right,
164
- bottom:
165
- top + (viewport?.height ?? window.innerHeight) - edges.bottom,
166
- },
167
- ),
168
- radius:
169
- Number.parseFloat(getComputedStyle(element).borderTopLeftRadius) || 0,
170
- ready: true,
171
- };
172
- setPosition((current) =>
173
- current.left === next.left &&
174
- current.top === next.top &&
175
- current.originX === next.originX &&
176
- current.originY === next.originY &&
177
- current.maxHeight === next.maxHeight &&
178
- current.width === next.width &&
179
- current.height === next.height &&
180
- current.radius === next.radius &&
181
- current.ready === next.ready
182
- ? current
183
- : next,
184
- );
185
- };
186
- const schedule = () => {
187
- cancelAnimationFrame(frame);
188
- frame = requestAnimationFrame(refit);
189
- };
190
- refit();
191
- viewport?.addEventListener("resize", schedule);
192
- viewport?.addEventListener("scroll", schedule);
193
- window.addEventListener("resize", schedule);
194
- return () => {
195
- cancelAnimationFrame(frame);
196
- viewport?.removeEventListener("resize", schedule);
197
- viewport?.removeEventListener("scroll", schedule);
198
- window.removeEventListener("resize", schedule);
199
- };
200
- }, [menu, present]);
201
-
202
- useEffect(() => {
203
- if (!present) return;
204
- const onPointer = (event: PointerEvent) => {
205
- if (
206
- !ref.current ||
207
- !belongsToFloatingSurface(ref.current, event.target as Element)
208
- )
209
- closeContextMenu(false);
210
- };
211
- const close = () => closeContextMenu(false);
212
- let scrollIntentUntil = 0;
213
- const markScroll = () => {
214
- scrollIntentUntil = performance.now() + 2000;
215
- };
216
- const onScrollKey = (event: KeyboardEvent) => {
217
- if (
218
- !ref.current?.contains(event.target as Node) &&
219
- ["PageDown", "PageUp", "Home", "End", " "].includes(event.key)
220
- )
221
- markScroll();
222
- };
223
- const onScroll = (event: Event) => {
224
- if (
225
- performance.now() < scrollIntentUntil &&
226
- !ref.current?.contains(event.target as Node)
227
- )
228
- close();
229
- };
230
- // Opened by a long-press: ignore the finger lifting off.
231
- const timer = setTimeout(() => {
232
- window.addEventListener("pointerdown", onPointer, true);
233
- }, 0);
234
- window.addEventListener("blur", close);
235
- window.addEventListener("wheel", markScroll, {
236
- capture: true,
237
- passive: true,
238
- });
239
- window.addEventListener("touchmove", markScroll, {
240
- capture: true,
241
- passive: true,
242
- });
243
- window.addEventListener("keydown", onScrollKey, true);
244
- window.addEventListener("scroll", onScroll, true);
245
- return () => {
246
- clearTimeout(timer);
247
- window.removeEventListener("pointerdown", onPointer, true);
248
- window.removeEventListener("blur", close);
249
- window.removeEventListener("wheel", markScroll, true);
250
- window.removeEventListener("touchmove", markScroll, true);
251
- window.removeEventListener("keydown", onScrollKey, true);
252
- window.removeEventListener("scroll", onScroll, true);
253
- };
254
- }, [present]);
255
-
256
- const source = menuSurfaceReveal(
257
- position.ready ? (menu.toolbarRect ?? menu.source) : undefined,
258
- position,
259
- );
260
- let actionIndex = -1;
261
- let dividerIndex = 0;
262
- let headingIndex = 0;
263
- return (
264
- <div
265
- ref={ref}
266
- role="menu"
267
- tabIndex={-1}
268
- onKeyDown={(event) => {
269
- if (!present) return;
270
- if (event.key === "Escape") {
271
- event.preventDefault();
272
- event.stopPropagation();
273
- closeContextMenu();
274
- return;
275
- }
276
- if (event.key === "Tab") {
277
- closeContextMenu();
278
- return;
279
- }
280
- const controls = Array.from(
281
- ref.current?.querySelectorAll<HTMLButtonElement>(
282
- "[role=menuitem]:not(:disabled)",
283
- ) ?? [],
284
- );
285
- if (!isMenuNavigationKey(event.key)) {
286
- if (
287
- event.key.length !== 1 ||
288
- !event.key.trim() ||
289
- event.altKey ||
290
- event.ctrlKey ||
291
- event.metaKey ||
292
- event.nativeEvent.isComposing
293
- )
294
- return;
295
- const now = performance.now();
296
- const query =
297
- (now - typeahead.current.at < 700 ? typeahead.current.query : "") +
298
- event.key;
299
- typeahead.current = { query, at: now };
300
- const labels = controls.map((control) => control.textContent ?? "");
301
- const current = controls.indexOf(
302
- document.activeElement as HTMLButtonElement,
303
- );
304
- let next = findMenuTypeaheadIndex(labels, query, current);
305
- if (next < 0) {
306
- typeahead.current.query = event.key;
307
- next = findMenuTypeaheadIndex(labels, event.key, current);
308
- }
309
- if (next >= 0) {
310
- event.preventDefault();
311
- controls[next]?.focus();
312
- }
313
- return;
314
- }
315
- event.preventDefault();
316
- if (!controls.length) return;
317
- const current = controls.indexOf(
318
- document.activeElement as HTMLButtonElement,
319
- );
320
- const next = nextMenuIndex(event.key, current, controls.length);
321
- controls[next]?.focus();
322
- }}
323
- {...{ [FLOATING_LAYER]: "" }}
324
- className={cn(
325
- "fixed isolate z-75 flex flex-col outline-none",
326
- surfaceSizes[menu.size],
327
- menu.touch && "min-w-60",
328
- !present && "pointer-events-none",
329
- )}
330
- style={{
331
- left: position.left,
332
- top: position.top,
333
- maxHeight: position.maxHeight,
334
- minWidth: menu.toolbarRect
335
- ? Math.min(
336
- Math.max(200, menu.toolbarRect.width),
337
- window.innerWidth - 24,
338
- )
339
- : undefined,
340
- visibility: position.ready ? undefined : "hidden",
341
- }}
342
- onContextMenu={(event) => event.preventDefault()}
343
- >
344
- {position.ready && (
345
- <motion.div
346
- aria-hidden="true"
347
- className="glass-menu pointer-events-none absolute top-0 left-0 -z-10 rounded-3xl"
348
- style={{ width: "100%", height: "100%" }}
349
- initial={reducedMotion || !position.ready ? false : source}
350
- animate={
351
- position.ready
352
- ? {
353
- x: 0,
354
- y: 0,
355
- width: position.width,
356
- height: position.height,
357
- opacity: 1,
358
- borderRadius: position.radius,
359
- }
360
- : undefined
361
- }
362
- exit={reducedMotion ? { opacity: 0 } : menuSurfaceExit(source)}
363
- transition={
364
- reducedMotion
365
- ? { duration: 0 }
366
- : { ...fluidOvershoot, opacity: { duration: 0.16 } }
367
- }
368
- />
369
- )}
370
- <motion.div
371
- ref={content}
372
- className="flex flex-col overflow-y-auto overscroll-contain"
373
- style={{
374
- maxHeight: position.maxHeight
375
- ? Math.max(0, position.maxHeight - 12)
376
- : undefined,
377
- }}
378
- initial={
379
- reducedMotion
380
- ? false
381
- : {
382
- opacity: 0,
383
- scale: 0.96,
384
- y: menu.source && menu.source.top > position.top ? 4 : -4,
385
- }
386
- }
387
- animate={{ opacity: 1, scale: 1, y: 0 }}
388
- exit={{
389
- opacity: 0,
390
- scale: 0.98,
391
- transition: {
392
- duration: reducedMotion ? 0 : 0.06,
393
- },
394
- }}
395
- transition={{
396
- duration: reducedMotion ? 0 : 0.2,
397
- ease: reducedMotion
398
- ? undefined
399
- : ([0.4, 0, 0.2, 1] as [number, number, number, number]),
400
- delay: reducedMotion || !menu.source ? 0 : 0.06,
401
- }}
402
- >
403
- {menu.items.map((item) => {
404
- if (item === "divider") {
405
- const key = `divider-${dividerIndex++}`;
406
- return <div key={key} className={dividerSizes[menu.size]} />;
407
- }
408
- if ("heading" in item) {
409
- const key = `heading-${headingIndex++}`;
410
- return (
411
- <span key={key} className={headingSizes[menu.size]}>
412
- {item.heading}
413
- </span>
414
- );
415
- }
416
- if (!item.disabled) actionIndex += 1;
417
- const current = actionIndex;
418
- const key = `item-${current}`;
419
- return (
420
- <button
421
- key={key}
422
- type="button"
423
- role="menuitem"
424
- tabIndex={-1}
425
- disabled={item.disabled}
426
- onFocus={() => setFocused(current)}
427
- onPointerEnter={() => !item.disabled && setFocused(current)}
428
- onClick={() => {
429
- closeContextMenu();
430
- item.onSelect();
431
- }}
432
- className={cn(
433
- itemSizes[menu.size],
434
- menu.touch ? "py-2.5" : "py-1.5",
435
- item.destructive ? "text-danger" : "text-label",
436
- focused === current &&
437
- !item.disabled &&
438
- (item.destructive ? "bg-danger/10" : "bg-fill"),
439
- )}
440
- >
441
- <span className={iconSlotSizes[menu.size]}>
442
- {item.checked ? (
443
- <CheckIcon
444
- size={checkIconSizes[menu.size]}
445
- strokeWidth={2.4}
446
- className="text-accent-text"
447
- />
448
- ) : (
449
- item.icon
450
- )}
451
- </span>
452
- <span className="grow truncate">{item.label}</span>
453
- </button>
454
- );
455
- })}
456
- </motion.div>
457
- </div>
458
- );
459
- }
@@ -1,167 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import type { MenuRect } from "./menu-reveal";
3
-
4
- export type ContextMenuAlignX = "start" | "end";
5
- export type ContextMenuAlignY = "top" | "bottom";
6
- export type ContextMenuEdge = "leading" | "trailing";
7
- export type ContextMenuSize = "sm" | "md" | "lg";
8
-
9
- /** One row of a context menu, or a divider between groups of rows. */
10
- export type ContextMenuItem =
11
- | {
12
- label: string;
13
- icon?: ReactNode;
14
- onSelect: () => void;
15
- destructive?: boolean;
16
- disabled?: boolean;
17
- /** Marks the current choice, e.g. a note's kind. */
18
- checked?: boolean;
19
- }
20
- | { heading: string }
21
- | "divider";
22
-
23
- export interface OpenMenu {
24
- id: number;
25
- anchor: Element | null;
26
- x: number;
27
- y: number;
28
- items: ContextMenuItem[];
29
- /** Opened by long-press: bigger rows for fingers. */
30
- touch: boolean;
31
- /** Surface, item and heading density. @default "md" */
32
- size: ContextMenuSize;
33
- /** Which edge of the menu sits at `x`: its left (`start`) or its right (`end`). */
34
- alignX: ContextMenuAlignX;
35
- /** Which edge of the menu sits at `y`: its top (`top`) or its bottom (`bottom`). */
36
- alignY: ContextMenuAlignY;
37
- source?: MenuRect;
38
- toolbar?: HTMLElement;
39
- toolbarRect?: MenuRect;
40
- restoreFocus?: boolean;
41
- }
42
-
43
- let menu: OpenMenu | null = null;
44
- /** The menu shown most recently, kept after it closes so a follow-up can stand in its place. */
45
- let last: OpenMenu | null = null;
46
- let nextId = 1;
47
- const listeners = new Set<() => void>();
48
- const emit = () => {
49
- for (const listener of listeners) listener();
50
- };
51
-
52
- /** Opens a menu at a point, such as where a pointer was pressed. */
53
- export function openContextMenu(
54
- x: number,
55
- y: number,
56
- items: ContextMenuItem[],
57
- touch = false,
58
- anchor: Element | null = typeof document === "undefined"
59
- ? null
60
- : document.activeElement,
61
- size: ContextMenuSize = "md",
62
- ) {
63
- menu = {
64
- id: nextId++,
65
- anchor,
66
- x,
67
- y,
68
- items,
69
- touch,
70
- size,
71
- alignX: "start",
72
- alignY: "top",
73
- };
74
- last = menu;
75
- emit();
76
- }
77
-
78
- /**
79
- * Opens a second menu where the last one stood, the way an iOS menu swaps
80
- * in a submenu: a long list (a note's fonts, its kinds) stays one row in the
81
- * first menu instead of making it tall.
82
- */
83
- export function openFollowUpMenu(items: ContextMenuItem[]) {
84
- if (!last) return;
85
- menu = { ...last, id: nextId++, items, source: undefined };
86
- last = menu;
87
- emit();
88
- }
89
-
90
- /**
91
- * Expands a control into a menu, lined up with its leading or trailing
92
- * edge and growing down (or up) from the control's bounds. Leading and
93
- * trailing follow the text direction, so right-to-left languages mirror.
94
- * The menu's real size decides where it goes; nothing is guessed.
95
- */
96
- export function openMenu(
97
- anchor: Element,
98
- items: ContextMenuItem[],
99
- {
100
- edge = "leading",
101
- above = false,
102
- toolbar,
103
- size = "md",
104
- }: {
105
- edge?: ContextMenuEdge;
106
- above?: boolean;
107
- /** Replace this action group with a horizontally expanding menu surface. */
108
- toolbar?: HTMLElement;
109
- /** Surface, item and heading density. @default "md" */
110
- size?: ContextMenuSize;
111
- } = {},
112
- ) {
113
- const rect = anchor.getBoundingClientRect();
114
- const toolbarRect = toolbar?.getBoundingClientRect();
115
- const rtl = getComputedStyle(anchor).direction === "rtl";
116
- // Trailing is the right edge in left-to-right text, the left edge in right-to-left.
117
- const right = (edge === "trailing") !== rtl;
118
- menu = {
119
- id: nextId++,
120
- anchor,
121
- x: right ? (toolbarRect ?? rect).right : (toolbarRect ?? rect).left,
122
- y: toolbar ? rect.top : above ? rect.bottom : rect.top,
123
- items,
124
- touch: false,
125
- size,
126
- alignX: right ? "end" : "start",
127
- alignY: above ? "bottom" : "top",
128
- toolbar,
129
- toolbarRect,
130
- source: {
131
- left: rect.left,
132
- top: rect.top,
133
- width: rect.width,
134
- height: rect.height,
135
- },
136
- };
137
- last = menu;
138
- emit();
139
- }
140
-
141
- export function closeContextMenu(restoreFocus = true) {
142
- if (!menu) return;
143
- const anchor = menu.anchor;
144
- const toolbar = menu.toolbar;
145
- menu.restoreFocus = restoreFocus;
146
- menu = null;
147
- if (
148
- restoreFocus &&
149
- !toolbar &&
150
- typeof HTMLElement !== "undefined" &&
151
- anchor instanceof HTMLElement &&
152
- anchor.isConnected
153
- )
154
- anchor.focus();
155
- emit();
156
- }
157
-
158
- export function subscribeContextMenu(listener: () => void) {
159
- listeners.add(listener);
160
- return () => {
161
- listeners.delete(listener);
162
- };
163
- }
164
-
165
- export function getContextMenu(): OpenMenu | null {
166
- return menu;
167
- }
@@ -1,36 +0,0 @@
1
- export type MenuNavigationKey = "ArrowDown" | "ArrowUp" | "Home" | "End";
2
-
3
- export function isMenuNavigationKey(key: string): key is MenuNavigationKey {
4
- return (
5
- key === "ArrowDown" || key === "ArrowUp" || key === "Home" || key === "End"
6
- );
7
- }
8
-
9
- /** Index of the next enabled action in a menu, with wrapping arrow navigation. */
10
- export function nextMenuIndex(
11
- key: MenuNavigationKey,
12
- current: number,
13
- count: number,
14
- ): number {
15
- if (count <= 0) return -1;
16
- if (key === "Home") return 0;
17
- if (key === "End") return count - 1;
18
- if (key === "ArrowDown") return (current + 1) % count;
19
- return current < 0 ? count - 1 : (current - 1 + count) % count;
20
- }
21
-
22
- /** Finds a matching label after the current action, wrapping at the end. */
23
- export function findMenuTypeaheadIndex(
24
- labels: ReadonlyArray<string>,
25
- query: string,
26
- current: number,
27
- ): number {
28
- if (!labels.length || !query.trim()) return -1;
29
- const needle = query.toLocaleLowerCase();
30
- for (let offset = 1; offset <= labels.length; offset++) {
31
- const index = (current + offset + labels.length) % labels.length;
32
- if (labels[index]?.trim().toLocaleLowerCase().startsWith(needle))
33
- return index;
34
- }
35
- return -1;
36
- }
@@ -1,38 +0,0 @@
1
- import type { OpenMenu } from "./context-menu-store";
2
- import type { MenuRect } from "./menu-reveal";
3
-
4
- type MenuAnchor = Pick<OpenMenu, "x" | "y" | "alignX" | "alignY">;
5
- type MenuSize = Pick<MenuRect, "width" | "height">;
6
- type MenuBounds = {
7
- left: number;
8
- top: number;
9
- right: number;
10
- bottom: number;
11
- };
12
-
13
- /** Fit within the current visible viewport, including a keyboard or Safari pan. */
14
- export function menuPosition(
15
- menu: MenuAnchor,
16
- size: MenuSize,
17
- bounds: MenuBounds,
18
- ) {
19
- const { width, height } = size;
20
- const { left, top, right, bottom } = bounds;
21
- const fitsAfterX = menu.x + width <= right;
22
- const fitsBeforeX = menu.x - width >= left;
23
- const endX = menu.alignX === "end" ? fitsBeforeX || !fitsAfterX : !fitsAfterX;
24
- const fitsBelow = menu.y + height <= bottom;
25
- const fitsAbove = menu.y - height >= top;
26
- const endY = menu.alignY === "bottom" ? fitsAbove || !fitsBelow : !fitsBelow;
27
- const clamp = (value: number, min: number, max: number) =>
28
- Math.min(Math.max(value, min), Math.max(min, max));
29
- return {
30
- left: clamp(endX ? menu.x - width : menu.x, left, right - width),
31
- top: clamp(endY ? menu.y - height : menu.y, top, bottom - height),
32
- originX: endX ? 1 : 0,
33
- originY: endY ? 1 : 0,
34
- maxHeight: Math.max(0, bottom - top),
35
- width,
36
- height: Math.min(height, Math.max(0, bottom - top)),
37
- };
38
- }