@kerfjs/ui 5.0.0-beta.7 → 5.0.0-beta.70

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 (723) hide show
  1. package/README.md +501 -139
  2. package/ai/application-ui-diagnostic-ids-v1.json +109 -0
  3. package/ai/application-ui-profile-sync.cjs +548 -0
  4. package/ai/application-ui-profile.d.mts +1 -0
  5. package/ai/application-ui-profile.d.ts +106 -0
  6. package/ai/application-ui-profile.defaults.json +96 -0
  7. package/ai/application-ui-profile.mjs +653 -0
  8. package/ai/application-ui-profile.schema.json +140 -0
  9. package/ai/catalog-authoring.json +36 -0
  10. package/ai/catalog-authoring.schema.json +109 -0
  11. package/ai/compile-time-contracts-v1.json +149 -0
  12. package/ai/compile-time-contracts-v1.schema.json +52 -0
  13. package/ai/component-catalog-extension.schema.json +104 -0
  14. package/ai/component-catalog.json +3910 -464
  15. package/ai/component-catalog.schema.json +92 -1
  16. package/ai/component-class-owners.cjs +83 -0
  17. package/ai/component-composition-extension.d.ts +7 -0
  18. package/ai/component-composition-extension.schema.json +7 -0
  19. package/ai/component-composition-rules.json +524 -0
  20. package/ai/component-composition.d.ts +127 -0
  21. package/ai/component-composition.json +7128 -0
  22. package/ai/component-composition.schema.json +399 -0
  23. package/ai/components/README.md +171 -0
  24. package/ai/components/application-tabs.md +65 -0
  25. package/ai/components/badge.md +72 -0
  26. package/ai/components/chip.md +72 -0
  27. package/ai/components/collapsible-panel.md +102 -0
  28. package/ai/components/content-item.md +93 -0
  29. package/ai/components/disclosure-arrow.md +77 -0
  30. package/ai/components/document-baseline.md +75 -0
  31. package/ai/components/empty-state.md +80 -0
  32. package/ai/components/feedback.md +71 -0
  33. package/ai/components/floating-toolbar.md +82 -0
  34. package/ai/components/foundation.md +65 -0
  35. package/ai/components/grid.md +98 -0
  36. package/ai/components/headers.md +63 -0
  37. package/ai/components/layout.md +75 -0
  38. package/ai/components/list-action-row.md +91 -0
  39. package/ai/components/list-header.md +89 -0
  40. package/ai/components/list-inset-control.md +74 -0
  41. package/ai/components/list-inset-text.md +72 -0
  42. package/ai/components/list-item.md +94 -0
  43. package/ai/components/list.md +105 -0
  44. package/ai/components/loading-spinner.md +73 -0
  45. package/ai/components/lucide-icon.md +78 -0
  46. package/ai/components/nav-stack.md +104 -0
  47. package/ai/components/pane.md +101 -0
  48. package/ai/components/popup-menu.md +171 -0
  49. package/ai/components/recipe-app-shell.md +57 -0
  50. package/ai/components/recipe-collapsible-sidebar.md +57 -0
  51. package/ai/components/recipe-compact-toolbar.md +57 -0
  52. package/ai/components/recipe-composer-form.md +57 -0
  53. package/ai/components/recipe-list-detail-dialog.md +57 -0
  54. package/ai/components/recipe-list-workspace-states.md +57 -0
  55. package/ai/components/recipe-loading-inspector.md +57 -0
  56. package/ai/components/recipe-navigation-sidebar.md +57 -0
  57. package/ai/components/recipe-navigation-stack.md +57 -0
  58. package/ai/components/recipe-workspace-header.md +57 -0
  59. package/ai/components/resize.md +106 -0
  60. package/ai/components/row.md +96 -0
  61. package/ai/components/segmented-control.md +82 -0
  62. package/ai/components/select.md +113 -0
  63. package/ai/components/skeleton.md +84 -0
  64. package/ai/components/spacer.md +86 -0
  65. package/ai/components/split-view.md +102 -0
  66. package/ai/components/state-banner.md +94 -0
  67. package/ai/components/sunken-panel.md +79 -0
  68. package/ai/components/surface-scaffold.md +78 -0
  69. package/ai/components/tab-bar.md +113 -0
  70. package/ai/components/tab-scaffold.md +94 -0
  71. package/ai/components/tabs.md +95 -0
  72. package/ai/components/text.md +85 -0
  73. package/ai/components/token-search-field.md +106 -0
  74. package/ai/components/toolbar-control-group.md +102 -0
  75. package/ai/components/toolbar-text.md +79 -0
  76. package/ai/components/toolbar.md +97 -0
  77. package/ai/components/value-table.md +73 -0
  78. package/ai/components/wa-accordion-item.md +55 -0
  79. package/ai/components/wa-accordion.md +65 -0
  80. package/ai/components/wa-animated-image.md +55 -0
  81. package/ai/components/wa-animation.md +55 -0
  82. package/ai/components/wa-avatar.md +55 -0
  83. package/ai/components/wa-badge.md +55 -0
  84. package/ai/components/wa-breadcrumb-item.md +53 -0
  85. package/ai/components/wa-breadcrumb.md +55 -0
  86. package/ai/components/wa-button-group.md +59 -0
  87. package/ai/components/wa-button.md +55 -0
  88. package/ai/components/wa-callout.md +58 -0
  89. package/ai/components/wa-card.md +59 -0
  90. package/ai/components/wa-carousel-item.md +53 -0
  91. package/ai/components/wa-carousel.md +55 -0
  92. package/ai/components/wa-checkbox-group.md +55 -0
  93. package/ai/components/wa-checkbox.md +55 -0
  94. package/ai/components/wa-color-picker.md +55 -0
  95. package/ai/components/wa-comparison.md +55 -0
  96. package/ai/components/wa-copy-button.md +55 -0
  97. package/ai/components/wa-details.md +61 -0
  98. package/ai/components/wa-dialog.md +59 -0
  99. package/ai/components/wa-divider.md +53 -0
  100. package/ai/components/wa-drawer.md +55 -0
  101. package/ai/components/wa-dropdown-item.md +60 -0
  102. package/ai/components/wa-dropdown.md +60 -0
  103. package/ai/components/wa-format-bytes.md +53 -0
  104. package/ai/components/wa-format-date.md +53 -0
  105. package/ai/components/wa-format-number.md +53 -0
  106. package/ai/components/wa-icon.md +58 -0
  107. package/ai/components/wa-include.md +53 -0
  108. package/ai/components/wa-input.md +59 -0
  109. package/ai/components/wa-intersection-observer.md +53 -0
  110. package/ai/components/wa-known-date.md +53 -0
  111. package/ai/components/wa-markdown.md +53 -0
  112. package/ai/components/wa-mutation-observer.md +53 -0
  113. package/ai/components/wa-number-input.md +55 -0
  114. package/ai/components/wa-option.md +59 -0
  115. package/ai/components/wa-otp-input.md +53 -0
  116. package/ai/components/wa-page.md +53 -0
  117. package/ai/components/wa-pagination.md +55 -0
  118. package/ai/components/wa-popover.md +55 -0
  119. package/ai/components/wa-popup.md +53 -0
  120. package/ai/components/wa-progress-bar.md +53 -0
  121. package/ai/components/wa-progress-ring.md +53 -0
  122. package/ai/components/wa-qr-code.md +53 -0
  123. package/ai/components/wa-radio-group.md +59 -0
  124. package/ai/components/wa-radio.md +55 -0
  125. package/ai/components/wa-random-content.md +53 -0
  126. package/ai/components/wa-rating.md +55 -0
  127. package/ai/components/wa-relative-time.md +53 -0
  128. package/ai/components/wa-resize-observer.md +53 -0
  129. package/ai/components/wa-scroller.md +53 -0
  130. package/ai/components/wa-select.md +63 -0
  131. package/ai/components/wa-skeleton.md +53 -0
  132. package/ai/components/wa-slider.md +55 -0
  133. package/ai/components/wa-spinner.md +58 -0
  134. package/ai/components/wa-split-panel.md +58 -0
  135. package/ai/components/wa-switch.md +53 -0
  136. package/ai/components/wa-tab-group.md +69 -0
  137. package/ai/components/wa-tab-panel.md +60 -0
  138. package/ai/components/wa-tab.md +59 -0
  139. package/ai/components/wa-tag.md +59 -0
  140. package/ai/components/wa-textarea.md +53 -0
  141. package/ai/components/wa-time-input.md +55 -0
  142. package/ai/components/wa-toast-item.md +60 -0
  143. package/ai/components/wa-toast.md +60 -0
  144. package/ai/components/wa-tooltip.md +55 -0
  145. package/ai/components/wa-tree-item.md +55 -0
  146. package/ai/components/wa-tree.md +55 -0
  147. package/ai/components/wa-zoomable-frame.md +55 -0
  148. package/ai/components/workbench.md +118 -0
  149. package/ai/public-api-signatures-v1.md +2748 -210
  150. package/ai/skill.md +286 -66
  151. package/ai/webawesome-jsx-signatures-v1.md +9 -2
  152. package/analyzer/cli.mjs +49 -0
  153. package/analyzer/component-ownership.d.mts +72 -0
  154. package/analyzer/component-ownership.mjs +286 -0
  155. package/analyzer/index.d.mts +52 -0
  156. package/analyzer/index.mjs +2038 -0
  157. package/analyzer/loud-pairs.d.mts +49 -0
  158. package/analyzer/loud-pairs.mjs +357 -0
  159. package/analyzer/report.schema.json +66 -0
  160. package/analyzer/selectors.d.mts +21 -0
  161. package/analyzer/selectors.mjs +212 -0
  162. package/catalog-projection-cli.mjs +96 -0
  163. package/catalog-projection.d.mts +55 -0
  164. package/catalog-projection.mjs +62 -0
  165. package/dist/app-tab.d.ts +39 -4
  166. package/dist/app-tab.js +2 -1
  167. package/dist/badge.d.ts +52 -0
  168. package/dist/badge.js +3 -0
  169. package/dist/badge.js.map +1 -0
  170. package/dist/browser/badge.js +3 -0
  171. package/dist/browser/catalog.js +26 -0
  172. package/dist/browser/chip.js +3 -0
  173. package/dist/browser/collapsible-panel.js +9 -0
  174. package/dist/browser/content-item.js +3 -0
  175. package/dist/browser/floating-toolbar.js +3 -0
  176. package/dist/browser/grid.js +3 -0
  177. package/dist/browser/list-action-row.js +5 -0
  178. package/dist/browser/{menu-header.js → list-header.js} +4 -2
  179. package/dist/browser/list-inset-control.js +3 -0
  180. package/dist/browser/list-inset-text.js +3 -0
  181. package/dist/browser/list-item.js +5 -0
  182. package/dist/browser/list.js +3 -0
  183. package/dist/browser/{panel-header.js → nav-stack.js} +5 -3
  184. package/dist/browser/pane.js +3 -0
  185. package/dist/browser/popup-menu.js +3 -0
  186. package/dist/browser/row.js +3 -0
  187. package/dist/browser/segmented-control.js +0 -1
  188. package/dist/browser/select.js +1 -0
  189. package/dist/browser/spacer.js +3 -0
  190. package/dist/browser/split-view.js +11 -0
  191. package/dist/browser/state-banner.js +1 -0
  192. package/dist/browser/sunken-panel.js +3 -0
  193. package/dist/browser/surface-scaffold.js +3 -0
  194. package/dist/browser/tab-scaffold.js +4 -0
  195. package/dist/browser/text.js +3 -0
  196. package/dist/browser/toolbar-control-group.js +1 -0
  197. package/dist/browser/workbench.js +14 -0
  198. package/dist/catalog-resources.d.ts +48 -0
  199. package/dist/catalog-resources.js +22 -0
  200. package/dist/catalog-resources.js.map +1 -0
  201. package/dist/catalog.d.ts +92 -0
  202. package/dist/catalog.js +503 -0
  203. package/dist/catalog.js.map +1 -0
  204. package/dist/chip.d.ts +35 -0
  205. package/dist/chip.js +3 -0
  206. package/dist/chip.js.map +1 -0
  207. package/dist/chunk-2G2ZJQYK.js +152 -0
  208. package/dist/chunk-2G2ZJQYK.js.map +1 -0
  209. package/dist/chunk-3BYFWTP3.js +108 -0
  210. package/dist/chunk-3BYFWTP3.js.map +1 -0
  211. package/dist/chunk-47CKKLBE.js +34 -0
  212. package/dist/chunk-47CKKLBE.js.map +1 -0
  213. package/dist/chunk-4SQK27MR.js +202 -0
  214. package/dist/chunk-4SQK27MR.js.map +1 -0
  215. package/dist/chunk-5I7QGQVT.js +24 -0
  216. package/dist/chunk-5I7QGQVT.js.map +1 -0
  217. package/dist/chunk-6DFDTWGG.js +288 -0
  218. package/dist/chunk-6DFDTWGG.js.map +1 -0
  219. package/dist/chunk-7OKX3EF6.js +135 -0
  220. package/dist/chunk-7OKX3EF6.js.map +1 -0
  221. package/dist/chunk-AHEG27M7.js +66 -0
  222. package/dist/chunk-AHEG27M7.js.map +1 -0
  223. package/dist/chunk-AYUHMAI6.js +48 -0
  224. package/dist/chunk-AYUHMAI6.js.map +1 -0
  225. package/dist/chunk-B2ZMR7NY.js +85 -0
  226. package/dist/chunk-B2ZMR7NY.js.map +1 -0
  227. package/dist/chunk-BFPBS5Y4.js +250 -0
  228. package/dist/chunk-BFPBS5Y4.js.map +1 -0
  229. package/dist/chunk-DB5ADJKF.js +775 -0
  230. package/dist/chunk-DB5ADJKF.js.map +1 -0
  231. package/dist/chunk-DC6CN2DS.js +123 -0
  232. package/dist/chunk-DC6CN2DS.js.map +1 -0
  233. package/dist/chunk-DG6G5EPF.js +35 -0
  234. package/dist/chunk-DG6G5EPF.js.map +1 -0
  235. package/dist/{chunk-56RJXPHG.js → chunk-G4S2QU6V.js} +7 -4
  236. package/dist/chunk-G4S2QU6V.js.map +1 -0
  237. package/dist/chunk-GLDWRCAM.js +49 -0
  238. package/dist/chunk-GLDWRCAM.js.map +1 -0
  239. package/dist/chunk-I3Q7KKYM.js +33 -0
  240. package/dist/chunk-I3Q7KKYM.js.map +1 -0
  241. package/dist/chunk-IA7TMD4Y.js +288 -0
  242. package/dist/chunk-IA7TMD4Y.js.map +1 -0
  243. package/dist/chunk-J3KGJ6P6.js +135 -0
  244. package/dist/chunk-J3KGJ6P6.js.map +1 -0
  245. package/dist/chunk-K47P7QZC.js +17 -0
  246. package/dist/chunk-K47P7QZC.js.map +1 -0
  247. package/dist/chunk-K67Y2JNF.js +222 -0
  248. package/dist/chunk-K67Y2JNF.js.map +1 -0
  249. package/dist/chunk-KCCEH7RF.js +492 -0
  250. package/dist/chunk-KCCEH7RF.js.map +1 -0
  251. package/dist/chunk-KLJKU6ZL.js +109 -0
  252. package/dist/chunk-KLJKU6ZL.js.map +1 -0
  253. package/dist/chunk-KVBRMEPM.js +44 -0
  254. package/dist/chunk-KVBRMEPM.js.map +1 -0
  255. package/dist/chunk-M6DEEBEF.js +156 -0
  256. package/dist/chunk-M6DEEBEF.js.map +1 -0
  257. package/dist/chunk-MEY33VWB.js +44 -0
  258. package/dist/chunk-MEY33VWB.js.map +1 -0
  259. package/dist/chunk-MP2GDBQZ.js +50 -0
  260. package/dist/chunk-MP2GDBQZ.js.map +1 -0
  261. package/dist/chunk-NC4CFOID.js +188 -0
  262. package/dist/chunk-NC4CFOID.js.map +1 -0
  263. package/dist/chunk-NCSWXG7G.js +80 -0
  264. package/dist/chunk-NCSWXG7G.js.map +1 -0
  265. package/dist/chunk-NN6GYOA2.js +47 -0
  266. package/dist/chunk-NN6GYOA2.js.map +1 -0
  267. package/dist/chunk-OXO2QJWV.js +55 -0
  268. package/dist/chunk-OXO2QJWV.js.map +1 -0
  269. package/dist/chunk-P7D3EMXM.js +52 -0
  270. package/dist/chunk-P7D3EMXM.js.map +1 -0
  271. package/dist/chunk-PSHUSWQH.js +18 -0
  272. package/dist/chunk-PSHUSWQH.js.map +1 -0
  273. package/dist/chunk-Q6YU3BT7.js +138 -0
  274. package/dist/chunk-Q6YU3BT7.js.map +1 -0
  275. package/dist/chunk-QJ5VFCW3.js +131 -0
  276. package/dist/chunk-QJ5VFCW3.js.map +1 -0
  277. package/dist/chunk-RGS4WX2M.js +44 -0
  278. package/dist/chunk-RGS4WX2M.js.map +1 -0
  279. package/dist/chunk-RNQNEENY.js +146 -0
  280. package/dist/chunk-RNQNEENY.js.map +1 -0
  281. package/dist/chunk-RVERAFFY.js +291 -0
  282. package/dist/chunk-RVERAFFY.js.map +1 -0
  283. package/dist/chunk-SMZGAPCU.js +70 -0
  284. package/dist/chunk-SMZGAPCU.js.map +1 -0
  285. package/dist/{chunk-7BR3DO2A.js → chunk-SRSJO5QE.js} +13 -4
  286. package/dist/chunk-SRSJO5QE.js.map +1 -0
  287. package/dist/chunk-T2E5WBCZ.js +482 -0
  288. package/dist/chunk-T2E5WBCZ.js.map +1 -0
  289. package/dist/chunk-TJK44RQC.js +452 -0
  290. package/dist/chunk-TJK44RQC.js.map +1 -0
  291. package/dist/chunk-UIDKY4UB.js +14 -0
  292. package/dist/chunk-UIDKY4UB.js.map +1 -0
  293. package/dist/chunk-V3DX3K65.js +43 -0
  294. package/dist/chunk-V3DX3K65.js.map +1 -0
  295. package/dist/chunk-VZOFZPSO.js +71 -0
  296. package/dist/chunk-VZOFZPSO.js.map +1 -0
  297. package/dist/chunk-W2AC6Q2A.js +83 -0
  298. package/dist/chunk-W2AC6Q2A.js.map +1 -0
  299. package/dist/chunk-WF75U3V4.js +33 -0
  300. package/dist/chunk-WF75U3V4.js.map +1 -0
  301. package/dist/chunk-WTSNV5RG.js +52 -0
  302. package/dist/chunk-WTSNV5RG.js.map +1 -0
  303. package/dist/{chunk-YGN7OMLT.js → chunk-X5QSICJ3.js} +8 -5
  304. package/dist/chunk-X5QSICJ3.js.map +1 -0
  305. package/dist/chunk-YDGNU2OD.js +61 -0
  306. package/dist/chunk-YDGNU2OD.js.map +1 -0
  307. package/dist/collapsible-panel.d.ts +133 -0
  308. package/dist/collapsible-panel.js +131 -0
  309. package/dist/collapsible-panel.js.map +1 -0
  310. package/dist/content-item.d.ts +81 -0
  311. package/dist/content-item.js +4 -0
  312. package/dist/content-item.js.map +1 -0
  313. package/dist/css-values.d.ts +107 -0
  314. package/dist/css-values.js +3 -0
  315. package/dist/css-values.js.map +1 -0
  316. package/dist/device-class.js +33 -5
  317. package/dist/device-class.js.map +1 -1
  318. package/dist/disclosure-arrow.d.ts +6 -1
  319. package/dist/disclosure-arrow.js +2 -1
  320. package/dist/empty-state.d.ts +5 -2
  321. package/dist/empty-state.js +2 -1
  322. package/dist/flex-alignment-4ms8ZbV8.d.ts +5 -0
  323. package/dist/floating-toolbar.d.ts +51 -0
  324. package/dist/floating-toolbar.js +3 -0
  325. package/dist/floating-toolbar.js.map +1 -0
  326. package/dist/grid.d.ts +50 -0
  327. package/dist/grid.js +5 -0
  328. package/dist/grid.js.map +1 -0
  329. package/dist/help-tags-register.d.ts +13 -0
  330. package/dist/help-tags-register.js +9 -0
  331. package/dist/help-tags-register.js.map +1 -0
  332. package/dist/index.d.ts +34 -14
  333. package/dist/index.js +43 -23
  334. package/dist/{menu-action-row.d.ts → list-action-row.d.ts} +21 -9
  335. package/dist/list-action-row.js +8 -0
  336. package/dist/list-action-row.js.map +1 -0
  337. package/dist/list-header.d.ts +99 -0
  338. package/dist/list-header.js +10 -0
  339. package/dist/list-header.js.map +1 -0
  340. package/dist/list-inset-control.d.ts +22 -0
  341. package/dist/list-inset-control.js +3 -0
  342. package/dist/list-inset-control.js.map +1 -0
  343. package/dist/list-inset-text.d.ts +30 -0
  344. package/dist/list-inset-text.js +4 -0
  345. package/dist/list-inset-text.js.map +1 -0
  346. package/dist/list-item.d.ts +62 -0
  347. package/dist/list-item.js +8 -0
  348. package/dist/list-item.js.map +1 -0
  349. package/dist/list.d.ts +63 -0
  350. package/dist/list.js +6 -0
  351. package/dist/list.js.map +1 -0
  352. package/dist/loading-spinner.d.ts +9 -2
  353. package/dist/loading-spinner.js +2 -1
  354. package/dist/lucide-icon.d.ts +9 -2
  355. package/dist/lucide-icon.js +2 -1
  356. package/dist/nav-stack.d.ts +66 -10
  357. package/dist/nav-stack.js +6 -1
  358. package/dist/pane.d.ts +108 -0
  359. package/dist/pane.js +4 -0
  360. package/dist/pane.js.map +1 -0
  361. package/dist/panel-toolbar-DDKh4uKd.d.ts +72 -0
  362. package/dist/popup-menu-register.d.ts +9 -0
  363. package/dist/popup-menu-register.js +244 -0
  364. package/dist/popup-menu-register.js.map +1 -0
  365. package/dist/popup-menu.d.ts +100 -0
  366. package/dist/popup-menu.js +3 -0
  367. package/dist/popup-menu.js.map +1 -0
  368. package/dist/resizable-region.d.ts +32 -3
  369. package/dist/resizable-region.js +1 -1
  370. package/dist/row.d.ts +48 -0
  371. package/dist/row.js +6 -0
  372. package/dist/row.js.map +1 -0
  373. package/dist/segmented-control.d.ts +12 -9
  374. package/dist/segmented-control.js +1 -2
  375. package/dist/select-register.d.ts +5 -1
  376. package/dist/select-register.js +243 -2
  377. package/dist/select-register.js.map +1 -1
  378. package/dist/select.d.ts +102 -8
  379. package/dist/select.js +3 -1
  380. package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
  381. package/dist/sides-BPSWde0A.d.ts +4 -0
  382. package/dist/skeleton.d.ts +14 -7
  383. package/dist/skeleton.js +2 -1
  384. package/dist/spacer.d.ts +18 -0
  385. package/dist/spacer.js +4 -0
  386. package/dist/spacer.js.map +1 -0
  387. package/dist/split-view.d.ts +39 -7
  388. package/dist/split-view.js +120 -10
  389. package/dist/split-view.js.map +1 -1
  390. package/dist/state-banner.d.ts +18 -6
  391. package/dist/state-banner.js +3 -1
  392. package/dist/styles/app-tab.css +221 -0
  393. package/dist/styles/badge.css +118 -0
  394. package/dist/styles/catalog/components/catalog-example-stack.css +9 -0
  395. package/dist/styles/catalog/components/catalog-example.css +168 -0
  396. package/dist/styles/catalog/components/catalog-stage.css +55 -0
  397. package/dist/styles/catalog/components/catalog.css +12 -0
  398. package/dist/styles/catalog.css +5 -0
  399. package/dist/styles/chip.css +132 -0
  400. package/dist/styles/collapsible-panel.css +575 -0
  401. package/dist/styles/content-item.css +75 -0
  402. package/dist/styles/document.css +23 -0
  403. package/dist/styles/floating-toolbar.css +119 -0
  404. package/dist/styles/foundation.css +178 -40
  405. package/dist/styles/grid.css +35 -0
  406. package/dist/styles/layout.css +3 -41
  407. package/dist/styles/list-action-row.css +258 -0
  408. package/dist/styles/list-header.css +229 -0
  409. package/dist/styles/list-inset-control.css +30 -0
  410. package/dist/styles/list-inset-text.css +29 -0
  411. package/dist/styles/list-item.css +255 -0
  412. package/dist/styles/list.css +133 -0
  413. package/dist/styles/loading-spinner.css +4 -0
  414. package/dist/styles/lucide-icon.css +5 -0
  415. package/dist/styles/nav-stack.css +172 -47
  416. package/dist/styles/pane.css +263 -0
  417. package/dist/styles/popup-menu.css +285 -0
  418. package/dist/styles/resizable-region.css +438 -4
  419. package/dist/styles/row.css +111 -0
  420. package/dist/styles/segmented-control.css +36 -9
  421. package/dist/styles/select.css +337 -21
  422. package/dist/styles/skeleton.css +64 -3
  423. package/dist/styles/spacer.css +11 -0
  424. package/dist/styles/split-view.css +114 -3
  425. package/dist/styles/state-banner.css +94 -19
  426. package/dist/styles/styles.css +13 -4
  427. package/dist/styles/sunken-panel.css +29 -0
  428. package/dist/styles/surface-scaffold.css +56 -0
  429. package/dist/styles/tab-bar.css +147 -9
  430. package/dist/styles/tab-scaffold.css +126 -3
  431. package/dist/styles/text.css +112 -0
  432. package/dist/styles/token-search-field.css +155 -55
  433. package/dist/styles/toolbar-control-group.css +608 -29
  434. package/dist/styles/toolbar-text.css +101 -8
  435. package/dist/styles/toolbar.css +334 -12
  436. package/dist/styles/value-table.css +34 -4
  437. package/dist/styles/webawesome.css +365 -10
  438. package/dist/styles/workbench.css +980 -7
  439. package/dist/sunken-panel.d.ts +27 -0
  440. package/dist/sunken-panel.js +3 -0
  441. package/dist/sunken-panel.js.map +1 -0
  442. package/dist/surface-scaffold.d.ts +30 -0
  443. package/dist/surface-scaffold.js +3 -0
  444. package/dist/surface-scaffold.js.map +1 -0
  445. package/dist/tab-bar.d.ts +39 -6
  446. package/dist/tab-bar.js +1 -1
  447. package/dist/tab-scaffold.d.ts +57 -7
  448. package/dist/tab-scaffold.js +83 -9
  449. package/dist/tab-scaffold.js.map +1 -1
  450. package/dist/text.d.ts +56 -0
  451. package/dist/text.js +3 -0
  452. package/dist/text.js.map +1 -0
  453. package/dist/token-search-field-CVGwDn2y.d.ts +154 -0
  454. package/dist/token-search-field.d.ts +3 -43
  455. package/dist/token-search-field.js +2 -1
  456. package/dist/token-search-model.d.ts +3 -0
  457. package/dist/token-search-model.js +3 -0
  458. package/dist/token-search-model.js.map +1 -0
  459. package/dist/toolbar-control-group.d.ts +77 -7
  460. package/dist/toolbar-control-group.js +3 -1
  461. package/dist/toolbar-text.d.ts +35 -4
  462. package/dist/toolbar-text.js +2 -1
  463. package/dist/toolbar.d.ts +59 -7
  464. package/dist/toolbar.js +1 -1
  465. package/dist/types-BuHELdXR.d.ts +117 -0
  466. package/dist/value-table.d.ts +11 -3
  467. package/dist/value-table.js +2 -1
  468. package/dist/webawesome.d.ts +8 -1
  469. package/dist/wire-catalog.d.ts +82 -0
  470. package/dist/wire-catalog.js +327 -0
  471. package/dist/wire-catalog.js.map +1 -0
  472. package/dist/wire-content-items.d.ts +11 -0
  473. package/dist/wire-content-items.js +114 -0
  474. package/dist/wire-content-items.js.map +1 -0
  475. package/dist/wire-nav-stack.d.ts +4 -1
  476. package/dist/wire-nav-stack.js +147 -7
  477. package/dist/wire-nav-stack.js.map +1 -1
  478. package/dist/wire-resizable-regions.d.ts +2 -1
  479. package/dist/wire-resizable-regions.js +2 -1
  480. package/dist/wire-scroll-dividers.d.ts +72 -0
  481. package/dist/wire-scroll-dividers.js +3 -0
  482. package/dist/wire-scroll-dividers.js.map +1 -0
  483. package/dist/wire-sidebar.d.ts +63 -0
  484. package/dist/wire-sidebar.js +231 -0
  485. package/dist/wire-sidebar.js.map +1 -0
  486. package/dist/wire-tab-bars.d.ts +19 -2
  487. package/dist/wire-tab-bars.js +1 -1
  488. package/dist/wire-tab-scaffold.js +9 -4
  489. package/dist/wire-tab-scaffold.js.map +1 -1
  490. package/dist/wire-token-search-fields.d.ts +65 -3
  491. package/dist/wire-token-search-fields.js +2 -1
  492. package/dist/wire-workbench.d.ts +116 -0
  493. package/dist/wire-workbench.js +6 -0
  494. package/dist/wire-workbench.js.map +1 -0
  495. package/dist/workbench.d.ts +244 -9
  496. package/dist/workbench.js +17 -15
  497. package/dist/workbench.js.map +1 -1
  498. package/docs/accessibility.md +476 -24
  499. package/docs/app-layouts.md +106 -8
  500. package/docs/apple-hig.md +1 -0
  501. package/docs/catalog.md +483 -0
  502. package/docs/collapsible-panel.md +371 -0
  503. package/docs/component-contract.md +658 -56
  504. package/docs/component-integration.md +75 -0
  505. package/docs/component-selection.md +529 -90
  506. package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
  507. package/docs/design/templates/empty-state/filtered.svg +1 -0
  508. package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
  509. package/docs/design/templates/empty-state/with-action.svg +1 -0
  510. package/docs/design/templates/empty-state-dark.svg +1 -0
  511. package/docs/design/templates/empty-state.svg +1 -0
  512. package/docs/design/templates/list/compact-dark.svg +1 -0
  513. package/docs/design/templates/list/compact.svg +1 -0
  514. package/docs/design/templates/list/stack-dark.svg +1 -0
  515. package/docs/design/templates/list/stack.svg +1 -0
  516. package/docs/design/templates/list-action-row/default-dark.svg +1 -0
  517. package/docs/design/templates/list-action-row/default.svg +1 -0
  518. package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
  519. package/docs/design/templates/list-action-row/selected.svg +1 -0
  520. package/docs/design/templates/list-action-row-dark.svg +1 -0
  521. package/docs/design/templates/list-action-row.svg +1 -0
  522. package/docs/design/templates/list-dark.svg +1 -0
  523. package/docs/design/templates/list-header/action-dark.svg +1 -0
  524. package/docs/design/templates/list-header/action.svg +1 -0
  525. package/docs/design/templates/list-header/count-dark.svg +1 -0
  526. package/docs/design/templates/list-header/count.svg +1 -0
  527. package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
  528. package/docs/design/templates/list-header/inline-action.svg +1 -0
  529. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
  530. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
  531. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
  532. package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
  533. package/docs/design/templates/list-header-dark.svg +1 -0
  534. package/docs/design/templates/list-header.svg +1 -0
  535. package/docs/design/templates/list-item/default-dark.svg +1 -0
  536. package/docs/design/templates/list-item/default.svg +1 -0
  537. package/docs/design/templates/list-item/multiline-dark.svg +1 -0
  538. package/docs/design/templates/list-item/multiline.svg +1 -0
  539. package/docs/design/templates/list-item/selected-dark.svg +1 -0
  540. package/docs/design/templates/list-item/selected.svg +1 -0
  541. package/docs/design/templates/list-item/trailing-dark.svg +1 -0
  542. package/docs/design/templates/list-item/trailing.svg +1 -0
  543. package/docs/design/templates/list-item-dark.svg +1 -0
  544. package/docs/design/templates/list-item.svg +1 -0
  545. package/docs/design/templates/list.svg +1 -0
  546. package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
  547. package/docs/design/templates/segmented-control/equal.svg +1 -0
  548. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
  549. package/docs/design/templates/segmented-control/pill-small.svg +1 -0
  550. package/docs/design/templates/segmented-control-dark.svg +1 -0
  551. package/docs/design/templates/segmented-control.svg +1 -0
  552. package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
  553. package/docs/design/templates/skeleton/avatar.svg +1 -0
  554. package/docs/design/templates/skeleton/block-dark.svg +1 -0
  555. package/docs/design/templates/skeleton/block.svg +1 -0
  556. package/docs/design/templates/skeleton/lines-dark.svg +1 -0
  557. package/docs/design/templates/skeleton/lines.svg +1 -0
  558. package/docs/design/templates/skeleton-dark.svg +1 -0
  559. package/docs/design/templates/skeleton.svg +1 -0
  560. package/docs/design/templates/state-banner/danger-dark.svg +1 -0
  561. package/docs/design/templates/state-banner/danger.svg +1 -0
  562. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
  563. package/docs/design/templates/state-banner/info-badge.svg +1 -0
  564. package/docs/design/templates/state-banner/info-dark.svg +1 -0
  565. package/docs/design/templates/state-banner/info.svg +1 -0
  566. package/docs/design/templates/state-banner/success-dark.svg +1 -0
  567. package/docs/design/templates/state-banner/success.svg +1 -0
  568. package/docs/design/templates/state-banner/warning-dark.svg +1 -0
  569. package/docs/design/templates/state-banner/warning.svg +1 -0
  570. package/docs/design/templates/state-banner-dark.svg +1 -0
  571. package/docs/design/templates/state-banner.svg +1 -0
  572. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
  573. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
  574. package/docs/design/templates/tab-bar-dark.svg +1 -0
  575. package/docs/design/templates/tab-bar.svg +1 -0
  576. package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
  577. package/docs/design/templates/token-search-field/empty.svg +1 -0
  578. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
  579. package/docs/design/templates/token-search-field/tokens.svg +1 -0
  580. package/docs/design/templates/token-search-field-dark.svg +1 -0
  581. package/docs/design/templates/token-search-field.svg +1 -0
  582. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
  583. package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
  584. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
  585. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
  586. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
  587. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
  588. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
  589. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
  590. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
  591. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
  592. package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
  593. package/docs/design/templates/toolbar-control-group.svg +1 -0
  594. package/docs/design/templates/toolbar-dark.svg +1 -0
  595. package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
  596. package/docs/design/templates/toolbar-text/default.svg +1 -0
  597. package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
  598. package/docs/design/templates/toolbar-text/large.svg +1 -0
  599. package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
  600. package/docs/design/templates/toolbar-text/small.svg +1 -0
  601. package/docs/design/templates/toolbar-text-dark.svg +1 -0
  602. package/docs/design/templates/toolbar-text.svg +1 -0
  603. package/docs/design/templates/toolbar.svg +1 -0
  604. package/docs/design/templates/value-table/details-dark.svg +1 -0
  605. package/docs/design/templates/value-table/details.svg +1 -0
  606. package/docs/design/templates/value-table-dark.svg +1 -0
  607. package/docs/design/templates/value-table.svg +1 -0
  608. package/docs/design/templates.md +138 -0
  609. package/docs/design-philosophy.md +48 -20
  610. package/docs/device-class.md +10 -9
  611. package/docs/document-baseline.md +38 -0
  612. package/docs/examples/application-ui-profile.json +60 -0
  613. package/docs/examples/command-palette-adapter.tsx +69 -17
  614. package/docs/examples/component-catalog-extension.json +52 -0
  615. package/docs/examples/component-composition-extension.json +80 -0
  616. package/docs/layout.md +534 -59
  617. package/docs/nav-stack.md +138 -14
  618. package/docs/recipes.md +137 -54
  619. package/docs/split-view.md +74 -6
  620. package/docs/sunken-panel.md +87 -0
  621. package/docs/surface-scaffold.md +28 -0
  622. package/docs/tab-scaffold.md +99 -10
  623. package/docs/type-contracts.md +134 -0
  624. package/docs/ui-analyzer.md +347 -0
  625. package/docs/ui-doctor.md +128 -0
  626. package/docs/ui-evaluator.md +139 -0
  627. package/docs/ux-demo.md +41 -16
  628. package/docs/webawesome-theme.md +218 -16
  629. package/docs/workbench.md +608 -12
  630. package/doctor/cli.mjs +120 -0
  631. package/doctor/config.schema.json +72 -0
  632. package/doctor/eslint-diagnostics.d.mts +24 -0
  633. package/doctor/eslint-diagnostics.mjs +24 -0
  634. package/doctor/index.d.mts +121 -0
  635. package/doctor/index.mjs +1324 -0
  636. package/doctor/report.schema.json +118 -0
  637. package/evaluator/cli.mjs +89 -0
  638. package/evaluator/index.d.mts +90 -0
  639. package/evaluator/index.mjs +1203 -0
  640. package/evaluator/report.schema.json +152 -0
  641. package/llms.txt +445 -48
  642. package/package.json +249 -37
  643. package/scripts/component-catalog-extension-validation.mjs +28 -0
  644. package/traversal-exclusions.mjs +27 -0
  645. package/ux-demo/recipes/app-shell.tsx +205 -17
  646. package/ux-demo/recipes/collapsible-sidebar.tsx +260 -0
  647. package/ux-demo/recipes/compact-toolbar.tsx +135 -14
  648. package/ux-demo/recipes/composer-form.tsx +133 -21
  649. package/ux-demo/recipes/list-detail-dialog.tsx +282 -0
  650. package/ux-demo/recipes/list-workspace-states.tsx +183 -11
  651. package/ux-demo/recipes/loaders.ts +15 -5
  652. package/ux-demo/recipes/loading-inspector.tsx +204 -0
  653. package/ux-demo/recipes/mount-recipe.ts +28 -10
  654. package/ux-demo/recipes/navigation-sidebar.tsx +139 -13
  655. package/ux-demo/recipes/navigation-stack.tsx +79 -24
  656. package/ux-demo/recipes/types.ts +23 -2
  657. package/ux-demo/recipes/workspace-header.tsx +86 -5
  658. package/dist/browser/menu-action-row.js +0 -4
  659. package/dist/browser/menu-item.js +0 -4
  660. package/dist/chunk-2RJBFNB6.js +0 -172
  661. package/dist/chunk-2RJBFNB6.js.map +0 -1
  662. package/dist/chunk-2Z5TWHKQ.js +0 -34
  663. package/dist/chunk-2Z5TWHKQ.js.map +0 -1
  664. package/dist/chunk-3YD6ZNRA.js +0 -34
  665. package/dist/chunk-3YD6ZNRA.js.map +0 -1
  666. package/dist/chunk-55DATV3A.js +0 -10
  667. package/dist/chunk-55DATV3A.js.map +0 -1
  668. package/dist/chunk-56RJXPHG.js.map +0 -1
  669. package/dist/chunk-7BR3DO2A.js.map +0 -1
  670. package/dist/chunk-7LDCTU7D.js +0 -134
  671. package/dist/chunk-7LDCTU7D.js.map +0 -1
  672. package/dist/chunk-AQNKJRFH.js +0 -79
  673. package/dist/chunk-AQNKJRFH.js.map +0 -1
  674. package/dist/chunk-B24C4A6T.js +0 -22
  675. package/dist/chunk-B24C4A6T.js.map +0 -1
  676. package/dist/chunk-DAFFDO33.js +0 -14
  677. package/dist/chunk-DAFFDO33.js.map +0 -1
  678. package/dist/chunk-H6URQGJI.js +0 -42
  679. package/dist/chunk-H6URQGJI.js.map +0 -1
  680. package/dist/chunk-I7INRJO4.js +0 -17
  681. package/dist/chunk-I7INRJO4.js.map +0 -1
  682. package/dist/chunk-KJYXOTG3.js +0 -10
  683. package/dist/chunk-KJYXOTG3.js.map +0 -1
  684. package/dist/chunk-LC3YSAZC.js +0 -39
  685. package/dist/chunk-LC3YSAZC.js.map +0 -1
  686. package/dist/chunk-M5JRI6MN.js +0 -27
  687. package/dist/chunk-M5JRI6MN.js.map +0 -1
  688. package/dist/chunk-MBR3TYNL.js +0 -14
  689. package/dist/chunk-MBR3TYNL.js.map +0 -1
  690. package/dist/chunk-MFKMHK5W.js +0 -10
  691. package/dist/chunk-MFKMHK5W.js.map +0 -1
  692. package/dist/chunk-MQIZAD4A.js +0 -227
  693. package/dist/chunk-MQIZAD4A.js.map +0 -1
  694. package/dist/chunk-N3SUXLLS.js +0 -23
  695. package/dist/chunk-N3SUXLLS.js.map +0 -1
  696. package/dist/chunk-PONXLV5U.js +0 -19
  697. package/dist/chunk-PONXLV5U.js.map +0 -1
  698. package/dist/chunk-TZNCCM5H.js +0 -20
  699. package/dist/chunk-TZNCCM5H.js.map +0 -1
  700. package/dist/chunk-W2FK7ZNY.js +0 -26
  701. package/dist/chunk-W2FK7ZNY.js.map +0 -1
  702. package/dist/chunk-WVPYVDXY.js +0 -15
  703. package/dist/chunk-WVPYVDXY.js.map +0 -1
  704. package/dist/chunk-YGN7OMLT.js.map +0 -1
  705. package/dist/chunk-YKUUZPED.js +0 -24
  706. package/dist/chunk-YKUUZPED.js.map +0 -1
  707. package/dist/menu-action-row.js +0 -5
  708. package/dist/menu-action-row.js.map +0 -1
  709. package/dist/menu-header.d.ts +0 -43
  710. package/dist/menu-header.js +0 -7
  711. package/dist/menu-header.js.map +0 -1
  712. package/dist/menu-item.d.ts +0 -33
  713. package/dist/menu-item.js +0 -5
  714. package/dist/menu-item.js.map +0 -1
  715. package/dist/panel-header.d.ts +0 -28
  716. package/dist/panel-header.js +0 -7
  717. package/dist/panel-header.js.map +0 -1
  718. package/dist/styles/menu-action-row.css +0 -160
  719. package/dist/styles/menu-header.css +0 -160
  720. package/dist/styles/menu-item.css +0 -123
  721. package/dist/styles/panel-header.css +0 -64
  722. package/ux-demo/recipes/master-detail-dialog.tsx +0 -45
  723. package/ux-demo/recipes/recipes.css +0 -355
@@ -0,0 +1,327 @@
1
+ import { wireWorkbench } from './chunk-TJK44RQC.js';
2
+
3
+ import { wireScrollDividers } from './chunk-6DFDTWGG.js';
4
+
5
+
6
+ import { delegate } from 'kerfjs';
7
+
8
+ var catalogDesktopMedia = "(min-width: 44.01rem)";
9
+ function revealCatalogEntry(root, id, {
10
+ block = "nearest",
11
+ inline = "nearest",
12
+ behavior = "auto",
13
+ media = catalogDesktopMedia
14
+ } = {}) {
15
+ const view = root.ownerDocument.defaultView;
16
+ if (!view || media && !view.matchMedia(media).matches) return () => {
17
+ };
18
+ const frame = view.requestAnimationFrame(() => {
19
+ for (const item of root.querySelectorAll("[data-item-id]")) {
20
+ if (item.dataset.itemId !== id) continue;
21
+ item.scrollIntoView({ block, inline, behavior });
22
+ break;
23
+ }
24
+ });
25
+ return () => view.cancelAnimationFrame(frame);
26
+ }
27
+ function pixels(value) {
28
+ const number = Number.parseFloat(value);
29
+ if (!Number.isFinite(number)) return 0;
30
+ return value.trim().endsWith("rem") ? number * 16 : number;
31
+ }
32
+ function isTransparent(color) {
33
+ const normalized = color.replace(/\s+/g, "");
34
+ return normalized === "transparent" || /(?:,|\/)0(?:\.0+)?\)$/.test(normalized);
35
+ }
36
+ function geometrySpecimens(canvas) {
37
+ const result = [];
38
+ for (const example of canvas.querySelectorAll(
39
+ "[data-catalog-example]"
40
+ )) {
41
+ if (example.closest("[data-catalog-geometry-overlay-skip]")) continue;
42
+ for (const child of example.children) {
43
+ if (child.matches("[data-catalog-geometry-overlay]") || child.matches("[data-catalog-example-label]") || child.matches("[data-catalog-example-note]"))
44
+ continue;
45
+ result.push(child);
46
+ }
47
+ }
48
+ for (const element of canvas.querySelectorAll(
49
+ "[data-component]"
50
+ )) {
51
+ if (element.closest("[data-catalog-geometry-overlay]") || element.closest("[data-catalog-geometry-overlay-skip]") || element.closest(".kui-catalog-example"))
52
+ continue;
53
+ const parent = element.parentElement?.closest("[data-component]");
54
+ if (parent && canvas.contains(parent)) continue;
55
+ result.push(element);
56
+ }
57
+ return result;
58
+ }
59
+ function geometryBox(document, className, left, top, width, height) {
60
+ const element = document.createElement("div");
61
+ element.className = className;
62
+ element.style.transform = `translate(${left}px, ${top}px)`;
63
+ element.style.width = `${Math.max(0, width)}px`;
64
+ element.style.height = `${Math.max(0, height)}px`;
65
+ return element;
66
+ }
67
+ function effectiveBorderWidth(width, style) {
68
+ return style === "none" || style === "hidden" ? 0 : pixels(width);
69
+ }
70
+ function wireCatalogGeometryOverlay(root) {
71
+ const catalog = root.matches('[data-component="catalog"]') ? root : root.querySelector('[data-component="catalog"]');
72
+ const canvas = catalog?.querySelector(".kui-catalog__canvas");
73
+ const layer = catalog?.querySelector(
74
+ "[data-catalog-geometry-overlay]"
75
+ );
76
+ const view = root.ownerDocument.defaultView;
77
+ if (!catalog || !canvas || !layer || !view) return () => {
78
+ };
79
+ let frame = 0;
80
+ const render = () => {
81
+ frame = 0;
82
+ layer.replaceChildren();
83
+ if (catalog.dataset.geometryOverlay !== "true") {
84
+ syncObservedSpecimens([]);
85
+ return;
86
+ }
87
+ const base = canvas.getBoundingClientRect();
88
+ const specimens = geometrySpecimens(canvas);
89
+ syncObservedSpecimens(specimens);
90
+ for (const [specimenIndex, element] of specimens.entries()) {
91
+ const rect = element.getBoundingClientRect();
92
+ const style = view.getComputedStyle(element);
93
+ const align = pixels(
94
+ style.getPropertyValue("--kui-catalog-example-align")
95
+ );
96
+ const top = pixels(style.marginTop);
97
+ const right = Math.max(
98
+ 0,
99
+ pixels(style.marginRight) - (style.direction === "rtl" ? align : 0)
100
+ );
101
+ const bottom = pixels(style.marginBottom);
102
+ const left = Math.max(
103
+ 0,
104
+ pixels(style.marginLeft) - (style.direction === "rtl" ? 0 : align)
105
+ );
106
+ const x = rect.left - base.left + canvas.scrollLeft;
107
+ const y = rect.top - base.top + canvas.scrollTop;
108
+ const borderWidths = [
109
+ effectiveBorderWidth(style.borderTopWidth, style.borderTopStyle),
110
+ effectiveBorderWidth(style.borderRightWidth, style.borderRightStyle),
111
+ effectiveBorderWidth(style.borderBottomWidth, style.borderBottomStyle),
112
+ effectiveBorderWidth(style.borderLeftWidth, style.borderLeftStyle)
113
+ ];
114
+ if (borderWidths.some((width) => width > 0)) {
115
+ const border = geometryBox(
116
+ root.ownerDocument,
117
+ "kui-catalog__geometry-border",
118
+ x,
119
+ y,
120
+ rect.width,
121
+ rect.height
122
+ );
123
+ border.dataset.catalogGeometrySpecimen = String(specimenIndex);
124
+ border.style.borderTopWidth = `${borderWidths[0]}px`;
125
+ border.style.borderRightWidth = `${borderWidths[1]}px`;
126
+ border.style.borderBottomWidth = `${borderWidths[2]}px`;
127
+ border.style.borderLeftWidth = `${borderWidths[3]}px`;
128
+ border.style.borderRadius = style.borderRadius;
129
+ layer.append(border);
130
+ } else if (isTransparent(style.backgroundColor)) {
131
+ const bound = geometryBox(
132
+ root.ownerDocument,
133
+ "kui-catalog__geometry-bound",
134
+ x,
135
+ y,
136
+ rect.width,
137
+ rect.height
138
+ );
139
+ bound.dataset.catalogGeometrySpecimen = String(specimenIndex);
140
+ layer.append(bound);
141
+ }
142
+ const margins = [
143
+ ["top", top, x - left, y - top, rect.width + left + right, top],
144
+ [
145
+ "bottom",
146
+ bottom,
147
+ x - left,
148
+ y + rect.height,
149
+ rect.width + left + right,
150
+ bottom
151
+ ],
152
+ ["left", left, x - left, y, left, rect.height],
153
+ ["right", right, x + rect.width, y, right, rect.height]
154
+ ];
155
+ for (const [side, size, marginX, marginY, width, height] of margins) {
156
+ if (size <= 0) continue;
157
+ const margin = geometryBox(
158
+ root.ownerDocument,
159
+ "kui-catalog__geometry-margin",
160
+ marginX,
161
+ marginY,
162
+ width,
163
+ height
164
+ );
165
+ margin.dataset.catalogGeometrySpecimen = String(specimenIndex);
166
+ margin.dataset.catalogGeometrySide = side;
167
+ layer.append(margin);
168
+ }
169
+ }
170
+ };
171
+ const schedule = () => {
172
+ if (!frame) frame = view.requestAnimationFrame(render);
173
+ };
174
+ const resizeObserver = new view.ResizeObserver(schedule);
175
+ resizeObserver.observe(canvas);
176
+ const observedSpecimens = /* @__PURE__ */ new Set();
177
+ const syncObservedSpecimens = (specimens) => {
178
+ const next = new Set(specimens);
179
+ for (const specimen of observedSpecimens) {
180
+ if (next.has(specimen)) continue;
181
+ resizeObserver.unobserve(specimen);
182
+ observedSpecimens.delete(specimen);
183
+ }
184
+ for (const specimen of next) {
185
+ if (observedSpecimens.has(specimen)) continue;
186
+ resizeObserver.observe(specimen);
187
+ observedSpecimens.add(specimen);
188
+ }
189
+ };
190
+ const mutationObserver = new view.MutationObserver((records) => {
191
+ if (records.some(
192
+ ({ target }) => target !== layer && !layer.contains(target)
193
+ ))
194
+ schedule();
195
+ });
196
+ mutationObserver.observe(catalog, {
197
+ attributes: true,
198
+ childList: true,
199
+ subtree: true
200
+ });
201
+ mutationObserver.observe(root.ownerDocument.documentElement, {
202
+ attributes: true
203
+ });
204
+ const documentHead = root.ownerDocument.head;
205
+ if (documentHead)
206
+ mutationObserver.observe(documentHead, {
207
+ attributes: true,
208
+ characterData: true,
209
+ childList: true,
210
+ subtree: true
211
+ });
212
+ const stylesheetLoaded = () => schedule();
213
+ documentHead?.addEventListener("load", stylesheetLoaded, true);
214
+ view.addEventListener("resize", schedule);
215
+ render();
216
+ return () => {
217
+ if (frame) view.cancelAnimationFrame(frame);
218
+ resizeObserver.disconnect();
219
+ mutationObserver.disconnect();
220
+ documentHead?.removeEventListener("load", stylesheetLoaded, true);
221
+ view.removeEventListener("resize", schedule);
222
+ layer.replaceChildren();
223
+ };
224
+ }
225
+ function wireCatalog(root, {
226
+ onSelect,
227
+ onToggleSidebar,
228
+ onToggleTheme,
229
+ onToggleSecondary,
230
+ urlParam,
231
+ revealSelection,
232
+ selectAction = "catalog-select",
233
+ toggleSidebarAction = "catalog-toggle-sidebar",
234
+ toggleThemeAction = "catalog-toggle-theme",
235
+ toggleSecondaryAction = "catalog-toggle-secondary",
236
+ collapsed,
237
+ sidebarSize,
238
+ sidebarStorageKey,
239
+ id: catalogId = "kui-catalog"
240
+ }) {
241
+ let cancelReveal;
242
+ const select = (id) => {
243
+ onSelect(id);
244
+ const view = root.ownerDocument.defaultView;
245
+ if (urlParam && view) {
246
+ const url = new URL(view.location.href);
247
+ url.searchParams.set(urlParam, id);
248
+ view.history.replaceState(null, "", url);
249
+ }
250
+ const rail = root.ownerDocument.getElementById(`${catalogId}-left-rail`);
251
+ if (collapsed && !collapsed.peek() && rail && root.ownerDocument.defaultView?.getComputedStyle(rail).position === "absolute")
252
+ collapsed.value = true;
253
+ if (revealSelection) {
254
+ cancelReveal?.();
255
+ cancelReveal = revealCatalogEntry(
256
+ root,
257
+ id,
258
+ revealSelection === true ? void 0 : revealSelection
259
+ );
260
+ }
261
+ };
262
+ const disposers = [
263
+ wireScrollDividers(root),
264
+ // Sidebar items AND the footer's related-entry popup-menu items both carry
265
+ // `data-action={selectAction}` + `data-item-id`, so one delegated click covers both.
266
+ delegate(
267
+ root,
268
+ "click",
269
+ `[data-action="${selectAction}"]`,
270
+ (_event, element) => {
271
+ const id = element.dataset.itemId;
272
+ if (id) select(id);
273
+ }
274
+ )
275
+ ];
276
+ if (onToggleSidebar) {
277
+ disposers.push(
278
+ delegate(
279
+ root,
280
+ "click",
281
+ `[data-action="${toggleSidebarAction}"]`,
282
+ () => onToggleSidebar()
283
+ )
284
+ );
285
+ }
286
+ if (onToggleTheme) {
287
+ disposers.push(
288
+ delegate(
289
+ root,
290
+ "click",
291
+ `[data-action="${toggleThemeAction}"]`,
292
+ () => onToggleTheme()
293
+ )
294
+ );
295
+ }
296
+ if (onToggleSecondary) {
297
+ disposers.push(
298
+ delegate(
299
+ root,
300
+ "click",
301
+ `[data-action="${toggleSecondaryAction}"]`,
302
+ () => onToggleSecondary()
303
+ )
304
+ );
305
+ }
306
+ if (collapsed || sidebarSize)
307
+ disposers.push(
308
+ wireWorkbench(root, {
309
+ id: catalogId,
310
+ panels: {
311
+ leftRail: {
312
+ collapsed,
313
+ size: sidebarSize,
314
+ storageKey: sidebarStorageKey
315
+ }
316
+ }
317
+ })
318
+ );
319
+ return () => {
320
+ cancelReveal?.();
321
+ for (const dispose of disposers.splice(0)) dispose();
322
+ };
323
+ }
324
+
325
+ export { revealCatalogEntry, wireCatalog, wireCatalogGeometryOverlay };
326
+
327
+ //# sourceMappingURL=wire-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/wire-catalog.ts"],"names":[],"mappings":"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","file":"wire-catalog.js","sourcesContent":["import { delegate, type Signal } from 'kerfjs';\n\nimport { wireScrollDividers } from './wire-scroll-dividers.js';\nimport { wireWorkbench } from './wire-workbench.js';\n\nexport interface WireCatalogOptions {\n /** Invoked with the entry id when a sidebar item or a related-entry option is chosen. */\n onSelect: (id: string) => void;\n /** Invoked when the sidebar collapse/expand control is activated. */\n onToggleSidebar?: () => void;\n /** Invoked when the theme toggle is activated. */\n onToggleTheme?: () => void;\n /** Invoked when the secondary (ecosystem) group's disclosure toggle is activated. */\n onToggleSecondary?: () => void;\n /** When set, `?<urlParam>=<id>` is written on select via `history.replaceState`. */\n urlParam?: string;\n /**\n * Reveal the chosen sidebar row after selection. `true` uses desktop-safe\n * defaults; pass options to customize scroll alignment or the media guard.\n */\n revealSelection?: boolean | CatalogRevealOptions;\n selectAction?: string;\n toggleSidebarAction?: string;\n toggleThemeAction?: string;\n toggleSecondaryAction?: string;\n /**\n * The sidebar's app-owned collapsed flag. With it, the catalog's Workbench\n * sidebar is wired like any Workbench rail: it becomes a transient overlay\n * on a small screen (collapsed as the breakpoint applies, closed on Escape\n * or a press outside, focus handed back), and choosing an entry from the\n * open overlay closes it.\n */\n collapsed?: Signal<boolean>;\n /**\n * The app-owned sidebar width signal for a Catalog rendered with\n * `sidebar={{ resizable: true, size: sidebarSize.value }}`. Each committed\n * drag or keyboard resize is written to it.\n */\n sidebarSize?: Signal<number>;\n /**\n * With `sidebarSize`, load and save the width under this storage key so the\n * catalog remembers the user's sidebar width.\n */\n sidebarStorageKey?: string;\n /** The Catalog's `id`, when it is not the default `kui-catalog`. */\n id?: string;\n}\n\nexport interface CatalogRevealOptions {\n /** Scroll alignment within the sidebar. Default `'nearest'`. */\n block?: ScrollLogicalPosition;\n /** Cross-axis alignment. Default `'nearest'`. */\n inline?: ScrollLogicalPosition;\n /** Scroll behavior. Default `'auto'`. */\n behavior?: ScrollBehavior;\n /**\n * Only reveal when this media query matches. Defaults to the Catalog's\n * desktop layout; pass `false` to reveal at every viewport size.\n */\n media?: string | false;\n}\n\n// The Workbench keeps the sidebar inline above its `narrow` breakpoint (704px).\nconst catalogDesktopMedia = '(min-width: 44.01rem)';\n\n/**\n * Reveal one Catalog sidebar entry after the controlled render settles without\n * moving focus. Returns a cancellation function for rapid selection changes.\n */\nexport function revealCatalogEntry(\n root: HTMLElement,\n id: string,\n {\n block = 'nearest',\n inline = 'nearest',\n behavior = 'auto',\n media = catalogDesktopMedia,\n }: CatalogRevealOptions = {},\n): () => void {\n const view = root.ownerDocument.defaultView;\n if (!view || (media && !view.matchMedia(media).matches)) return () => {};\n const frame = view.requestAnimationFrame(() => {\n for (const item of root.querySelectorAll<HTMLElement>('[data-item-id]')) {\n if (item.dataset.itemId !== id) continue;\n item.scrollIntoView({ block, inline, behavior });\n break;\n }\n });\n return () => view.cancelAnimationFrame(frame);\n}\n\nfunction pixels(value: string): number {\n const number = Number.parseFloat(value);\n if (!Number.isFinite(number)) return 0;\n return value.trim().endsWith('rem') ? number * 16 : number;\n}\n\nfunction isTransparent(color: string): boolean {\n const normalized = color.replace(/\\s+/g, '');\n return (\n normalized === 'transparent' || /(?:,|\\/)0(?:\\.0+)?\\)$/.test(normalized)\n );\n}\n\nfunction geometrySpecimens(canvas: HTMLElement): Element[] {\n const result: Element[] = [];\n for (const example of canvas.querySelectorAll<HTMLElement>(\n '[data-catalog-example]',\n )) {\n if (example.closest('[data-catalog-geometry-overlay-skip]')) continue;\n for (const child of example.children) {\n if (\n child.matches('[data-catalog-geometry-overlay]') ||\n child.matches('[data-catalog-example-label]') ||\n child.matches('[data-catalog-example-note]')\n )\n continue;\n result.push(child);\n }\n }\n for (const element of canvas.querySelectorAll<HTMLElement>(\n '[data-component]',\n )) {\n if (\n element.closest('[data-catalog-geometry-overlay]') ||\n element.closest('[data-catalog-geometry-overlay-skip]') ||\n element.closest('.kui-catalog-example')\n )\n continue;\n const parent =\n element.parentElement?.closest<HTMLElement>('[data-component]');\n if (parent && canvas.contains(parent)) continue;\n result.push(element);\n }\n return result;\n}\n\nfunction geometryBox(\n document: Document,\n className: string,\n left: number,\n top: number,\n width: number,\n height: number,\n): HTMLElement {\n const element = document.createElement('div');\n element.className = className;\n element.style.transform = `translate(${left}px, ${top}px)`;\n element.style.width = `${Math.max(0, width)}px`;\n element.style.height = `${Math.max(0, height)}px`;\n return element;\n}\n\nfunction effectiveBorderWidth(width: string, style: string): number {\n return style === 'none' || style === 'hidden' ? 0 : pixels(width);\n}\n\n/**\n * Keep a Catalog's opt-in geometry overlay synchronized with its preview.\n * Specimens receive computed border highlights (or a dashed bound when they\n * have no border and are transparent), while positive computed margins use\n * devtools-style orange bands. CSS/stylesheet-only changes are observed too.\n * Returns a disposer.\n */\nexport function wireCatalogGeometryOverlay(root: HTMLElement): () => void {\n const catalog = root.matches('[data-component=\"catalog\"]')\n ? root\n : root.querySelector<HTMLElement>('[data-component=\"catalog\"]');\n const canvas = catalog?.querySelector<HTMLElement>('.kui-catalog__canvas');\n const layer = catalog?.querySelector<HTMLElement>(\n '[data-catalog-geometry-overlay]',\n );\n const view = root.ownerDocument.defaultView;\n if (!catalog || !canvas || !layer || !view) return () => {};\n\n let frame = 0;\n const render = (): void => {\n frame = 0;\n layer.replaceChildren();\n if (catalog.dataset.geometryOverlay !== 'true') {\n syncObservedSpecimens([]);\n return;\n }\n const base = canvas.getBoundingClientRect();\n const specimens = geometrySpecimens(canvas);\n syncObservedSpecimens(specimens);\n for (const [specimenIndex, element] of specimens.entries()) {\n const rect = element.getBoundingClientRect();\n const style = view.getComputedStyle(element);\n const align = pixels(\n style.getPropertyValue('--kui-catalog-example-align'),\n );\n const top = pixels(style.marginTop);\n const right = Math.max(\n 0,\n pixels(style.marginRight) - (style.direction === 'rtl' ? align : 0),\n );\n const bottom = pixels(style.marginBottom);\n const left = Math.max(\n 0,\n pixels(style.marginLeft) - (style.direction === 'rtl' ? 0 : align),\n );\n const x = rect.left - base.left + canvas.scrollLeft;\n const y = rect.top - base.top + canvas.scrollTop;\n const borderWidths = [\n effectiveBorderWidth(style.borderTopWidth, style.borderTopStyle),\n effectiveBorderWidth(style.borderRightWidth, style.borderRightStyle),\n effectiveBorderWidth(style.borderBottomWidth, style.borderBottomStyle),\n effectiveBorderWidth(style.borderLeftWidth, style.borderLeftStyle),\n ];\n if (borderWidths.some((width) => width > 0)) {\n const border = geometryBox(\n root.ownerDocument,\n 'kui-catalog__geometry-border',\n x,\n y,\n rect.width,\n rect.height,\n );\n border.dataset.catalogGeometrySpecimen = String(specimenIndex);\n border.style.borderTopWidth = `${borderWidths[0]}px`;\n border.style.borderRightWidth = `${borderWidths[1]}px`;\n border.style.borderBottomWidth = `${borderWidths[2]}px`;\n border.style.borderLeftWidth = `${borderWidths[3]}px`;\n border.style.borderRadius = style.borderRadius;\n layer.append(border);\n } else if (isTransparent(style.backgroundColor)) {\n const bound = geometryBox(\n root.ownerDocument,\n 'kui-catalog__geometry-bound',\n x,\n y,\n rect.width,\n rect.height,\n );\n bound.dataset.catalogGeometrySpecimen = String(specimenIndex);\n layer.append(bound);\n }\n const margins: Array<\n readonly [string, number, number, number, number, number]\n > = [\n ['top', top, x - left, y - top, rect.width + left + right, top],\n [\n 'bottom',\n bottom,\n x - left,\n y + rect.height,\n rect.width + left + right,\n bottom,\n ],\n ['left', left, x - left, y, left, rect.height],\n ['right', right, x + rect.width, y, right, rect.height],\n ];\n for (const [side, size, marginX, marginY, width, height] of margins) {\n if (size <= 0) continue;\n const margin = geometryBox(\n root.ownerDocument,\n 'kui-catalog__geometry-margin',\n marginX,\n marginY,\n width,\n height,\n );\n margin.dataset.catalogGeometrySpecimen = String(specimenIndex);\n margin.dataset.catalogGeometrySide = side;\n layer.append(margin);\n }\n }\n };\n const schedule = (): void => {\n if (!frame) frame = view.requestAnimationFrame(render);\n };\n const resizeObserver = new view.ResizeObserver(schedule);\n resizeObserver.observe(canvas);\n const observedSpecimens = new Set<Element>();\n const syncObservedSpecimens = (specimens: Element[]): void => {\n const next = new Set(specimens);\n for (const specimen of observedSpecimens) {\n if (next.has(specimen)) continue;\n resizeObserver.unobserve(specimen);\n observedSpecimens.delete(specimen);\n }\n for (const specimen of next) {\n if (observedSpecimens.has(specimen)) continue;\n resizeObserver.observe(specimen);\n observedSpecimens.add(specimen);\n }\n };\n const mutationObserver = new view.MutationObserver((records) => {\n if (\n records.some(\n ({ target }) => target !== layer && !layer.contains(target as Node),\n )\n )\n schedule();\n });\n mutationObserver.observe(catalog, {\n attributes: true,\n childList: true,\n subtree: true,\n });\n mutationObserver.observe(root.ownerDocument.documentElement, {\n attributes: true,\n });\n const documentHead = root.ownerDocument.head;\n if (documentHead)\n mutationObserver.observe(documentHead, {\n attributes: true,\n characterData: true,\n childList: true,\n subtree: true,\n });\n const stylesheetLoaded = (): void => schedule();\n documentHead?.addEventListener('load', stylesheetLoaded, true);\n view.addEventListener('resize', schedule);\n render();\n return () => {\n if (frame) view.cancelAnimationFrame(frame);\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n documentHead?.removeEventListener('load', stylesheetLoaded, true);\n view.removeEventListener('resize', schedule);\n layer.replaceChildren();\n };\n}\n\n/**\n * Wire a {@link Catalog}'s interactions with one delegated listener set: sidebar\n * item selection (and the related-entry popup menu), the sidebar collapse toggle, and\n * the theme toggle. The app owns the `active`/`collapsed`/`theme` signals and updates\n * them in the callbacks; optionally mirror the active id into the URL via `urlParam`.\n * It also wires the scroll dividers below root (`wireScrollDividers`), so the\n * catalog's panes and every example in it show their chrome dividers only\n * while scrolled. Returns a disposer.\n */\nexport function wireCatalog(\n root: HTMLElement,\n {\n onSelect,\n onToggleSidebar,\n onToggleTheme,\n onToggleSecondary,\n urlParam,\n revealSelection,\n selectAction = 'catalog-select',\n toggleSidebarAction = 'catalog-toggle-sidebar',\n toggleThemeAction = 'catalog-toggle-theme',\n toggleSecondaryAction = 'catalog-toggle-secondary',\n collapsed,\n sidebarSize,\n sidebarStorageKey,\n id: catalogId = 'kui-catalog',\n }: WireCatalogOptions,\n): () => void {\n let cancelReveal: (() => void) | undefined;\n const select = (id: string) => {\n onSelect(id);\n const view = root.ownerDocument.defaultView;\n if (urlParam && view) {\n const url = new URL(view.location.href);\n url.searchParams.set(urlParam, id);\n view.history.replaceState(null, '', url);\n }\n // An open overlay sidebar gives way to the entry just chosen from it.\n const rail = root.ownerDocument.getElementById(`${catalogId}-left-rail`);\n if (\n collapsed &&\n !collapsed.peek() &&\n rail &&\n root.ownerDocument.defaultView?.getComputedStyle(rail).position ===\n 'absolute'\n )\n collapsed.value = true;\n if (revealSelection) {\n cancelReveal?.();\n cancelReveal = revealCatalogEntry(\n root,\n id,\n revealSelection === true ? undefined : revealSelection,\n );\n }\n };\n\n const disposers: Array<() => void> = [\n wireScrollDividers(root),\n // Sidebar items AND the footer's related-entry popup-menu items both carry\n // `data-action={selectAction}` + `data-item-id`, so one delegated click covers both.\n delegate(\n root,\n 'click',\n `[data-action=\"${selectAction}\"]`,\n (_event, element) => {\n const id = (element as HTMLElement).dataset.itemId;\n if (id) select(id);\n },\n ),\n ];\n if (onToggleSidebar) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleSidebarAction}\"]`, () =>\n onToggleSidebar(),\n ),\n );\n }\n if (onToggleTheme) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleThemeAction}\"]`, () =>\n onToggleTheme(),\n ),\n );\n }\n if (onToggleSecondary) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleSecondaryAction}\"]`, () =>\n onToggleSecondary(),\n ),\n );\n }\n if (collapsed || sidebarSize)\n disposers.push(\n wireWorkbench(root, {\n id: catalogId,\n panels: {\n leftRail: {\n collapsed,\n size: sidebarSize,\n storageKey: sidebarStorageKey,\n },\n },\n }),\n );\n return () => {\n cancelReveal?.();\n for (const dispose of disposers.splice(0)) dispose();\n };\n}\n"]}
@@ -0,0 +1,11 @@
1
+ /** True when a card action originated on the card rather than a nested control. */
2
+ declare function isContentItemActivation(event: Event, item: HTMLElement): boolean;
3
+ /**
4
+ * Give interactive ContentItems native-like Enter/Space activation with one
5
+ * delegated listener pair. Space activates on release and is cancelled if
6
+ * focus moves; the item's own `data-action` still goes through the app's
7
+ * ordinary delegated click handler. Returns a disposer.
8
+ */
9
+ declare function wireContentItems(root: HTMLElement): () => void;
10
+
11
+ export { isContentItemActivation, wireContentItems };
@@ -0,0 +1,114 @@
1
+ // src/wire-content-items.ts
2
+ var ITEM_SELECTOR = '[data-component="content-item"][data-interactive="true"]';
3
+ var NESTED_CONTROL_SELECTOR = 'button, a[href], input, select, textarea, [contenteditable="true"], [role="button"]';
4
+ var MULTI_GRID_SELECTOR = '[role="grid"][aria-multiselectable="true"]';
5
+ function nextTile(item, rows, key) {
6
+ const current = item.getBoundingClientRect();
7
+ const centerX = current.left + current.width / 2;
8
+ const candidates = rows.filter((row) => row !== item).map((row) => {
9
+ const rect = row.getBoundingClientRect();
10
+ return { row, x: rect.left + rect.width / 2, y: rect.top };
11
+ });
12
+ const sameLine = (y) => Math.abs(y - current.top) < 1;
13
+ const directed = candidates.filter(
14
+ ({ x, y }) => key === "ArrowLeft" ? sameLine(y) && x < centerX : key === "ArrowRight" ? sameLine(y) && x > centerX : key === "ArrowUp" ? y < current.top - 1 : y > current.top + 1
15
+ );
16
+ directed.sort((a, b) => {
17
+ if (key === "ArrowLeft") return b.x - a.x;
18
+ if (key === "ArrowRight") return a.x - b.x;
19
+ const vertical = Math.abs(a.y - current.top) - Math.abs(b.y - current.top);
20
+ return vertical || Math.abs(a.x - centerX) - Math.abs(b.x - centerX);
21
+ });
22
+ return directed[0]?.row;
23
+ }
24
+ function actionItem(root, event) {
25
+ const target = event.target;
26
+ if (!(target instanceof Element)) return null;
27
+ const item = target.closest(ITEM_SELECTOR);
28
+ if (!item || !root.contains(item) || item.dataset.disabled === "true")
29
+ return null;
30
+ for (const node of event.composedPath()) {
31
+ if (node === item) break;
32
+ if (node instanceof Element && node.matches(NESTED_CONTROL_SELECTOR))
33
+ return null;
34
+ }
35
+ return item;
36
+ }
37
+ function isContentItemActivation(event, item) {
38
+ return actionItem(item, event) === item;
39
+ }
40
+ function wireContentItems(root) {
41
+ let pendingSpace = null;
42
+ const clearSpace = () => {
43
+ pendingSpace?.removeAttribute("data-kui-pressed");
44
+ pendingSpace = null;
45
+ };
46
+ const keydown = (event) => {
47
+ if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey)
48
+ return;
49
+ const item = actionItem(root, event);
50
+ if (!item) return;
51
+ if (item.dataset.selectionMode === "multiple" && [
52
+ "ArrowDown",
53
+ "ArrowUp",
54
+ "ArrowLeft",
55
+ "ArrowRight",
56
+ "Home",
57
+ "End"
58
+ ].includes(event.key)) {
59
+ const grid = item.closest(MULTI_GRID_SELECTOR);
60
+ if (!grid) return;
61
+ const rows = Array.from(
62
+ grid.querySelectorAll(
63
+ `${ITEM_SELECTOR}[data-selection-mode="multiple"]:not([data-disabled="true"])`
64
+ )
65
+ ).filter((row) => row.closest(MULTI_GRID_SELECTOR) === grid);
66
+ const index = rows.indexOf(item);
67
+ if (index < 0) return;
68
+ const isTileGrid = grid.getAttribute("data-component") === "grid";
69
+ const next = event.key === "Home" ? rows[0] : event.key === "End" ? rows[rows.length - 1] : isTileGrid ? nextTile(item, rows, event.key) : event.key === "ArrowDown" || event.key === "ArrowUp" ? rows[index + (event.key === "ArrowDown" ? 1 : -1)] : void 0;
70
+ if (next) {
71
+ event.preventDefault();
72
+ next.focus();
73
+ }
74
+ return;
75
+ }
76
+ if (event.key === "Enter") {
77
+ event.preventDefault();
78
+ item.click();
79
+ return;
80
+ }
81
+ if (event.key === " " || event.key === "Spacebar") {
82
+ event.preventDefault();
83
+ if (event.repeat) return;
84
+ clearSpace();
85
+ pendingSpace = item;
86
+ item.setAttribute("data-kui-pressed", "true");
87
+ }
88
+ };
89
+ const keyup = (event) => {
90
+ if (event.key !== " " && event.key !== "Spacebar") return;
91
+ const item = pendingSpace;
92
+ if (!item) return;
93
+ event.preventDefault();
94
+ clearSpace();
95
+ if (item === actionItem(root, event) && item.ownerDocument.activeElement === item)
96
+ item.click();
97
+ };
98
+ const focusout = (event) => {
99
+ if (event.target === pendingSpace) clearSpace();
100
+ };
101
+ root.addEventListener("keydown", keydown);
102
+ root.addEventListener("keyup", keyup);
103
+ root.addEventListener("focusout", focusout);
104
+ return () => {
105
+ clearSpace();
106
+ root.removeEventListener("keydown", keydown);
107
+ root.removeEventListener("keyup", keyup);
108
+ root.removeEventListener("focusout", focusout);
109
+ };
110
+ }
111
+
112
+ export { isContentItemActivation, wireContentItems };
113
+
114
+ //# sourceMappingURL=wire-content-items.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/wire-content-items.ts"],"names":[],"mappings":"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","file":"wire-content-items.js","sourcesContent":["const ITEM_SELECTOR =\n '[data-component=\"content-item\"][data-interactive=\"true\"]';\nconst NESTED_CONTROL_SELECTOR =\n 'button, a[href], input, select, textarea, [contenteditable=\"true\"], [role=\"button\"]';\nconst MULTI_GRID_SELECTOR = '[role=\"grid\"][aria-multiselectable=\"true\"]';\n\nfunction nextTile(\n item: HTMLElement,\n rows: HTMLElement[],\n key: string,\n): HTMLElement | undefined {\n const current = item.getBoundingClientRect();\n const centerX = current.left + current.width / 2;\n const candidates = rows\n .filter((row) => row !== item)\n .map((row) => {\n const rect = row.getBoundingClientRect();\n return { row, x: rect.left + rect.width / 2, y: rect.top };\n });\n const sameLine = (y: number) => Math.abs(y - current.top) < 1;\n const directed = candidates.filter(({ x, y }) =>\n key === 'ArrowLeft'\n ? sameLine(y) && x < centerX\n : key === 'ArrowRight'\n ? sameLine(y) && x > centerX\n : key === 'ArrowUp'\n ? y < current.top - 1\n : y > current.top + 1,\n );\n directed.sort((a, b) => {\n if (key === 'ArrowLeft') return b.x - a.x;\n if (key === 'ArrowRight') return a.x - b.x;\n const vertical = Math.abs(a.y - current.top) - Math.abs(b.y - current.top);\n return vertical || Math.abs(a.x - centerX) - Math.abs(b.x - centerX);\n });\n return directed[0]?.row;\n}\n\nfunction actionItem(root: HTMLElement, event: Event) {\n const target = event.target;\n if (!(target instanceof Element)) return null;\n const item = target.closest<HTMLElement>(ITEM_SELECTOR);\n if (!item || !root.contains(item) || item.dataset.disabled === 'true')\n return null;\n // Composed events expose native controls inside a custom element's shadow\n // root even though event.target is retargeted to its host here.\n for (const node of event.composedPath()) {\n if (node === item) break;\n if (node instanceof Element && node.matches(NESTED_CONTROL_SELECTOR))\n return null;\n }\n return item;\n}\n\n/** True when a card action originated on the card rather than a nested control. */\nexport function isContentItemActivation(\n event: Event,\n item: HTMLElement,\n): boolean {\n return actionItem(item, event) === item;\n}\n\n/**\n * Give interactive ContentItems native-like Enter/Space activation with one\n * delegated listener pair. Space activates on release and is cancelled if\n * focus moves; the item's own `data-action` still goes through the app's\n * ordinary delegated click handler. Returns a disposer.\n */\nexport function wireContentItems(root: HTMLElement): () => void {\n let pendingSpace: HTMLElement | null = null;\n\n const clearSpace = () => {\n pendingSpace?.removeAttribute('data-kui-pressed');\n pendingSpace = null;\n };\n\n const keydown = (event: KeyboardEvent) => {\n if (\n event.defaultPrevented ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey\n )\n return;\n const item = actionItem(root, event);\n if (!item) return;\n if (\n item.dataset.selectionMode === 'multiple' &&\n [\n 'ArrowDown',\n 'ArrowUp',\n 'ArrowLeft',\n 'ArrowRight',\n 'Home',\n 'End',\n ].includes(event.key)\n ) {\n const grid = item.closest(MULTI_GRID_SELECTOR);\n if (!grid) return;\n const rows = Array.from(\n grid.querySelectorAll<HTMLElement>(\n `${ITEM_SELECTOR}[data-selection-mode=\"multiple\"]:not([data-disabled=\"true\"])`,\n ),\n ).filter((row) => row.closest(MULTI_GRID_SELECTOR) === grid);\n const index = rows.indexOf(item);\n if (index < 0) return;\n const isTileGrid = grid.getAttribute('data-component') === 'grid';\n const next =\n event.key === 'Home'\n ? rows[0]\n : event.key === 'End'\n ? rows[rows.length - 1]\n : isTileGrid\n ? nextTile(item, rows, event.key)\n : event.key === 'ArrowDown' || event.key === 'ArrowUp'\n ? rows[index + (event.key === 'ArrowDown' ? 1 : -1)]\n : undefined;\n if (next) {\n event.preventDefault();\n next.focus();\n }\n return;\n }\n if (event.key === 'Enter') {\n event.preventDefault();\n item.click();\n return;\n }\n if (event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n if (event.repeat) return;\n clearSpace();\n pendingSpace = item;\n item.setAttribute('data-kui-pressed', 'true');\n }\n };\n\n const keyup = (event: KeyboardEvent) => {\n if (event.key !== ' ' && event.key !== 'Spacebar') return;\n const item = pendingSpace;\n if (!item) return;\n event.preventDefault();\n clearSpace();\n if (\n item === actionItem(root, event) &&\n item.ownerDocument.activeElement === item\n )\n item.click();\n };\n\n const focusout = (event: FocusEvent) => {\n if (event.target === pendingSpace) clearSpace();\n };\n\n root.addEventListener('keydown', keydown);\n root.addEventListener('keyup', keyup);\n root.addEventListener('focusout', focusout);\n return () => {\n clearSpace();\n root.removeEventListener('keydown', keydown);\n root.removeEventListener('keyup', keyup);\n root.removeEventListener('focusout', focusout);\n };\n}\n"]}
@@ -8,7 +8,10 @@ interface WireNavStackOptions {
8
8
  * Animate a `NavStack`'s push/pop transitions and wire its back control. The app
9
9
  * owns the stack (a signal of `NavStackView[]`) and re-renders `NavStack` when it
10
10
  * changes; this helper slides the content and settles the chrome across each
11
- * change, and calls `onBack` when the back control is used. Returns a disposer.
11
+ * change, moves focus into every new top view, restores that view's last focused
12
+ * descendant on pop, and calls `onBack` when the back control is used. Mark a
13
+ * preferred initial target with `data-nav-focus`; otherwise the first focusable
14
+ * descendant (or the view itself) receives focus. Returns a disposer.
12
15
  */
13
16
  declare function wireNavStack(root: Element, options?: WireNavStackOptions): () => void;
14
17