@panphora/bevel 0.1.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 (539) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +226 -0
  3. package/bevel-fonts.css +16 -0
  4. package/bevel.css +3075 -0
  5. package/bevel.js +2126 -0
  6. package/dist/react/components/activity-feed.d.ts +89 -0
  7. package/dist/react/components/activity-feed.js +54 -0
  8. package/dist/react/components/alert-dialog.d.ts +14 -0
  9. package/dist/react/components/alert-dialog.js +19 -0
  10. package/dist/react/components/app-shell.d.ts +98 -0
  11. package/dist/react/components/app-shell.js +86 -0
  12. package/dist/react/components/app-toolbar.d.ts +19 -0
  13. package/dist/react/components/app-toolbar.js +22 -0
  14. package/dist/react/components/avatar-group.d.ts +67 -0
  15. package/dist/react/components/avatar-group.js +49 -0
  16. package/dist/react/components/badge-and-pill.d.ts +34 -0
  17. package/dist/react/components/badge-and-pill.js +12 -0
  18. package/dist/react/components/breadcrumbs.d.ts +56 -0
  19. package/dist/react/components/breadcrumbs.js +44 -0
  20. package/dist/react/components/bulk-bar.d.ts +22 -0
  21. package/dist/react/components/bulk-bar.js +59 -0
  22. package/dist/react/components/button.d.ts +15 -0
  23. package/dist/react/components/button.js +20 -0
  24. package/dist/react/components/callout-and-hint.d.ts +17 -0
  25. package/dist/react/components/callout-and-hint.js +8 -0
  26. package/dist/react/components/checkbox.d.ts +5 -0
  27. package/dist/react/components/checkbox.js +13 -0
  28. package/dist/react/components/chip.d.ts +149 -0
  29. package/dist/react/components/chip.js +29 -0
  30. package/dist/react/components/code-block.d.ts +50 -0
  31. package/dist/react/components/code-block.js +77 -0
  32. package/dist/react/components/code-editor.d.ts +122 -0
  33. package/dist/react/components/code-editor.js +695 -0
  34. package/dist/react/components/column-manager.d.ts +28 -0
  35. package/dist/react/components/column-manager.js +85 -0
  36. package/dist/react/components/combobox.d.ts +32 -0
  37. package/dist/react/components/combobox.js +37 -0
  38. package/dist/react/components/data-grid.d.ts +108 -0
  39. package/dist/react/components/data-grid.js +159 -0
  40. package/dist/react/components/data-table.d.ts +2 -0
  41. package/dist/react/components/data-table.js +6 -0
  42. package/dist/react/components/date.d.ts +23 -0
  43. package/dist/react/components/date.js +11 -0
  44. package/dist/react/components/details.d.ts +13 -0
  45. package/dist/react/components/details.js +20 -0
  46. package/dist/react/components/dialog.d.ts +74 -0
  47. package/dist/react/components/dialog.js +31 -0
  48. package/dist/react/components/diff-view.d.ts +73 -0
  49. package/dist/react/components/diff-view.js +68 -0
  50. package/dist/react/components/documents.d.ts +70 -0
  51. package/dist/react/components/documents.js +10 -0
  52. package/dist/react/components/drawer.d.ts +45 -0
  53. package/dist/react/components/drawer.js +35 -0
  54. package/dist/react/components/editable-grid-cells.d.ts +32 -0
  55. package/dist/react/components/editable-grid-cells.js +116 -0
  56. package/dist/react/components/eyebrow-kicker-lede-pull-quote.d.ts +39 -0
  57. package/dist/react/components/eyebrow-kicker-lede-pull-quote.js +12 -0
  58. package/dist/react/components/field.d.ts +32 -0
  59. package/dist/react/components/field.js +27 -0
  60. package/dist/react/components/file-tree.d.ts +75 -0
  61. package/dist/react/components/file-tree.js +247 -0
  62. package/dist/react/components/file.d.ts +43 -0
  63. package/dist/react/components/file.js +73 -0
  64. package/dist/react/components/files-table.d.ts +174 -0
  65. package/dist/react/components/files-table.js +237 -0
  66. package/dist/react/components/filter-builder.d.ts +37 -0
  67. package/dist/react/components/filter-builder.js +109 -0
  68. package/dist/react/components/form-error-summary.d.ts +16 -0
  69. package/dist/react/components/form-error-summary.js +49 -0
  70. package/dist/react/components/icon-button.d.ts +8 -0
  71. package/dist/react/components/icon-button.js +14 -0
  72. package/dist/react/components/icon.d.ts +7 -0
  73. package/dist/react/components/icon.js +15 -0
  74. package/dist/react/components/image.d.ts +72 -0
  75. package/dist/react/components/image.js +24 -0
  76. package/dist/react/components/inline-edit.d.ts +70 -0
  77. package/dist/react/components/inline-edit.js +149 -0
  78. package/dist/react/components/input.d.ts +29 -0
  79. package/dist/react/components/input.js +20 -0
  80. package/dist/react/components/kanban-board.d.ts +140 -0
  81. package/dist/react/components/kanban-board.js +374 -0
  82. package/dist/react/components/layout.d.ts +51 -0
  83. package/dist/react/components/layout.js +28 -0
  84. package/dist/react/components/list.d.ts +28 -0
  85. package/dist/react/components/list.js +6 -0
  86. package/dist/react/components/masthead-and-verdict.d.ts +60 -0
  87. package/dist/react/components/masthead-and-verdict.js +8 -0
  88. package/dist/react/components/menu.d.ts +26 -0
  89. package/dist/react/components/menu.js +31 -0
  90. package/dist/react/components/multi-select-picker.d.ts +49 -0
  91. package/dist/react/components/multi-select-picker.js +20 -0
  92. package/dist/react/components/note.d.ts +33 -0
  93. package/dist/react/components/note.js +8 -0
  94. package/dist/react/components/number-field.d.ts +16 -0
  95. package/dist/react/components/number-field.js +17 -0
  96. package/dist/react/components/pagination.d.ts +45 -0
  97. package/dist/react/components/pagination.js +87 -0
  98. package/dist/react/components/persistent-action-banner.d.ts +71 -0
  99. package/dist/react/components/persistent-action-banner.js +39 -0
  100. package/dist/react/components/popconfirm.d.ts +42 -0
  101. package/dist/react/components/popconfirm.js +59 -0
  102. package/dist/react/components/popover.d.ts +16 -0
  103. package/dist/react/components/popover.js +21 -0
  104. package/dist/react/components/progress-and-gauge.d.ts +44 -0
  105. package/dist/react/components/progress-and-gauge.js +19 -0
  106. package/dist/react/components/radio.d.ts +7 -0
  107. package/dist/react/components/radio.js +13 -0
  108. package/dist/react/components/rich-text-toolbar.d.ts +26 -0
  109. package/dist/react/components/rich-text-toolbar.js +64 -0
  110. package/dist/react/components/rows-and-card.d.ts +88 -0
  111. package/dist/react/components/rows-and-card.js +10 -0
  112. package/dist/react/components/save-status-indicator.d.ts +11 -0
  113. package/dist/react/components/save-status-indicator.js +33 -0
  114. package/dist/react/components/segmented-control.d.ts +21 -0
  115. package/dist/react/components/segmented-control.js +15 -0
  116. package/dist/react/components/select.d.ts +29 -0
  117. package/dist/react/components/select.js +29 -0
  118. package/dist/react/components/selectable-cards.d.ts +30 -0
  119. package/dist/react/components/selectable-cards.js +29 -0
  120. package/dist/react/components/settings-rows.d.ts +51 -0
  121. package/dist/react/components/settings-rows.js +8 -0
  122. package/dist/react/components/sidebar-nav.d.ts +77 -0
  123. package/dist/react/components/sidebar-nav.js +41 -0
  124. package/dist/react/components/skeleton-and-empty.d.ts +51 -0
  125. package/dist/react/components/skeleton-and-empty.js +14 -0
  126. package/dist/react/components/slider.d.ts +19 -0
  127. package/dist/react/components/slider.js +17 -0
  128. package/dist/react/components/small-charts.d.ts +60 -0
  129. package/dist/react/components/small-charts.js +76 -0
  130. package/dist/react/components/sortable.d.ts +30 -0
  131. package/dist/react/components/sortable.js +85 -0
  132. package/dist/react/components/split-button.d.ts +38 -0
  133. package/dist/react/components/split-button.js +43 -0
  134. package/dist/react/components/split-panes.d.ts +35 -0
  135. package/dist/react/components/split-panes.js +102 -0
  136. package/dist/react/components/stat-tiles.d.ts +54 -0
  137. package/dist/react/components/stat-tiles.js +8 -0
  138. package/dist/react/components/steps.d.ts +11 -0
  139. package/dist/react/components/steps.js +13 -0
  140. package/dist/react/components/switch.d.ts +6 -0
  141. package/dist/react/components/switch.js +13 -0
  142. package/dist/react/components/table.d.ts +61 -0
  143. package/dist/react/components/table.js +6 -0
  144. package/dist/react/components/tabs.d.ts +7 -0
  145. package/dist/react/components/tabs.js +13 -0
  146. package/dist/react/components/tags.d.ts +33 -0
  147. package/dist/react/components/tags.js +83 -0
  148. package/dist/react/components/textarea.d.ts +10 -0
  149. package/dist/react/components/textarea.js +6 -0
  150. package/dist/react/components/toast.d.ts +35 -0
  151. package/dist/react/components/toast.js +90 -0
  152. package/dist/react/components/tooltip-and-key.d.ts +20 -0
  153. package/dist/react/components/tooltip-and-key.js +20 -0
  154. package/dist/react/components/tree-view.d.ts +34 -0
  155. package/dist/react/components/tree-view.js +118 -0
  156. package/dist/react/components/upload-dropzone.d.ts +92 -0
  157. package/dist/react/components/upload-dropzone.js +116 -0
  158. package/dist/react/components/wizard-shell.d.ts +78 -0
  159. package/dist/react/components/wizard-shell.js +176 -0
  160. package/dist/react/fonts.css.d.ts +1 -0
  161. package/dist/react/index.d.ts +76 -0
  162. package/dist/react/index.js +77 -0
  163. package/dist/react/integrations/quickcrop.d.ts +58 -0
  164. package/dist/react/integrations/quickcrop.js +137 -0
  165. package/dist/react/integrations/richclay.d.ts +43 -0
  166. package/dist/react/integrations/richclay.js +129 -0
  167. package/dist/react/internal/classes.d.ts +3 -0
  168. package/dist/react/internal/classes.js +10 -0
  169. package/dist/react/internal/close-mark.d.ts +1 -0
  170. package/dist/react/internal/close-mark.js +10 -0
  171. package/dist/react/internal/controllable-state.d.ts +9 -0
  172. package/dist/react/internal/controllable-state.js +22 -0
  173. package/dist/react/internal/drop-effect.d.ts +28 -0
  174. package/dist/react/internal/drop-effect.js +8 -0
  175. package/dist/react/internal/form-reset.d.ts +2 -0
  176. package/dist/react/internal/form-reset.js +22 -0
  177. package/dist/react/internal/format.d.ts +1 -0
  178. package/dist/react/internal/format.js +14 -0
  179. package/dist/react/internal/link.d.ts +2 -0
  180. package/dist/react/internal/link.js +8 -0
  181. package/dist/react/internal/part.d.ts +20 -0
  182. package/dist/react/internal/part.js +47 -0
  183. package/dist/react/internal/pointer-session.d.ts +8 -0
  184. package/dist/react/internal/pointer-session.js +60 -0
  185. package/dist/react/internal/refs.d.ts +2 -0
  186. package/dist/react/internal/refs.js +22 -0
  187. package/dist/react/internal/rich-text.d.ts +28 -0
  188. package/dist/react/internal/rich-text.js +4 -0
  189. package/dist/react/internal/table-context.d.ts +39 -0
  190. package/dist/react/internal/table-context.js +12 -0
  191. package/dist/react/internal/use-object-url.d.ts +1 -0
  192. package/dist/react/internal/use-object-url.js +15 -0
  193. package/dist/react/layout.css +274 -0
  194. package/dist/react/layout.css.d.ts +1 -0
  195. package/dist/react/models/filter.d.ts +31 -0
  196. package/dist/react/models/filter.js +79 -0
  197. package/dist/react/models/kanban.d.ts +51 -0
  198. package/dist/react/models/kanban.js +35 -0
  199. package/dist/react/models/reorder.d.ts +9 -0
  200. package/dist/react/models/reorder.js +23 -0
  201. package/dist/react/models/table.d.ts +85 -0
  202. package/dist/react/models/table.js +144 -0
  203. package/dist/react/models/tree.d.ts +16 -0
  204. package/dist/react/models/tree.js +26 -0
  205. package/dist/react/provider.d.ts +18 -0
  206. package/dist/react/provider.js +31 -0
  207. package/dist/react/recipes/context-hypercms.d.ts +17 -0
  208. package/dist/react/recipes/context-hypercms.js +71 -0
  209. package/dist/react/recipes/context-quickcrop.d.ts +8 -0
  210. package/dist/react/recipes/context-quickcrop.js +49 -0
  211. package/dist/react/theme.css +8004 -0
  212. package/dist/react/theme.css.d.ts +1 -0
  213. package/examples/README.md +34 -0
  214. package/examples/components/activity-feed.html +28 -0
  215. package/examples/components/app-shell.html +12 -0
  216. package/examples/components/app-toolbar.html +38 -0
  217. package/examples/components/avatar-group.html +27 -0
  218. package/examples/components/breadcrumbs.html +26 -0
  219. package/examples/components/bulk-bar.html +22 -0
  220. package/examples/components/code-block.html +12 -0
  221. package/examples/components/code-editor.html +25 -0
  222. package/examples/components/column-manager.html +9 -0
  223. package/examples/components/combobox.html +13 -0
  224. package/examples/components/context-hypercms.css +41 -0
  225. package/examples/components/context-hypercms.html +40 -0
  226. package/examples/components/context-hypercms.js +62 -0
  227. package/examples/components/context-quickcrop.html +137 -0
  228. package/examples/components/diff-view.html +9 -0
  229. package/examples/components/drawer.html +11 -0
  230. package/examples/components/editable-grid-cells.html +9 -0
  231. package/examples/components/file-browser.html +53 -0
  232. package/examples/components/file-tree.html +34 -0
  233. package/examples/components/files-table.html +80 -0
  234. package/examples/components/filter-builder.html +11 -0
  235. package/examples/components/form-error-summary.html +11 -0
  236. package/examples/components/index.html +51 -0
  237. package/examples/components/inline-edit.html +42 -0
  238. package/examples/components/kanban-board.html +42 -0
  239. package/examples/components/manifest.json +3279 -0
  240. package/examples/components/modal.html +11 -0
  241. package/examples/components/multi-select-picker.html +13 -0
  242. package/examples/components/pagination.html +32 -0
  243. package/examples/components/persistent-action-banner.html +23 -0
  244. package/examples/components/popconfirm.html +13 -0
  245. package/examples/components/popover-menu.html +13 -0
  246. package/examples/components/reference/baseline/DECISIONS.md +85 -0
  247. package/examples/components/reference/baseline/README.md +58 -0
  248. package/examples/components/reference/baseline/bevel-fonts.css +16 -0
  249. package/examples/components/reference/baseline/bevel.css +1339 -0
  250. package/examples/components/reference/baseline/bevel.js +496 -0
  251. package/examples/components/reference/baseline/fonts/LICENSE-ibm-plex-mono.txt +93 -0
  252. package/examples/components/reference/baseline/fonts/LICENSE-ibm-plex-sans.txt +93 -0
  253. package/examples/components/reference/baseline/fonts/LICENSE-newsreader.txt +93 -0
  254. package/examples/components/reference/baseline/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
  255. package/examples/components/reference/baseline/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
  256. package/examples/components/reference/baseline/fonts/ibm-plex-mono-latin-600-normal.woff2 +0 -0
  257. package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-400-italic.woff2 +0 -0
  258. package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
  259. package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
  260. package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
  261. package/examples/components/reference/baseline/fonts/newsreader-latin-opsz-italic.woff2 +0 -0
  262. package/examples/components/reference/baseline/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
  263. package/examples/components/reference/fable/IMPROVEMENTS.md +106 -0
  264. package/examples/components/reference/fable/PARENT-REPAIRS.md +17 -0
  265. package/examples/components/reference/fable/__pycache__/build_repairs.cpython-311.pyc +0 -0
  266. package/examples/components/reference/fable/__pycache__/kanban.cpython-311.pyc +0 -0
  267. package/examples/components/reference/fable/as-authored/IMPROVEMENTS-completed.md +106 -0
  268. package/examples/components/reference/fable/as-authored/base-astra.css +17 -0
  269. package/examples/components/reference/fable/as-authored/base-parent.css +416 -0
  270. package/examples/components/reference/fable/as-authored/build.py +858 -0
  271. package/examples/components/reference/fable/as-authored/fable.css +823 -0
  272. package/examples/components/reference/fable/as-authored/kanban-completed.css +235 -0
  273. package/examples/components/reference/fable/as-authored/kanban-completed.html +53 -0
  274. package/examples/components/reference/fable/as-authored/kanban-completed.py +212 -0
  275. package/examples/components/reference/fable/as-authored/kanban.py +207 -0
  276. package/examples/components/reference/fable/base-astra.css +17 -0
  277. package/examples/components/reference/fable/base-parent.css +416 -0
  278. package/examples/components/reference/fable/build.py +858 -0
  279. package/examples/components/reference/fable/build_repairs.py +25 -0
  280. package/examples/components/reference/fable/components/activity-feed.html +3 -0
  281. package/examples/components/reference/fable/components/app-toolbar.html +3 -0
  282. package/examples/components/reference/fable/components/avatar-group.html +4 -0
  283. package/examples/components/reference/fable/components/breadcrumbs.html +3 -0
  284. package/examples/components/reference/fable/components/code-block.html +9 -0
  285. package/examples/components/reference/fable/components/column-manager.html +3 -0
  286. package/examples/components/reference/fable/components/combobox.html +6 -0
  287. package/examples/components/reference/fable/components/context-hypercms.html +3 -0
  288. package/examples/components/reference/fable/components/context-quickcrop.html +4 -0
  289. package/examples/components/reference/fable/components/diff-view.html +13 -0
  290. package/examples/components/reference/fable/components/drawer.html +3 -0
  291. package/examples/components/reference/fable/components/editable-grid-cells.html +3 -0
  292. package/examples/components/reference/fable/components/filter-builder.html +3 -0
  293. package/examples/components/reference/fable/components/form-error-summary.html +4 -0
  294. package/examples/components/reference/fable/components/inline-edit.html +3 -0
  295. package/examples/components/reference/fable/components/kanban-board.html +53 -0
  296. package/examples/components/reference/fable/components/modal.html +3 -0
  297. package/examples/components/reference/fable/components/multi-select-picker.html +5 -0
  298. package/examples/components/reference/fable/components/pagination.html +3 -0
  299. package/examples/components/reference/fable/components/persistent-action-banner.html +4 -0
  300. package/examples/components/reference/fable/components/popconfirm.html +5 -0
  301. package/examples/components/reference/fable/components/popover-menu.html +3 -0
  302. package/examples/components/reference/fable/components/rich-text-toolbar.html +3 -0
  303. package/examples/components/reference/fable/components/save-status-indicator.html +2 -0
  304. package/examples/components/reference/fable/components/selectable-cards.html +3 -0
  305. package/examples/components/reference/fable/components/settings-rows.html +3 -0
  306. package/examples/components/reference/fable/components/sidebar-nav.html +4 -0
  307. package/examples/components/reference/fable/components/small-charts.html +5 -0
  308. package/examples/components/reference/fable/components/split-button.html +4 -0
  309. package/examples/components/reference/fable/components/split-panes.html +8 -0
  310. package/examples/components/reference/fable/components/stat-tiles.html +3 -0
  311. package/examples/components/reference/fable/components/toast-stack.html +5 -0
  312. package/examples/components/reference/fable/components/tree-view.html +4 -0
  313. package/examples/components/reference/fable/components/upload-dropzone.html +6 -0
  314. package/examples/components/reference/fable/components/wizard-shell.html +3 -0
  315. package/examples/components/reference/fable/coverage.json +414 -0
  316. package/examples/components/reference/fable/fable.css +823 -0
  317. package/examples/components/reference/fable/index.html +5 -0
  318. package/examples/components/reference/fable/kanban.css +237 -0
  319. package/examples/components/reference/fable/kanban.py +212 -0
  320. package/examples/components/reference/fable/parent-repairs.css +9 -0
  321. package/examples/components/reference/fixtures/data.json +102 -0
  322. package/examples/components/reference/fixtures/host.js +47 -0
  323. package/examples/components/reference/fixtures/static-host.js +39 -0
  324. package/examples/components/reference/fixtures/workspace.jpg +0 -0
  325. package/examples/components/reference/parent/CHANGES.md +179 -0
  326. package/examples/components/reference/parent/__pycache__/kanban.cpython-311.pyc +0 -0
  327. package/examples/components/reference/parent/base-astra.css +17 -0
  328. package/examples/components/reference/parent/base-parent.css +416 -0
  329. package/examples/components/reference/parent/build.py +148 -0
  330. package/examples/components/reference/parent/components/activity-feed.html +2 -0
  331. package/examples/components/reference/parent/components/app-toolbar.html +2 -0
  332. package/examples/components/reference/parent/components/avatar-group.html +4 -0
  333. package/examples/components/reference/parent/components/breadcrumbs.html +2 -0
  334. package/examples/components/reference/parent/components/code-block.html +8 -0
  335. package/examples/components/reference/parent/components/column-manager.html +2 -0
  336. package/examples/components/reference/parent/components/combobox.html +6 -0
  337. package/examples/components/reference/parent/components/context-hypercms.html +2 -0
  338. package/examples/components/reference/parent/components/context-quickcrop.html +4 -0
  339. package/examples/components/reference/parent/components/diff-view.html +4 -0
  340. package/examples/components/reference/parent/components/drawer.html +2 -0
  341. package/examples/components/reference/parent/components/editable-grid-cells.html +2 -0
  342. package/examples/components/reference/parent/components/filter-builder.html +2 -0
  343. package/examples/components/reference/parent/components/form-error-summary.html +2 -0
  344. package/examples/components/reference/parent/components/inline-edit.html +2 -0
  345. package/examples/components/reference/parent/components/kanban-board.html +84 -0
  346. package/examples/components/reference/parent/components/modal.html +2 -0
  347. package/examples/components/reference/parent/components/multi-select-picker.html +5 -0
  348. package/examples/components/reference/parent/components/pagination.html +2 -0
  349. package/examples/components/reference/parent/components/persistent-action-banner.html +4 -0
  350. package/examples/components/reference/parent/components/popconfirm.html +5 -0
  351. package/examples/components/reference/parent/components/popover-menu.html +2 -0
  352. package/examples/components/reference/parent/components/rich-text-toolbar.html +2 -0
  353. package/examples/components/reference/parent/components/save-status-indicator.html +2 -0
  354. package/examples/components/reference/parent/components/selectable-cards.html +2 -0
  355. package/examples/components/reference/parent/components/settings-rows.html +2 -0
  356. package/examples/components/reference/parent/components/sidebar-nav.html +4 -0
  357. package/examples/components/reference/parent/components/small-charts.html +2 -0
  358. package/examples/components/reference/parent/components/split-button.html +5 -0
  359. package/examples/components/reference/parent/components/split-panes.html +8 -0
  360. package/examples/components/reference/parent/components/stat-tiles.html +2 -0
  361. package/examples/components/reference/parent/components/toast-stack.html +5 -0
  362. package/examples/components/reference/parent/components/tree-view.html +4 -0
  363. package/examples/components/reference/parent/components/upload-dropzone.html +6 -0
  364. package/examples/components/reference/parent/components/wizard-shell.html +2 -0
  365. package/examples/components/reference/parent/coverage.json +414 -0
  366. package/examples/components/reference/parent/index.html +1 -0
  367. package/examples/components/reference/parent/kanban.css +114 -0
  368. package/examples/components/reference/parent/kanban.py +55 -0
  369. package/examples/components/reference/parent/refinement.css +53 -0
  370. package/examples/components/reference/selected/build.py +70 -0
  371. package/examples/components/reference/selected/components/activity-feed.html +3 -0
  372. package/examples/components/reference/selected/components/app-toolbar.html +3 -0
  373. package/examples/components/reference/selected/components/avatar-group.html +4 -0
  374. package/examples/components/reference/selected/components/breadcrumbs.html +3 -0
  375. package/examples/components/reference/selected/components/code-block.html +9 -0
  376. package/examples/components/reference/selected/components/column-manager.html +3 -0
  377. package/examples/components/reference/selected/components/combobox.html +6 -0
  378. package/examples/components/reference/selected/components/context-hypercms.html +3 -0
  379. package/examples/components/reference/selected/components/context-quickcrop.html +4 -0
  380. package/examples/components/reference/selected/components/diff-view.html +13 -0
  381. package/examples/components/reference/selected/components/drawer.html +3 -0
  382. package/examples/components/reference/selected/components/editable-grid-cells.html +3 -0
  383. package/examples/components/reference/selected/components/filter-builder.html +3 -0
  384. package/examples/components/reference/selected/components/form-error-summary.html +4 -0
  385. package/examples/components/reference/selected/components/inline-edit.html +3 -0
  386. package/examples/components/reference/selected/components/kanban-board.html +53 -0
  387. package/examples/components/reference/selected/components/modal.html +2 -0
  388. package/examples/components/reference/selected/components/multi-select-picker.html +5 -0
  389. package/examples/components/reference/selected/components/pagination.html +3 -0
  390. package/examples/components/reference/selected/components/persistent-action-banner.html +4 -0
  391. package/examples/components/reference/selected/components/popconfirm.html +5 -0
  392. package/examples/components/reference/selected/components/popover-menu.html +3 -0
  393. package/examples/components/reference/selected/components/rich-text-toolbar.html +3 -0
  394. package/examples/components/reference/selected/components/save-status-indicator.html +2 -0
  395. package/examples/components/reference/selected/components/selectable-cards.html +3 -0
  396. package/examples/components/reference/selected/components/settings-rows.html +3 -0
  397. package/examples/components/reference/selected/components/sidebar-nav.html +4 -0
  398. package/examples/components/reference/selected/components/small-charts.html +5 -0
  399. package/examples/components/reference/selected/components/split-button.html +4 -0
  400. package/examples/components/reference/selected/components/split-panes.html +8 -0
  401. package/examples/components/reference/selected/components/stat-tiles.html +3 -0
  402. package/examples/components/reference/selected/components/toast-stack.html +5 -0
  403. package/examples/components/reference/selected/components/tree-view.html +4 -0
  404. package/examples/components/reference/selected/components/upload-dropzone.html +6 -0
  405. package/examples/components/reference/selected/components/wizard-shell.html +3 -0
  406. package/examples/components/reference/selected/corrections.css +11 -0
  407. package/examples/components/reference/selected/coverage.json +413 -0
  408. package/examples/components/reference/selected/gallery-build.mjs +49 -0
  409. package/examples/components/reference/selected/gallery-spec.json +12 -0
  410. package/examples/components/reference/selected/index.html +1 -0
  411. package/examples/components/reference/selected/kanban-comparison.json +6 -0
  412. package/examples/components/reference/selected/manifest.json +476 -0
  413. package/examples/components/reference/sha256.json +142 -0
  414. package/examples/components/reference/sources/diagonal-close.svg +1 -0
  415. package/examples/components/reference/sources/hyperclay/public-assets/css/hyperclay-app-source.css +614 -0
  416. package/examples/components/reference/sources/hyperclay/public-assets/js/app.js +94 -0
  417. package/examples/components/reference/sources/hyperclayjs/src/ui/theModal.js +897 -0
  418. package/examples/components/reference/sources/hypercms/scripts/build-theme.js +203 -0
  419. package/examples/components/reference/sources/hypercms/src/anchor.js +24 -0
  420. package/examples/components/reference/sources/hypercms/src/apply-loop.js +167 -0
  421. package/examples/components/reference/sources/hypercms/src/diagnostics.js +44 -0
  422. package/examples/components/reference/sources/hypercms/src/enhance.js +173 -0
  423. package/examples/components/reference/sources/hypercms/src/events.js +955 -0
  424. package/examples/components/reference/sources/hypercms/src/form-builder.js +518 -0
  425. package/examples/components/reference/sources/hypercms/src/form-rules.js +208 -0
  426. package/examples/components/reference/sources/hypercms/src/hooks.js +100 -0
  427. package/examples/components/reference/sources/hypercms/src/hypercms-bundle.js +10 -0
  428. package/examples/components/reference/sources/hypercms/src/hypercms.js +347 -0
  429. package/examples/components/reference/sources/hypercms/src/morph.js +10 -0
  430. package/examples/components/reference/sources/hypercms/src/path.js +61 -0
  431. package/examples/components/reference/sources/hypercms/src/place.js +131 -0
  432. package/examples/components/reference/sources/hypercms/src/platform.js +131 -0
  433. package/examples/components/reference/sources/hypercms/src/refresh.js +87 -0
  434. package/examples/components/reference/sources/hypercms/src/richclay-bridge.js +140 -0
  435. package/examples/components/reference/sources/hypercms/src/row-identity.js +111 -0
  436. package/examples/components/reference/sources/hypercms/src/scaffold.js +10 -0
  437. package/examples/components/reference/sources/hypercms/src/session.js +303 -0
  438. package/examples/components/reference/sources/hypercms/src/shell.js +248 -0
  439. package/examples/components/reference/sources/hypercms/src/styles.css +298 -0
  440. package/examples/components/reference/sources/hypercms/src/targets.js +144 -0
  441. package/examples/components/reference/sources/hypercms/src/templates.js +656 -0
  442. package/examples/components/reference/sources/hypercms/src/theme/pixel-quiet.overrides.css +761 -0
  443. package/examples/components/reference/sources/hypercms/src/theme.generated.css +1772 -0
  444. package/examples/components/reference/sources/hypercms/src/toggle.js +666 -0
  445. package/examples/components/reference/sources/hypercms/src/unresolved.js +211 -0
  446. package/examples/components/reference/sources/hypercms/src/vendor/mirk.vendor.js +212 -0
  447. package/examples/components/reference/sources/hypercms/src/views/inline-layer.js +421 -0
  448. package/examples/components/reference/sources/hypercms/src/views/inline.js +1072 -0
  449. package/examples/components/reference/sources/hypercms/src/views/sidebar.js +97 -0
  450. package/examples/components/reference/sources/modal-reference.html +301 -0
  451. package/examples/components/reference/sources/quickcrop/quickcrop.css +124 -0
  452. package/examples/components/reference/sources/quickcrop/quickcrop.js +400 -0
  453. package/examples/components/reference/sources/richclay/richclay.css +416 -0
  454. package/examples/components/reference/sources/richclay/richclay.js +2962 -0
  455. package/examples/components/reference/sources/richclay/src/a11y.js +67 -0
  456. package/examples/components/reference/sources/richclay/src/browser-global.js +7 -0
  457. package/examples/components/reference/sources/richclay/src/buttons.js +254 -0
  458. package/examples/components/reference/sources/richclay/src/hyperclay.js +470 -0
  459. package/examples/components/reference/sources/richclay/src/normalize.js +380 -0
  460. package/examples/components/reference/sources/richclay/src/richclay.js +1356 -0
  461. package/examples/components/reference/sources/richclay/src/sanitize.js +189 -0
  462. package/examples/components/reference/sources/richclay/src/styles.js +23 -0
  463. package/examples/components/reference/sources/richclay/src/toolbar-float.js +175 -0
  464. package/examples/components/reference/sources/richclay/src/toolbar.js +394 -0
  465. package/examples/components/reference/sources/richclay/src/vendor-bundle.js +15 -0
  466. package/examples/components/reference/sources/richclay/vendor/DOMPURIFY-LICENSE +202 -0
  467. package/examples/components/reference/sources/richclay/vendor/DOMPURIFY-LICENSE-MPL +373 -0
  468. package/examples/components/reference/sources/richclay/vendor/SQUIRE-LICENSE +21 -0
  469. package/examples/components/reference/sources/richclay/vendor/purify.es.mjs +2249 -0
  470. package/examples/components/reference/sources/richclay/vendor/purify.min.js +3 -0
  471. package/examples/components/reference/sources/richclay/vendor/squire.js +22 -0
  472. package/examples/components/reference/sources/richclay/vendor/squire.mjs +22 -0
  473. package/examples/components/reference/sources/richclay/vendor/squire.provenance.json +19 -0
  474. package/examples/components/rich-text-toolbar.html +43 -0
  475. package/examples/components/save-status-indicator.html +11 -0
  476. package/examples/components/selectable-cards.html +9 -0
  477. package/examples/components/settings-rows.html +10 -0
  478. package/examples/components/sidebar-nav.html +9 -0
  479. package/examples/components/small-charts.html +21 -0
  480. package/examples/components/split-button.html +13 -0
  481. package/examples/components/split-panes-editor.html +6 -0
  482. package/examples/components/split-panes.html +9 -0
  483. package/examples/components/stat-tiles.html +23 -0
  484. package/examples/components/toast-stack.html +21 -0
  485. package/examples/components/tree-view.html +9 -0
  486. package/examples/components/upload-dropzone.html +88 -0
  487. package/examples/components/wizard-shell.html +50 -0
  488. package/examples/datastar/index.html +38 -0
  489. package/examples/datastar/server.mjs +31 -0
  490. package/examples/fixtures/field-guide.pdf +14 -0
  491. package/examples/fixtures/workspace.jpg +0 -0
  492. package/examples/setup-peers.mjs +35 -0
  493. package/fonts/LICENSE-ibm-plex-mono.txt +93 -0
  494. package/fonts/LICENSE-ibm-plex-sans.txt +93 -0
  495. package/fonts/LICENSE-newsreader.txt +93 -0
  496. package/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
  497. package/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
  498. package/fonts/ibm-plex-mono-latin-600-normal.woff2 +0 -0
  499. package/fonts/ibm-plex-sans-latin-400-italic.woff2 +0 -0
  500. package/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
  501. package/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
  502. package/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
  503. package/fonts/newsreader-latin-opsz-italic.woff2 +0 -0
  504. package/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
  505. package/icons/LICENSE +21 -0
  506. package/icons/house.json +71 -0
  507. package/icons/icons.d.ts +17 -0
  508. package/icons/icons.js +648 -0
  509. package/icons/icons.svg +126 -0
  510. package/icons/marks/build-tray.source.mjs +45 -0
  511. package/icons/marks/hyperclay-local.svg +11 -0
  512. package/icons/phosphor.json +53 -0
  513. package/icons/round.json +8 -0
  514. package/integrations/datastar.js +202 -0
  515. package/integrations/quickcrop.css +26 -0
  516. package/integrations/quickcrop.js +56 -0
  517. package/integrations/richclay.css +100 -0
  518. package/integrations/richclay.js +131 -0
  519. package/package.json +630 -0
  520. package/react/README.md +244 -0
  521. package/src/README.md +83 -0
  522. package/vendor/datastar/datastar-1.0.3.js +10 -0
  523. package/vendor/datastar/provenance.json +6 -0
  524. package/vendor/floating-ui/LICENSE-core +20 -0
  525. package/vendor/floating-ui/LICENSE-dom +20 -0
  526. package/vendor/floating-ui/floating-ui.core.umd.min.js +1 -0
  527. package/vendor/floating-ui/floating-ui.dom.umd.min.js +1 -0
  528. package/vendor/floating-ui/provenance.json +17 -0
  529. package/vendor/richclay/LICENSE +16 -0
  530. package/vendor/richclay/THIRD-PARTY-NOTICES.md +45 -0
  531. package/vendor/richclay/provenance.json +17 -0
  532. package/vendor/richclay/richclay.css +404 -0
  533. package/vendor/richclay/richclay.js +2940 -0
  534. package/vendor/richclay/vendor/DOMPURIFY-LICENSE +202 -0
  535. package/vendor/richclay/vendor/DOMPURIFY-LICENSE-MPL +373 -0
  536. package/vendor/richclay/vendor/SQUIRE-LICENSE +21 -0
  537. package/vendor/richclay/vendor/purify.min.js +3 -0
  538. package/vendor/richclay/vendor/squire.js +22 -0
  539. package/vendor/richclay/vendor/squire.provenance.json +30 -0
@@ -0,0 +1,421 @@
1
+ // The visible layer of the inline view: one handle per non-text target, one
2
+ // ↑ ↓ ✕ strip per list row and one Add per list, drawn over the page and kept in
3
+ // step with it.
4
+ //
5
+ // Two mechanisms, kept deliberately separate, because merging them was the first
6
+ // draft's mistake (plan §3.1.2 and §3.5). An IntersectionObserver answers "is
7
+ // this anchor showing", and it accounts for an overflow:hidden ancestor clipping
8
+ // an anchor that is still inside the viewport, which no viewport comparison can
9
+ // see. It does NOT fire when a visible element merely moves, so it can never
10
+ // drive placement. Placement is a separate frame-coalesced pass driven by scroll
11
+ // and resize.
12
+ //
13
+ // The list controls live here rather than in a layer of their own so they are
14
+ // placed by that same pass and hidden by that same observer. They carry no
15
+ // knowledge of the form: a click reports which list and which row it belongs to
16
+ // and the view does the rest, because acting on a page row from here would move
17
+ // the page outside the rollback snapshot (inline.js listAction).
18
+
19
+ import { placeHandle } from '../place.js'
20
+ import { isAnchorable } from '../anchor.js'
21
+
22
+ // The strip, in the order it reads. Spelled out as data because the first/last
23
+ // rule below is about which of these three a row gets, and a rule is easier to
24
+ // see against a list than against three blocks of markup.
25
+ const ROW_ACTIONS = [
26
+ ['move-up', '↑', 'Move up'],
27
+ ['move-down', '↓', 'Move down'],
28
+ ['remove', '✕', 'Remove'],
29
+ ]
30
+
31
+ // A list control is pinned INSIDE its anchor's top-right corner. 'corner'
32
+ // because place.js's adaptive rule measures the anchor against the control and
33
+ // sends a small one BESIDE it, which is right for a handle floating near a link
34
+ // and wrong for a strip that belongs to a row: measured in Chrome, every card
35
+ // row shorter than ~47px put its strip wholly outside the card. inset 0 because
36
+ // a handle straddles its corner on purpose and a strip must not — §3.3 asks for
37
+ // a strip pinned to the card's top-right, inside it.
38
+ const CONTROL_PLACEMENT = { prefer: 'corner', inset: 0 }
39
+
40
+ // Can this row carry its own strip? Measured against the row's real box, never
41
+ // guessed from its tag. Three buttons are ~84px wide at minimum and a run of
42
+ // pills has a ~60px pitch, so a strip drawn on every such row would cover its
43
+ // neighbours wherever it was put — geometry, not a placement bug.
44
+ function hosts(row, strip) {
45
+ return strip.width <= row.width && strip.height <= row.height
46
+ }
47
+
48
+ export function createInlineLayer({ doc, layerEl, onActivate, onListAction }) {
49
+ const win = doc.defaultView
50
+ // Every positioned thing the layer draws, whatever kind: a handle, a row
51
+ // strip, a list's Add. One array, because all three are placed by one pass.
52
+ let placements = []
53
+ // Anchor element -> the placements riding on it. One element can carry two:
54
+ // in a scalar array of images, every row is also a handle target.
55
+ let index = new Map()
56
+ // The count is the number of HANDLES, which is what the session bar reports as
57
+ // editable areas. A strip is not an area of its own; it operates on one.
58
+ let handleCount = 0
59
+ // Every resolved target, keyed by the page element it sits on — not just the
60
+ // ones that got a handle. The highlight and the page-level click have to
61
+ // reach a text or a native target too, and neither of those has an entry.
62
+ let targets = new Map()
63
+ let observer = null
64
+ let frame = 0
65
+ let listening = false
66
+ let follower = null
67
+ let highlighted = null
68
+ // The rows showing a strip they are too small to host: the one under the
69
+ // pointer, and the one holding focus. Two slots rather than one so a strip
70
+ // does not vanish from under the keyboard while the pointer rests elsewhere;
71
+ // only ever ONE is drawn (hover wins), so two strips can never collide.
72
+ let hoveredRow = null
73
+ let focusedRow = null
74
+ // Row element AND its strip node, both mapped to the row. The strip is drawn
75
+ // over the row it belongs to, so pointing at the strip has to read as
76
+ // pointing at the row or it would hide under the pointer that came for it.
77
+ let rowOwners = new Map()
78
+ // A toggle, not a mode: the strips and the Adds go away and the handles stay,
79
+ // so someone reading a page they are editing can see it without leaving the
80
+ // session. Layer state rather than per-placement state, so it survives the
81
+ // rebuild every refresh does.
82
+ let controlsHidden = false
83
+
84
+ // ONE reusable outline, moved to whatever is hovered. Marking each target
85
+ // with an attribute instead would write editor state into an authored
86
+ // element, which is the class of problem richclay-bridge.js exists to undo.
87
+ const highlight = doc.createElement('div')
88
+ highlight.className = 'hcms-inline-highlight'
89
+ highlight.hidden = true
90
+ highlight.setAttribute('aria-hidden', 'true')
91
+ layerEl.appendChild(highlight)
92
+
93
+ function schedule() {
94
+ if (frame || !win) return
95
+ // The same degradation toggle.js applies in scheduleSurface: a window with
96
+ // no requestAnimationFrame gets a synchronous pass instead of a crash on
97
+ // mount. Every browser has it; a non-visual jsdom does not.
98
+ if (typeof win.requestAnimationFrame !== 'function') return placeAll()
99
+ frame = win.requestAnimationFrame(() => {
100
+ frame = 0
101
+ placeAll()
102
+ })
103
+ }
104
+
105
+ const revealedRow = () => hoveredRow || focusedRow
106
+
107
+ function placeAll() {
108
+ if (!win) return
109
+ const viewport = { width: win.innerWidth, height: win.innerHeight }
110
+ const revealed = revealedRow()
111
+ for (const spot of placements) {
112
+ if (!spot.visible || (spot.control && controlsHidden)) {
113
+ spot.node.hidden = true
114
+ continue
115
+ }
116
+ // hidden must come off BEFORE measuring: a hidden node has a zero rect.
117
+ spot.node.hidden = false
118
+ const anchor = spot.el.getBoundingClientRect()
119
+ const handle = spot.node.getBoundingClientRect()
120
+ // A row too small to hold its strip shows it only while that row is the
121
+ // one being pointed at or typed in. This deviates from §3.3's "always
122
+ // visible", and only for rows that cannot physically hold the control.
123
+ if (spot.kind === 'row' && spot.el !== revealed && !hosts(anchor, handle)) {
124
+ spot.node.hidden = true
125
+ continue
126
+ }
127
+ const prefer = spot.kind === 'handle' ? null : CONTROL_PLACEMENT
128
+ const { x, y } = placeHandle({ anchor, handle, viewport, ...prefer })
129
+ spot.node.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`
130
+ }
131
+ placeHighlight()
132
+ follower?.()
133
+ }
134
+
135
+ // The row `el` belongs to, walking up from it: one Map lookup per ancestor,
136
+ // the same shape elementToTarget uses for targets.
137
+ function rowAt(el) {
138
+ for (let node = el; node && node.nodeType === 1; node = node.parentElement) {
139
+ const row = rowOwners.get(node)
140
+ if (row) return row
141
+ }
142
+ return null
143
+ }
144
+
145
+ function onFocusIn(event) {
146
+ const before = revealedRow()
147
+ focusedRow = rowAt(event.target)
148
+ // Focus landing on a strip's own button is the keyboard taking over, so the
149
+ // pointer's row must not out-vote it: otherwise tabbing to ↑ would hide the
150
+ // strip the focus is standing on.
151
+ if (focusedRow && layerEl.contains(event.target)) hoveredRow = null
152
+ if (revealedRow() !== before) schedule()
153
+ }
154
+
155
+ function onFocusOut(event) {
156
+ // The one case focusin cannot answer: focus left for nothing at all, so no
157
+ // later focusin arrives to say which row it is in now.
158
+ if (event.relatedTarget || !focusedRow) return
159
+ const before = revealedRow()
160
+ focusedRow = null
161
+ if (revealedRow() !== before) schedule()
162
+ }
163
+
164
+ // The highlight carries an explicit width/height, so it never measures itself
165
+ // and the hidden-before-measuring trap the handles have does not apply.
166
+ function placeHighlight() {
167
+ if (!highlighted || highlight.hidden) return
168
+ const rect = highlighted.getBoundingClientRect()
169
+ highlight.style.width = `${Math.round(rect.width)}px`
170
+ highlight.style.height = `${Math.round(rect.height)}px`
171
+ highlight.style.transform = `translate(${Math.round(rect.left)}px, ${Math.round(rect.top)}px)`
172
+ }
173
+
174
+ function observe() {
175
+ if (!win || typeof win.IntersectionObserver !== 'function') {
176
+ // Degraded, not broken: treat everything as visible and let the placement
177
+ // pass and place.js's viewport clamp do what they can.
178
+ for (const spot of placements) spot.visible = true
179
+ return
180
+ }
181
+ observer = new win.IntersectionObserver((records) => {
182
+ let changed = false
183
+ for (const record of records) {
184
+ for (const spot of index.get(record.target) || []) {
185
+ if (spot.visible !== record.isIntersecting) {
186
+ spot.visible = record.isIntersecting
187
+ changed = true
188
+ }
189
+ }
190
+ }
191
+ if (changed) schedule()
192
+ }, { threshold: 0 })
193
+ for (const el of index.keys()) observer.observe(el)
194
+ }
195
+
196
+ function listen() {
197
+ if (listening || !win) return
198
+ // capture, so a scroll inside an overflow container reaches us too. A
199
+ // handle over a target inside a scrolling panel has to track that panel,
200
+ // and a scroll event on it does not bubble to the window.
201
+ win.addEventListener('scroll', schedule, { passive: true, capture: true })
202
+ win.addEventListener('resize', schedule, { passive: true })
203
+ // focusin/focusout, not focus/blur: only these two bubble, and the strip's
204
+ // buttons and the page rows are in different subtrees.
205
+ doc.addEventListener('focusin', onFocusIn)
206
+ doc.addEventListener('focusout', onFocusOut)
207
+ listening = true
208
+ }
209
+
210
+ function unlisten() {
211
+ if (!listening || !win) return
212
+ win.removeEventListener('scroll', schedule, { capture: true })
213
+ win.removeEventListener('resize', schedule)
214
+ doc.removeEventListener('focusin', onFocusIn)
215
+ doc.removeEventListener('focusout', onFocusOut)
216
+ listening = false
217
+ }
218
+
219
+ // `kind` is 'handle', 'row' or 'add': it decides how the node is placed, and
220
+ // everything but a handle is a list control that Hide controls takes away.
221
+ function addPlacement(el, node, kind) {
222
+ const spot = { el, node, kind, control: kind !== 'handle', visible: false }
223
+ placements.push(spot)
224
+ const riders = index.get(el)
225
+ if (riders) riders.push(spot)
226
+ else index.set(el, [spot])
227
+ layerEl.appendChild(node)
228
+ return spot
229
+ }
230
+
231
+ function makeHandle(target) {
232
+ const path = target.path.join('.')
233
+ const button = doc.createElement('button')
234
+ button.type = 'button'
235
+ button.className = 'hcms-inline-handle mirk-button mirk-button--small'
236
+ button.setAttribute('data-hcms-target', path)
237
+ // The icon kind is carried as data rather than as a different glyph: one
238
+ // mark reads as one affordance, and CSS can differentiate later without
239
+ // changing the markup.
240
+ if (target.icon) button.setAttribute('data-hcms-icon', target.icon)
241
+ button.setAttribute('aria-label', `Edit ${path}`)
242
+ button.innerHTML = '<span class="mirk-button__label">✎</span>'
243
+ button.addEventListener('click', (event) => {
244
+ event.preventDefault()
245
+ event.stopPropagation()
246
+ onActivate?.(target, button)
247
+ })
248
+ return button
249
+ }
250
+
251
+ function makeListButton(action, glyph, label) {
252
+ const button = doc.createElement('button')
253
+ button.type = 'button'
254
+ button.className = 'hcms-inline-list-button mirk-button mirk-button--small'
255
+ button.setAttribute('data-hcms-list-action', action)
256
+ button.setAttribute('aria-label', label)
257
+ button.innerHTML = `<span class="mirk-button__label">${glyph}</span>`
258
+ return button
259
+ }
260
+
261
+ // One row's strip. The index is stamped here because the first-row and
262
+ // last-row visibility rules below need the position the layer was built with.
263
+ // The action deliberately does NOT trust it: listAction re-resolves the row
264
+ // from the element it is handed, because a refresh trails a structural change
265
+ // by an observer batch, and a second click inside that window would otherwise
266
+ // act on whatever had taken this row's number.
267
+ function makeRowControls(list, row, rowIndex, count) {
268
+ const path = list.path.join('.')
269
+ const strip = doc.createElement('div')
270
+ strip.className = 'hcms-inline-row-controls'
271
+ strip.setAttribute('data-hcms-list', path)
272
+ strip.setAttribute('data-hcms-row', String(rowIndex))
273
+ for (const [action, glyph, label] of ROW_ACTIONS) {
274
+ const button = makeListButton(action, glyph, `${label} ${path}.${rowIndex}`)
275
+ // The same rule updateArrayButtonsVisibility applies to the sidebar's own
276
+ // buttons (events.js:855), rather than a second rule that could disagree
277
+ // with it: the first row cannot move up, the last cannot move down.
278
+ if (action === 'move-up' && rowIndex === 0) button.hidden = true
279
+ if (action === 'move-down' && rowIndex === count - 1) button.hidden = true
280
+ button.addEventListener('click', (event) => {
281
+ event.preventDefault()
282
+ event.stopPropagation()
283
+ onListAction?.({ action, list, index: rowIndex, row })
284
+ })
285
+ strip.appendChild(button)
286
+ }
287
+ return strip
288
+ }
289
+
290
+ function makeAdd(list) {
291
+ const path = list.path.join('.')
292
+ const button = makeListButton('add', '+ Add', `Add to ${path || 'the list'}`)
293
+ button.classList.add('hcms-inline-list-add')
294
+ button.setAttribute('data-hcms-list', path)
295
+ button.addEventListener('click', (event) => {
296
+ event.preventDefault()
297
+ event.stopPropagation()
298
+ onListAction?.({ action: 'add', list, index: list.items.length })
299
+ })
300
+ return button
301
+ }
302
+
303
+ function addListControls(list) {
304
+ const rows = list.items || []
305
+ rows.forEach((el, i) => {
306
+ // The same floor the handles clear. A row below it cannot carry a strip
307
+ // any better than it can carry a handle, and the strip would end up at the
308
+ // viewport clamp with nothing to belong to.
309
+ if (!isAnchorable(el)) return
310
+ const strip = makeRowControls(list, el, i, rows.length)
311
+ addPlacement(el, strip, 'row')
312
+ rowOwners.set(el, el)
313
+ rowOwners.set(strip, el)
314
+ })
315
+ // Deliberately NOT gated on isAnchorable, unlike the rows above. An emptied
316
+ // list is the one most in need of an Add, and a <ul> holding nothing but its
317
+ // hidden [cms-template] seed measures zero height — the floor would take the
318
+ // Add away from exactly the list that cannot be grown any other way.
319
+ if (list.container) addPlacement(list.container, makeAdd(list), 'add')
320
+ }
321
+
322
+ function clearEntries() {
323
+ observer?.disconnect()
324
+ observer = null
325
+ for (const spot of placements) spot.node.remove()
326
+ placements = []
327
+ index = new Map()
328
+ targets = new Map()
329
+ rowOwners = new Map()
330
+ handleCount = 0
331
+ }
332
+
333
+ return {
334
+ setTargets(list, lists) {
335
+ clearEntries()
336
+ for (const target of list || []) {
337
+ // Indexed whatever its kind, because the highlight and the click reach
338
+ // every target; the handle below is the part only 'handle' gets.
339
+ targets.set(target.el, target)
340
+ // Only the 'handle' kind gets one, which is what the kind name says. A
341
+ // text target's affordance is the caret richclay puts in it, and a
342
+ // native target already carries its own control: targets.js is explicit
343
+ // that a native gets "nothing at all". A handle over a live <input>
344
+ // would cover the very control it was advertising.
345
+ if (target.kind !== 'handle') continue
346
+ if (!isAnchorable(target.el)) continue
347
+ addPlacement(target.el, makeHandle(target), 'handle')
348
+ handleCount++
349
+ }
350
+ for (const listSpec of lists || []) addListControls(listSpec)
351
+ observe()
352
+ listen()
353
+ schedule()
354
+ },
355
+ refresh: schedule,
356
+ get count() { return handleCount },
357
+
358
+ get controlsHidden() { return controlsHidden },
359
+
360
+ // Hidden immediately rather than on the next frame, so the toggle reads as
361
+ // instant; showing them again goes through the placement pass, which is what
362
+ // gives them their coordinates back.
363
+ setControlsHidden(hidden) {
364
+ controlsHidden = !!hidden
365
+ if (controlsHidden) {
366
+ for (const spot of placements) if (spot.control) spot.node.hidden = true
367
+ }
368
+ schedule()
369
+ },
370
+
371
+ // The nearest target containing `el`, walking up from it. One Map lookup
372
+ // per ancestor rather than a scan of the target list per pointer event.
373
+ elementToTarget(el) {
374
+ for (let node = el; node && node.nodeType === 1; node = node.parentElement) {
375
+ const target = targets.get(node)
376
+ if (target) return target
377
+ }
378
+ return null
379
+ },
380
+
381
+ // Where the pointer is, answered off the one pointer path the highlight
382
+ // already rides (inline.js bindPage). Takes the RAW element under the
383
+ // pointer rather than a resolved target: a strip is not a target at all,
384
+ // and reading it as "off the row" would hide it under the pointer.
385
+ setHoveredRow(el) {
386
+ const before = revealedRow()
387
+ hoveredRow = el ? rowAt(el) : null
388
+ if (revealedRow() !== before) schedule()
389
+ },
390
+
391
+ showHighlight(el) {
392
+ if (!el) return
393
+ highlighted = el
394
+ highlight.hidden = false
395
+ placeHighlight()
396
+ },
397
+
398
+ hideHighlight() {
399
+ highlighted = null
400
+ highlight.hidden = true
401
+ },
402
+
403
+ // The seam the view uses to ride the same frame-coalesced pass the handles
404
+ // do, so an open popover tracks a scroll without a second rAF loop.
405
+ setFollower(fn) {
406
+ follower = typeof fn === 'function' ? fn : null
407
+ },
408
+
409
+ destroy() {
410
+ if (frame && win) win.cancelAnimationFrame(frame)
411
+ frame = 0
412
+ follower = null
413
+ highlighted = null
414
+ hoveredRow = null
415
+ focusedRow = null
416
+ highlight.remove()
417
+ unlisten()
418
+ clearEntries()
419
+ },
420
+ }
421
+ }