@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,470 @@
1
+ import { flattenBlocks, hasBlockDescendant } from "./normalize.js";
2
+
3
+ export const RICHCLAY_SELECTOR = "[data-richclay], [richclay], [editable], [clay-editable]";
4
+
5
+ // The names that say "richclay" and nothing else. `editable` is deliberately not
6
+ // among them: it is the friendly spelling, and it is also a name other people use.
7
+ const RICHCLAY_OPT_IN = "[data-richclay], [richclay], [clay-editable]";
8
+
9
+ // Both spellings of the option-carrying attribute, in the order they are consulted.
10
+ // `clay-editable` is the escape hatch for a page whose custom element already owns
11
+ // the bare name, so it has to behave identically down to the token list: a spelling
12
+ // that mounts a different editor is worse than no escape hatch at all.
13
+ const EDITABLE_ATTRS = ["editable", "clay-editable"];
14
+
15
+ const singleLineSelector = ':is([editable~="single-line"], [clay-editable~="single-line"])';
16
+
17
+ // A custom element's tag name always contains a hyphen, and `editable` is a common
18
+ // boolean property on one: Lit reflects `@property({ type: Boolean }) editable`
19
+ // straight to this attribute, where it means whatever that component decided and
20
+ // never rich text. Mounting an editor on such an element makes its rendered output
21
+ // typeable and writes that output into the author's saved file, which is damage the
22
+ // author cannot see until they open the file. A custom element that does want
23
+ // richclay asks by name.
24
+ export function isRichClayHost(el) {
25
+ if (!el || typeof el.matches !== "function") return false;
26
+ if (!el.tagName.includes("-")) return true;
27
+ return el.matches(RICHCLAY_OPT_IN);
28
+ }
29
+ export const CHROME_SELECTOR =
30
+ "[data-richclay-toolbar], [data-richclay-menu], [data-richclay-dialog], [data-richclay-live], [data-richclay-float]";
31
+
32
+ const runtimeClasses = [
33
+ "richclay-editor",
34
+ "richclay-inline",
35
+ "richclay-active",
36
+ "richclay-empty",
37
+ "richclay-focused"
38
+ ];
39
+
40
+ const installedWindows = new WeakSet();
41
+ const armedWindows = new WeakSet();
42
+
43
+ // Both clients dispatch the same moment under different names.
44
+ const PLATFORM_READY = ["clay:ready", "hyperclay:ready"];
45
+
46
+ function platformReadyPromise(win) {
47
+ return (
48
+ [win.clay?.ready, win.hyperclay?.ready].find(
49
+ ready => ready && typeof ready.then === "function"
50
+ ) || null
51
+ );
52
+ }
53
+
54
+ function platformEditMode(win) {
55
+ if (typeof win.clay?.isEditMode === "boolean") return win.clay.isEditMode;
56
+ if (typeof win.hyperclay?.isEditMode === "boolean") return win.hyperclay.isEditMode;
57
+ return null;
58
+ }
59
+
60
+ // A bare namespace object proves nothing: every clayjs satellite creates
61
+ // window.clay for its own bookkeeping, and <div id="clay"> makes one via named
62
+ // window access. What distinguishes a real core is its lifecycle contract.
63
+ function hasPlatformLifecycle(win) {
64
+ const modules = win.hyperclayModules;
65
+ const legacyHyperclayLoader =
66
+ win.__hyperclayNoAutoExport === false &&
67
+ modules &&
68
+ typeof modules === "object" &&
69
+ typeof modules.nodeType !== "number";
70
+
71
+ return (
72
+ platformEditMode(win) !== null ||
73
+ Boolean(platformReadyPromise(win)) ||
74
+ Boolean(legacyHyperclayLoader)
75
+ );
76
+ }
77
+
78
+ // Two clients provide this API and they spell three things differently. hyperclayjs
79
+ // owns window.hyperclay; clayjs owns window.clay and renamed the save transform to
80
+ // addDocumentTransform. Reading `clay ?? hyperclay` as one namespace would resolve to
81
+ // clay and then find no beforeSave, so richclay would silently stop stripping its own
82
+ // chrome and every save would write toolbars into the author's file. Hence per
83
+ // capability rather than per namespace.
84
+ function platformDocumentTransform(win) {
85
+ return win.clay?.addDocumentTransform || win.hyperclay?.beforeSave || null;
86
+ }
87
+
88
+ // onSnapshot runs on EVERY snapshot, save and live sync alike; the document
89
+ // transform runs only on the save branch, after the sync frame has already been
90
+ // dispatched. Registering only on the latter meant every live-sync frame carried
91
+ // contenteditable, the active classes and the runtime data-richclay to every
92
+ // other browser, whose own watcher subscribes to data-richclay and mounted an
93
+ // editor on it. Prefer the snapshot hook; fall back for a client too old to have
94
+ // one.
95
+ function platformSnapshotTransform(win) {
96
+ return win.clay?.onSnapshot || win.hyperclay?.onSnapshot || null;
97
+ }
98
+
99
+ // richclay's stylesheet carries save-remove, so no rule in richclay.css reaches
100
+ // the saved file. A <pre> has `white-space: pre` and never wraps, so without
101
+ // containment one long line runs off the side of the published page. These four
102
+ // declarations are the only ones that have to outlive edit mode, so they ride the
103
+ // markup instead of the stylesheet.
104
+ const PRE_CONTAINMENT = {
105
+ boxSizing: "border-box",
106
+ minWidth: "100%",
107
+ overflow: "auto",
108
+ width: "0"
109
+ };
110
+
111
+ export function shouldUseHyperclay(options = {}, win = window) {
112
+ if (options.hyperclay === false) return false;
113
+ if (options.hyperclay === true) return true;
114
+ return Boolean(hasPlatformLifecycle(win) || hasEditmodeSignal(win));
115
+ }
116
+
117
+ export function isHyperclayEditMode(win = window) {
118
+ const fromQuery = readEditmodeParam(win);
119
+ if (fromQuery !== null) return fromQuery;
120
+
121
+ if (typeof win.__hyperclayEditMode === "boolean") {
122
+ return win.__hyperclayEditMode;
123
+ }
124
+
125
+ const fromPlatform = platformEditMode(win);
126
+ if (fromPlatform !== null) return fromPlatform;
127
+
128
+ return readEditmodeCookie(win);
129
+ }
130
+
131
+ export function shouldActivateEditor(options = {}, win = window) {
132
+ if (options.readOnly) return false;
133
+ if (!shouldUseHyperclay(options, win)) return true;
134
+ return isHyperclayEditMode(win);
135
+ }
136
+
137
+ // The editable attribute's value is a space-separated token list, like class.
138
+ // Unknown tokens are ignored for forward compatibility.
139
+ export function parseEditableOptions(element) {
140
+ const name = EDITABLE_ATTRS.find(attr => element.hasAttribute(attr));
141
+ if (!name) return null;
142
+ const tokens = new Set(
143
+ (element.getAttribute(name) || "").trim().split(/\s+/).filter(Boolean)
144
+ );
145
+ const options = {
146
+ inline: true,
147
+ singleLine: tokens.has("single-line"),
148
+ toolbarOnSelect: tokens.has("toolbar-on-select")
149
+ };
150
+ if (tokens.has("no-toolbar")) options.toolbar = false;
151
+ return options;
152
+ }
153
+
154
+ export function installHyperclayBridge(win = window) {
155
+ if (installedWindows.has(win)) return;
156
+ const register = platformSnapshotTransform(win) || platformDocumentTransform(win);
157
+ if (typeof register !== "function") {
158
+ armBridgeRetry(win);
159
+ return;
160
+ }
161
+
162
+ register(docElem => stripRichClayFromClone(docElem));
163
+ installedWindows.add(win);
164
+ }
165
+
166
+ // hyperclayjs publishes the transform from deep in its core waterfall while
167
+ // richclay arrives as one flat vendor bundle, and a flat bundle always resolves
168
+ // before a multi-level waterfall, so this first read reliably misses. Nothing
169
+ // constructs a region again afterwards, so with no retry the bridge never installs
170
+ // and every save writes richclay's chrome into the author's file. clayjs is immune
171
+ // by construction, assembling addDocumentTransform before any plugin import; the
172
+ // readiness pair is the signal hyperclayjs added for exactly this handshake.
173
+ function armBridgeRetry(win) {
174
+ if (armedWindows.has(win)) return;
175
+ const doc = win.document;
176
+ const ready = platformReadyPromise(win);
177
+ if (!doc && !ready) return;
178
+ armedWindows.add(win);
179
+
180
+ const retry = () => {
181
+ installHyperclayBridge(win);
182
+ if (installedWindows.has(win)) disarm();
183
+ };
184
+ const disarm = () => {
185
+ if (!doc) return;
186
+ PLATFORM_READY.forEach(name => doc.removeEventListener(name, retry));
187
+ };
188
+
189
+ if (doc) PLATFORM_READY.forEach(name => doc.addEventListener(name, retry));
190
+ // A loader that never settles must not surface as an unhandled rejection.
191
+ if (ready) ready.then(retry, () => {});
192
+ }
193
+
194
+ export function stripRichClayFromClone(docElem) {
195
+ docElem.querySelectorAll?.(CHROME_SELECTOR).forEach(node => node.remove());
196
+
197
+ docElem.querySelectorAll?.(RICHCLAY_SELECTOR).forEach(region => {
198
+ // richclay only cleans up after itself. A region it never took ownership of,
199
+ // because it refused the root or was never activated, is the author's markup
200
+ // and has to come through the save byte for byte. setupEditorAttributes sets
201
+ // this marker in the same breath as every other runtime attribute, so its
202
+ // absence means there is nothing here to strip and nothing here to repair.
203
+ if (region.getAttribute("data-richclay-active") !== "true") return;
204
+ removeRuntimeState(region, "save");
205
+ // The only place this has to be right. Damage happens when markup reaches the
206
+ // file, so a flatten here sits downstream of every Squire route: setHTML,
207
+ // clear formatting, the image resizer, shortcuts, paste, and whatever a future
208
+ // Squire adds. Three rounds of chasing entry points end here.
209
+ //
210
+ // It cannot destroy the author's own blocks, which is what round 3b's version
211
+ // did: a block inside a region with a <p> ancestor cannot have come from their
212
+ // file, because the parser would have ejected it before richclay ever saw it.
213
+ // And it runs on a clone, so it cannot disturb the caret or the undo stack.
214
+ if (needsFlattening(region)) {
215
+ const doc = region.ownerDocument;
216
+ const singleLine = Boolean(region.matches?.(singleLineSelector));
217
+ flattenBlocks(region, () =>
218
+ singleLine ? doc.createTextNode(" ") : doc.createElement("br")
219
+ );
220
+ // flattenBlocks only unwraps blocks, so it cannot repair <a> inside <a>. Same
221
+ // idea, one tag: keep the text, drop the nested duplicate.
222
+ region.querySelectorAll(region.localName).forEach(nested => {
223
+ while (nested.firstChild) nested.parentNode.insertBefore(nested.firstChild, nested);
224
+ nested.remove();
225
+ });
226
+ }
227
+ if (region.matches?.(singleLineSelector)) unwrapLoneSingleLineBlock(region);
228
+ region.querySelectorAll("#squire-selection-start, #squire-selection-end").forEach(node => {
229
+ node.remove();
230
+ });
231
+ region.querySelectorAll(".squire-image-resize-container").forEach(node => node.remove());
232
+ stripZeroWidthArtifacts(region);
233
+ // PRE_CONTAINMENT keeps a long line from running off the side of the published
234
+ // page, where richclay's stylesheet has been stripped by save-remove. It has to
235
+ // ride the markup for that reason. It must not ride an author's own <pre>: those
236
+ // are theirs, their CSS already handles them, and writing width: 0 into a file
237
+ // that was only opened breaks the byte-identical-on-open invariant everything
238
+ // else here defends. Only a <pre> richclay made gets contained.
239
+ const codeBlocks = (region.matches?.("pre")
240
+ ? [region, ...region.querySelectorAll("pre")]
241
+ : Array.from(region.querySelectorAll("pre"))
242
+ ).filter(pre => pre.hasAttribute("data-richclay-pre"));
243
+
244
+ codeBlocks.forEach(pre => {
245
+ Object.entries(PRE_CONTAINMENT).forEach(([property, value]) => {
246
+ if (!pre.style[property]) pre.style[property] = value;
247
+ });
248
+ pre.removeAttribute("data-richclay-pre");
249
+ });
250
+ });
251
+
252
+ // Squire leaves its selection bookmarks wherever the command was operating,
253
+ // which is not always inside a region. Sweeping the document costs one query and
254
+ // cannot leave one behind.
255
+ docElem
256
+ .querySelectorAll?.("#squire-selection-start, #squire-selection-end")
257
+ .forEach(node => node.remove());
258
+ }
259
+
260
+ // The region's nearest block ancestor is the smallest subtree whose serialization
261
+ // reproduces the ejection, for `p > span > span editable` as well as for
262
+ // `div > h2 editable`. Deliberately no BODY: a region with no block ancestor at
263
+ // all reparses correctly on its own, and scoping to BODY would serialize the
264
+ // whole page on every save.
265
+ const BLOCK_SCOPE =
266
+ "p, td, th, li, dl, dt, dd, table, blockquote, div, section, article, aside, main, header, footer, figure, figcaption";
267
+ const MEASURE_ATTR = "data-richclay-measure";
268
+
269
+ // Round trip the region through the real parser and see whether it still owns its
270
+ // own content. This cannot be wrong about the parser, because it is the parser: it
271
+ // covers the <p> rule, the whole implicitly-closes family (heading in heading, li
272
+ // in li, a in a, dt/dd, td in td, button, form), and anything a future spec adds,
273
+ // with no list to maintain and no list to get wrong for a fourth time.
274
+ //
275
+ // It also draws the line the old structural predicate could not see. A <ul> pasted
276
+ // into an <h2 editable> is stable, so it measures clean and is left alone; an <h3>
277
+ // pasted into the same region ejects, so it is flattened. The hook no longer has to
278
+ // know the difference between markup that is merely invalid and markup that is
279
+ // doomed, because it can watch which one happens.
280
+ function ejectsOnReload(region) {
281
+ const doc = region.ownerDocument;
282
+ const scope = region.closest(BLOCK_SCOPE) || region;
283
+ region.setAttribute(MEASURE_ATTR, "");
284
+ const probe = doc.createElement("div");
285
+ try {
286
+ probe.innerHTML = scope.outerHTML;
287
+ } finally {
288
+ region.removeAttribute(MEASURE_ATTR);
289
+ }
290
+ const reparsed = probe.querySelector(`[${MEASURE_ATTR}]`);
291
+ return !reparsed || reparsed.textContent !== region.textContent;
292
+ }
293
+
294
+ // A region can also lose content to an element of its own tag: the parser closes
295
+ // the outer one when the inner start tag arrives. Asking the region which tag it is
296
+ // keeps this out of list territory.
297
+ const selfNests = region => Boolean(region.querySelector(region.localName));
298
+
299
+ // hasBlockDescendant first, and not only as an optimisation: a region with no block
300
+ // in it has nothing this hook could flatten, so measuring it would be work with no
301
+ // possible outcome. Measured on an 8-paragraph region: the check is 0.02 ms and the
302
+ // reparse it skips is 0.43 ms, so an ordinary save pays almost nothing.
303
+ const needsFlattening = region =>
304
+ Boolean(region.matches?.(singleLineSelector)) ||
305
+ ((hasBlockDescendant(region) || selfNests(region)) && ejectsOnReload(region));
306
+
307
+ // Shared runtime-state removal used by both the save strip (on the cloned
308
+ // document) and destroy() (on the live element). The contenteditable marker
309
+ // records provenance: "true" means richclay added the attribute; any other
310
+ // value is the author's original non-"true" value; no marker with the
311
+ // attribute present means the author wrote contenteditable="true" themselves.
312
+ export function removeRuntimeState(region, mode) {
313
+ const origin = region.getAttribute("data-richclay-runtime-contenteditable");
314
+
315
+ if (region.hasAttribute("contenteditable")) {
316
+ if (origin === "true") {
317
+ region.removeAttribute("contenteditable");
318
+ } else if (origin) {
319
+ if (mode === "destroy") {
320
+ region.setAttribute("contenteditable", origin);
321
+ } else {
322
+ region.setAttribute("inert-contenteditable", origin);
323
+ region.removeAttribute("contenteditable");
324
+ }
325
+ } else if (mode === "save") {
326
+ region.setAttribute("inert-contenteditable", region.getAttribute("contenteditable"));
327
+ region.removeAttribute("contenteditable");
328
+ }
329
+ // destroy with no marker: the author wrote contenteditable; leave it.
330
+ }
331
+
332
+ runtimeClasses.forEach(className => region.classList.remove(className));
333
+ if (region.getAttribute("class") === "") region.removeAttribute("class");
334
+
335
+ removeRuntimeAttribute(region, "role", "data-richclay-runtime-role");
336
+ removeRuntimeAttribute(region, "aria-multiline", "data-richclay-runtime-aria-multiline");
337
+ removeRuntimeAttribute(region, "no-undo", "data-richclay-runtime-no-undo");
338
+ if (region.getAttribute("data-richclay-runtime-display") === "true") {
339
+ region.style.removeProperty("display");
340
+ if (region.getAttribute("style") === "") region.removeAttribute("style");
341
+ }
342
+ removeRuntimeDescribedBy(region);
343
+
344
+ region.removeAttribute("data-richclay-active");
345
+ region.removeAttribute("data-richclay-placeholder");
346
+ region.removeAttribute("data-richclay-pre");
347
+ region.removeAttribute("data-richclay-runtime-role");
348
+ region.removeAttribute("data-richclay-runtime-aria-multiline");
349
+ region.removeAttribute("data-richclay-runtime-no-undo");
350
+ region.removeAttribute("data-richclay-runtime-describedby");
351
+ region.removeAttribute("data-richclay-runtime-contenteditable");
352
+ region.removeAttribute("data-richclay-runtime-display");
353
+
354
+ // Only a marker richclay invented comes off; an authored data-richclay has no
355
+ // provenance attribute and survives byte for byte. Note this list is an
356
+ // explicit enumeration, not a prefix sweep, so a new runtime attribute is only
357
+ // removed if it is named here.
358
+ if (region.getAttribute("data-richclay-runtime-marker") === "true") {
359
+ region.removeAttribute("data-richclay");
360
+ }
361
+ region.removeAttribute("data-richclay-runtime-marker");
362
+ }
363
+
364
+ function stripZeroWidthArtifacts(region) {
365
+ const zwsp = String.fromCharCode(0x200b);
366
+ const stack = [region];
367
+ while (stack.length) {
368
+ const node = stack.pop();
369
+ node.childNodes.forEach(child => {
370
+ if (child.nodeType === 3) {
371
+ if (child.nodeValue.includes(zwsp)) {
372
+ child.nodeValue = child.nodeValue.split(zwsp).join("");
373
+ }
374
+ } else if (child.nodeType === 1) {
375
+ stack.push(child);
376
+ }
377
+ });
378
+ }
379
+ // Drop inline wrappers Squire left empty once the caret placeholder is gone.
380
+ region.querySelectorAll("b, i, u, s, em, strong, code, sub, sup, span").forEach(el => {
381
+ if (el.children.length === 0 && (el.textContent || "") === "" && el.attributes.length === 0) {
382
+ el.remove();
383
+ }
384
+ });
385
+ }
386
+
387
+ // Safety net for single-line regions: with the fidelity-first attach Squire
388
+ // never wraps the content, but if a lone bare <P> wrapper ever appears, the
389
+ // saved file must not contain it.
390
+ function unwrapLoneSingleLineBlock(region) {
391
+ const meaningful = Array.from(region.childNodes).filter(
392
+ node => node.nodeType !== 3 || (node.nodeValue || "").trim() !== ""
393
+ );
394
+ if (meaningful.length !== 1) return;
395
+ const block = meaningful[0];
396
+ if (block.nodeType !== 1 || block.nodeName !== "P" || block.attributes.length > 0) return;
397
+ while (block.firstChild) region.insertBefore(block.firstChild, block);
398
+ block.remove();
399
+ }
400
+
401
+ export function consumeInertContenteditable(element) {
402
+ if (!element.hasAttribute("inert-contenteditable")) return null;
403
+
404
+ let value = element.getAttribute("inert-contenteditable");
405
+ if (!["false", "plaintext-only"].includes(value)) value = "true";
406
+ element.setAttribute("contenteditable", value);
407
+ element.removeAttribute("inert-contenteditable");
408
+ if (value === "true") {
409
+ // Self-heal: a saved inert "true" is redundant with what activation
410
+ // re-adds. Mark it runtime so the next save drops it from the file
411
+ // instead of round-tripping it forever.
412
+ element.setAttribute("data-richclay-runtime-contenteditable", "true");
413
+ }
414
+ return value;
415
+ }
416
+
417
+ export function markChrome(element) {
418
+ // snapshot-remove drops it from every Hyperclay snapshot (save, live-sync, and
419
+ // dirty comparison). no-watch additionally keeps the mutation observer from
420
+ // walking this high-churn subtree at all. Both stay out of the saved file.
421
+ element.setAttribute("snapshot-remove", "");
422
+ element.setAttribute("no-watch", "");
423
+ return element;
424
+ }
425
+
426
+ function readEditmodeParam(win) {
427
+ try {
428
+ const params = new URLSearchParams(win.location?.search || "");
429
+ if (params.get("editmode") === "true") return true;
430
+ if (params.get("editmode") === "false") return false;
431
+ } catch {
432
+ return null;
433
+ }
434
+ return null;
435
+ }
436
+
437
+ function hasEditmodeSignal(win) {
438
+ return readEditmodeParam(win) !== null || typeof win.__hyperclayEditMode === "boolean";
439
+ }
440
+
441
+ function readEditmodeCookie(win) {
442
+ // Hyperclay signals an owner's edit session with the isAdminOfCurrentResource
443
+ // cookie (see hyperclayjs isAdminOfCurrentResource.js); any non-empty value
444
+ // means the logged-in owner is editing. Read it directly so richclay stays
445
+ // standalone and never imports hyperclayjs.
446
+ const cookie = win.document?.cookie || "";
447
+ const match = cookie.match(/(?:^|;\s*)isAdminOfCurrentResource=([^;]*)/);
448
+ return Boolean(match && match[1] !== "");
449
+ }
450
+
451
+ function removeRuntimeAttribute(region, attribute, marker) {
452
+ if (!region.hasAttribute(marker)) return;
453
+ region.removeAttribute(attribute);
454
+ }
455
+
456
+ function removeRuntimeDescribedBy(region) {
457
+ const id = region.getAttribute("data-richclay-runtime-describedby");
458
+ if (!id) return;
459
+
460
+ const ids = (region.getAttribute("aria-describedby") || "")
461
+ .split(/\s+/)
462
+ .filter(Boolean)
463
+ .filter(value => value !== id);
464
+
465
+ if (ids.length) {
466
+ region.setAttribute("aria-describedby", ids.join(" "));
467
+ } else {
468
+ region.removeAttribute("aria-describedby");
469
+ }
470
+ }