@exsto/ds 0.0.1-rc.2 → 0.0.1-rc.22

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 (346) hide show
  1. package/README.md +171 -28
  2. package/dist/date-picker.js +2 -0
  3. package/dist/ds/src/date-picker.d.ts +9 -0
  4. package/dist/ds/src/file-input.d.ts +9 -0
  5. package/dist/ds/src/index.d.ts +2 -3
  6. package/dist/ds/src/rich-text-editor.d.ts +8 -0
  7. package/dist/ds/src/time-field.d.ts +9 -0
  8. package/dist/file-input.js +2 -0
  9. package/dist/index.js +79 -2
  10. package/dist/rich-text-editor.js +4 -0
  11. package/dist/source-hash.txt +1 -0
  12. package/dist/styles.css +1201 -404
  13. package/dist/theme.css +125 -7
  14. package/dist/time-field.js +2 -0
  15. package/dist/ui/src/components/edyn/animated-number/animated-number.d.ts +30 -0
  16. package/dist/ui/src/components/edyn/animated-number/animated-number.js +108 -0
  17. package/dist/ui/src/components/edyn/animated-number/animated-number.js.map +1 -0
  18. package/dist/ui/src/components/edyn/animated-number/animated-number.test.d.ts +9 -0
  19. package/dist/ui/src/components/edyn/animated-number/index.d.ts +1 -0
  20. package/dist/ui/src/components/edyn/audio-player/audio-player.d.ts +3 -2
  21. package/dist/ui/src/components/edyn/audio-player/audio-player.js +86 -0
  22. package/dist/ui/src/components/edyn/audio-player/audio-player.js.map +1 -0
  23. package/dist/ui/src/components/edyn/date-picker/date-picker.d.ts +86 -0
  24. package/dist/ui/src/components/edyn/date-picker/date-picker.js +302 -0
  25. package/dist/ui/src/components/edyn/date-picker/date-picker.js.map +1 -0
  26. package/dist/ui/src/components/edyn/date-picker/date-picker.state.test.d.ts +9 -0
  27. package/dist/ui/src/components/edyn/date-picker/date-text.d.ts +40 -0
  28. package/dist/ui/src/components/edyn/date-picker/date-text.js +105 -0
  29. package/dist/ui/src/components/edyn/date-picker/date-text.js.map +1 -0
  30. package/dist/ui/src/components/edyn/date-picker/index.d.ts +2 -0
  31. package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.d.ts +28 -0
  32. package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.js +70 -0
  33. package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.js.map +1 -0
  34. package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.test.d.ts +9 -0
  35. package/dist/ui/src/components/edyn/date-range-picker/index.d.ts +1 -0
  36. package/dist/ui/src/components/edyn/file-input/file-input.d.ts +90 -0
  37. package/dist/ui/src/components/edyn/file-input/file-input.js +261 -0
  38. package/dist/ui/src/components/edyn/file-input/file-input.js.map +1 -0
  39. package/dist/ui/src/components/edyn/file-input/file-input.test.d.ts +8 -0
  40. package/dist/ui/src/components/edyn/file-input/index.d.ts +1 -0
  41. package/dist/ui/src/components/edyn/initials-avatar/index.d.ts +1 -0
  42. package/dist/ui/src/components/edyn/initials-avatar/initials-avatar.d.ts +54 -0
  43. package/dist/ui/src/components/edyn/initials-avatar/initials-avatar.js +86 -0
  44. package/dist/ui/src/components/edyn/initials-avatar/initials-avatar.js.map +1 -0
  45. package/dist/ui/src/components/edyn/initials-avatar/initials-avatar.test.d.ts +10 -0
  46. package/dist/ui/src/components/edyn/multi-select/index.d.ts +1 -0
  47. package/dist/ui/src/components/edyn/multi-select/multi-select.d.ts +117 -0
  48. package/dist/ui/src/components/edyn/multi-select/multi-select.js +342 -0
  49. package/dist/ui/src/components/edyn/multi-select/multi-select.js.map +1 -0
  50. package/dist/ui/src/components/edyn/multi-select/multi-select.test.d.ts +9 -0
  51. package/dist/ui/src/components/edyn/presence/index.d.ts +1 -0
  52. package/dist/ui/src/components/edyn/presence/presence.d.ts +15 -0
  53. package/dist/ui/src/components/edyn/presence/presence.js +58 -0
  54. package/dist/ui/src/components/edyn/presence/presence.js.map +1 -0
  55. package/dist/ui/src/components/edyn/presence/presence.test.d.ts +8 -0
  56. package/dist/ui/src/components/edyn/progress-line/index.d.ts +1 -0
  57. package/dist/ui/src/components/edyn/progress-line/progress-line.d.ts +23 -0
  58. package/dist/ui/src/components/edyn/progress-line/progress-line.js +100 -0
  59. package/dist/ui/src/components/edyn/progress-line/progress-line.js.map +1 -0
  60. package/dist/ui/src/components/edyn/progress-line/progress-line.test.d.ts +9 -0
  61. package/dist/ui/src/components/edyn/rich-text-content/allow-list.d.ts +11 -0
  62. package/dist/ui/src/components/edyn/rich-text-content/allow-list.js +37 -0
  63. package/dist/ui/src/components/edyn/rich-text-content/allow-list.js.map +1 -0
  64. package/dist/ui/src/components/edyn/rich-text-content/index.d.ts +2 -0
  65. package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.d.ts +22 -0
  66. package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.js +124 -0
  67. package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.js.map +1 -0
  68. package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.test.d.ts +8 -0
  69. package/dist/ui/src/components/edyn/rich-text-editor/extensions.d.ts +18 -0
  70. package/dist/ui/src/components/edyn/rich-text-editor/extensions.js +124 -0
  71. package/dist/ui/src/components/edyn/rich-text-editor/extensions.js.map +1 -0
  72. package/dist/ui/src/components/edyn/rich-text-editor/index.d.ts +3 -0
  73. package/dist/ui/src/components/edyn/rich-text-editor/mention-list.d.ts +17 -0
  74. package/dist/ui/src/components/edyn/rich-text-editor/mention-list.js +232 -0
  75. package/dist/ui/src/components/edyn/rich-text-editor/mention-list.js.map +1 -0
  76. package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.d.ts +53 -0
  77. package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.js +244 -0
  78. package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.js.map +1 -0
  79. package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.test.d.ts +6 -0
  80. package/dist/ui/src/components/edyn/rich-text-editor/serialize.d.ts +13 -0
  81. package/dist/ui/src/components/edyn/rich-text-editor/serialize.js +55 -0
  82. package/dist/ui/src/components/edyn/rich-text-editor/serialize.js.map +1 -0
  83. package/dist/ui/src/components/edyn/rich-text-editor/sync.d.ts +19 -0
  84. package/dist/ui/src/components/edyn/rich-text-editor/sync.js +34 -0
  85. package/dist/ui/src/components/edyn/rich-text-editor/sync.js.map +1 -0
  86. package/dist/ui/src/components/edyn/rich-text-editor/sync.test.d.ts +11 -0
  87. package/dist/ui/src/components/edyn/rich-text-editor/toolbar.d.ts +20 -0
  88. package/dist/ui/src/components/edyn/rich-text-editor/toolbar.js +235 -0
  89. package/dist/ui/src/components/edyn/rich-text-editor/toolbar.js.map +1 -0
  90. package/dist/ui/src/components/edyn/rich-text-editor/types.d.ts +68 -0
  91. package/dist/ui/src/components/edyn/rich-text-editor/types.js +26 -0
  92. package/dist/ui/src/components/edyn/rich-text-editor/types.js.map +1 -0
  93. package/dist/ui/src/components/edyn/time-field/index.d.ts +1 -0
  94. package/dist/ui/src/components/edyn/time-field/time-field.d.ts +85 -0
  95. package/dist/ui/src/components/edyn/time-field/time-field.js +337 -0
  96. package/dist/ui/src/components/edyn/time-field/time-field.js.map +1 -0
  97. package/dist/ui/src/components/edyn/time-field/time-field.test.d.ts +8 -0
  98. package/dist/ui/src/components/edyn/video-player/video-player.d.ts +2 -2
  99. package/dist/ui/src/components/edyn/video-player/video-player.js +132 -0
  100. package/dist/ui/src/components/edyn/video-player/video-player.js.map +1 -0
  101. package/dist/ui/src/components/forwarded-props.test.d.ts +8 -0
  102. package/dist/ui/src/components/ui/accordion/accordion.d.ts +9 -8
  103. package/dist/ui/src/components/ui/accordion/accordion.js +83 -0
  104. package/dist/ui/src/components/ui/accordion/accordion.js.map +1 -0
  105. package/dist/ui/src/components/ui/alert/alert.js +47 -0
  106. package/dist/ui/src/components/ui/alert/alert.js.map +1 -0
  107. package/dist/ui/src/components/ui/alert-dialog/alert-dialog.js +97 -0
  108. package/dist/ui/src/components/ui/alert-dialog/alert-dialog.js.map +1 -0
  109. package/dist/ui/src/components/ui/aspect-ratio/aspect-ratio.js +15 -0
  110. package/dist/ui/src/components/ui/aspect-ratio/aspect-ratio.js.map +1 -0
  111. package/dist/ui/src/components/ui/attachment/attachment.d.ts +1 -1
  112. package/dist/ui/src/components/ui/attachment/attachment.js +105 -0
  113. package/dist/ui/src/components/ui/attachment/attachment.js.map +1 -0
  114. package/dist/ui/src/components/ui/avatar/avatar.js +51 -0
  115. package/dist/ui/src/components/ui/avatar/avatar.js.map +1 -0
  116. package/dist/ui/src/components/ui/badge/badge.d.ts +1 -1
  117. package/dist/ui/src/components/ui/badge/badge.js +47 -0
  118. package/dist/ui/src/components/ui/badge/badge.js.map +1 -0
  119. package/dist/ui/src/components/ui/breadcrumb/breadcrumb.js +73 -0
  120. package/dist/ui/src/components/ui/breadcrumb/breadcrumb.js.map +1 -0
  121. package/dist/ui/src/components/ui/bubble/bubble.js +74 -0
  122. package/dist/ui/src/components/ui/bubble/bubble.js.map +1 -0
  123. package/dist/ui/src/components/ui/button/button.behavior.test.d.ts +8 -0
  124. package/dist/ui/src/components/ui/button/button.d.ts +1 -1
  125. package/dist/ui/src/components/ui/button/button.js +68 -0
  126. package/dist/ui/src/components/ui/button/button.js.map +1 -0
  127. package/dist/ui/src/components/ui/button-group/button-group.js +37 -0
  128. package/dist/ui/src/components/ui/button-group/button-group.js.map +1 -0
  129. package/dist/ui/src/components/ui/calendar/calendar.behavior.test.d.ts +9 -0
  130. package/dist/ui/src/components/ui/calendar/calendar.d.ts +1 -1
  131. package/dist/ui/src/components/ui/calendar/calendar.js +141 -0
  132. package/dist/ui/src/components/ui/calendar/calendar.js.map +1 -0
  133. package/dist/ui/src/components/ui/card/card.js +57 -0
  134. package/dist/ui/src/components/ui/card/card.js.map +1 -0
  135. package/dist/ui/src/components/ui/carousel/carousel.js +136 -0
  136. package/dist/ui/src/components/ui/carousel/carousel.js.map +1 -0
  137. package/dist/ui/src/components/ui/chart/chart.js +168 -0
  138. package/dist/ui/src/components/ui/chart/chart.js.map +1 -0
  139. package/dist/ui/src/components/ui/checkbox/checkbox.js +21 -0
  140. package/dist/ui/src/components/ui/checkbox/checkbox.js.map +1 -0
  141. package/dist/ui/src/components/ui/collapsible/collapsible.js +26 -0
  142. package/dist/ui/src/components/ui/collapsible/collapsible.js.map +1 -0
  143. package/dist/ui/src/components/ui/combobox/combobox.d.ts +15 -1
  144. package/dist/ui/src/components/ui/combobox/combobox.js +111 -0
  145. package/dist/ui/src/components/ui/combobox/combobox.js.map +1 -0
  146. package/dist/ui/src/components/ui/command/command.d.ts +17 -1
  147. package/dist/ui/src/components/ui/command/command.js +118 -0
  148. package/dist/ui/src/components/ui/command/command.js.map +1 -0
  149. package/dist/ui/src/components/ui/context-menu/context-menu.d.ts +1 -1
  150. package/dist/ui/src/components/ui/context-menu/context-menu.js +145 -0
  151. package/dist/ui/src/components/ui/context-menu/context-menu.js.map +1 -0
  152. package/dist/ui/src/components/ui/dialog/dialog.js +94 -0
  153. package/dist/ui/src/components/ui/dialog/dialog.js.map +1 -0
  154. package/dist/ui/src/components/ui/direction/direction.js +2 -0
  155. package/dist/ui/src/components/ui/drawer/drawer.js +88 -0
  156. package/dist/ui/src/components/ui/drawer/drawer.js.map +1 -0
  157. package/dist/ui/src/components/ui/dropdown-menu/dropdown-menu.d.ts +12 -1
  158. package/dist/ui/src/components/ui/dropdown-menu/dropdown-menu.js +159 -0
  159. package/dist/ui/src/components/ui/dropdown-menu/dropdown-menu.js.map +1 -0
  160. package/dist/ui/src/components/ui/empty/empty.d.ts +5 -1
  161. package/dist/ui/src/components/ui/empty/empty.js +72 -0
  162. package/dist/ui/src/components/ui/empty/empty.js.map +1 -0
  163. package/dist/ui/src/components/ui/field/field.js +36 -0
  164. package/dist/ui/src/components/ui/field/field.js.map +1 -0
  165. package/dist/ui/src/components/ui/hover-card/hover-card.js +39 -0
  166. package/dist/ui/src/components/ui/hover-card/hover-card.js.map +1 -0
  167. package/dist/ui/src/components/ui/indicator/indicator.js +79 -0
  168. package/dist/ui/src/components/ui/indicator/indicator.js.map +1 -0
  169. package/dist/ui/src/components/ui/input/input.js +16 -0
  170. package/dist/ui/src/components/ui/input/input.js.map +1 -0
  171. package/dist/ui/src/components/ui/input-group/input-group.d.ts +1 -1
  172. package/dist/ui/src/components/ui/input-group/input-group.js +77 -0
  173. package/dist/ui/src/components/ui/input-group/input-group.js.map +1 -0
  174. package/dist/ui/src/components/ui/input-otp/input-otp.js +48 -0
  175. package/dist/ui/src/components/ui/input-otp/input-otp.js.map +1 -0
  176. package/dist/ui/src/components/ui/item/item.d.ts +1 -1
  177. package/dist/ui/src/components/ui/item/item.js +122 -0
  178. package/dist/ui/src/components/ui/item/item.js.map +1 -0
  179. package/dist/ui/src/components/ui/kbd/kbd.js +21 -0
  180. package/dist/ui/src/components/ui/kbd/kbd.js.map +1 -0
  181. package/dist/ui/src/components/ui/label/label.js +14 -0
  182. package/dist/ui/src/components/ui/label/label.js.map +1 -0
  183. package/dist/ui/src/components/ui/marker/marker.js +44 -0
  184. package/dist/ui/src/components/ui/marker/marker.js.map +1 -0
  185. package/dist/ui/src/components/ui/menubar/menubar.js +140 -0
  186. package/dist/ui/src/components/ui/menubar/menubar.js.map +1 -0
  187. package/dist/ui/src/components/ui/message/message.js +50 -0
  188. package/dist/ui/src/components/ui/message/message.js.map +1 -0
  189. package/dist/ui/src/components/ui/message-scroller/message-scroller.js +61 -0
  190. package/dist/ui/src/components/ui/message-scroller/message-scroller.js.map +1 -0
  191. package/dist/ui/src/components/ui/native-select/native-select.js +39 -0
  192. package/dist/ui/src/components/ui/native-select/native-select.js.map +1 -0
  193. package/dist/ui/src/components/ui/navigation-menu/navigation-menu.js +87 -0
  194. package/dist/ui/src/components/ui/navigation-menu/navigation-menu.js.map +1 -0
  195. package/dist/ui/src/components/ui/pagination/pagination.d.ts +3 -2
  196. package/dist/ui/src/components/ui/pagination/pagination.js +104 -0
  197. package/dist/ui/src/components/ui/pagination/pagination.js.map +1 -0
  198. package/dist/ui/src/components/ui/popover/popover.d.ts +1 -1
  199. package/dist/ui/src/components/ui/popover/popover.js +59 -0
  200. package/dist/ui/src/components/ui/popover/popover.js.map +1 -0
  201. package/dist/ui/src/components/ui/progress/progress.behavior.test.d.ts +8 -0
  202. package/dist/ui/src/components/ui/progress/progress.d.ts +43 -1
  203. package/dist/ui/src/components/ui/progress/progress.js +70 -0
  204. package/dist/ui/src/components/ui/progress/progress.js.map +1 -0
  205. package/dist/ui/src/components/ui/questionnaire/questionnaire.js +171 -0
  206. package/dist/ui/src/components/ui/questionnaire/questionnaire.js.map +1 -0
  207. package/dist/ui/src/components/ui/radio-group/radio-group.js +29 -0
  208. package/dist/ui/src/components/ui/radio-group/radio-group.js.map +1 -0
  209. package/dist/ui/src/components/ui/resizable/resizable.js +29 -0
  210. package/dist/ui/src/components/ui/resizable/resizable.js.map +1 -0
  211. package/dist/ui/src/components/ui/scroll-area/index.d.ts +1 -0
  212. package/dist/ui/src/components/ui/scroll-area/popup-list-scroll.d.ts +13 -0
  213. package/dist/ui/src/components/ui/scroll-area/popup-list-scroll.js +69 -0
  214. package/dist/ui/src/components/ui/scroll-area/popup-list-scroll.js.map +1 -0
  215. package/dist/ui/src/components/ui/scroll-area/scroll-area.behavior.test.d.ts +12 -0
  216. package/dist/ui/src/components/ui/scroll-area/scroll-area.d.ts +57 -6
  217. package/dist/ui/src/components/ui/scroll-area/scroll-area.js +125 -0
  218. package/dist/ui/src/components/ui/scroll-area/scroll-area.js.map +1 -0
  219. package/dist/ui/src/components/ui/select/select.js +97 -0
  220. package/dist/ui/src/components/ui/select/select.js.map +1 -0
  221. package/dist/ui/src/components/ui/separator/separator.behavior.test.d.ts +14 -0
  222. package/dist/ui/src/components/ui/separator/separator.d.ts +14 -0
  223. package/dist/ui/src/components/ui/separator/separator.js +30 -0
  224. package/dist/ui/src/components/ui/separator/separator.js.map +1 -0
  225. package/dist/ui/src/components/ui/sheet/sheet.d.ts +8 -0
  226. package/dist/ui/src/components/ui/sheet/sheet.js +99 -0
  227. package/dist/ui/src/components/ui/sheet/sheet.js.map +1 -0
  228. package/dist/ui/src/components/ui/sidebar/sidebar.js +383 -0
  229. package/dist/ui/src/components/ui/sidebar/sidebar.js.map +1 -0
  230. package/dist/ui/src/components/ui/skeleton/skeleton.js +14 -0
  231. package/dist/ui/src/components/ui/skeleton/skeleton.js.map +1 -0
  232. package/dist/ui/src/components/ui/slider/slider.js +49 -0
  233. package/dist/ui/src/components/ui/slider/slider.js.map +1 -0
  234. package/dist/ui/src/components/ui/spinner/spinner.js +28 -0
  235. package/dist/ui/src/components/ui/spinner/spinner.js.map +1 -0
  236. package/dist/ui/src/components/ui/switch/switch.js +20 -0
  237. package/dist/ui/src/components/ui/switch/switch.js.map +1 -0
  238. package/dist/ui/src/components/ui/table/table.behavior.test.d.ts +4 -5
  239. package/dist/ui/src/components/ui/table/table.d.ts +15 -1
  240. package/dist/ui/src/components/ui/table/table.js +81 -0
  241. package/dist/ui/src/components/ui/table/table.js.map +1 -0
  242. package/dist/ui/src/components/ui/tabs/tabs.d.ts +14 -8
  243. package/dist/ui/src/components/ui/tabs/tabs.js +115 -0
  244. package/dist/ui/src/components/ui/tabs/tabs.js.map +1 -0
  245. package/dist/ui/src/components/ui/textarea/textarea.js +14 -0
  246. package/dist/ui/src/components/ui/textarea/textarea.js.map +1 -0
  247. package/dist/ui/src/components/ui/toast/toast.js +124 -0
  248. package/dist/ui/src/components/ui/toast/toast.js.map +1 -0
  249. package/dist/ui/src/components/ui/toggle/toggle.js +37 -0
  250. package/dist/ui/src/components/ui/toggle/toggle.js.map +1 -0
  251. package/dist/ui/src/components/ui/toggle-group/toggle-group.js +56 -0
  252. package/dist/ui/src/components/ui/toggle-group/toggle-group.js.map +1 -0
  253. package/dist/ui/src/components/ui/tooltip/tooltip.js +43 -0
  254. package/dist/ui/src/components/ui/tooltip/tooltip.js.map +1 -0
  255. package/dist/ui/src/hooks/use-holds-focusable.d.ts +3 -0
  256. package/dist/ui/src/hooks/use-holds-focusable.js +33 -0
  257. package/dist/ui/src/hooks/use-holds-focusable.js.map +1 -0
  258. package/dist/ui/src/hooks/use-media-player.js +140 -0
  259. package/dist/ui/src/hooks/use-media-player.js.map +1 -0
  260. package/dist/ui/src/hooks/use-merged-refs.js +18 -0
  261. package/dist/ui/src/hooks/use-merged-refs.js.map +1 -0
  262. package/dist/ui/src/hooks/use-mobile.js +20 -0
  263. package/dist/ui/src/hooks/use-mobile.js.map +1 -0
  264. package/dist/ui/src/index.d.ts +8 -0
  265. package/dist/ui/src/lib/first-weekday.d.ts +6 -0
  266. package/dist/ui/src/lib/first-weekday.js +34 -0
  267. package/dist/ui/src/lib/first-weekday.js.map +1 -0
  268. package/dist/ui/src/lib/focus-guards.d.ts +2 -0
  269. package/dist/ui/src/lib/focus-guards.js +44 -0
  270. package/dist/ui/src/lib/focus-guards.js.map +1 -0
  271. package/dist/ui/src/lib/focus-ring.test.d.ts +8 -0
  272. package/dist/ui/src/lib/popup-list.d.ts +75 -0
  273. package/dist/ui/src/lib/popup-list.js +48 -0
  274. package/dist/ui/src/lib/popup-list.js.map +1 -0
  275. package/dist/ui/src/lib/popup-list.test.d.ts +10 -0
  276. package/dist/ui/src/lib/utils.js +21 -0
  277. package/dist/ui/src/lib/utils.js.map +1 -0
  278. package/package.json +36 -8
  279. package/dist/chunks/toggle-group-ByNq8g7H.js +0 -4263
  280. package/dist/chunks/toggle-group-ByNq8g7H.js.map +0 -1
  281. package/dist/dom/src/context.d.ts +0 -34
  282. package/dist/dom/src/define-element.d.ts +0 -11
  283. package/dist/dom/src/field-control.d.ts +0 -5
  284. package/dist/dom/src/index.d.ts +0 -6
  285. package/dist/dom/src/mode.d.ts +0 -8
  286. package/dist/dom/src/styles.d.ts +0 -6
  287. package/dist/dom/src/theme-state.d.ts +0 -1
  288. package/dist/dom/src/types.d.ts +0 -65
  289. package/dist/ds/src/elements.d.ts +0 -12
  290. package/dist/elements/src/edx-accordion.d.ts +0 -14
  291. package/dist/elements/src/edx-accordion.test.d.ts +0 -1
  292. package/dist/elements/src/edx-alert.d.ts +0 -14
  293. package/dist/elements/src/edx-audio-player.d.ts +0 -11
  294. package/dist/elements/src/edx-avatar.d.ts +0 -10
  295. package/dist/elements/src/edx-badge.d.ts +0 -12
  296. package/dist/elements/src/edx-breadcrumb.d.ts +0 -11
  297. package/dist/elements/src/edx-button-group.d.ts +0 -7
  298. package/dist/elements/src/edx-button.d.ts +0 -20
  299. package/dist/elements/src/edx-calendar.d.ts +0 -21
  300. package/dist/elements/src/edx-card.d.ts +0 -8
  301. package/dist/elements/src/edx-checkbox.d.ts +0 -18
  302. package/dist/elements/src/edx-combobox.d.ts +0 -28
  303. package/dist/elements/src/edx-content-components.d.ts +0 -2
  304. package/dist/elements/src/edx-dialog.d.ts +0 -20
  305. package/dist/elements/src/edx-drawer.d.ts +0 -21
  306. package/dist/elements/src/edx-dropdown-menu.d.ts +0 -29
  307. package/dist/elements/src/edx-field.d.ts +0 -9
  308. package/dist/elements/src/edx-field.test.d.ts +0 -1
  309. package/dist/elements/src/edx-indicator.d.ts +0 -14
  310. package/dist/elements/src/edx-input-group.d.ts +0 -32
  311. package/dist/elements/src/edx-input-otp.d.ts +0 -19
  312. package/dist/elements/src/edx-input.d.ts +0 -31
  313. package/dist/elements/src/edx-interactive-components.d.ts +0 -2
  314. package/dist/elements/src/edx-label.d.ts +0 -6
  315. package/dist/elements/src/edx-pagination.d.ts +0 -8
  316. package/dist/elements/src/edx-popover.d.ts +0 -24
  317. package/dist/elements/src/edx-progress.d.ts +0 -10
  318. package/dist/elements/src/edx-radio-group.d.ts +0 -22
  319. package/dist/elements/src/edx-radio-group.test.d.ts +0 -1
  320. package/dist/elements/src/edx-scroll-area.d.ts +0 -15
  321. package/dist/elements/src/edx-scroll-area.test.d.ts +0 -1
  322. package/dist/elements/src/edx-select.d.ts +0 -34
  323. package/dist/elements/src/edx-separator.d.ts +0 -10
  324. package/dist/elements/src/edx-skeleton.d.ts +0 -8
  325. package/dist/elements/src/edx-slider.d.ts +0 -17
  326. package/dist/elements/src/edx-slider.test.d.ts +0 -1
  327. package/dist/elements/src/edx-switch.d.ts +0 -18
  328. package/dist/elements/src/edx-table.d.ts +0 -13
  329. package/dist/elements/src/edx-table.test.d.ts +0 -1
  330. package/dist/elements/src/edx-tabs.d.ts +0 -15
  331. package/dist/elements/src/edx-tabs.test.d.ts +0 -1
  332. package/dist/elements/src/edx-textarea.d.ts +0 -25
  333. package/dist/elements/src/edx-toggle-group.d.ts +0 -27
  334. package/dist/elements/src/edx-toggle-group.test.d.ts +0 -1
  335. package/dist/elements/src/edx-toggle.d.ts +0 -18
  336. package/dist/elements/src/edx-tooltip.d.ts +0 -28
  337. package/dist/elements/src/edx-video-player.d.ts +0 -16
  338. package/dist/elements/src/field-control-bridge.d.ts +0 -7
  339. package/dist/elements/src/index.d.ts +0 -14
  340. package/dist/elements/src/projected-content.test.d.ts +0 -1
  341. package/dist/elements/src/registry.d.ts +0 -39
  342. package/dist/elements/src/registry.test.d.ts +0 -1
  343. package/dist/elements.js +0 -4020
  344. package/dist/elements.js.map +0 -1
  345. /package/dist/{dom/src/define-element.test.d.ts → ui/src/components/edyn/date-picker/date-text.test.d.ts} +0 -0
  346. /package/dist/{dom/src/native-slot.test.d.ts → ui/src/lib/first-weekday.test.d.ts} +0 -0
@@ -0,0 +1,3 @@
1
+ import { RefObject } from 'react';
2
+ /** Whether something inside the element can take Tab, kept current as its content changes. */
3
+ export declare const useHoldsFocusable: (ref: RefObject<HTMLElement | null>, enabled?: boolean) => boolean;
@@ -0,0 +1,33 @@
1
+ import { useEffect, useState } from "react";
2
+ //#region ../ui/src/hooks/use-holds-focusable.ts
3
+ /** What takes Tab inside a region: if any is there, the region is not a stop of its own. */
4
+ var FOCUSABLE_INSIDE = "a[href], button:not(:disabled), input:not([type=\"hidden\"]):not(:disabled), select:not(:disabled), textarea:not(:disabled), summary, [contenteditable], [tabindex]:not([tabindex=\"-1\"])";
5
+ /** Whether something inside the element can take Tab, kept current as its content changes. */
6
+ var useHoldsFocusable = (ref, enabled = true) => {
7
+ const [holds, setHolds] = useState(false);
8
+ useEffect(() => {
9
+ const el = ref.current;
10
+ if (!el || !enabled) return;
11
+ const read = () => setHolds(el.querySelector(FOCUSABLE_INSIDE) !== null);
12
+ read();
13
+ const observer = new MutationObserver(read);
14
+ observer.observe(el, {
15
+ childList: true,
16
+ subtree: true,
17
+ attributes: true,
18
+ attributeFilter: [
19
+ "tabindex",
20
+ "disabled",
21
+ "href"
22
+ ]
23
+ });
24
+ return () => {
25
+ observer.disconnect();
26
+ };
27
+ }, [ref, enabled]);
28
+ return holds;
29
+ };
30
+ //#endregion
31
+ export { useHoldsFocusable };
32
+
33
+ //# sourceMappingURL=use-holds-focusable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-holds-focusable.js","names":[],"sources":["../../../../../ui/src/hooks/use-holds-focusable.ts"],"sourcesContent":["import { type RefObject, useEffect, useState } from 'react';\n\n/** What takes Tab inside a region: if any is there, the region is not a stop of its own. */\nconst FOCUSABLE_INSIDE =\n 'a[href], button:not(:disabled), input:not([type=\"hidden\"]):not(:disabled), select:not(:disabled), textarea:not(:disabled), summary, [contenteditable], [tabindex]:not([tabindex=\"-1\"])';\n\n/** Whether something inside the element can take Tab, kept current as its content changes. */\nexport const useHoldsFocusable = (ref: RefObject<HTMLElement | null>, enabled = true): boolean => {\n const [holds, setHolds] = useState(false);\n\n useEffect(() => {\n const el = ref.current;\n if (!el || !enabled) {\n return;\n }\n const read = () => setHolds(el.querySelector(FOCUSABLE_INSIDE) !== null);\n read();\n const observer = new MutationObserver(read);\n observer.observe(el, { childList: true, subtree: true, attributes: true, attributeFilter: ['tabindex', 'disabled', 'href'] });\n return () => {\n observer.disconnect();\n };\n }, [ref, enabled]);\n\n return holds;\n};\n"],"mappings":";;;AAGA,IAAM,mBACJ;;AAGF,IAAa,qBAAqB,KAAoC,UAAU,SAAkB;CAChG,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK;CAExC,gBAAgB;EACd,MAAM,KAAK,IAAI;EACf,IAAI,CAAC,MAAM,CAAC,SACV;EAEF,MAAM,aAAa,SAAS,GAAG,cAAc,gBAAgB,MAAM,IAAI;EACvE,KAAK;EACL,MAAM,WAAW,IAAI,iBAAiB,IAAI;EAC1C,SAAS,QAAQ,IAAI;GAAE,WAAW;GAAM,SAAS;GAAM,YAAY;GAAM,iBAAiB;IAAC;IAAY;IAAY;GAAM;EAAE,CAAC;EAC5H,aAAa;GACX,SAAS,WAAW;EACtB;CACF,GAAG,CAAC,KAAK,OAAO,CAAC;CAEjB,OAAO;AACT"}
@@ -0,0 +1,140 @@
1
+ import * as React from "react";
2
+ //#region ../ui/src/hooks/use-media-player.ts
3
+ /** `0:00` for anything that is not a finite, non-negative number, so a loading or errored source still renders. */
4
+ var formatMediaTime = (seconds) => {
5
+ if (!Number.isFinite(seconds) || seconds < 0) return "0:00";
6
+ const whole = Math.floor(seconds);
7
+ const hours = Math.floor(whole / 3600);
8
+ const minutes = Math.floor(whole % 3600 / 60);
9
+ const rest = whole % 60;
10
+ const padded = `${String(rest).padStart(2, "0")}`;
11
+ if (hours > 0) return `${hours}:${String(minutes).padStart(2, "0")}:${padded}`;
12
+ return `${minutes}:${padded}`;
13
+ };
14
+ /**
15
+ * Shared playback engine for the Audio and Video players. Both wrap the same
16
+ * HTMLMediaElement API, so the state machine lives here once and each component
17
+ * owns only its own layout and controls.
18
+ */
19
+ var useMediaPlayer = (options = {}) => {
20
+ const { onPlay, onPause, onEnded, onTimeUpdate } = options;
21
+ const refMedia = React.useRef(null);
22
+ const [state, setState] = React.useState({
23
+ playing: false,
24
+ currentTime: 0,
25
+ duration: 0,
26
+ volume: 1,
27
+ muted: false
28
+ });
29
+ React.useEffect(() => {
30
+ const media = refMedia.current;
31
+ if (!media) return;
32
+ const syncMeta = () => {
33
+ setState((previous) => ({
34
+ ...previous,
35
+ duration: Number.isFinite(media.duration) ? media.duration : 0,
36
+ volume: media.volume,
37
+ muted: media.muted
38
+ }));
39
+ };
40
+ const handlePlay = () => {
41
+ setState((previous) => ({
42
+ ...previous,
43
+ playing: true
44
+ }));
45
+ onPlay?.();
46
+ };
47
+ const handlePause = () => {
48
+ setState((previous) => ({
49
+ ...previous,
50
+ playing: false
51
+ }));
52
+ onPause?.();
53
+ };
54
+ const handleEnded = () => {
55
+ setState((previous) => ({
56
+ ...previous,
57
+ playing: false
58
+ }));
59
+ onEnded?.();
60
+ };
61
+ const handleTimeUpdate = () => {
62
+ setState((previous) => ({
63
+ ...previous,
64
+ currentTime: media.currentTime
65
+ }));
66
+ onTimeUpdate?.(media.currentTime, Number.isFinite(media.duration) ? media.duration : 0);
67
+ };
68
+ const handleVolumeChange = () => {
69
+ setState((previous) => ({
70
+ ...previous,
71
+ volume: media.volume,
72
+ muted: media.muted
73
+ }));
74
+ };
75
+ syncMeta();
76
+ media.addEventListener("loadedmetadata", syncMeta);
77
+ media.addEventListener("durationchange", syncMeta);
78
+ media.addEventListener("play", handlePlay);
79
+ media.addEventListener("pause", handlePause);
80
+ media.addEventListener("ended", handleEnded);
81
+ media.addEventListener("timeupdate", handleTimeUpdate);
82
+ media.addEventListener("volumechange", handleVolumeChange);
83
+ return () => {
84
+ media.removeEventListener("loadedmetadata", syncMeta);
85
+ media.removeEventListener("durationchange", syncMeta);
86
+ media.removeEventListener("play", handlePlay);
87
+ media.removeEventListener("pause", handlePause);
88
+ media.removeEventListener("ended", handleEnded);
89
+ media.removeEventListener("timeupdate", handleTimeUpdate);
90
+ media.removeEventListener("volumechange", handleVolumeChange);
91
+ };
92
+ }, [
93
+ onPlay,
94
+ onPause,
95
+ onEnded,
96
+ onTimeUpdate
97
+ ]);
98
+ const toggle = React.useCallback(() => {
99
+ const media = refMedia.current;
100
+ if (!media) return;
101
+ if (media.paused) {
102
+ media.play().catch(() => void 0);
103
+ return;
104
+ }
105
+ media.pause();
106
+ }, []);
107
+ const seek = React.useCallback((seconds) => {
108
+ const media = refMedia.current;
109
+ if (!media || !Number.isFinite(seconds)) return;
110
+ media.currentTime = seconds;
111
+ setState((previous) => ({
112
+ ...previous,
113
+ currentTime: seconds
114
+ }));
115
+ }, []);
116
+ const changeVolume = React.useCallback((volume) => {
117
+ const media = refMedia.current;
118
+ if (!media || !Number.isFinite(volume)) return;
119
+ const next = Math.min(1, Math.max(0, volume));
120
+ media.volume = next;
121
+ media.muted = next === 0;
122
+ }, []);
123
+ const toggleMute = React.useCallback(() => {
124
+ const media = refMedia.current;
125
+ if (!media) return;
126
+ media.muted = !media.muted;
127
+ }, []);
128
+ return {
129
+ ...state,
130
+ refMedia,
131
+ toggle,
132
+ seek,
133
+ changeVolume,
134
+ toggleMute
135
+ };
136
+ };
137
+ //#endregion
138
+ export { formatMediaTime, useMediaPlayer };
139
+
140
+ //# sourceMappingURL=use-media-player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-player.js","names":[],"sources":["../../../../../ui/src/hooks/use-media-player.ts"],"sourcesContent":["import * as React from 'react';\n\nexport interface IMediaPlayerState {\n playing: boolean;\n currentTime: number;\n duration: number;\n volume: number;\n muted: boolean;\n}\n\nexport interface IUseMediaPlayerOptions {\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onTimeUpdate?: (currentTime: number, duration: number) => void;\n}\n\nexport interface IUseMediaPlayerResult<TElement extends HTMLMediaElement> extends IMediaPlayerState {\n refMedia: React.RefObject<TElement | null>;\n toggle: () => void;\n seek: (seconds: number) => void;\n changeVolume: (volume: number) => void;\n toggleMute: () => void;\n}\n\n/** `0:00` for anything that is not a finite, non-negative number, so a loading or errored source still renders. */\nexport const formatMediaTime = (seconds: number): string => {\n if (!Number.isFinite(seconds) || seconds < 0) {\n return '0:00';\n }\n const whole = Math.floor(seconds);\n const hours = Math.floor(whole / 3600);\n const minutes = Math.floor((whole % 3600) / 60);\n const rest = whole % 60;\n const padded = `${String(rest).padStart(2, '0')}`;\n if (hours > 0) {\n return `${hours}:${String(minutes).padStart(2, '0')}:${padded}`;\n }\n return `${minutes}:${padded}`;\n};\n\n/**\n * Shared playback engine for the Audio and Video players. Both wrap the same\n * HTMLMediaElement API, so the state machine lives here once and each component\n * owns only its own layout and controls.\n */\nexport const useMediaPlayer = <TElement extends HTMLMediaElement>(options: IUseMediaPlayerOptions = {}): IUseMediaPlayerResult<TElement> => {\n const { onPlay, onPause, onEnded, onTimeUpdate } = options;\n const refMedia = React.useRef<TElement | null>(null);\n const [state, setState] = React.useState<IMediaPlayerState>({\n playing: false,\n currentTime: 0,\n duration: 0,\n volume: 1,\n muted: false,\n });\n\n React.useEffect(() => {\n const media = refMedia.current;\n if (!media) {\n return;\n }\n\n const syncMeta = () => {\n setState((previous) => ({\n ...previous,\n duration: Number.isFinite(media.duration) ? media.duration : 0,\n volume: media.volume,\n muted: media.muted,\n }));\n };\n const handlePlay = () => {\n setState((previous) => ({ ...previous, playing: true }));\n onPlay?.();\n };\n const handlePause = () => {\n setState((previous) => ({ ...previous, playing: false }));\n onPause?.();\n };\n const handleEnded = () => {\n setState((previous) => ({ ...previous, playing: false }));\n onEnded?.();\n };\n const handleTimeUpdate = () => {\n setState((previous) => ({ ...previous, currentTime: media.currentTime }));\n onTimeUpdate?.(media.currentTime, Number.isFinite(media.duration) ? media.duration : 0);\n };\n const handleVolumeChange = () => {\n setState((previous) => ({ ...previous, volume: media.volume, muted: media.muted }));\n };\n\n syncMeta();\n media.addEventListener('loadedmetadata', syncMeta);\n media.addEventListener('durationchange', syncMeta);\n media.addEventListener('play', handlePlay);\n media.addEventListener('pause', handlePause);\n media.addEventListener('ended', handleEnded);\n media.addEventListener('timeupdate', handleTimeUpdate);\n media.addEventListener('volumechange', handleVolumeChange);\n\n return () => {\n media.removeEventListener('loadedmetadata', syncMeta);\n media.removeEventListener('durationchange', syncMeta);\n media.removeEventListener('play', handlePlay);\n media.removeEventListener('pause', handlePause);\n media.removeEventListener('ended', handleEnded);\n media.removeEventListener('timeupdate', handleTimeUpdate);\n media.removeEventListener('volumechange', handleVolumeChange);\n };\n }, [onPlay, onPause, onEnded, onTimeUpdate]);\n\n const toggle = React.useCallback(() => {\n const media = refMedia.current;\n if (!media) {\n return;\n }\n if (media.paused) {\n // Autoplay policies reject this when the gesture is not trusted; the pause\n // state is already correct, so swallowing keeps the UI truthful.\n void media.play().catch(() => undefined);\n return;\n }\n media.pause();\n }, []);\n\n const seek = React.useCallback((seconds: number) => {\n const media = refMedia.current;\n if (!media || !Number.isFinite(seconds)) {\n return;\n }\n media.currentTime = seconds;\n setState((previous) => ({ ...previous, currentTime: seconds }));\n }, []);\n\n const changeVolume = React.useCallback((volume: number) => {\n const media = refMedia.current;\n if (!media || !Number.isFinite(volume)) {\n return;\n }\n const next = Math.min(1, Math.max(0, volume));\n media.volume = next;\n media.muted = next === 0;\n }, []);\n\n const toggleMute = React.useCallback(() => {\n const media = refMedia.current;\n if (!media) {\n return;\n }\n media.muted = !media.muted;\n }, []);\n\n return { ...state, refMedia, toggle, seek, changeVolume, toggleMute };\n};\n"],"mappings":";;;AA0BA,IAAa,mBAAmB,YAA4B;CAC1D,IAAI,CAAC,OAAO,SAAS,OAAO,KAAK,UAAU,GACzC,OAAO;CAET,MAAM,QAAQ,KAAK,MAAM,OAAO;CAChC,MAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI;CACrC,MAAM,UAAU,KAAK,MAAO,QAAQ,OAAQ,EAAE;CAC9C,MAAM,OAAO,QAAQ;CACrB,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;CAC9C,IAAI,QAAQ,GACV,OAAO,GAAG,MAAM,GAAG,OAAO,OAAO,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG;CAEzD,OAAO,GAAG,QAAQ,GAAG;AACvB;;;;;;AAOA,IAAa,kBAAqD,UAAkC,CAAC,MAAuC;CAC1I,MAAM,EAAE,QAAQ,SAAS,SAAS,iBAAiB;CACnD,MAAM,WAAW,MAAM,OAAwB,IAAI;CACnD,MAAM,CAAC,OAAO,YAAY,MAAM,SAA4B;EAC1D,SAAS;EACT,aAAa;EACb,UAAU;EACV,QAAQ;EACR,OAAO;CACT,CAAC;CAED,MAAM,gBAAgB;EACpB,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,OACH;EAGF,MAAM,iBAAiB;GACrB,UAAU,cAAc;IACtB,GAAG;IACH,UAAU,OAAO,SAAS,MAAM,QAAQ,IAAI,MAAM,WAAW;IAC7D,QAAQ,MAAM;IACd,OAAO,MAAM;GACf,EAAE;EACJ;EACA,MAAM,mBAAmB;GACvB,UAAU,cAAc;IAAE,GAAG;IAAU,SAAS;GAAK,EAAE;GACvD,SAAS;EACX;EACA,MAAM,oBAAoB;GACxB,UAAU,cAAc;IAAE,GAAG;IAAU,SAAS;GAAM,EAAE;GACxD,UAAU;EACZ;EACA,MAAM,oBAAoB;GACxB,UAAU,cAAc;IAAE,GAAG;IAAU,SAAS;GAAM,EAAE;GACxD,UAAU;EACZ;EACA,MAAM,yBAAyB;GAC7B,UAAU,cAAc;IAAE,GAAG;IAAU,aAAa,MAAM;GAAY,EAAE;GACxE,eAAe,MAAM,aAAa,OAAO,SAAS,MAAM,QAAQ,IAAI,MAAM,WAAW,CAAC;EACxF;EACA,MAAM,2BAA2B;GAC/B,UAAU,cAAc;IAAE,GAAG;IAAU,QAAQ,MAAM;IAAQ,OAAO,MAAM;GAAM,EAAE;EACpF;EAEA,SAAS;EACT,MAAM,iBAAiB,kBAAkB,QAAQ;EACjD,MAAM,iBAAiB,kBAAkB,QAAQ;EACjD,MAAM,iBAAiB,QAAQ,UAAU;EACzC,MAAM,iBAAiB,SAAS,WAAW;EAC3C,MAAM,iBAAiB,SAAS,WAAW;EAC3C,MAAM,iBAAiB,cAAc,gBAAgB;EACrD,MAAM,iBAAiB,gBAAgB,kBAAkB;EAEzD,aAAa;GACX,MAAM,oBAAoB,kBAAkB,QAAQ;GACpD,MAAM,oBAAoB,kBAAkB,QAAQ;GACpD,MAAM,oBAAoB,QAAQ,UAAU;GAC5C,MAAM,oBAAoB,SAAS,WAAW;GAC9C,MAAM,oBAAoB,SAAS,WAAW;GAC9C,MAAM,oBAAoB,cAAc,gBAAgB;GACxD,MAAM,oBAAoB,gBAAgB,kBAAkB;EAC9D;CACF,GAAG;EAAC;EAAQ;EAAS;EAAS;CAAY,CAAC;CAE3C,MAAM,SAAS,MAAM,kBAAkB;EACrC,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,OACH;EAEF,IAAI,MAAM,QAAQ;GAGhB,MAAW,KAAK,CAAC,CAAC,YAAY,KAAA,CAAS;GACvC;EACF;EACA,MAAM,MAAM;CACd,GAAG,CAAC,CAAC;CAEL,MAAM,OAAO,MAAM,aAAa,YAAoB;EAClD,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,SAAS,CAAC,OAAO,SAAS,OAAO,GACpC;EAEF,MAAM,cAAc;EACpB,UAAU,cAAc;GAAE,GAAG;GAAU,aAAa;EAAQ,EAAE;CAChE,GAAG,CAAC,CAAC;CAEL,MAAM,eAAe,MAAM,aAAa,WAAmB;EACzD,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,SAAS,CAAC,OAAO,SAAS,MAAM,GACnC;EAEF,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC;EAC5C,MAAM,SAAS;EACf,MAAM,QAAQ,SAAS;CACzB,GAAG,CAAC,CAAC;CAEL,MAAM,aAAa,MAAM,kBAAkB;EACzC,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,OACH;EAEF,MAAM,QAAQ,CAAC,MAAM;CACvB,GAAG,CAAC,CAAC;CAEL,OAAO;EAAE,GAAG;EAAO;EAAU;EAAQ;EAAM;EAAc;CAAW;AACtE"}
@@ -0,0 +1,18 @@
1
+ import { useCallback } from "react";
2
+ //#region ../ui/src/hooks/use-merged-refs.ts
3
+ var assignRef = (ref, value) => {
4
+ if (typeof ref === "function") ref(value);
5
+ else if (ref !== null) ref.current = value;
6
+ };
7
+ var mergeRefs = (...refs) => {
8
+ return (node) => {
9
+ for (const ref of refs) if (ref) assignRef(ref, node);
10
+ };
11
+ };
12
+ var useMergedRefs = (...refs) => {
13
+ return useCallback(mergeRefs(...refs), [...refs]);
14
+ };
15
+ //#endregion
16
+ export { useMergedRefs };
17
+
18
+ //# sourceMappingURL=use-merged-refs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-merged-refs.js","names":[],"sources":["../../../../../ui/src/hooks/use-merged-refs.ts"],"sourcesContent":["import { type Ref, type RefCallback, useCallback } from 'react';\n\ntype TPossibleRef<T> = Ref<T> | undefined;\n\nconst assignRef = <T>(ref: TPossibleRef<T>, value: T) => {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref !== null) {\n // Using type assertion to RefObject since we know it's not null\n (ref as { current: T }).current = value;\n }\n};\n\nconst mergeRefs = <T>(...refs: TPossibleRef<T>[]) => {\n return (node: T) => {\n for (const ref of refs) {\n if (ref) {\n assignRef(ref, node);\n }\n }\n };\n};\n\nexport const useMergedRefs = <T>(...refs: TPossibleRef<T>[]) => {\n return useCallback(mergeRefs(...refs), [...refs]) as RefCallback<T>;\n};\n"],"mappings":";;AAIA,IAAM,aAAgB,KAAsB,UAAa;CACvD,IAAI,OAAO,QAAQ,YACjB,IAAI,KAAK;MACJ,IAAI,QAAQ,MAEjB,IAAwB,UAAU;AAEtC;AAEA,IAAM,aAAgB,GAAG,SAA4B;CACnD,QAAQ,SAAY;EAClB,KAAK,MAAM,OAAO,MAChB,IAAI,KACF,UAAU,KAAK,IAAI;CAGzB;AACF;AAEA,IAAa,iBAAoB,GAAG,SAA4B;CAC9D,OAAO,YAAY,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC;AAClD"}
@@ -0,0 +1,20 @@
1
+ import * as React from "react";
2
+ //#region ../ui/src/hooks/use-mobile.ts
3
+ var MOBILE_BREAKPOINT = 768;
4
+ var useIsMobile = () => {
5
+ const [isMobile, setIsMobile] = React.useState(void 0);
6
+ React.useEffect(() => {
7
+ const mql = window.matchMedia(`(max-width: 767px)`);
8
+ const onChange = () => {
9
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
10
+ };
11
+ mql.addEventListener("change", onChange);
12
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
13
+ return () => mql.removeEventListener("change", onChange);
14
+ }, []);
15
+ return !!isMobile;
16
+ };
17
+ //#endregion
18
+ export { useIsMobile };
19
+
20
+ //# sourceMappingURL=use-mobile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-mobile.js","names":[],"sources":["../../../../../ui/src/hooks/use-mobile.ts"],"sourcesContent":["import * as React from 'react';\n\nconst MOBILE_BREAKPOINT = 768;\n\nexport const useIsMobile = () => {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n };\n mql.addEventListener('change', onChange);\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n return () => mql.removeEventListener('change', onChange);\n }, []);\n\n return !!isMobile;\n};\n"],"mappings":";;AAEA,IAAM,oBAAoB;AAE1B,IAAa,oBAAoB;CAC/B,MAAM,CAAC,UAAU,eAAe,MAAM,SAA8B,KAAA,CAAS;CAE7E,MAAM,gBAAgB;EACpB,MAAM,MAAM,OAAO,WAAW,oBAAyC;EACvE,MAAM,iBAAiB;GACrB,YAAY,OAAO,aAAa,iBAAiB;EACnD;EACA,IAAI,iBAAiB,UAAU,QAAQ;EACvC,YAAY,OAAO,aAAa,iBAAiB;EACjD,aAAa,IAAI,oBAAoB,UAAU,QAAQ;CACzD,GAAG,CAAC,CAAC;CAEL,OAAO,CAAC,CAAC;AACX"}
@@ -1,4 +1,11 @@
1
+ export * from './components/edyn/animated-number';
1
2
  export * from './components/edyn/audio-player';
3
+ export * from './components/edyn/date-range-picker';
4
+ export * from './components/edyn/initials-avatar';
5
+ export * from './components/edyn/multi-select';
6
+ export * from './components/edyn/presence';
7
+ export * from './components/edyn/progress-line';
8
+ export * from './components/edyn/rich-text-content';
2
9
  export * from './components/edyn/video-player';
3
10
  export * from './components/ui/accordion';
4
11
  export * from './components/ui/alert';
@@ -65,4 +72,5 @@ export * from './components/ui/tooltip';
65
72
  export * from './hooks/use-media-player';
66
73
  export * from './hooks/use-merged-refs';
67
74
  export * from './hooks/use-mobile';
75
+ export { POPUP_FRAME_CLASS, POPUP_GROUP_LABEL_CLASS, POPUP_ITEM_INDICATOR_CLASS, POPUP_LAYER_CLASS, POPUP_LIST_HEIGHT_CLASS, POPUP_LIST_WIDTH_CLASS, popupItemClass, type TPopupItemFlavor, } from './lib/popup-list';
68
76
  export { cn } from './lib/utils';
@@ -0,0 +1,6 @@
1
+ export type TWeekday = 0 | 1 | 2 | 3 | 4 | 5 | 6;
2
+ /**
3
+ * The weekday a locale starts its week on, 0 for Sunday to 6 for Saturday, from Intl, so en-GB starts on Monday and en-US on
4
+ * Sunday with no locale data of our own shipped. A browser without week info gets the region's usual start.
5
+ */
6
+ export declare const firstWeekdayOf: (locale: string) => TWeekday;
@@ -0,0 +1,34 @@
1
+ //#region ../ui/src/lib/first-weekday.ts
2
+ var SUNDAY_FIRST = /* @__PURE__ */ new Set([
3
+ "US",
4
+ "CA",
5
+ "MX",
6
+ "BR",
7
+ "JP",
8
+ "IL",
9
+ "IN",
10
+ "PH",
11
+ "ZA",
12
+ "KR",
13
+ "TW",
14
+ "HK",
15
+ "SA"
16
+ ]);
17
+ /**
18
+ * The weekday a locale starts its week on, 0 for Sunday to 6 for Saturday, from Intl, so en-GB starts on Monday and en-US on
19
+ * Sunday with no locale data of our own shipped. A browser without week info gets the region's usual start.
20
+ */
21
+ var firstWeekdayOf = (locale) => {
22
+ try {
23
+ const info = new Intl.Locale(locale);
24
+ const first = info.getWeekInfo?.().firstDay ?? info.weekInfo?.firstDay;
25
+ if (first !== void 0) return first % 7;
26
+ return SUNDAY_FIRST.has(info.region ?? "") ? 0 : 1;
27
+ } catch {
28
+ return 0;
29
+ }
30
+ };
31
+ //#endregion
32
+ export { firstWeekdayOf };
33
+
34
+ //# sourceMappingURL=first-weekday.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"first-weekday.js","names":[],"sources":["../../../../../ui/src/lib/first-weekday.ts"],"sourcesContent":["export type TWeekday = 0 | 1 | 2 | 3 | 4 | 5 | 6;\n\n// Regions whose week starts on a Sunday, for a browser that cannot say (Intl week info is not everywhere yet).\nconst SUNDAY_FIRST = new Set(['US', 'CA', 'MX', 'BR', 'JP', 'IL', 'IN', 'PH', 'ZA', 'KR', 'TW', 'HK', 'SA']);\n\n/**\n * The weekday a locale starts its week on, 0 for Sunday to 6 for Saturday, from Intl, so en-GB starts on Monday and en-US on\n * Sunday with no locale data of our own shipped. A browser without week info gets the region's usual start.\n */\nexport const firstWeekdayOf = (locale: string): TWeekday => {\n try {\n const info = new Intl.Locale(locale) as Intl.Locale & { getWeekInfo?: () => { firstDay: number }; weekInfo?: { firstDay: number } };\n const first = info.getWeekInfo?.().firstDay ?? info.weekInfo?.firstDay;\n if (first !== undefined) {\n // Intl counts Monday as 1 to Sunday as 7; the calendar counts Sunday as 0.\n return (first % 7) as TWeekday;\n }\n return SUNDAY_FIRST.has(info.region ?? '') ? 0 : 1;\n } catch {\n return 0;\n }\n};\n"],"mappings":";AAGA,IAAM,+BAAe,IAAI,IAAI;CAAC;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;AAAI,CAAC;;;;;AAM3G,IAAa,kBAAkB,WAA6B;CAC1D,IAAI;EACF,MAAM,OAAO,IAAI,KAAK,OAAO,MAAM;EACnC,MAAM,QAAQ,KAAK,cAAc,CAAC,CAAC,YAAY,KAAK,UAAU;EAC9D,IAAI,UAAU,KAAA,GAEZ,OAAQ,QAAQ;EAElB,OAAO,aAAa,IAAI,KAAK,UAAU,EAAE,IAAI,IAAI;CACnD,QAAQ;EACN,OAAO;CACT;AACF"}
@@ -0,0 +1,2 @@
1
+ /** Call from a popup's content component: while it is mounted, the focus guards around popups are not aria-hidden. */
2
+ export declare const useExposedFocusGuards: () => void;
@@ -0,0 +1,44 @@
1
+ import { useEffect } from "react";
2
+ //#region ../ui/src/lib/focus-guards.ts
3
+ /**
4
+ * Base UI's focus-trap sentinels around an open popup are focusable and `aria-hidden`, which axe's aria-hidden-focus rule
5
+ * reports. `useExposedFocusGuards` takes the `aria-hidden` off them while a popup is open; one observer serves every open popup.
6
+ */
7
+ var HIDDEN_GUARD = "[data-base-ui-focus-guard][aria-hidden]";
8
+ /** Takes `aria-hidden` off the guards in a subtree, or off the node itself when it is one. */
9
+ var expose = (root) => {
10
+ if (root instanceof Element && root.matches(HIDDEN_GUARD)) root.removeAttribute("aria-hidden");
11
+ for (const guard of root.querySelectorAll(HIDDEN_GUARD)) guard.removeAttribute("aria-hidden");
12
+ };
13
+ var users = 0;
14
+ var observer;
15
+ var start = () => {
16
+ users += 1;
17
+ expose(document);
18
+ if (observer !== void 0) return;
19
+ observer = new MutationObserver((records) => {
20
+ for (const record of records) for (const added of record.addedNodes) if (added instanceof Element) expose(added);
21
+ });
22
+ observer.observe(document.body, {
23
+ childList: true,
24
+ subtree: true
25
+ });
26
+ };
27
+ var stop = () => {
28
+ users -= 1;
29
+ if (users === 0) {
30
+ observer?.disconnect();
31
+ observer = void 0;
32
+ }
33
+ };
34
+ /** Call from a popup's content component: while it is mounted, the focus guards around popups are not aria-hidden. */
35
+ var useExposedFocusGuards = () => {
36
+ useEffect(() => {
37
+ start();
38
+ return stop;
39
+ }, []);
40
+ };
41
+ //#endregion
42
+ export { useExposedFocusGuards };
43
+
44
+ //# sourceMappingURL=focus-guards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-guards.js","names":[],"sources":["../../../../../ui/src/lib/focus-guards.ts"],"sourcesContent":["import { useEffect } from 'react';\n\n/**\n * Base UI's focus-trap sentinels around an open popup are focusable and `aria-hidden`, which axe's aria-hidden-focus rule\n * reports. `useExposedFocusGuards` takes the `aria-hidden` off them while a popup is open; one observer serves every open popup.\n */\n\nconst HIDDEN_GUARD = '[data-base-ui-focus-guard][aria-hidden]';\n\n/** Takes `aria-hidden` off the guards in a subtree, or off the node itself when it is one. */\nconst expose = (root: ParentNode | Element): void => {\n if (root instanceof Element && root.matches(HIDDEN_GUARD)) {\n root.removeAttribute('aria-hidden');\n }\n for (const guard of root.querySelectorAll(HIDDEN_GUARD)) {\n guard.removeAttribute('aria-hidden');\n }\n};\n\nlet users = 0;\nlet observer: MutationObserver | undefined;\n\nconst start = (): void => {\n users += 1;\n expose(document);\n if (observer !== undefined) {\n return;\n }\n observer = new MutationObserver((records) => {\n for (const record of records) {\n for (const added of record.addedNodes) {\n if (added instanceof Element) {\n expose(added);\n }\n }\n }\n });\n observer.observe(document.body, { childList: true, subtree: true });\n};\n\nconst stop = (): void => {\n users -= 1;\n if (users === 0) {\n observer?.disconnect();\n observer = undefined;\n }\n};\n\n/** Call from a popup's content component: while it is mounted, the focus guards around popups are not aria-hidden. */\nexport const useExposedFocusGuards = (): void => {\n useEffect(() => {\n start();\n return stop;\n }, []);\n};\n"],"mappings":";;;;;;AAOA,IAAM,eAAe;;AAGrB,IAAM,UAAU,SAAqC;CACnD,IAAI,gBAAgB,WAAW,KAAK,QAAQ,YAAY,GACtD,KAAK,gBAAgB,aAAa;CAEpC,KAAK,MAAM,SAAS,KAAK,iBAAiB,YAAY,GACpD,MAAM,gBAAgB,aAAa;AAEvC;AAEA,IAAI,QAAQ;AACZ,IAAI;AAEJ,IAAM,cAAoB;CACxB,SAAS;CACT,OAAO,QAAQ;CACf,IAAI,aAAa,KAAA,GACf;CAEF,WAAW,IAAI,kBAAkB,YAAY;EAC3C,KAAK,MAAM,UAAU,SACnB,KAAK,MAAM,SAAS,OAAO,YACzB,IAAI,iBAAiB,SACnB,OAAO,KAAK;CAIpB,CAAC;CACD,SAAS,QAAQ,SAAS,MAAM;EAAE,WAAW;EAAM,SAAS;CAAK,CAAC;AACpE;AAEA,IAAM,aAAmB;CACvB,SAAS;CACT,IAAI,UAAU,GAAG;EACf,UAAU,WAAW;EACrB,WAAW,KAAA;CACb;AACF;;AAGA,IAAa,8BAAoC;CAC/C,gBAAgB;EACd,MAAM;EACN,OAAO;CACT,GAAG,CAAC,CAAC;AACP"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The default focus ring must be visible, not just present. WCAG 1.4.11 asks 3:1 for the
3
+ * parts of a control that show its state, and the ring is drawn outside the control, on
4
+ * whatever surface it sits on. This reads the real tokens.css, converts OKLCH to sRGB and
5
+ * measures the default --ring against every surface a control sits on, in both themes.
6
+ * An app that sets its own --ring (a brand) is outside this: it owns that colour.
7
+ */
8
+ export {};
@@ -0,0 +1,75 @@
1
+ /**
2
+ * The one look for a list in a popup or a menu: the command palette, Select,
3
+ * Combobox, MultiSelect and the dropdown menus.
4
+ *
5
+ * These lists used to disagree with each other in every detail that shows:
6
+ * three different radii, two different paddings, a grey fill for the highlight
7
+ * in one and the accent in another, and the chosen item marked by a check on
8
+ * the left in Select and on the right in the menus. Picking something from one
9
+ * list then felt like a different product from picking something in the next.
10
+ *
11
+ * It lives here as classes rather than as a stylesheet so a caller's own
12
+ * className still wins: an unlayered rule would beat every utility, including
13
+ * the one someone passes for a single list.
14
+ *
15
+ * ONE ITEM: transparent at rest, 32px tall, 6px radius (--radius-sm), 6px by
16
+ * 8px of padding, text-sm, its own icons 16px and muted. Under the pointer or
17
+ * the keyboard it takes one translucent fill of the text colour, and its icons
18
+ * the text colour. Chosen is medium weight with a check at the END, never a
19
+ * fill, so "where I am" and "what I picked" can be told apart at a glance.
20
+ */
21
+ /**
22
+ * Which primitive renders the item, because the two disagree about the same
23
+ * attribute names in a way that silently breaks the styling:
24
+ *
25
+ * - cmdk writes `data-selected="false"` and `data-disabled="false"` on items
26
+ * that are neither, so a bare `data-selected:` variant matches EVERY item and
27
+ * highlights the whole list. Its states have to be matched by value.
28
+ * - Base UI omits the attribute instead, so presence is the test there. That
29
+ * needs the BRACKET form for `selected`: shadcn redefines the bare
30
+ * `data-selected:` variant to match only data-selected="true" (for the
31
+ * calendar), and Base UI writes it as an empty string, so the bare form
32
+ * compiles and silently never applies. `highlighted` and `disabled` have no
33
+ * such override, so those stay bare.
34
+ * - And the same name means different things: cmdk's `data-selected` is the
35
+ * keyboard cursor, Base UI's is the chosen value. In cmdk the chosen state is
36
+ * `data-checked`, which the DS's own CommandItem sets.
37
+ */
38
+ export type TPopupItemFlavor = 'base-ui' | 'cmdk';
39
+ /** The shared item look. `checkable` leaves room at the end for the check. */
40
+ export declare const popupItemClass: (flavor?: TPopupItemFlavor, checkable?: boolean) => string;
41
+ /**
42
+ * The check's slot, at the end of the item and the same size whether or not the
43
+ * check is in it, so a list does not shift as the choice moves.
44
+ */
45
+ export declare const POPUP_ITEM_INDICATOR_CLASS = "pointer-events-none absolute right-2 flex size-4 items-center justify-center text-foreground [&_svg]:size-3.5";
46
+ /** A group's heading in any of these lists. */
47
+ export declare const POPUP_GROUP_LABEL_CLASS = "px-2 py-1.5 text-xs font-medium text-muted-foreground";
48
+ /**
49
+ * The frame of every popup that holds a list: Select, Combobox, MultiSelect and the menus. One radius, and one outline, the
50
+ * 1px ring of the text colour at 10% that the menus, Popover and the dialogs already wear. It is a ring and not a border so
51
+ * the frame takes no room: the popup is exactly as tall as its rows, which is what lets a list end on a whole row (see
52
+ * POPUP_LIST_HEIGHT_CLASS). Select used to draw a 14px border, Combobox a 10px one, and the menus a ring.
53
+ *
54
+ * `outline-none` is the popup's own focus outline, switched off: a popup is a container, and the highlighted row is where
55
+ * focus is shown.
56
+ */
57
+ export declare const POPUP_FRAME_CLASS = "rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none";
58
+ /**
59
+ * How wide a popup is, for every popup alike: never narrower than the control it opens from (and never under 8rem, for a
60
+ * control that is only an icon), as wide as its longest row up to 28rem or what the window leaves from the control's start
61
+ * (the popup is aligned to that start), whichever is less. A control wider than that cap keeps its own width. Longer rows
62
+ * are cut by their item, they do not widen the popup.
63
+ *
64
+ * The popups used to disagree: the menus were the control's width, MultiSelect at least 16rem and at most 24rem, Combobox
65
+ * followed the control, and an app's command palette in a popover was 18rem whatever it held.
66
+ */
67
+ export declare const POPUP_LIST_WIDTH_CLASS = "w-max min-w-[max(8rem,var(--anchor-width))] max-w-[max(var(--anchor-width),min(28rem,var(--available-width)))]";
68
+ /**
69
+ * How tall the scrolling part of a popup grows: eight rows, or the whole rows the positioner's room allows, ending on a row.
70
+ * The 0.25rem of air above and below is its own margin (`my-1`), so the list inside takes `px-1` and no vertical padding.
71
+ * PopupListScroll is the ScrollArea ready made, and counts rows only (`--popup-list-cap`). See docs/architecture.md.
72
+ */
73
+ export declare const POPUP_LIST_HEIGHT_CLASS = "my-1 min-h-0 max-h-[var(--popup-list-cap,min(16rem,round(down,var(--available-height,100dvh)_-_0.5rem,2rem)))]";
74
+ /** Where a popup is drawn: `z-60` on its Positioner, above the `z-50` of the Sheet, Dialog or Drawer it opens from. */
75
+ export declare const POPUP_LAYER_CLASS = "z-60";
@@ -0,0 +1,48 @@
1
+ import { cn } from "./utils.js";
2
+ //#region ../ui/src/lib/popup-list.ts
3
+ var ITEM_BASE = "relative flex min-h-8 cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-foreground outline-none select-none [&>svg]:pointer-events-none [&>svg]:shrink-0 [&>svg]:text-muted-foreground [&>svg:not([class*='size-'])]:size-4";
4
+ var ITEM_STATES = {
5
+ "base-ui": "data-highlighted:bg-foreground/6 data-highlighted:[&>svg]:text-foreground data-[selected]:font-medium data-disabled:pointer-events-none data-disabled:opacity-50",
6
+ cmdk: "data-[selected=true]:bg-foreground/6 data-[selected=true]:[&>svg]:text-foreground data-[checked=true]:font-medium data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50"
7
+ };
8
+ /** The shared item look. `checkable` leaves room at the end for the check. */
9
+ var popupItemClass = (flavor = "base-ui", checkable = false) => cn(ITEM_BASE, ITEM_STATES[flavor], checkable && "pr-8");
10
+ /**
11
+ * The check's slot, at the end of the item and the same size whether or not the
12
+ * check is in it, so a list does not shift as the choice moves.
13
+ */
14
+ var POPUP_ITEM_INDICATOR_CLASS = "pointer-events-none absolute right-2 flex size-4 items-center justify-center text-foreground [&_svg]:size-3.5";
15
+ /** A group's heading in any of these lists. */
16
+ var POPUP_GROUP_LABEL_CLASS = "px-2 py-1.5 text-xs font-medium text-muted-foreground";
17
+ /**
18
+ * The frame of every popup that holds a list: Select, Combobox, MultiSelect and the menus. One radius, and one outline, the
19
+ * 1px ring of the text colour at 10% that the menus, Popover and the dialogs already wear. It is a ring and not a border so
20
+ * the frame takes no room: the popup is exactly as tall as its rows, which is what lets a list end on a whole row (see
21
+ * POPUP_LIST_HEIGHT_CLASS). Select used to draw a 14px border, Combobox a 10px one, and the menus a ring.
22
+ *
23
+ * `outline-none` is the popup's own focus outline, switched off: a popup is a container, and the highlighted row is where
24
+ * focus is shown.
25
+ */
26
+ var POPUP_FRAME_CLASS = "rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none";
27
+ /**
28
+ * How wide a popup is, for every popup alike: never narrower than the control it opens from (and never under 8rem, for a
29
+ * control that is only an icon), as wide as its longest row up to 28rem or what the window leaves from the control's start
30
+ * (the popup is aligned to that start), whichever is less. A control wider than that cap keeps its own width. Longer rows
31
+ * are cut by their item, they do not widen the popup.
32
+ *
33
+ * The popups used to disagree: the menus were the control's width, MultiSelect at least 16rem and at most 24rem, Combobox
34
+ * followed the control, and an app's command palette in a popover was 18rem whatever it held.
35
+ */
36
+ var POPUP_LIST_WIDTH_CLASS = "w-max min-w-[max(8rem,var(--anchor-width))] max-w-[max(var(--anchor-width),min(28rem,var(--available-width)))]";
37
+ /**
38
+ * How tall the scrolling part of a popup grows: eight rows, or the whole rows the positioner's room allows, ending on a row.
39
+ * The 0.25rem of air above and below is its own margin (`my-1`), so the list inside takes `px-1` and no vertical padding.
40
+ * PopupListScroll is the ScrollArea ready made, and counts rows only (`--popup-list-cap`). See docs/architecture.md.
41
+ */
42
+ var POPUP_LIST_HEIGHT_CLASS = "my-1 min-h-0 max-h-[var(--popup-list-cap,min(16rem,round(down,var(--available-height,100dvh)_-_0.5rem,2rem)))]";
43
+ /** Where a popup is drawn: `z-60` on its Positioner, above the `z-50` of the Sheet, Dialog or Drawer it opens from. */
44
+ var POPUP_LAYER_CLASS = "z-60";
45
+ //#endregion
46
+ export { POPUP_FRAME_CLASS, POPUP_GROUP_LABEL_CLASS, POPUP_ITEM_INDICATOR_CLASS, POPUP_LAYER_CLASS, POPUP_LIST_HEIGHT_CLASS, POPUP_LIST_WIDTH_CLASS, popupItemClass };
47
+
48
+ //# sourceMappingURL=popup-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popup-list.js","names":[],"sources":["../../../../../ui/src/lib/popup-list.ts"],"sourcesContent":["import { cn } from '@edyn/ui/lib/utils';\n\n/**\n * The one look for a list in a popup or a menu: the command palette, Select,\n * Combobox, MultiSelect and the dropdown menus.\n *\n * These lists used to disagree with each other in every detail that shows:\n * three different radii, two different paddings, a grey fill for the highlight\n * in one and the accent in another, and the chosen item marked by a check on\n * the left in Select and on the right in the menus. Picking something from one\n * list then felt like a different product from picking something in the next.\n *\n * It lives here as classes rather than as a stylesheet so a caller's own\n * className still wins: an unlayered rule would beat every utility, including\n * the one someone passes for a single list.\n *\n * ONE ITEM: transparent at rest, 32px tall, 6px radius (--radius-sm), 6px by\n * 8px of padding, text-sm, its own icons 16px and muted. Under the pointer or\n * the keyboard it takes one translucent fill of the text colour, and its icons\n * the text colour. Chosen is medium weight with a check at the END, never a\n * fill, so \"where I am\" and \"what I picked\" can be told apart at a glance.\n */\n\n/**\n * Which primitive renders the item, because the two disagree about the same\n * attribute names in a way that silently breaks the styling:\n *\n * - cmdk writes `data-selected=\"false\"` and `data-disabled=\"false\"` on items\n * that are neither, so a bare `data-selected:` variant matches EVERY item and\n * highlights the whole list. Its states have to be matched by value.\n * - Base UI omits the attribute instead, so presence is the test there. That\n * needs the BRACKET form for `selected`: shadcn redefines the bare\n * `data-selected:` variant to match only data-selected=\"true\" (for the\n * calendar), and Base UI writes it as an empty string, so the bare form\n * compiles and silently never applies. `highlighted` and `disabled` have no\n * such override, so those stay bare.\n * - And the same name means different things: cmdk's `data-selected` is the\n * keyboard cursor, Base UI's is the chosen value. In cmdk the chosen state is\n * `data-checked`, which the DS's own CommandItem sets.\n */\nexport type TPopupItemFlavor = 'base-ui' | 'cmdk';\n\nconst ITEM_BASE =\n \"relative flex min-h-8 cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-foreground outline-none select-none [&>svg]:pointer-events-none [&>svg]:shrink-0 [&>svg]:text-muted-foreground [&>svg:not([class*='size-'])]:size-4\";\n\nconst ITEM_STATES: Record<TPopupItemFlavor, string> = {\n 'base-ui':\n 'data-highlighted:bg-foreground/6 data-highlighted:[&>svg]:text-foreground data-[selected]:font-medium data-disabled:pointer-events-none data-disabled:opacity-50',\n cmdk: 'data-[selected=true]:bg-foreground/6 data-[selected=true]:[&>svg]:text-foreground data-[checked=true]:font-medium data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50',\n};\n\n/** The shared item look. `checkable` leaves room at the end for the check. */\nexport const popupItemClass = (flavor: TPopupItemFlavor = 'base-ui', checkable = false): string =>\n cn(ITEM_BASE, ITEM_STATES[flavor], checkable && 'pr-8');\n\n/**\n * The check's slot, at the end of the item and the same size whether or not the\n * check is in it, so a list does not shift as the choice moves.\n */\nexport const POPUP_ITEM_INDICATOR_CLASS =\n 'pointer-events-none absolute right-2 flex size-4 items-center justify-center text-foreground [&_svg]:size-3.5';\n\n/** A group's heading in any of these lists. */\nexport const POPUP_GROUP_LABEL_CLASS = 'px-2 py-1.5 text-xs font-medium text-muted-foreground';\n\n/**\n * The frame of every popup that holds a list: Select, Combobox, MultiSelect and the menus. One radius, and one outline, the\n * 1px ring of the text colour at 10% that the menus, Popover and the dialogs already wear. It is a ring and not a border so\n * the frame takes no room: the popup is exactly as tall as its rows, which is what lets a list end on a whole row (see\n * POPUP_LIST_HEIGHT_CLASS). Select used to draw a 14px border, Combobox a 10px one, and the menus a ring.\n *\n * `outline-none` is the popup's own focus outline, switched off: a popup is a container, and the highlighted row is where\n * focus is shown.\n */\nexport const POPUP_FRAME_CLASS = 'rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none';\n\n/**\n * How wide a popup is, for every popup alike: never narrower than the control it opens from (and never under 8rem, for a\n * control that is only an icon), as wide as its longest row up to 28rem or what the window leaves from the control's start\n * (the popup is aligned to that start), whichever is less. A control wider than that cap keeps its own width. Longer rows\n * are cut by their item, they do not widen the popup.\n *\n * The popups used to disagree: the menus were the control's width, MultiSelect at least 16rem and at most 24rem, Combobox\n * followed the control, and an app's command palette in a popover was 18rem whatever it held.\n */\nexport const POPUP_LIST_WIDTH_CLASS =\n 'w-max min-w-[max(8rem,var(--anchor-width))] max-w-[max(var(--anchor-width),min(28rem,var(--available-width)))]';\n\n/**\n * How tall the scrolling part of a popup grows: eight rows, or the whole rows the positioner's room allows, ending on a row.\n * The 0.25rem of air above and below is its own margin (`my-1`), so the list inside takes `px-1` and no vertical padding.\n * PopupListScroll is the ScrollArea ready made, and counts rows only (`--popup-list-cap`). See docs/architecture.md.\n */\nexport const POPUP_LIST_HEIGHT_CLASS =\n 'my-1 min-h-0 max-h-[var(--popup-list-cap,min(16rem,round(down,var(--available-height,100dvh)_-_0.5rem,2rem)))]';\n\n/** Where a popup is drawn: `z-60` on its Positioner, above the `z-50` of the Sheet, Dialog or Drawer it opens from. */\nexport const POPUP_LAYER_CLASS = 'z-60';\n"],"mappings":";;AA0CA,IAAM,YACJ;AAEF,IAAM,cAAgD;CACpD,WACE;CACF,MAAM;AACR;;AAGA,IAAa,kBAAkB,SAA2B,WAAW,YAAY,UAC/E,GAAG,WAAW,YAAY,SAAS,aAAa,MAAM;;;;;AAMxD,IAAa,6BACX;;AAGF,IAAa,0BAA0B;;;;;;;;;;AAWvC,IAAa,oBAAoB;;;;;;;;;;AAWjC,IAAa,yBACX;;;;;;AAOF,IAAa,0BACX;;AAGF,IAAa,oBAAoB"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The shared popup list style, and the trap it exists to keep closed.
3
+ *
4
+ * PATH TAKEN: the look itself is measured in a real browser across the lists and
5
+ * both themes (e2e/popup-lists.spec.ts), because computed padding and radius are
6
+ * the only honest proof of "one look". What is checked here is the part a
7
+ * stylesheet cannot: that each list takes its item look from one place, and that
8
+ * the two primitives' disagreeing attribute conventions are matched correctly.
9
+ */
10
+ export {};
@@ -0,0 +1,21 @@
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+ //#region ../ui/src/lib/utils.ts
4
+ var cn = (...inputs) => twMerge(clsx(inputs));
5
+ /**
6
+ * Normalise a size prop to a CSS length.
7
+ *
8
+ * Bare numbers become px, which is also what a bare numeric *string* means: an
9
+ * element attribute arrives as a string, so `width="480"` and `width={480}` have
10
+ * to land on the same value. Anything with a unit, a percentage or a keyword
11
+ * passes through untouched.
12
+ */
13
+ var cssLength = (value) => {
14
+ if (value == null || value === "") return;
15
+ if (typeof value === "number") return Number.isFinite(value) ? `${value}px` : void 0;
16
+ return /^-?\d*\.?\d+$/.test(value.trim()) ? `${value.trim()}px` : value;
17
+ };
18
+ //#endregion
19
+ export { cn, cssLength };
20
+
21
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../../../ui/src/lib/utils.ts"],"sourcesContent":["import type { ClassValue } from 'clsx';\nimport { clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport const cn = (...inputs: ClassValue[]): string => twMerge(clsx(inputs));\n\n/** A CSS length as a component prop: a number is px, a string is used verbatim. */\nexport type TCssLength = number | string;\n\n/**\n * Normalise a size prop to a CSS length.\n *\n * Bare numbers become px, which is also what a bare numeric *string* means: an\n * element attribute arrives as a string, so `width=\"480\"` and `width={480}` have\n * to land on the same value. Anything with a unit, a percentage or a keyword\n * passes through untouched.\n */\nexport const cssLength = (value: TCssLength | null | undefined): string | undefined => {\n if (value == null || value === '') {\n return undefined;\n }\n\n if (typeof value === 'number') {\n return Number.isFinite(value) ? `${value}px` : undefined;\n }\n\n return /^-?\\d*\\.?\\d+$/.test(value.trim()) ? `${value.trim()}px` : value;\n};\n"],"mappings":";;;AAIA,IAAa,MAAM,GAAG,WAAiC,QAAQ,KAAK,MAAM,CAAC;;;;;;;;;AAa3E,IAAa,aAAa,UAA6D;CACrF,IAAI,SAAS,QAAQ,UAAU,IAC7B;CAGF,IAAI,OAAO,UAAU,UACnB,OAAO,OAAO,SAAS,KAAK,IAAI,GAAG,MAAM,MAAM,KAAA;CAGjD,OAAO,gBAAgB,KAAK,MAAM,KAAK,CAAC,IAAI,GAAG,MAAM,KAAK,EAAE,MAAM;AACpE"}