aeon-ui-engine 1.8.0 → 1.9.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 (527) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/package.json +5 -2
  3. package/packages/core/dist/index.d.ts +116 -1
  4. package/packages/core/dist/index.js +202 -1
  5. package/packages/core/src/anatomy.ts +13 -1
  6. package/packages/core/src/index.ts +2 -0
  7. package/packages/core/src/list-window.ts +149 -0
  8. package/packages/core/src/sound.ts +154 -0
  9. package/packages/panda/package.json +6 -3
  10. package/packages/panda/panda.config.ts +12 -0
  11. package/packages/panda/src/recipes/clipboard.ts +40 -0
  12. package/packages/panda/src/recipes/composer.ts +4 -3
  13. package/packages/panda/src/recipes/index.ts +4 -0
  14. package/packages/panda/src/recipes/prose.ts +110 -0
  15. package/packages/panda/src/recipes/segment-group.ts +50 -0
  16. package/packages/panda/src/recipes/textarea.ts +60 -0
  17. package/packages/panda/styled-system/css/conditions.d.ts +7 -0
  18. package/packages/panda/styled-system/css/conditions.js +32 -0
  19. package/packages/panda/styled-system/css/css.d.ts +6 -6
  20. package/packages/panda/styled-system/css/css.js +63 -0
  21. package/packages/panda/styled-system/css/cva.d.ts +2 -3
  22. package/packages/panda/styled-system/css/cva.js +51 -0
  23. package/packages/panda/styled-system/css/cx.d.ts +5 -4
  24. package/packages/panda/styled-system/css/{cx.mjs → cx.js} +5 -4
  25. package/packages/panda/styled-system/css/first-that-works.d.ts +22 -0
  26. package/packages/panda/styled-system/css/first-that-works.js +1 -0
  27. package/packages/panda/styled-system/css/index.d.ts +6 -3
  28. package/packages/panda/styled-system/css/index.js +8 -0
  29. package/packages/panda/styled-system/css/keyframes.d.ts +5 -0
  30. package/packages/panda/styled-system/css/keyframes.js +8 -0
  31. package/packages/panda/styled-system/css/position-try.d.ts +5 -0
  32. package/packages/panda/styled-system/css/position-try.js +11 -0
  33. package/packages/panda/styled-system/css/sva.d.ts +1 -2
  34. package/packages/panda/styled-system/css/sva.js +49 -0
  35. package/packages/panda/styled-system/css/view-transition.d.ts +7 -0
  36. package/packages/panda/styled-system/css/view-transition.js +18 -0
  37. package/packages/panda/styled-system/helpers.d.ts +67 -0
  38. package/packages/panda/styled-system/helpers.js +624 -0
  39. package/packages/panda/styled-system/jsx/aspect-ratio.d.ts +3 -6
  40. package/packages/panda/styled-system/jsx/aspect-ratio.js +11 -0
  41. package/packages/panda/styled-system/jsx/bleed.d.ts +4 -7
  42. package/packages/panda/styled-system/jsx/bleed.js +11 -0
  43. package/packages/panda/styled-system/jsx/box.d.ts +4 -7
  44. package/packages/panda/styled-system/jsx/box.js +11 -0
  45. package/packages/panda/styled-system/jsx/center.d.ts +4 -7
  46. package/packages/panda/styled-system/jsx/center.js +11 -0
  47. package/packages/panda/styled-system/jsx/circle.d.ts +4 -7
  48. package/packages/panda/styled-system/jsx/circle.js +11 -0
  49. package/packages/panda/styled-system/jsx/container.d.ts +4 -7
  50. package/packages/panda/styled-system/jsx/container.js +11 -0
  51. package/packages/panda/styled-system/jsx/cq.d.ts +4 -7
  52. package/packages/panda/styled-system/jsx/cq.js +11 -0
  53. package/packages/panda/styled-system/jsx/create-recipe-context.d.ts +31 -0
  54. package/packages/panda/styled-system/jsx/create-recipe-context.js +38 -0
  55. package/packages/panda/styled-system/jsx/create-slot-recipe-context.d.ts +49 -0
  56. package/packages/panda/styled-system/jsx/create-slot-recipe-context.js +124 -0
  57. package/packages/panda/styled-system/jsx/divider.d.ts +4 -7
  58. package/packages/panda/styled-system/jsx/divider.js +11 -0
  59. package/packages/panda/styled-system/jsx/factory.d.ts +2 -2
  60. package/packages/panda/styled-system/jsx/factory.js +91 -0
  61. package/packages/panda/styled-system/jsx/flex.d.ts +4 -7
  62. package/packages/panda/styled-system/jsx/flex.js +11 -0
  63. package/packages/panda/styled-system/jsx/float.d.ts +4 -7
  64. package/packages/panda/styled-system/jsx/float.js +11 -0
  65. package/packages/panda/styled-system/jsx/grid-item.d.ts +4 -7
  66. package/packages/panda/styled-system/jsx/grid-item.js +11 -0
  67. package/packages/panda/styled-system/jsx/grid.d.ts +4 -7
  68. package/packages/panda/styled-system/jsx/grid.js +11 -0
  69. package/packages/panda/styled-system/jsx/helper.d.ts +34 -0
  70. package/packages/panda/styled-system/jsx/helper.js +92 -0
  71. package/packages/panda/styled-system/jsx/hstack.d.ts +4 -7
  72. package/packages/panda/styled-system/jsx/hstack.js +11 -0
  73. package/packages/panda/styled-system/jsx/index.d.ts +17 -17
  74. package/packages/panda/styled-system/jsx/index.js +24 -0
  75. package/packages/panda/styled-system/jsx/is-valid-prop.d.ts +5 -10
  76. package/packages/panda/styled-system/jsx/is-valid-prop.js +12 -0
  77. package/packages/panda/styled-system/jsx/link-overlay.d.ts +4 -7
  78. package/packages/panda/styled-system/jsx/link-overlay.js +11 -0
  79. package/packages/panda/styled-system/jsx/spacer.d.ts +4 -7
  80. package/packages/panda/styled-system/jsx/spacer.js +11 -0
  81. package/packages/panda/styled-system/jsx/square.d.ts +4 -7
  82. package/packages/panda/styled-system/jsx/square.js +11 -0
  83. package/packages/panda/styled-system/jsx/stack.d.ts +4 -7
  84. package/packages/panda/styled-system/jsx/stack.js +11 -0
  85. package/packages/panda/styled-system/jsx/visually-hidden.d.ts +4 -7
  86. package/packages/panda/styled-system/jsx/visually-hidden.js +11 -0
  87. package/packages/panda/styled-system/jsx/vstack.d.ts +4 -7
  88. package/packages/panda/styled-system/jsx/vstack.js +11 -0
  89. package/packages/panda/styled-system/jsx/wrap.d.ts +4 -7
  90. package/packages/panda/styled-system/jsx/wrap.js +11 -0
  91. package/packages/panda/styled-system/patterns/aspect-ratio.d.ts +8 -9
  92. package/packages/panda/styled-system/patterns/aspect-ratio.js +37 -0
  93. package/packages/panda/styled-system/patterns/bleed.d.ts +9 -10
  94. package/packages/panda/styled-system/patterns/bleed.js +30 -0
  95. package/packages/panda/styled-system/patterns/box.d.ts +8 -11
  96. package/packages/panda/styled-system/patterns/box.js +16 -0
  97. package/packages/panda/styled-system/patterns/center.d.ts +8 -9
  98. package/packages/panda/styled-system/patterns/center.js +22 -0
  99. package/packages/panda/styled-system/patterns/circle.d.ts +8 -9
  100. package/packages/panda/styled-system/patterns/circle.js +26 -0
  101. package/packages/panda/styled-system/patterns/container.d.ts +8 -11
  102. package/packages/panda/styled-system/patterns/container.js +26 -0
  103. package/packages/panda/styled-system/patterns/cq.d.ts +10 -10
  104. package/packages/panda/styled-system/patterns/cq.js +24 -0
  105. package/packages/panda/styled-system/patterns/divider.d.ts +11 -11
  106. package/packages/panda/styled-system/patterns/divider.js +31 -0
  107. package/packages/panda/styled-system/patterns/flex.d.ts +14 -15
  108. package/packages/panda/styled-system/patterns/flex.js +27 -0
  109. package/packages/panda/styled-system/patterns/float.d.ts +12 -12
  110. package/packages/panda/styled-system/patterns/float.js +84 -0
  111. package/packages/panda/styled-system/patterns/grid-item.d.ts +13 -14
  112. package/packages/panda/styled-system/patterns/grid-item.js +26 -0
  113. package/packages/panda/styled-system/patterns/grid.d.ts +13 -13
  114. package/packages/panda/styled-system/patterns/grid.js +30 -0
  115. package/packages/panda/styled-system/patterns/hstack.d.ts +9 -10
  116. package/packages/panda/styled-system/patterns/hstack.js +27 -0
  117. package/packages/panda/styled-system/patterns/index.d.ts +14 -15
  118. package/packages/panda/styled-system/patterns/index.js +20 -0
  119. package/packages/panda/styled-system/patterns/link-overlay.d.ts +8 -11
  120. package/packages/panda/styled-system/patterns/link-overlay.js +25 -0
  121. package/packages/panda/styled-system/patterns/runtime.js +25 -0
  122. package/packages/panda/styled-system/patterns/spacer.d.ts +9 -9
  123. package/packages/panda/styled-system/patterns/spacer.js +26 -0
  124. package/packages/panda/styled-system/patterns/square.d.ts +8 -9
  125. package/packages/panda/styled-system/patterns/square.js +25 -0
  126. package/packages/panda/styled-system/patterns/stack.d.ts +11 -12
  127. package/packages/panda/styled-system/patterns/stack.js +30 -0
  128. package/packages/panda/styled-system/patterns/visually-hidden.d.ts +8 -11
  129. package/packages/panda/styled-system/patterns/visually-hidden.js +19 -0
  130. package/packages/panda/styled-system/patterns/vstack.d.ts +9 -10
  131. package/packages/panda/styled-system/patterns/vstack.js +27 -0
  132. package/packages/panda/styled-system/patterns/wrap.d.ts +12 -13
  133. package/packages/panda/styled-system/patterns/wrap.js +26 -0
  134. package/packages/panda/styled-system/recipes/aeon-accordion.d.ts +9 -26
  135. package/packages/panda/styled-system/recipes/aeon-accordion.js +5 -0
  136. package/packages/panda/styled-system/recipes/aeon-app-shell.d.ts +10 -26
  137. package/packages/panda/styled-system/recipes/aeon-app-shell.js +5 -0
  138. package/packages/panda/styled-system/recipes/aeon-async.d.ts +9 -26
  139. package/packages/panda/styled-system/recipes/aeon-async.js +5 -0
  140. package/packages/panda/styled-system/recipes/aeon-avatar.d.ts +10 -28
  141. package/packages/panda/styled-system/recipes/aeon-avatar.js +5 -0
  142. package/packages/panda/styled-system/recipes/aeon-badge.d.ts +8 -26
  143. package/packages/panda/styled-system/recipes/aeon-badge.js +5 -0
  144. package/packages/panda/styled-system/recipes/aeon-bar.d.ts +13 -32
  145. package/packages/panda/styled-system/recipes/aeon-bar.js +5 -0
  146. package/packages/panda/styled-system/recipes/aeon-button-group.d.ts +10 -33
  147. package/packages/panda/styled-system/recipes/aeon-button-group.js +5 -0
  148. package/packages/panda/styled-system/recipes/aeon-button.d.ts +10 -33
  149. package/packages/panda/styled-system/recipes/aeon-button.js +5 -0
  150. package/packages/panda/styled-system/recipes/aeon-checkbox.d.ts +9 -24
  151. package/packages/panda/styled-system/recipes/aeon-checkbox.js +5 -0
  152. package/packages/panda/styled-system/recipes/aeon-clipboard.d.ts +16 -0
  153. package/packages/panda/styled-system/recipes/aeon-clipboard.js +5 -0
  154. package/packages/panda/styled-system/recipes/aeon-combobox.d.ts +9 -26
  155. package/packages/panda/styled-system/recipes/aeon-combobox.js +5 -0
  156. package/packages/panda/styled-system/recipes/aeon-composer.d.ts +9 -24
  157. package/packages/panda/styled-system/recipes/aeon-composer.js +5 -0
  158. package/packages/panda/styled-system/recipes/aeon-content.d.ts +10 -26
  159. package/packages/panda/styled-system/recipes/aeon-content.js +5 -0
  160. package/packages/panda/styled-system/recipes/aeon-conversation.d.ts +9 -24
  161. package/packages/panda/styled-system/recipes/aeon-conversation.js +5 -0
  162. package/packages/panda/styled-system/recipes/aeon-dialog.d.ts +9 -24
  163. package/packages/panda/styled-system/recipes/aeon-dialog.js +5 -0
  164. package/packages/panda/styled-system/recipes/aeon-entry.d.ts +11 -30
  165. package/packages/panda/styled-system/recipes/aeon-entry.js +5 -0
  166. package/packages/panda/styled-system/recipes/aeon-field.d.ts +9 -26
  167. package/packages/panda/styled-system/recipes/aeon-field.js +5 -0
  168. package/packages/panda/styled-system/recipes/aeon-file-upload.d.ts +9 -24
  169. package/packages/panda/styled-system/recipes/aeon-file-upload.js +5 -0
  170. package/packages/panda/styled-system/recipes/aeon-identity.d.ts +10 -28
  171. package/packages/panda/styled-system/recipes/aeon-identity.js +5 -0
  172. package/packages/panda/styled-system/recipes/aeon-list-row.d.ts +9 -26
  173. package/packages/panda/styled-system/recipes/aeon-list-row.js +5 -0
  174. package/packages/panda/styled-system/recipes/aeon-menu.d.ts +9 -24
  175. package/packages/panda/styled-system/recipes/aeon-menu.js +5 -0
  176. package/packages/panda/styled-system/recipes/aeon-metric-strip.d.ts +10 -28
  177. package/packages/panda/styled-system/recipes/aeon-metric-strip.js +5 -0
  178. package/packages/panda/styled-system/recipes/aeon-nav.d.ts +11 -30
  179. package/packages/panda/styled-system/recipes/aeon-nav.js +5 -0
  180. package/packages/panda/styled-system/recipes/aeon-panel.d.ts +10 -26
  181. package/packages/panda/styled-system/recipes/aeon-panel.js +5 -0
  182. package/packages/panda/styled-system/recipes/aeon-pin-input.d.ts +9 -24
  183. package/packages/panda/styled-system/recipes/aeon-pin-input.js +5 -0
  184. package/packages/panda/styled-system/recipes/aeon-popover.d.ts +9 -24
  185. package/packages/panda/styled-system/recipes/aeon-popover.js +5 -0
  186. package/packages/panda/styled-system/recipes/aeon-profile-header.d.ts +10 -28
  187. package/packages/panda/styled-system/recipes/aeon-profile-header.js +5 -0
  188. package/packages/panda/styled-system/recipes/aeon-progress.d.ts +9 -24
  189. package/packages/panda/styled-system/recipes/aeon-progress.js +5 -0
  190. package/packages/panda/styled-system/recipes/aeon-prose.d.ts +16 -0
  191. package/packages/panda/styled-system/recipes/aeon-prose.js +5 -0
  192. package/packages/panda/styled-system/recipes/aeon-radio-group.d.ts +9 -24
  193. package/packages/panda/styled-system/recipes/aeon-radio-group.js +5 -0
  194. package/packages/panda/styled-system/recipes/aeon-range-slider.d.ts +9 -24
  195. package/packages/panda/styled-system/recipes/aeon-range-slider.js +5 -0
  196. package/packages/panda/styled-system/recipes/aeon-scroll.d.ts +12 -36
  197. package/packages/panda/styled-system/recipes/aeon-scroll.js +5 -0
  198. package/packages/panda/styled-system/recipes/aeon-segment-group.d.ts +18 -0
  199. package/packages/panda/styled-system/recipes/aeon-segment-group.js +5 -0
  200. package/packages/panda/styled-system/recipes/aeon-select.d.ts +9 -26
  201. package/packages/panda/styled-system/recipes/aeon-select.js +5 -0
  202. package/packages/panda/styled-system/recipes/aeon-separator.d.ts +10 -26
  203. package/packages/panda/styled-system/recipes/aeon-separator.js +5 -0
  204. package/packages/panda/styled-system/recipes/aeon-slider.d.ts +9 -24
  205. package/packages/panda/styled-system/recipes/aeon-slider.js +5 -0
  206. package/packages/panda/styled-system/recipes/aeon-switch.d.ts +9 -24
  207. package/packages/panda/styled-system/recipes/aeon-switch.js +5 -0
  208. package/packages/panda/styled-system/recipes/aeon-tabs.d.ts +9 -24
  209. package/packages/panda/styled-system/recipes/aeon-tabs.js +5 -0
  210. package/packages/panda/styled-system/recipes/aeon-textarea.d.ts +18 -0
  211. package/packages/panda/styled-system/recipes/aeon-textarea.js +5 -0
  212. package/packages/panda/styled-system/recipes/aeon-theme-switcher.d.ts +10 -26
  213. package/packages/panda/styled-system/recipes/aeon-theme-switcher.js +5 -0
  214. package/packages/panda/styled-system/recipes/aeon-thread.d.ts +9 -24
  215. package/packages/panda/styled-system/recipes/aeon-thread.js +5 -0
  216. package/packages/panda/styled-system/recipes/aeon-toast.d.ts +9 -24
  217. package/packages/panda/styled-system/recipes/aeon-toast.js +5 -0
  218. package/packages/panda/styled-system/recipes/aeon-tooltip.d.ts +9 -24
  219. package/packages/panda/styled-system/recipes/aeon-tooltip.js +5 -0
  220. package/packages/panda/styled-system/recipes/index.d.ts +31 -28
  221. package/packages/panda/styled-system/recipes/index.js +43 -0
  222. package/packages/panda/styled-system/recipes/runtime.js +133 -0
  223. package/packages/panda/styled-system/styles.css +1899 -2106
  224. package/packages/panda/styled-system/tokens/index.d.ts +4 -5
  225. package/packages/panda/styled-system/tokens/index.js +18 -0
  226. package/packages/panda/styled-system/types/index.d.ts +3 -6
  227. package/packages/panda/styled-system/types/jsx.d.ts +36 -27
  228. package/packages/panda/styled-system/types/pattern.d.ts +18 -70
  229. package/packages/panda/styled-system/types/recipe.d.ts +50 -154
  230. package/packages/panda/styled-system/types/system.d.ts +1826 -0
  231. package/packages/panda/styled-system/types/tokens.d.ts +65 -0
  232. package/packages/panda/tsconfig.json +3 -1
  233. package/packages/primitives/dist/chunk-5BNAV4S2.js +258 -0
  234. package/packages/primitives/dist/chunk-HYHCIMHC.js +45 -0
  235. package/packages/primitives/dist/index.d.ts +2 -0
  236. package/packages/primitives/dist/index.js +30 -12
  237. package/packages/primitives/dist/machines/app-nav.d.ts +3 -3
  238. package/packages/primitives/dist/machines/cache.d.ts +223 -0
  239. package/packages/primitives/dist/machines/cache.js +14 -0
  240. package/packages/primitives/dist/machines/clipboard.d.ts +46 -0
  241. package/packages/primitives/dist/machines/clipboard.js +8 -0
  242. package/packages/primitives/dist/machines/tabs.d.ts +2 -2
  243. package/packages/primitives/src/index.ts +2 -0
  244. package/packages/primitives/src/machines/cache.ts +395 -0
  245. package/packages/primitives/src/machines/clipboard.ts +56 -0
  246. package/packages/react/dist/index.d.ts +106 -10
  247. package/packages/react/dist/index.js +1350 -994
  248. package/packages/react/src/clipboard/index.tsx +117 -0
  249. package/packages/react/src/composer/index.tsx +14 -5
  250. package/packages/react/src/index.ts +4 -0
  251. package/packages/react/src/prose/index.tsx +11 -0
  252. package/packages/react/src/radio-group/index.tsx +2 -1
  253. package/packages/react/src/scroll/index.tsx +1 -0
  254. package/packages/react/src/scroll/use-windowed-range.ts +118 -0
  255. package/packages/react/src/segment-group/index.tsx +171 -0
  256. package/packages/react/src/select/index.tsx +11 -2
  257. package/packages/react/src/tabs/index.tsx +19 -7
  258. package/packages/react/src/textarea/index.tsx +75 -0
  259. package/packages/react/src/utils/assign-ref.ts +7 -0
  260. package/packages/schemas/dist/index.d.ts +8 -0
  261. package/packages/schemas/dist/index.js +59 -0
  262. package/packages/schemas/json/catalog.json +493 -0
  263. package/packages/schemas/json/clipboard.json +136 -0
  264. package/packages/schemas/json/prose.json +103 -0
  265. package/packages/schemas/json/segmentGroup.json +131 -0
  266. package/packages/schemas/json/textarea.json +119 -0
  267. package/packages/schemas/registry/catalog.json +34 -0
  268. package/packages/schemas/registry/components/clipboard.json +136 -0
  269. package/packages/schemas/registry/components/prose.json +103 -0
  270. package/packages/schemas/registry/components/segmentGroup.json +131 -0
  271. package/packages/schemas/registry/components/textarea.json +119 -0
  272. package/packages/schemas/registry/machines/clipboard.json +110 -0
  273. package/packages/schemas/scripts/emit.ts +2 -0
  274. package/packages/schemas/src/components.ts +63 -0
  275. package/packages/ui/dist/index.d.ts +27 -3
  276. package/packages/ui/dist/index.js +232 -165
  277. package/packages/ui/src/clipboard.tsx +51 -0
  278. package/packages/ui/src/index.ts +4 -0
  279. package/packages/ui/src/prose.tsx +15 -0
  280. package/packages/ui/src/segment-group.tsx +28 -0
  281. package/packages/ui/src/textarea.tsx +17 -0
  282. package/scripts/vite-aliases.mjs +2 -2
  283. package/packages/cli/node_modules/.bin/esbuild +0 -21
  284. package/packages/cli/node_modules/.bin/jiti +0 -21
  285. package/packages/cli/node_modules/.bin/tsc +0 -21
  286. package/packages/cli/node_modules/.bin/tsserver +0 -21
  287. package/packages/cli/node_modules/.bin/tsup +0 -21
  288. package/packages/cli/node_modules/.bin/tsup-node +0 -21
  289. package/packages/cli/node_modules/.bin/tsx +0 -21
  290. package/packages/cli/node_modules/.bin/vite +0 -21
  291. package/packages/cli/node_modules/.bin/vitest +0 -21
  292. package/packages/core/node_modules/.bin/esbuild +0 -21
  293. package/packages/core/node_modules/.bin/jiti +0 -21
  294. package/packages/core/node_modules/.bin/tsc +0 -21
  295. package/packages/core/node_modules/.bin/tsserver +0 -21
  296. package/packages/core/node_modules/.bin/tsup +0 -21
  297. package/packages/core/node_modules/.bin/tsup-node +0 -21
  298. package/packages/core/node_modules/.bin/tsx +0 -21
  299. package/packages/core/node_modules/.bin/vite +0 -21
  300. package/packages/core/node_modules/.bin/vitest +0 -21
  301. package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  302. package/packages/core/src/identicon.test.ts +0 -39
  303. package/packages/core/src/machine.test.ts +0 -79
  304. package/packages/core/src/theme.test.ts +0 -14
  305. package/packages/geometry/node_modules/.bin/esbuild +0 -21
  306. package/packages/geometry/node_modules/.bin/jiti +0 -21
  307. package/packages/geometry/node_modules/.bin/tsc +0 -21
  308. package/packages/geometry/node_modules/.bin/tsserver +0 -21
  309. package/packages/geometry/node_modules/.bin/tsup +0 -21
  310. package/packages/geometry/node_modules/.bin/tsup-node +0 -21
  311. package/packages/geometry/node_modules/.bin/tsx +0 -21
  312. package/packages/panda/styled-system/css/conditions.mjs +0 -36
  313. package/packages/panda/styled-system/css/css.mjs +0 -45
  314. package/packages/panda/styled-system/css/cva.mjs +0 -87
  315. package/packages/panda/styled-system/css/index.mjs +0 -4
  316. package/packages/panda/styled-system/css/sva.mjs +0 -46
  317. package/packages/panda/styled-system/helpers.mjs +0 -328
  318. package/packages/panda/styled-system/jsx/aspect-ratio.mjs +0 -14
  319. package/packages/panda/styled-system/jsx/bleed.mjs +0 -14
  320. package/packages/panda/styled-system/jsx/box.mjs +0 -14
  321. package/packages/panda/styled-system/jsx/center.mjs +0 -14
  322. package/packages/panda/styled-system/jsx/circle.mjs +0 -14
  323. package/packages/panda/styled-system/jsx/container.mjs +0 -14
  324. package/packages/panda/styled-system/jsx/cq.mjs +0 -14
  325. package/packages/panda/styled-system/jsx/create-style-context.d.ts +0 -54
  326. package/packages/panda/styled-system/jsx/create-style-context.mjs +0 -121
  327. package/packages/panda/styled-system/jsx/divider.mjs +0 -14
  328. package/packages/panda/styled-system/jsx/factory-helper.mjs +0 -22
  329. package/packages/panda/styled-system/jsx/factory.mjs +0 -89
  330. package/packages/panda/styled-system/jsx/flex.mjs +0 -14
  331. package/packages/panda/styled-system/jsx/float.mjs +0 -14
  332. package/packages/panda/styled-system/jsx/grid-item.mjs +0 -14
  333. package/packages/panda/styled-system/jsx/grid.mjs +0 -14
  334. package/packages/panda/styled-system/jsx/hstack.mjs +0 -14
  335. package/packages/panda/styled-system/jsx/index.mjs +0 -23
  336. package/packages/panda/styled-system/jsx/is-valid-prop.mjs +0 -17
  337. package/packages/panda/styled-system/jsx/link-overlay.mjs +0 -14
  338. package/packages/panda/styled-system/jsx/spacer.mjs +0 -14
  339. package/packages/panda/styled-system/jsx/square.mjs +0 -14
  340. package/packages/panda/styled-system/jsx/stack.mjs +0 -14
  341. package/packages/panda/styled-system/jsx/visually-hidden.mjs +0 -14
  342. package/packages/panda/styled-system/jsx/vstack.mjs +0 -14
  343. package/packages/panda/styled-system/jsx/wrap.mjs +0 -14
  344. package/packages/panda/styled-system/patterns/aspect-ratio.mjs +0 -38
  345. package/packages/panda/styled-system/patterns/bleed.mjs +0 -24
  346. package/packages/panda/styled-system/patterns/box.mjs +0 -15
  347. package/packages/panda/styled-system/patterns/center.mjs +0 -21
  348. package/packages/panda/styled-system/patterns/circle.mjs +0 -25
  349. package/packages/panda/styled-system/patterns/container.mjs +0 -21
  350. package/packages/panda/styled-system/patterns/cq.mjs +0 -21
  351. package/packages/panda/styled-system/patterns/divider.mjs +0 -25
  352. package/packages/panda/styled-system/patterns/flex.mjs +0 -26
  353. package/packages/panda/styled-system/patterns/float.mjs +0 -52
  354. package/packages/panda/styled-system/patterns/grid-item.mjs +0 -25
  355. package/packages/panda/styled-system/patterns/grid.mjs +0 -27
  356. package/packages/panda/styled-system/patterns/hstack.mjs +0 -24
  357. package/packages/panda/styled-system/patterns/index.mjs +0 -20
  358. package/packages/panda/styled-system/patterns/link-overlay.mjs +0 -24
  359. package/packages/panda/styled-system/patterns/spacer.mjs +0 -25
  360. package/packages/panda/styled-system/patterns/square.mjs +0 -24
  361. package/packages/panda/styled-system/patterns/stack.mjs +0 -24
  362. package/packages/panda/styled-system/patterns/visually-hidden.mjs +0 -18
  363. package/packages/panda/styled-system/patterns/vstack.mjs +0 -24
  364. package/packages/panda/styled-system/patterns/wrap.mjs +0 -25
  365. package/packages/panda/styled-system/recipes/aeon-accordion.mjs +0 -49
  366. package/packages/panda/styled-system/recipes/aeon-app-shell.mjs +0 -70
  367. package/packages/panda/styled-system/recipes/aeon-async.mjs +0 -57
  368. package/packages/panda/styled-system/recipes/aeon-avatar.mjs +0 -57
  369. package/packages/panda/styled-system/recipes/aeon-badge.mjs +0 -32
  370. package/packages/panda/styled-system/recipes/aeon-bar.mjs +0 -77
  371. package/packages/panda/styled-system/recipes/aeon-button-group.mjs +0 -37
  372. package/packages/panda/styled-system/recipes/aeon-button.mjs +0 -39
  373. package/packages/panda/styled-system/recipes/aeon-checkbox.mjs +0 -49
  374. package/packages/panda/styled-system/recipes/aeon-combobox.mjs +0 -53
  375. package/packages/panda/styled-system/recipes/aeon-composer.mjs +0 -57
  376. package/packages/panda/styled-system/recipes/aeon-content.mjs +0 -70
  377. package/packages/panda/styled-system/recipes/aeon-conversation.mjs +0 -61
  378. package/packages/panda/styled-system/recipes/aeon-dialog.mjs +0 -61
  379. package/packages/panda/styled-system/recipes/aeon-entry.mjs +0 -100
  380. package/packages/panda/styled-system/recipes/aeon-field.mjs +0 -53
  381. package/packages/panda/styled-system/recipes/aeon-file-upload.mjs +0 -61
  382. package/packages/panda/styled-system/recipes/aeon-identity.mjs +0 -63
  383. package/packages/panda/styled-system/recipes/aeon-list-row.mjs +0 -49
  384. package/packages/panda/styled-system/recipes/aeon-menu.mjs +0 -53
  385. package/packages/panda/styled-system/recipes/aeon-metric-strip.mjs +0 -54
  386. package/packages/panda/styled-system/recipes/aeon-nav.mjs +0 -69
  387. package/packages/panda/styled-system/recipes/aeon-panel.mjs +0 -58
  388. package/packages/panda/styled-system/recipes/aeon-pin-input.mjs +0 -37
  389. package/packages/panda/styled-system/recipes/aeon-popover.mjs +0 -53
  390. package/packages/panda/styled-system/recipes/aeon-profile-header.mjs +0 -62
  391. package/packages/panda/styled-system/recipes/aeon-progress.mjs +0 -45
  392. package/packages/panda/styled-system/recipes/aeon-radio-group.mjs +0 -49
  393. package/packages/panda/styled-system/recipes/aeon-range-slider.mjs +0 -49
  394. package/packages/panda/styled-system/recipes/aeon-scroll.mjs +0 -64
  395. package/packages/panda/styled-system/recipes/aeon-select.mjs +0 -57
  396. package/packages/panda/styled-system/recipes/aeon-separator.mjs +0 -42
  397. package/packages/panda/styled-system/recipes/aeon-slider.mjs +0 -49
  398. package/packages/panda/styled-system/recipes/aeon-switch.mjs +0 -49
  399. package/packages/panda/styled-system/recipes/aeon-tabs.mjs +0 -49
  400. package/packages/panda/styled-system/recipes/aeon-theme-switcher.mjs +0 -59
  401. package/packages/panda/styled-system/recipes/aeon-thread.mjs +0 -73
  402. package/packages/panda/styled-system/recipes/aeon-toast.mjs +0 -49
  403. package/packages/panda/styled-system/recipes/aeon-tooltip.mjs +0 -49
  404. package/packages/panda/styled-system/recipes/create-recipe.mjs +0 -82
  405. package/packages/panda/styled-system/recipes/index.mjs +0 -39
  406. package/packages/panda/styled-system/tokens/index.mjs +0 -2224
  407. package/packages/panda/styled-system/tokens/tokens.d.ts +0 -60
  408. package/packages/panda/styled-system/types/composition.d.ts +0 -227
  409. package/packages/panda/styled-system/types/conditions.d.ts +0 -346
  410. package/packages/panda/styled-system/types/csstype.d.ts +0 -22570
  411. package/packages/panda/styled-system/types/global.d.ts +0 -20
  412. package/packages/panda/styled-system/types/parts.d.ts +0 -8
  413. package/packages/panda/styled-system/types/prop-type.d.ts +0 -250
  414. package/packages/panda/styled-system/types/selectors.d.ts +0 -59
  415. package/packages/panda/styled-system/types/static-css.d.ts +0 -56
  416. package/packages/panda/styled-system/types/style-props.d.ts +0 -8089
  417. package/packages/panda/styled-system/types/system-types.d.ts +0 -151
  418. package/packages/primitives/node_modules/.bin/esbuild +0 -21
  419. package/packages/primitives/node_modules/.bin/jiti +0 -21
  420. package/packages/primitives/node_modules/.bin/tsc +0 -21
  421. package/packages/primitives/node_modules/.bin/tsserver +0 -21
  422. package/packages/primitives/node_modules/.bin/tsup +0 -21
  423. package/packages/primitives/node_modules/.bin/tsup-node +0 -21
  424. package/packages/primitives/node_modules/.bin/tsx +0 -21
  425. package/packages/primitives/node_modules/.bin/vite +0 -21
  426. package/packages/primitives/node_modules/.bin/vitest +0 -21
  427. package/packages/primitives/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  428. package/packages/primitives/src/__tests__/app-nav.test.ts +0 -30
  429. package/packages/primitives/src/__tests__/file-upload.test.ts +0 -25
  430. package/packages/primitives/src/__tests__/floating-surface.test.ts +0 -29
  431. package/packages/primitives/src/__tests__/range-slider.test.ts +0 -39
  432. package/packages/react/node_modules/.bin/esbuild +0 -21
  433. package/packages/react/node_modules/.bin/jiti +0 -21
  434. package/packages/react/node_modules/.bin/tsc +0 -21
  435. package/packages/react/node_modules/.bin/tsserver +0 -21
  436. package/packages/react/node_modules/.bin/tsup +0 -21
  437. package/packages/react/node_modules/.bin/tsup-node +0 -21
  438. package/packages/react/node_modules/.bin/tsx +0 -21
  439. package/packages/react/node_modules/.bin/vite +0 -21
  440. package/packages/react/node_modules/.bin/vitest +0 -21
  441. package/packages/react/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  442. package/packages/react/src/avatar/avatar.test.tsx +0 -27
  443. package/packages/react/src/dialog/dialog.test.tsx +0 -77
  444. package/packages/react/src/select/select.test.tsx +0 -81
  445. package/packages/react/src/toast/toast.test.tsx +0 -40
  446. package/packages/react/src/tooltip/tooltip.test.tsx +0 -122
  447. package/packages/react-scene/node_modules/.bin/jiti +0 -21
  448. package/packages/react-scene/node_modules/.bin/tsc +0 -21
  449. package/packages/react-scene/node_modules/.bin/tsserver +0 -21
  450. package/packages/react-scene/node_modules/.bin/tsup +0 -21
  451. package/packages/react-scene/node_modules/.bin/tsup-node +0 -21
  452. package/packages/react-scene/node_modules/.bin/tsx +0 -21
  453. package/packages/scene/node_modules/.bin/jiti +0 -21
  454. package/packages/scene/node_modules/.bin/tsc +0 -21
  455. package/packages/scene/node_modules/.bin/tsserver +0 -21
  456. package/packages/scene/node_modules/.bin/tsup +0 -21
  457. package/packages/scene/node_modules/.bin/tsup-node +0 -21
  458. package/packages/scene/node_modules/.bin/tsx +0 -21
  459. package/packages/schemas/node_modules/.bin/esbuild +0 -21
  460. package/packages/schemas/node_modules/.bin/jiti +0 -21
  461. package/packages/schemas/node_modules/.bin/tsc +0 -21
  462. package/packages/schemas/node_modules/.bin/tsserver +0 -21
  463. package/packages/schemas/node_modules/.bin/tsup +0 -21
  464. package/packages/schemas/node_modules/.bin/tsup-node +0 -21
  465. package/packages/schemas/node_modules/.bin/tsx +0 -21
  466. package/packages/schemas/node_modules/.bin/vite +0 -21
  467. package/packages/schemas/node_modules/.bin/vitest +0 -21
  468. package/packages/schemas/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  469. package/packages/schemas/src/aeon-to-schema.test.ts +0 -70
  470. package/packages/schemas/src/index.test.ts +0 -108
  471. package/packages/signal/node_modules/.bin/jiti +0 -21
  472. package/packages/signal/node_modules/.bin/tsc +0 -21
  473. package/packages/signal/node_modules/.bin/tsserver +0 -21
  474. package/packages/signal/node_modules/.bin/tsup +0 -21
  475. package/packages/signal/node_modules/.bin/tsup-node +0 -21
  476. package/packages/signal/node_modules/.bin/tsx +0 -21
  477. package/packages/site/node_modules/.bin/jiti +0 -21
  478. package/packages/site/node_modules/.bin/tsc +0 -21
  479. package/packages/site/node_modules/.bin/tsserver +0 -21
  480. package/packages/site/node_modules/.bin/tsup +0 -21
  481. package/packages/site/node_modules/.bin/tsup-node +0 -21
  482. package/packages/site/node_modules/.bin/tsx +0 -21
  483. package/packages/solid/node_modules/.bin/jiti +0 -21
  484. package/packages/solid/node_modules/.bin/tsc +0 -21
  485. package/packages/solid/node_modules/.bin/tsserver +0 -21
  486. package/packages/solid/node_modules/.bin/tsup +0 -21
  487. package/packages/solid/node_modules/.bin/tsup-node +0 -21
  488. package/packages/solid/node_modules/.bin/tsx +0 -21
  489. package/packages/surface/node_modules/.bin/jiti +0 -21
  490. package/packages/surface/node_modules/.bin/tsc +0 -21
  491. package/packages/surface/node_modules/.bin/tsserver +0 -21
  492. package/packages/surface/node_modules/.bin/tsup +0 -21
  493. package/packages/surface/node_modules/.bin/tsup-node +0 -21
  494. package/packages/surface/node_modules/.bin/tsx +0 -21
  495. package/packages/svelte/node_modules/.bin/acorn +0 -21
  496. package/packages/svelte/node_modules/.bin/esbuild +0 -21
  497. package/packages/svelte/node_modules/.bin/jiti +0 -21
  498. package/packages/svelte/node_modules/.bin/svelte-check +0 -21
  499. package/packages/svelte/node_modules/.bin/tsc +0 -21
  500. package/packages/svelte/node_modules/.bin/tsserver +0 -21
  501. package/packages/svelte/node_modules/.bin/tsup +0 -21
  502. package/packages/svelte/node_modules/.bin/tsup-node +0 -21
  503. package/packages/svelte/node_modules/.bin/tsx +0 -21
  504. package/packages/svelte/node_modules/.bin/vite +0 -21
  505. package/packages/tree/node_modules/.bin/esbuild +0 -21
  506. package/packages/tree/node_modules/.bin/jiti +0 -21
  507. package/packages/tree/node_modules/.bin/tsc +0 -21
  508. package/packages/tree/node_modules/.bin/tsserver +0 -21
  509. package/packages/tree/node_modules/.bin/tsup +0 -21
  510. package/packages/tree/node_modules/.bin/tsup-node +0 -21
  511. package/packages/tree/node_modules/.bin/tsx +0 -21
  512. package/packages/tree/node_modules/.bin/vite +0 -21
  513. package/packages/tree/node_modules/.bin/vitest +0 -21
  514. package/packages/tree/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  515. package/packages/tree/src/exclusive-action.test.ts +0 -54
  516. package/packages/ui/node_modules/.bin/jiti +0 -21
  517. package/packages/ui/node_modules/.bin/tsc +0 -21
  518. package/packages/ui/node_modules/.bin/tsserver +0 -21
  519. package/packages/ui/node_modules/.bin/tsup +0 -21
  520. package/packages/ui/node_modules/.bin/tsup-node +0 -21
  521. package/packages/ui/node_modules/.bin/tsx +0 -21
  522. package/packages/vue/node_modules/.bin/jiti +0 -21
  523. package/packages/vue/node_modules/.bin/tsc +0 -21
  524. package/packages/vue/node_modules/.bin/tsserver +0 -21
  525. package/packages/vue/node_modules/.bin/tsup +0 -21
  526. package/packages/vue/node_modules/.bin/tsup-node +0 -21
  527. package/packages/vue/node_modules/.bin/tsx +0 -21
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased]
4
+
5
+ ## [1.9.0] - 2026-10-21
6
+
7
+ ### Added
8
+
9
+ - **Chart cache (`@aeon-ui/primitives`).** `createChartCache({ id, load, ttl, tags? })` is a keyed cache charts invoke as `cache.actor`, shared by every chart instance. Each key is a `cacheEntryMachine` (`idle`, `loading`, `ready`, `stale`, `refreshing`, `failed`): one load per key, a time-to-live per key, stale data served while it revalidates, and `CACHE.INVALIDATE` by key or tag. `peek()` returns a stable view for selectors. Ids naming secrets, keys or spend decisions are refused.
10
+ - **Windowed lists.** `computeListWindow` (`@aeon-ui/core`) and `useWindowedRange` (`@aeon-ui/react`) mount only the rows in view, for vertical lists and horizontal strips.
11
+ - **Sounds (`@aeon-ui/core`).** `playSound(name)` plays short UI sounds synthesized with Web Audio (`tap`, `copy`, `send`, `success`, `attention`, `error`, `ready`); no audio files. Silent until the app calls `configureSounds({ enabled: true, volume })`. The same sound fired twice within 60 ms plays once. `createSoundPlayer` takes a context factory for tests.
12
+ - **`Clipboard` sounds.** `clipboardMachine` plays `copy` on entering `copied` and `error` on entering `failed`, through the `soundCopied` / `soundFailed` actions.
13
+ - **`Clipboard`.** One-click copy on `clipboardMachine` (idle, copying, copied, failed); the styled trigger swaps a copy icon for a check and a live region announces the result.
14
+ - **`Prose`.** Styles rendered markdown in em, so it follows the surrounding font size; draws list markers the reset strips, and `<ol start>` numbers correctly.
15
+ - **`Textarea`.** Grows with its content between `minRows` and `maxRows`; `outline` and `ghost` variants.
16
+ - **`SegmentGroup`.** Compact single choice on `tabsMachine`; arrow keys, Home and End move the selection and skip disabled items.
17
+ - **`Composer.Input` `minRows` / `maxRows`.** The input grows with its text (default 1 to 4 lines) instead of staying one fixed height.
18
+
19
+ ### Changed
20
+
21
+ - **Panda CSS 2.** `@aeon-ui/panda` runs on `@pandacss/dev` 2.3 and lists `preset-base` and `preset-panda` itself, since v2 adds no presets on its own. Generated `styled-system` files are `.js` instead of `.mjs`.
22
+
23
+ - **`Select.Positioner` `anchorRef`, `placement`, `matchAnchorWidth`.** The same options `Popover.Positioner` takes: a compact trigger pinned to the end of a row can open its listbox across the row it belongs to, so option labels and details are not squeezed to the trigger's width.
24
+
25
+ ### Fixed
26
+
27
+ - **Controlled `Tabs.Root` reports clicks.** With `value` set, a trigger click calls `onValueChange` with the clicked value; before, it changed only machine state the controlled value ignored, so the tab never switched. `Tabs.Root` also takes div attributes.
28
+ - **`RadioGroup.Root` takes `aria-label`.** Its props extend div attributes, so `aria-label`, `id` and the rest type-check (the root already passed them through).
29
+ - **`anatomy()` carries its `scope` at runtime.** The type promised `.scope`, but the object had none, so `scopeAttrs(x.scope, …)` emitted `data-aeon-scope="undefined"`.
30
+
3
31
  ## [1.8.0] - 2026-09-27
4
32
 
5
33
  ### Added
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "aeon-ui-engine",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
7
- "aeon-ui": "./packages/cli/dist/bin.js"
7
+ "aeon-ui": "packages/cli/dist/bin.js"
8
8
  },
9
9
  "exports": {
10
10
  "./vite": "./scripts/vite-aliases.mjs",
@@ -17,6 +17,9 @@
17
17
  },
18
18
  "files": [
19
19
  "packages",
20
+ "!packages/*/node_modules",
21
+ "!packages/**/*.test.ts",
22
+ "!packages/**/*.test.tsx",
20
23
  "scripts",
21
24
  "tsconfig.base.json",
22
25
  "CONSUMER.md",
@@ -159,6 +159,22 @@ declare const composerAnatomy: Record<"root" | "actions" | "input" | "send" | "s
159
159
  declare const separatorAnatomy: Record<"root", "root"> & {
160
160
  scope: string;
161
161
  };
162
+ /** Long-form rich text (rendered markdown). Styles its descendants; no state of its own. */
163
+ declare const proseAnatomy: Record<"root", "root"> & {
164
+ scope: string;
165
+ };
166
+ /** Multi-line input that grows with its content between `minRows` and `maxRows`. */
167
+ declare const textareaAnatomy: Record<"root", "root"> & {
168
+ scope: string;
169
+ };
170
+ /** Compact single choice rendered as adjacent buttons; same chart family as Tabs / RadioGroup. */
171
+ declare const segmentGroupAnatomy: Record<"root" | "item", "root" | "item"> & {
172
+ scope: string;
173
+ };
174
+ /** Copy a value to the clipboard; root state idle | copying | copied | failed. */
175
+ declare const clipboardAnatomy: Record<"root" | "indicator" | "trigger" | "status", "root" | "indicator" | "trigger" | "status"> & {
176
+ scope: string;
177
+ };
162
178
  /** Progress bar — idle / loading / complete on root `data-aeon-state`. */
163
179
  declare const progressAnatomy: Record<"root" | "label" | "track" | "range", "root" | "label" | "track" | "range"> & {
164
180
  scope: string;
@@ -308,6 +324,67 @@ interface ScrollSnapshot {
308
324
  /** Derive overflow + edge states from a scrollable element. */
309
325
  declare function getScrollSnapshot(el: HTMLElement): ScrollSnapshot;
310
326
 
327
+ /**
328
+ * Windowed slice of a long list or grid: which items to mount and how much
329
+ * space stands in for the rest. Geometry, not lifecycle, so like Scroll it is
330
+ * a pure function over measurements, never a machine.
331
+ */
332
+ interface ListWindow {
333
+ /** First mounted item index. */
334
+ start: number;
335
+ /** One past the last mounted item index. */
336
+ end: number;
337
+ /** Pixels standing in for the rows above the window. */
338
+ padStart: number;
339
+ /** Pixels standing in for the rows below the window. */
340
+ padEnd: number;
341
+ }
342
+ /** The direction a list scrolls: rows down a column, or items along a strip. */
343
+ type ListWindowAxis = 'y' | 'x';
344
+ interface ListWindowInput {
345
+ total: number;
346
+ /** Row pitch in pixels along the scroll axis, gap included. */
347
+ rowExtent: number;
348
+ /** Items per row; 1 for a list. */
349
+ columns?: number;
350
+ /** Rows mounted beyond each edge of the viewport. */
351
+ overscan?: number;
352
+ /** How far the list's content has moved past the start of its viewport. */
353
+ scrolledPast: number;
354
+ /** Viewport length along the scroll axis. */
355
+ viewportHeight: number;
356
+ /** Below this many items the whole list mounts. */
357
+ minItems?: number;
358
+ }
359
+ /**
360
+ * Below this, windowing costs more than it saves and a mis-measured row would
361
+ * visibly shift a short list.
362
+ */
363
+ declare const LIST_WINDOW_MIN_ITEMS = 60;
364
+ declare function fullListWindow(total: number): ListWindow;
365
+ declare function sameListWindow(a: ListWindow, b: ListWindow): boolean;
366
+ declare function computeListWindow(input: ListWindowInput): ListWindow;
367
+ /** Attribute that marks a spacer, so row measuring skips it. */
368
+ declare const LIST_WINDOW_PAD_ATTR = "data-aeon-window-pad";
369
+ declare function listWindowPadAttrs(edge: 'start' | 'end'): Record<string, string | boolean>;
370
+ /** The element that actually scrolls a list: the nearest ancestor overflowing on the axis, else the window. */
371
+ declare function resolveScrollRoot(el: HTMLElement | null, axis?: ListWindowAxis): HTMLElement | Window;
372
+ declare function scrollRootHeight(root: HTMLElement | Window): number;
373
+ /** Viewport length along the axis. */
374
+ declare function scrollRootExtent(root: HTMLElement | Window, axis?: ListWindowAxis): number;
375
+ declare function scrollRootTop(root: HTMLElement | Window): number;
376
+ /**
377
+ * How far the list's content has moved past the viewport. A list that is its
378
+ * own scroll root reports its scroll offset: subtracting its own edge from
379
+ * itself is always 0, which kept the first rows mounted while the scrollbar
380
+ * travelled through the end spacer.
381
+ */
382
+ declare function scrollRootScrolledPast(root: HTMLElement | Window, list: HTMLElement, axis?: ListWindowAxis): number;
383
+ /** Real column count for a grid; 1 for a list. The hint is only a fallback. */
384
+ declare function measureListColumns(style: CSSStyleDeclaration, hint?: number): number;
385
+ /** Row pitch along the axis from a rendered row, so spacers match what is on screen. */
386
+ declare function measureListRowExtent(list: HTMLElement, style: CSSStyleDeclaration, hint: number, rowSelector?: string, axis?: ListWindowAxis): number;
387
+
311
388
  /**
312
389
  * Responsive play-surface layout — logical coordinate plane + composition modes.
313
390
  *
@@ -530,4 +607,42 @@ declare function identiconColor(seed: string): {
530
607
  /** SVG data URL for `<img src>` / CSS background. */
531
608
  declare function identiconDataUrl(seed: string, size?: number): string;
532
609
 
533
- export { AEON_PRINCIPLE, AEON_THEME_TRANSITION_CLASS, type AeonActor, type AeonColorMode, type AeonContext, type AeonDataAttrs, type AeonEvent, type AeonPalette, type AeonSnapshot, type AeonStateValue, type AeonThemeDefinition, type ApplyBrandPaletteOptions, type BrandPalette, type BrandPaletteInput, DEFAULT_COMPACT_MQ, type FieldFace, type LayoutComposition, type LayoutCompositionSpec, type LayoutMode, NORM_PLANE, type NormOrigin, type NormPoint, type NormRect, type RegionLayoutSlot, type ResponsiveLayoutSpec, type ScrollOverflow, type ScrollSnapshot, UI_IS_FUNCTION_OF_STATE, accordionAnatomy, anatomy, appNavAnatomy, appShellAnatomy, applyAeonTheme, applyBrandPalette, asyncAnatomy, avatarAnatomy, barAnatomy, brandPaletteToCssText, brandPaletteToCssVars, buttonAnatomy, checkboxAnatomy, clampNorm, clientFromNorm, comboboxAnatomy, composerAnatomy, contentAnatomy, conversationAnatomy, dialogAnatomy, entryAnatomy, fieldAnatomy, fieldFace, fieldRegions, fileUploadAnatomy, getCompactMq, getRegionValue, getScrollSnapshot, identiconColor, identiconDataUrl, identiconGrid, identiconSeedBytes, identityAnatomy, initAeonTheme, insetNormCluster, isAeonColorMode, isAeonMode, isAeonThemeId, layoutCompositionForMode, layoutModeAttrs, listRowAnatomy, matchLayoutMode, measureElement, menuAnatomy, metricStripAnatomy, navAnatomy, normFromClient, normalizeBrandPalette, panelAnatomy, partAttrs, partOnlyAttrs, pinInputAnatomy, playSurfaceAnatomy, popoverAnatomy, profileHeaderAnatomy, progressAnatomy, promptAnatomy, radioGroupAnatomy, rangeSliderAnatomy, regionBoundsForMode, regionLeaf, regionMatches, regionPath, registerAeonThemes, resolveAeonColorMode, resolveRegionRect, runAeonThemeTransition, scopeAttrs, scrollAnatomy, selectAnatomy, separatorAnatomy, sliderAnatomy, stateToAttr, statusBannerAnatomy, switchAnatomy, syncAeonColorMode, tabsAnatomy, themeSwitcherAnatomy, threadAnatomy, toastAnatomy, tooltipAnatomy };
610
+ /**
611
+ * Short UI sounds synthesized with Web Audio: no files to ship or license.
612
+ * Silent until an app calls `configureSounds({ enabled: true })`.
613
+ */
614
+ type SoundName = 'tap' | 'copy' | 'send' | 'success' | 'attention' | 'error' | 'ready';
615
+ interface Tone {
616
+ /** Start frequency in Hz. */
617
+ freq: number;
618
+ /** End frequency in Hz; glides from `freq` over the tone. */
619
+ to?: number;
620
+ /** Offset from the sound's start, in seconds. */
621
+ at: number;
622
+ /** Time to fade out, in seconds. */
623
+ duration: number;
624
+ type?: OscillatorType;
625
+ /** Peak gain before the master volume, 0 to 1. */
626
+ gain: number;
627
+ }
628
+ declare const soundPresets: Record<SoundName, readonly Tone[]>;
629
+ interface SoundSettings {
630
+ enabled: boolean;
631
+ /** Master volume, 0 to 1. */
632
+ volume: number;
633
+ }
634
+ /** The slice of `AudioContext` the player uses; tests pass a fake. */
635
+ type SoundContext = Pick<AudioContext, 'currentTime' | 'state' | 'resume' | 'createOscillator' | 'createGain' | 'createBiquadFilter' | 'destination'>;
636
+ interface SoundPlayer {
637
+ play(name: SoundName): void;
638
+ configure(settings: Partial<SoundSettings>): void;
639
+ settings(): SoundSettings;
640
+ }
641
+ declare function createSoundPlayer(createContext?: () => SoundContext | null, initial?: Partial<SoundSettings>): SoundPlayer;
642
+ /** Play a preset through the shared player; a no-op while sounds are off. */
643
+ declare const playSound: (name: SoundName) => void;
644
+ /** Turn the shared player on or off and set its volume. */
645
+ declare const configureSounds: (settings: Partial<SoundSettings>) => void;
646
+ declare const soundSettings: () => SoundSettings;
647
+
648
+ export { AEON_PRINCIPLE, AEON_THEME_TRANSITION_CLASS, type AeonActor, type AeonColorMode, type AeonContext, type AeonDataAttrs, type AeonEvent, type AeonPalette, type AeonSnapshot, type AeonStateValue, type AeonThemeDefinition, type ApplyBrandPaletteOptions, type BrandPalette, type BrandPaletteInput, DEFAULT_COMPACT_MQ, type FieldFace, LIST_WINDOW_MIN_ITEMS, LIST_WINDOW_PAD_ATTR, type LayoutComposition, type LayoutCompositionSpec, type LayoutMode, type ListWindow, type ListWindowAxis, type ListWindowInput, NORM_PLANE, type NormOrigin, type NormPoint, type NormRect, type RegionLayoutSlot, type ResponsiveLayoutSpec, type ScrollOverflow, type ScrollSnapshot, type SoundContext, type SoundName, type SoundPlayer, type SoundSettings, type Tone, UI_IS_FUNCTION_OF_STATE, accordionAnatomy, anatomy, appNavAnatomy, appShellAnatomy, applyAeonTheme, applyBrandPalette, asyncAnatomy, avatarAnatomy, barAnatomy, brandPaletteToCssText, brandPaletteToCssVars, buttonAnatomy, checkboxAnatomy, clampNorm, clientFromNorm, clipboardAnatomy, comboboxAnatomy, composerAnatomy, computeListWindow, configureSounds, contentAnatomy, conversationAnatomy, createSoundPlayer, dialogAnatomy, entryAnatomy, fieldAnatomy, fieldFace, fieldRegions, fileUploadAnatomy, fullListWindow, getCompactMq, getRegionValue, getScrollSnapshot, identiconColor, identiconDataUrl, identiconGrid, identiconSeedBytes, identityAnatomy, initAeonTheme, insetNormCluster, isAeonColorMode, isAeonMode, isAeonThemeId, layoutCompositionForMode, layoutModeAttrs, listRowAnatomy, listWindowPadAttrs, matchLayoutMode, measureElement, measureListColumns, measureListRowExtent, menuAnatomy, metricStripAnatomy, navAnatomy, normFromClient, normalizeBrandPalette, panelAnatomy, partAttrs, partOnlyAttrs, pinInputAnatomy, playSound, playSurfaceAnatomy, popoverAnatomy, profileHeaderAnatomy, progressAnatomy, promptAnatomy, proseAnatomy, radioGroupAnatomy, rangeSliderAnatomy, regionBoundsForMode, regionLeaf, regionMatches, regionPath, registerAeonThemes, resolveAeonColorMode, resolveRegionRect, resolveScrollRoot, runAeonThemeTransition, sameListWindow, scopeAttrs, scrollAnatomy, scrollRootExtent, scrollRootHeight, scrollRootScrolledPast, scrollRootTop, segmentGroupAnatomy, selectAnatomy, separatorAnatomy, sliderAnatomy, soundPresets, soundSettings, stateToAttr, statusBannerAnatomy, switchAnatomy, syncAeonColorMode, tabsAnatomy, textareaAnatomy, themeSwitcherAnatomy, threadAnatomy, toastAnatomy, tooltipAnatomy };
@@ -4,7 +4,7 @@ var UI_IS_FUNCTION_OF_STATE = "UI = f(state)";
4
4
 
5
5
  // src/anatomy.ts
6
6
  function anatomy(scope, parts) {
7
- return Object.fromEntries(parts.map((p) => [p, p]));
7
+ return { ...Object.fromEntries(parts.map((p) => [p, p])), scope };
8
8
  }
9
9
  var buttonAnatomy = anatomy("button", [
10
10
  "root",
@@ -224,6 +224,10 @@ var composerAnatomy = anatomy("composer", [
224
224
  "toolbar"
225
225
  ]);
226
226
  var separatorAnatomy = anatomy("separator", ["root"]);
227
+ var proseAnatomy = anatomy("prose", ["root"]);
228
+ var textareaAnatomy = anatomy("textarea", ["root"]);
229
+ var segmentGroupAnatomy = anatomy("segmentGroup", ["root", "item"]);
230
+ var clipboardAnatomy = anatomy("clipboard", ["root", "trigger", "indicator", "status"]);
227
231
  var progressAnatomy = anatomy("progress", ["root", "track", "range", "label"]);
228
232
  var radioGroupAnatomy = anatomy("radioGroup", [
229
233
  "root",
@@ -453,6 +457,81 @@ function getScrollSnapshot(el) {
453
457
  };
454
458
  }
455
459
 
460
+ // src/list-window.ts
461
+ var LIST_WINDOW_MIN_ITEMS = 60;
462
+ function fullListWindow(total) {
463
+ return { start: 0, end: Math.max(0, total), padStart: 0, padEnd: 0 };
464
+ }
465
+ function sameListWindow(a, b) {
466
+ return a.start === b.start && a.end === b.end && a.padStart === b.padStart && a.padEnd === b.padEnd;
467
+ }
468
+ function computeListWindow(input) {
469
+ const total = Math.max(0, Math.floor(input.total));
470
+ const minItems = input.minItems ?? LIST_WINDOW_MIN_ITEMS;
471
+ const rowExtent = input.rowExtent;
472
+ if (total < minItems || !(rowExtent > 0)) return fullListWindow(total);
473
+ const columns = Math.max(1, Math.floor(input.columns ?? 1));
474
+ const overscan = Math.max(0, Math.floor(input.overscan ?? 8));
475
+ const rows = Math.ceil(total / columns);
476
+ const firstRow = Math.max(0, Math.floor(Math.max(0, input.scrolledPast) / rowExtent) - overscan);
477
+ const visibleRows = Math.ceil(Math.max(0, input.viewportHeight) / rowExtent) + overscan * 2;
478
+ const startRow = Math.min(firstRow, Math.max(0, rows - visibleRows));
479
+ const endRow = Math.min(rows, startRow + visibleRows);
480
+ return {
481
+ start: startRow * columns,
482
+ end: Math.min(total, endRow * columns),
483
+ padStart: startRow * rowExtent,
484
+ padEnd: Math.max(0, (rows - endRow) * rowExtent)
485
+ };
486
+ }
487
+ var LIST_WINDOW_PAD_ATTR = "data-aeon-window-pad";
488
+ function listWindowPadAttrs(edge) {
489
+ return { [LIST_WINDOW_PAD_ATTR]: edge, "aria-hidden": true };
490
+ }
491
+ function resolveScrollRoot(el, axis = "y") {
492
+ let node = el;
493
+ while (node) {
494
+ const style = getComputedStyle(node);
495
+ const overflow = axis === "x" ? style.overflowX : style.overflowY;
496
+ if (overflow === "auto" || overflow === "scroll") return node;
497
+ node = node.parentElement;
498
+ }
499
+ return window;
500
+ }
501
+ function scrollRootHeight(root) {
502
+ return root === window ? window.innerHeight : root.clientHeight;
503
+ }
504
+ function scrollRootExtent(root, axis = "y") {
505
+ if (axis === "y") return scrollRootHeight(root);
506
+ return root === window ? window.innerWidth : root.clientWidth;
507
+ }
508
+ function scrollRootTop(root) {
509
+ return root === window ? 0 : root.getBoundingClientRect().top;
510
+ }
511
+ function scrollRootScrolledPast(root, list, axis = "y") {
512
+ if (root === list) return axis === "x" ? list.scrollLeft : list.scrollTop;
513
+ if (axis === "y") return Math.max(0, scrollRootTop(root) - list.getBoundingClientRect().top);
514
+ const rootLeft = root === window ? 0 : root.getBoundingClientRect().left;
515
+ return Math.max(0, rootLeft - list.getBoundingClientRect().left);
516
+ }
517
+ function measureListColumns(style, hint = 1) {
518
+ if (!style.display.includes("grid")) return 1;
519
+ const tracks = style.gridTemplateColumns.trim();
520
+ if (!tracks || tracks === "none") return Math.max(1, hint);
521
+ return Math.max(1, tracks.split(/\s+/).length);
522
+ }
523
+ function measureListRowExtent(list, style, hint, rowSelector, axis = "y") {
524
+ const row = Array.from(list.children).find(
525
+ (node) => node instanceof HTMLElement && !node.hasAttribute(LIST_WINDOW_PAD_ATTR) && (!rowSelector || node.matches(rowSelector))
526
+ );
527
+ if (!row) return hint;
528
+ const rect = row.getBoundingClientRect();
529
+ const size = axis === "x" ? rect.width : rect.height;
530
+ if (size <= 0) return hint;
531
+ const gap = Number.parseFloat(axis === "x" ? style.columnGap : style.rowGap);
532
+ return size + (Number.isFinite(gap) ? gap : 0);
533
+ }
534
+
456
535
  // src/layout.ts
457
536
  var NORM_PLANE = {
458
537
  bottomLeft: "bottom-left",
@@ -767,10 +846,112 @@ function identiconDataUrl(seed, size = 128) {
767
846
  const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><rect width="${size}" height="${size}" fill="${bg}"/>` + rects + `</svg>`;
768
847
  return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
769
848
  }
849
+
850
+ // src/sound.ts
851
+ var pluck = (freq, at, duration, gain) => [
852
+ { freq, at, duration, type: "sine", gain },
853
+ { freq: freq * 2.76, at, duration: duration * 0.4, type: "sine", gain: gain * 0.05 },
854
+ { freq: freq * 5.4, at, duration: Math.min(0.03, duration * 0.2), type: "sine", gain: gain * 0.02 }
855
+ ];
856
+ var soundPresets = {
857
+ tap: pluck(880, 0, 0.07, 0.28),
858
+ copy: [...pluck(784, 0, 0.09, 0.3), ...pluck(1175, 0.06, 0.16, 0.26)],
859
+ send: [...pluck(587, 0, 0.1, 0.3), ...pluck(880, 0.05, 0.18, 0.26)],
860
+ success: [...pluck(523, 0, 0.22, 0.28), ...pluck(659, 0.08, 0.24, 0.25), ...pluck(784, 0.16, 0.42, 0.24)],
861
+ attention: [...pluck(988, 0, 0.16, 0.24), ...pluck(988, 0.15, 0.3, 0.18)],
862
+ error: [
863
+ { freq: 392, at: 0, duration: 0.14, type: "triangle", gain: 0.3 },
864
+ { freq: 311, at: 0.12, duration: 0.24, type: "triangle", gain: 0.28 }
865
+ ],
866
+ ready: [...pluck(659, 0, 0.16, 0.22), ...pluck(784, 0.07, 0.18, 0.22), ...pluck(988, 0.14, 0.2, 0.22), ...pluck(1319, 0.21, 0.5, 0.2)]
867
+ };
868
+ var ATTACK = 4e-3;
869
+ var LOWPASS_HZ = 4600;
870
+ var FLOOR = 1e-4;
871
+ var REPEAT_GAP = 0.06;
872
+ var clamp01 = (n) => Number.isFinite(n) ? Math.min(1, Math.max(0, n)) : 0;
873
+ function browserContext() {
874
+ const Ctor = typeof window === "undefined" ? void 0 : window.AudioContext ?? window.webkitAudioContext;
875
+ return Ctor ? new Ctor() : null;
876
+ }
877
+ function resumeOnGesture(ctx) {
878
+ if (typeof window === "undefined") return;
879
+ const resume = () => {
880
+ void ctx.resume().catch(() => {
881
+ });
882
+ window.removeEventListener("pointerdown", resume, true);
883
+ window.removeEventListener("keydown", resume, true);
884
+ };
885
+ window.addEventListener("pointerdown", resume, true);
886
+ window.addEventListener("keydown", resume, true);
887
+ }
888
+ function createSoundPlayer(createContext = browserContext, initial = {}) {
889
+ let current = { enabled: false, volume: 0.5, ...initial };
890
+ current.volume = clamp01(current.volume);
891
+ let ctx;
892
+ let output = null;
893
+ const lastPlayed = /* @__PURE__ */ new Map();
894
+ const context = () => {
895
+ if (ctx === void 0) {
896
+ try {
897
+ ctx = createContext();
898
+ } catch {
899
+ ctx = null;
900
+ }
901
+ if (ctx) {
902
+ const filter = ctx.createBiquadFilter();
903
+ filter.type = "lowpass";
904
+ filter.frequency.value = LOWPASS_HZ;
905
+ filter.connect(ctx.destination);
906
+ output = filter;
907
+ if (ctx.state === "suspended") resumeOnGesture(ctx);
908
+ }
909
+ }
910
+ return ctx;
911
+ };
912
+ return {
913
+ play(name) {
914
+ if (!current.enabled || current.volume === 0) return;
915
+ const audio = context();
916
+ if (!audio || !output || audio.state === "closed") return;
917
+ const now = audio.currentTime;
918
+ const last = lastPlayed.get(name);
919
+ if (last !== void 0 && now - last < REPEAT_GAP) return;
920
+ lastPlayed.set(name, now);
921
+ for (const tone of soundPresets[name]) {
922
+ const start = now + tone.at;
923
+ const end = start + tone.duration;
924
+ const osc = audio.createOscillator();
925
+ const gain = audio.createGain();
926
+ osc.type = tone.type ?? "sine";
927
+ osc.frequency.setValueAtTime(tone.freq, start);
928
+ if (tone.to !== void 0) osc.frequency.exponentialRampToValueAtTime(tone.to, end);
929
+ gain.gain.setValueAtTime(FLOOR, start);
930
+ gain.gain.linearRampToValueAtTime(Math.max(FLOOR, tone.gain * current.volume), start + ATTACK);
931
+ gain.gain.exponentialRampToValueAtTime(FLOOR, end);
932
+ osc.connect(gain);
933
+ gain.connect(output);
934
+ osc.start(start);
935
+ osc.stop(end + 0.02);
936
+ }
937
+ },
938
+ configure(settings) {
939
+ current = { ...current, ...settings };
940
+ current.volume = clamp01(current.volume);
941
+ },
942
+ settings: () => ({ ...current })
943
+ };
944
+ }
945
+ var shared = createSoundPlayer();
946
+ var playSound = (name) => shared.play(name);
947
+ var configureSounds = (settings) => shared.configure(settings);
948
+ var soundSettings = () => shared.settings();
770
949
  export {
771
950
  AEON_PRINCIPLE,
772
951
  AEON_THEME_TRANSITION_CLASS,
773
952
  DEFAULT_COMPACT_MQ,
953
+ LIST_WINDOW_MIN_ITEMS,
954
+ LIST_WINDOW_PAD_ATTR,
774
955
  NORM_PLANE,
775
956
  UI_IS_FUNCTION_OF_STATE,
776
957
  accordionAnatomy,
@@ -788,17 +969,22 @@ export {
788
969
  checkboxAnatomy,
789
970
  clampNorm,
790
971
  clientFromNorm,
972
+ clipboardAnatomy,
791
973
  comboboxAnatomy,
792
974
  composerAnatomy,
975
+ computeListWindow,
976
+ configureSounds,
793
977
  contentAnatomy,
794
978
  conversationAnatomy,
795
979
  setup as createAeonMachine,
980
+ createSoundPlayer,
796
981
  dialogAnatomy,
797
982
  entryAnatomy,
798
983
  fieldAnatomy,
799
984
  fieldFace,
800
985
  fieldRegions,
801
986
  fileUploadAnatomy,
987
+ fullListWindow,
802
988
  getCompactMq,
803
989
  getRegionValue,
804
990
  getScrollSnapshot,
@@ -815,8 +1001,11 @@ export {
815
1001
  layoutCompositionForMode,
816
1002
  layoutModeAttrs,
817
1003
  listRowAnatomy,
1004
+ listWindowPadAttrs,
818
1005
  matchLayoutMode,
819
1006
  measureElement,
1007
+ measureListColumns,
1008
+ measureListRowExtent,
820
1009
  menuAnatomy,
821
1010
  metricStripAnatomy,
822
1011
  navAnatomy,
@@ -826,11 +1015,13 @@ export {
826
1015
  partAttrs,
827
1016
  partOnlyAttrs,
828
1017
  pinInputAnatomy,
1018
+ playSound,
829
1019
  playSurfaceAnatomy,
830
1020
  popoverAnatomy,
831
1021
  profileHeaderAnatomy,
832
1022
  progressAnatomy,
833
1023
  promptAnatomy,
1024
+ proseAnatomy,
834
1025
  radioGroupAnatomy,
835
1026
  rangeSliderAnatomy,
836
1027
  regionBoundsForMode,
@@ -840,17 +1031,27 @@ export {
840
1031
  registerAeonThemes,
841
1032
  resolveAeonColorMode,
842
1033
  resolveRegionRect,
1034
+ resolveScrollRoot,
843
1035
  runAeonThemeTransition,
1036
+ sameListWindow,
844
1037
  scopeAttrs,
845
1038
  scrollAnatomy,
1039
+ scrollRootExtent,
1040
+ scrollRootHeight,
1041
+ scrollRootScrolledPast,
1042
+ scrollRootTop,
1043
+ segmentGroupAnatomy,
846
1044
  selectAnatomy,
847
1045
  separatorAnatomy,
848
1046
  sliderAnatomy,
1047
+ soundPresets,
1048
+ soundSettings,
849
1049
  stateToAttr,
850
1050
  statusBannerAnatomy,
851
1051
  switchAnatomy,
852
1052
  syncAeonColorMode,
853
1053
  tabsAnatomy,
1054
+ textareaAnatomy,
854
1055
  themeSwitcherAnatomy,
855
1056
  threadAnatomy,
856
1057
  toastAnatomy,
@@ -1,6 +1,6 @@
1
1
  /** Part keys for compound components — scope + named parts for styling and docs. */
2
2
  export function anatomy<const T extends readonly string[]>(scope: string, parts: T) {
3
- return Object.fromEntries(parts.map((p) => [p, p])) as Record<T[number], T[number]> & {
3
+ return { ...Object.fromEntries(parts.map((p) => [p, p])), scope } as Record<T[number], T[number]> & {
4
4
  scope: typeof scope
5
5
  }
6
6
  }
@@ -310,6 +310,18 @@ export const composerAnatomy = anatomy('composer', [
310
310
 
311
311
  export const separatorAnatomy = anatomy('separator', ['root'] as const)
312
312
 
313
+ /** Long-form rich text (rendered markdown). Styles its descendants; no state of its own. */
314
+ export const proseAnatomy = anatomy('prose', ['root'] as const)
315
+
316
+ /** Multi-line input that grows with its content between `minRows` and `maxRows`. */
317
+ export const textareaAnatomy = anatomy('textarea', ['root'] as const)
318
+
319
+ /** Compact single choice rendered as adjacent buttons; same chart family as Tabs / RadioGroup. */
320
+ export const segmentGroupAnatomy = anatomy('segmentGroup', ['root', 'item'] as const)
321
+
322
+ /** Copy a value to the clipboard; root state idle | copying | copied | failed. */
323
+ export const clipboardAnatomy = anatomy('clipboard', ['root', 'trigger', 'indicator', 'status'] as const)
324
+
313
325
  /** Progress bar — idle / loading / complete on root `data-aeon-state`. */
314
326
  export const progressAnatomy = anatomy('progress', ['root', 'track', 'range', 'label'] as const)
315
327
 
@@ -4,7 +4,9 @@ export * from './attrs.js'
4
4
  export * from './machine.js'
5
5
  export * from './types.js'
6
6
  export * from './scroll.js'
7
+ export * from './list-window.js'
7
8
  export * from './layout.js'
8
9
  export * from './theme.js'
9
10
  export * from './brand-theme.js'
10
11
  export * from './identicon.js'
12
+ export * from './sound.js'
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Windowed slice of a long list or grid: which items to mount and how much
3
+ * space stands in for the rest. Geometry, not lifecycle, so like Scroll it is
4
+ * a pure function over measurements, never a machine.
5
+ */
6
+
7
+ export interface ListWindow {
8
+ /** First mounted item index. */
9
+ start: number
10
+ /** One past the last mounted item index. */
11
+ end: number
12
+ /** Pixels standing in for the rows above the window. */
13
+ padStart: number
14
+ /** Pixels standing in for the rows below the window. */
15
+ padEnd: number
16
+ }
17
+
18
+ /** The direction a list scrolls: rows down a column, or items along a strip. */
19
+ export type ListWindowAxis = 'y' | 'x'
20
+
21
+ export interface ListWindowInput {
22
+ total: number
23
+ /** Row pitch in pixels along the scroll axis, gap included. */
24
+ rowExtent: number
25
+ /** Items per row; 1 for a list. */
26
+ columns?: number
27
+ /** Rows mounted beyond each edge of the viewport. */
28
+ overscan?: number
29
+ /** How far the list's content has moved past the start of its viewport. */
30
+ scrolledPast: number
31
+ /** Viewport length along the scroll axis. */
32
+ viewportHeight: number
33
+ /** Below this many items the whole list mounts. */
34
+ minItems?: number
35
+ }
36
+
37
+ /**
38
+ * Below this, windowing costs more than it saves and a mis-measured row would
39
+ * visibly shift a short list.
40
+ */
41
+ export const LIST_WINDOW_MIN_ITEMS = 60
42
+
43
+ export function fullListWindow(total: number): ListWindow {
44
+ return { start: 0, end: Math.max(0, total), padStart: 0, padEnd: 0 }
45
+ }
46
+
47
+ export function sameListWindow(a: ListWindow, b: ListWindow): boolean {
48
+ return a.start === b.start && a.end === b.end && a.padStart === b.padStart && a.padEnd === b.padEnd
49
+ }
50
+
51
+ export function computeListWindow(input: ListWindowInput): ListWindow {
52
+ const total = Math.max(0, Math.floor(input.total))
53
+ const minItems = input.minItems ?? LIST_WINDOW_MIN_ITEMS
54
+ const rowExtent = input.rowExtent
55
+ if (total < minItems || !(rowExtent > 0)) return fullListWindow(total)
56
+ const columns = Math.max(1, Math.floor(input.columns ?? 1))
57
+ const overscan = Math.max(0, Math.floor(input.overscan ?? 8))
58
+ const rows = Math.ceil(total / columns)
59
+ const firstRow = Math.max(0, Math.floor(Math.max(0, input.scrolledPast) / rowExtent) - overscan)
60
+ const visibleRows = Math.ceil(Math.max(0, input.viewportHeight) / rowExtent) + overscan * 2
61
+ const startRow = Math.min(firstRow, Math.max(0, rows - visibleRows))
62
+ const endRow = Math.min(rows, startRow + visibleRows)
63
+ return {
64
+ start: startRow * columns,
65
+ end: Math.min(total, endRow * columns),
66
+ padStart: startRow * rowExtent,
67
+ padEnd: Math.max(0, (rows - endRow) * rowExtent),
68
+ }
69
+ }
70
+
71
+ /** Attribute that marks a spacer, so row measuring skips it. */
72
+ export const LIST_WINDOW_PAD_ATTR = 'data-aeon-window-pad'
73
+
74
+ export function listWindowPadAttrs(edge: 'start' | 'end'): Record<string, string | boolean> {
75
+ return { [LIST_WINDOW_PAD_ATTR]: edge, 'aria-hidden': true }
76
+ }
77
+
78
+ /** The element that actually scrolls a list: the nearest ancestor overflowing on the axis, else the window. */
79
+ export function resolveScrollRoot(el: HTMLElement | null, axis: ListWindowAxis = 'y'): HTMLElement | Window {
80
+ let node: HTMLElement | null = el
81
+ while (node) {
82
+ const style = getComputedStyle(node)
83
+ const overflow = axis === 'x' ? style.overflowX : style.overflowY
84
+ if (overflow === 'auto' || overflow === 'scroll') return node
85
+ node = node.parentElement
86
+ }
87
+ return window
88
+ }
89
+
90
+ export function scrollRootHeight(root: HTMLElement | Window): number {
91
+ return root === window ? window.innerHeight : (root as HTMLElement).clientHeight
92
+ }
93
+
94
+ /** Viewport length along the axis. */
95
+ export function scrollRootExtent(root: HTMLElement | Window, axis: ListWindowAxis = 'y'): number {
96
+ if (axis === 'y') return scrollRootHeight(root)
97
+ return root === window ? window.innerWidth : (root as HTMLElement).clientWidth
98
+ }
99
+
100
+ export function scrollRootTop(root: HTMLElement | Window): number {
101
+ return root === window ? 0 : (root as HTMLElement).getBoundingClientRect().top
102
+ }
103
+
104
+ /**
105
+ * How far the list's content has moved past the viewport. A list that is its
106
+ * own scroll root reports its scroll offset: subtracting its own edge from
107
+ * itself is always 0, which kept the first rows mounted while the scrollbar
108
+ * travelled through the end spacer.
109
+ */
110
+ export function scrollRootScrolledPast(
111
+ root: HTMLElement | Window,
112
+ list: HTMLElement,
113
+ axis: ListWindowAxis = 'y',
114
+ ): number {
115
+ if (root === list) return axis === 'x' ? list.scrollLeft : list.scrollTop
116
+ if (axis === 'y') return Math.max(0, scrollRootTop(root) - list.getBoundingClientRect().top)
117
+ const rootLeft = root === window ? 0 : (root as HTMLElement).getBoundingClientRect().left
118
+ return Math.max(0, rootLeft - list.getBoundingClientRect().left)
119
+ }
120
+
121
+ /** Real column count for a grid; 1 for a list. The hint is only a fallback. */
122
+ export function measureListColumns(style: CSSStyleDeclaration, hint = 1): number {
123
+ if (!style.display.includes('grid')) return 1
124
+ const tracks = style.gridTemplateColumns.trim()
125
+ if (!tracks || tracks === 'none') return Math.max(1, hint)
126
+ return Math.max(1, tracks.split(/\s+/).length)
127
+ }
128
+
129
+ /** Row pitch along the axis from a rendered row, so spacers match what is on screen. */
130
+ export function measureListRowExtent(
131
+ list: HTMLElement,
132
+ style: CSSStyleDeclaration,
133
+ hint: number,
134
+ rowSelector?: string,
135
+ axis: ListWindowAxis = 'y',
136
+ ): number {
137
+ const row = Array.from(list.children).find(
138
+ (node): node is HTMLElement =>
139
+ node instanceof HTMLElement &&
140
+ !node.hasAttribute(LIST_WINDOW_PAD_ATTR) &&
141
+ (!rowSelector || node.matches(rowSelector)),
142
+ )
143
+ if (!row) return hint
144
+ const rect = row.getBoundingClientRect()
145
+ const size = axis === 'x' ? rect.width : rect.height
146
+ if (size <= 0) return hint
147
+ const gap = Number.parseFloat(axis === 'x' ? style.columnGap : style.rowGap)
148
+ return size + (Number.isFinite(gap) ? gap : 0)
149
+ }