@bettercms-ai/kit 1.0.0 → 2.0.0-next.1

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 (619) hide show
  1. package/README.md +33 -0
  2. package/dist/adapters/dock-values.d.ts +28 -0
  3. package/dist/adapters/dock-values.js +41 -0
  4. package/dist/adapters/dock-values.js.map +1 -0
  5. package/{adapters → dist/adapters}/icons.js +2 -2
  6. package/dist/adapters/icons.js.map +1 -0
  7. package/{adapters → dist/adapters}/lossy.d.ts +94 -31
  8. package/dist/adapters/lossy.js +419 -0
  9. package/dist/adapters/lossy.js.map +1 -0
  10. package/{adapters → dist/adapters}/prod-types.d.ts +91 -26
  11. package/{adapters → dist/adapters}/prod-types.js +82 -13
  12. package/dist/adapters/prod-types.js.map +1 -0
  13. package/{adapters → dist/adapters}/schema.d.ts +40 -1
  14. package/{adapters → dist/adapters}/schema.js +1038 -204
  15. package/dist/adapters/schema.js.map +1 -0
  16. package/{adapters → dist/adapters}/values.d.ts +26 -5
  17. package/{adapters → dist/adapters}/values.js +87 -17
  18. package/dist/adapters/values.js.map +1 -0
  19. package/dist/brand/logo.js +96 -0
  20. package/dist/brand/logo.js.map +1 -0
  21. package/{context.d.ts → dist/context.d.ts} +131 -2
  22. package/{context.js → dist/context.js} +44 -2
  23. package/dist/context.js.map +1 -0
  24. package/{controls → dist/controls}/button.d.ts +19 -5
  25. package/{controls → dist/controls}/button.js +125 -54
  26. package/dist/controls/button.js.map +1 -0
  27. package/{controls → dist/controls}/c1.js +1 -1
  28. package/dist/controls/c1.js.map +1 -0
  29. package/{controls → dist/controls}/c2.js +1 -1
  30. package/dist/controls/c2.js.map +1 -0
  31. package/{controls → dist/controls}/choice.d.ts +7 -2
  32. package/{controls → dist/controls}/choice.js +71 -18
  33. package/dist/controls/choice.js.map +1 -0
  34. package/{controls → dist/controls}/code-register.js +1 -1
  35. package/dist/controls/code-register.js.map +1 -0
  36. package/{controls → dist/controls}/code.js +10 -9
  37. package/dist/controls/code.js.map +1 -0
  38. package/{controls → dist/controls}/color.js +8 -8
  39. package/dist/controls/color.js.map +1 -0
  40. package/{controls → dist/controls}/component-services.d.ts +42 -0
  41. package/dist/controls/component-services.js +7 -0
  42. package/dist/controls/component-services.js.map +1 -0
  43. package/{controls → dist/controls}/date-register.js +1 -1
  44. package/dist/controls/date-register.js.map +1 -0
  45. package/{controls → dist/controls}/date-zone.js +8 -2
  46. package/dist/controls/date-zone.js.map +1 -0
  47. package/{controls → dist/controls}/date.js +32 -24
  48. package/dist/controls/date.js.map +1 -0
  49. package/dist/controls/form-picker-register.d.ts +7 -0
  50. package/{controls → dist/controls}/form-picker-register.js +2 -6
  51. package/dist/controls/form-picker-register.js.map +1 -0
  52. package/{controls → dist/controls}/form-picker.js +11 -9
  53. package/dist/controls/form-picker.js.map +1 -0
  54. package/{controls → dist/controls}/icon-register.js +1 -1
  55. package/dist/controls/icon-register.js.map +1 -0
  56. package/{controls → dist/controls}/icon.d.ts +4 -2
  57. package/{controls → dist/controls}/icon.js +32 -27
  58. package/dist/controls/icon.js.map +1 -0
  59. package/{controls → dist/controls}/index.d.ts +1 -1
  60. package/{controls → dist/controls}/index.js +4 -3
  61. package/dist/controls/index.js.map +1 -0
  62. package/{controls → dist/controls}/json-register.js +1 -1
  63. package/dist/controls/json-register.js.map +1 -0
  64. package/{controls → dist/controls}/json.js +13 -3
  65. package/dist/controls/json.js.map +1 -0
  66. package/{controls → dist/controls}/link.js +116 -200
  67. package/dist/controls/link.js.map +1 -0
  68. package/{controls → dist/controls}/location-register.js +1 -1
  69. package/dist/controls/location-register.js.map +1 -0
  70. package/{controls → dist/controls}/location.js +59 -40
  71. package/dist/controls/location.js.map +1 -0
  72. package/{controls → dist/controls}/media-register.js +1 -1
  73. package/dist/controls/media-register.js.map +1 -0
  74. package/{controls → dist/controls}/media-services.d.ts +6 -0
  75. package/dist/controls/media-services.js +0 -0
  76. package/{controls → dist/controls}/media.d.ts +21 -4
  77. package/{controls → dist/controls}/media.js +407 -130
  78. package/dist/controls/media.js.map +1 -0
  79. package/{controls → dist/controls}/number.js +10 -9
  80. package/dist/controls/number.js.map +1 -0
  81. package/{controls → dist/controls}/reference-register.js +1 -1
  82. package/dist/controls/reference-register.js.map +1 -0
  83. package/{controls → dist/controls}/reference-services.d.ts +4 -0
  84. package/dist/controls/reference-services.js +0 -0
  85. package/{controls → dist/controls}/reference.d.ts +1 -1
  86. package/{controls → dist/controls}/reference.js +93 -77
  87. package/dist/controls/reference.js.map +1 -0
  88. package/dist/controls/rich-text/article-shell.d.ts +145 -0
  89. package/dist/controls/rich-text/article-shell.js +510 -0
  90. package/dist/controls/rich-text/article-shell.js.map +1 -0
  91. package/dist/controls/rich-text/author.d.ts +25 -0
  92. package/dist/controls/rich-text/author.js +104 -0
  93. package/dist/controls/rich-text/author.js.map +1 -0
  94. package/dist/controls/rich-text/blocks.d.ts +60 -0
  95. package/{controls → dist/controls}/rich-text/blocks.js +164 -389
  96. package/dist/controls/rich-text/blocks.js.map +1 -0
  97. package/dist/controls/rich-text/button.d.ts +23 -0
  98. package/dist/controls/rich-text/button.js +85 -0
  99. package/dist/controls/rich-text/button.js.map +1 -0
  100. package/{controls → dist/controls}/rich-text/catalog.d.ts +7 -4
  101. package/{controls → dist/controls}/rich-text/catalog.js +94 -68
  102. package/dist/controls/rich-text/catalog.js.map +1 -0
  103. package/dist/controls/rich-text/checklist.d.ts +24 -0
  104. package/dist/controls/rich-text/checklist.js +115 -0
  105. package/dist/controls/rich-text/checklist.js.map +1 -0
  106. package/{controls → dist/controls}/rich-text/codec.d.ts +9 -1
  107. package/{controls → dist/controls}/rich-text/codec.js +7 -2
  108. package/dist/controls/rich-text/codec.js.map +1 -0
  109. package/dist/controls/rich-text/columns.d.ts +41 -0
  110. package/dist/controls/rich-text/columns.js +181 -0
  111. package/dist/controls/rich-text/columns.js.map +1 -0
  112. package/{controls → dist/controls}/rich-text/component-card.d.ts +1 -1
  113. package/{controls → dist/controls}/rich-text/component-card.js +417 -99
  114. package/dist/controls/rich-text/component-card.js.map +1 -0
  115. package/dist/controls/rich-text/component-panel.d.ts +47 -0
  116. package/dist/controls/rich-text/component-panel.js +141 -0
  117. package/dist/controls/rich-text/component-panel.js.map +1 -0
  118. package/{controls → dist/controls}/rich-text/control.d.ts +1 -2
  119. package/{controls → dist/controls}/rich-text/control.js +84 -42
  120. package/dist/controls/rich-text/control.js.map +1 -0
  121. package/{controls → dist/controls}/rich-text/dom.d.ts +53 -9
  122. package/{controls → dist/controls}/rich-text/dom.js +388 -50
  123. package/dist/controls/rich-text/dom.js.map +1 -0
  124. package/{controls → dist/controls}/rich-text/editor.d.ts +7 -0
  125. package/{controls → dist/controls}/rich-text/editor.js +226 -44
  126. package/dist/controls/rich-text/editor.js.map +1 -0
  127. package/dist/controls/rich-text/embed.d.ts +28 -0
  128. package/dist/controls/rich-text/embed.js +210 -0
  129. package/dist/controls/rich-text/embed.js.map +1 -0
  130. package/{controls → dist/controls}/rich-text/floating.d.ts +6 -1
  131. package/{controls → dist/controls}/rich-text/floating.js +35 -18
  132. package/dist/controls/rich-text/floating.js.map +1 -0
  133. package/dist/controls/rich-text/footnote.d.ts +41 -0
  134. package/dist/controls/rich-text/footnote.js +185 -0
  135. package/dist/controls/rich-text/footnote.js.map +1 -0
  136. package/dist/controls/rich-text/gallery.d.ts +28 -0
  137. package/dist/controls/rich-text/gallery.js +167 -0
  138. package/dist/controls/rich-text/gallery.js.map +1 -0
  139. package/{controls → dist/controls}/rich-text/index.js +1 -1
  140. package/dist/controls/rich-text/index.js.map +1 -0
  141. package/{controls → dist/controls}/rich-text/link-form.d.ts +3 -1
  142. package/dist/controls/rich-text/link-form.js +147 -0
  143. package/dist/controls/rich-text/link-form.js.map +1 -0
  144. package/{controls → dist/controls}/rich-text/markdown.js +4 -2
  145. package/dist/controls/rich-text/markdown.js.map +1 -0
  146. package/{controls → dist/controls}/rich-text/ops.js +17 -15
  147. package/dist/controls/rich-text/ops.js.map +1 -0
  148. package/dist/controls/rich-text/plain.d.ts +17 -0
  149. package/dist/controls/rich-text/plain.js +44 -0
  150. package/dist/controls/rich-text/plain.js.map +1 -0
  151. package/dist/controls/rich-text/related.d.ts +36 -0
  152. package/dist/controls/rich-text/related.js +213 -0
  153. package/dist/controls/rich-text/related.js.map +1 -0
  154. package/dist/controls/rich-text/toc.d.ts +46 -0
  155. package/dist/controls/rich-text/toc.js +161 -0
  156. package/dist/controls/rich-text/toc.js.map +1 -0
  157. package/{controls → dist/controls}/rich-text/toolbar.d.ts +6 -2
  158. package/{controls → dist/controls}/rich-text/toolbar.js +12 -7
  159. package/dist/controls/rich-text/toolbar.js.map +1 -0
  160. package/{controls → dist/controls}/scale.js +5 -5
  161. package/dist/controls/scale.js.map +1 -0
  162. package/dist/controls/slot-register.d.ts +6 -0
  163. package/{controls → dist/controls}/slot-register.js +2 -5
  164. package/dist/controls/slot-register.js.map +1 -0
  165. package/{controls → dist/controls}/slot-services.d.ts +25 -0
  166. package/dist/controls/slot-services.js +155 -0
  167. package/dist/controls/slot-services.js.map +1 -0
  168. package/{controls → dist/controls}/slot.js +42 -24
  169. package/dist/controls/slot.js.map +1 -0
  170. package/{controls → dist/controls}/table/index.js +1 -1
  171. package/dist/controls/table/index.js.map +1 -0
  172. package/{controls → dist/controls}/table/prod.js +3 -3
  173. package/dist/controls/table/prod.js.map +1 -0
  174. package/{controls → dist/controls}/table/refs.js +13 -2
  175. package/dist/controls/table/refs.js.map +1 -0
  176. package/{controls → dist/controls}/table/stored.js +1 -1
  177. package/dist/controls/table/stored.js.map +1 -0
  178. package/{controls → dist/controls}/table/table-editor.js +51 -48
  179. package/dist/controls/table/table-editor.js.map +1 -0
  180. package/{controls → dist/controls}/table/table-link.js +3 -3
  181. package/dist/controls/table/table-link.js.map +1 -0
  182. package/{controls → dist/controls}/table/table.js +3 -3
  183. package/dist/controls/table/table.js.map +1 -0
  184. package/{controls → dist/controls}/text.d.ts +2 -2
  185. package/{controls → dist/controls}/text.js +78 -43
  186. package/dist/controls/text.js.map +1 -0
  187. package/dist/controls/unknown-value.d.ts +17 -0
  188. package/dist/controls/unknown-value.js +66 -0
  189. package/dist/controls/unknown-value.js.map +1 -0
  190. package/dist/core/core.d.ts +70 -0
  191. package/dist/core/core.js +187 -0
  192. package/dist/core/core.js.map +1 -0
  193. package/dist/core/facets.d.ts +355 -0
  194. package/dist/core/facets.js +342 -0
  195. package/dist/core/facets.js.map +1 -0
  196. package/dist/core/index.d.ts +3 -0
  197. package/dist/core/index.js +3 -0
  198. package/{engine → dist/engine}/array.js +34 -21
  199. package/dist/engine/array.js.map +1 -0
  200. package/{engine → dist/engine}/bits.js +1 -1
  201. package/dist/engine/bits.js.map +1 -0
  202. package/{engine → dist/engine}/breadcrumb.d.ts +3 -3
  203. package/{engine → dist/engine}/breadcrumb.js +12 -36
  204. package/dist/engine/breadcrumb.js.map +1 -0
  205. package/{engine → dist/engine}/expand.d.ts +2 -4
  206. package/{engine → dist/engine}/expand.js +5 -22
  207. package/dist/engine/expand.js.map +1 -0
  208. package/{engine → dist/engine}/field-list.js +1 -1
  209. package/dist/engine/field-list.js.map +1 -0
  210. package/{engine → dist/engine}/field-shell.js +249 -121
  211. package/dist/engine/field-shell.js.map +1 -0
  212. package/{engine → dist/engine}/frame.d.ts +3 -1
  213. package/{engine → dist/engine}/frame.js +16 -14
  214. package/dist/engine/frame.js.map +1 -0
  215. package/{engine → dist/engine}/group-summary.d.ts +2 -1
  216. package/{engine → dist/engine}/group-summary.js +7 -3
  217. package/dist/engine/group-summary.js.map +1 -0
  218. package/{engine → dist/engine}/grouping.d.ts +19 -5
  219. package/{engine → dist/engine}/grouping.js +193 -21
  220. package/dist/engine/grouping.js.map +1 -0
  221. package/{engine → dist/engine}/item-list.d.ts +11 -1
  222. package/{engine → dist/engine}/item-list.js +35 -13
  223. package/dist/engine/item-list.js.map +1 -0
  224. package/{engine → dist/engine}/kit-field.js +45 -10
  225. package/dist/engine/kit-field.js.map +1 -0
  226. package/{engine → dist/engine}/schema-form.d.ts +27 -2
  227. package/{engine → dist/engine}/schema-form.js +182 -40
  228. package/dist/engine/schema-form.js.map +1 -0
  229. package/{engine → dist/engine}/slot.js +5 -15
  230. package/dist/engine/slot.js.map +1 -0
  231. package/dist/index.js +58 -0
  232. package/dist/index.js.map +1 -0
  233. package/{kit.css → dist/kit.css} +19 -0
  234. package/{lib → dist/lib}/cn.js +7 -4
  235. package/dist/lib/cn.js.map +1 -0
  236. package/{lib → dist/lib}/columns.js +4 -1
  237. package/dist/lib/columns.js.map +1 -0
  238. package/{lib → dist/lib}/frames.js +2 -2
  239. package/dist/lib/frames.js.map +1 -0
  240. package/dist/lib/icon-image.d.ts +10 -0
  241. package/dist/lib/icon-image.js +8 -0
  242. package/dist/lib/icon-image.js.map +1 -0
  243. package/{lib → dist/lib}/icons.js +4 -3
  244. package/dist/lib/icons.js.map +1 -0
  245. package/dist/lib/input-modality.d.ts +11 -0
  246. package/dist/lib/input-modality.js +47 -0
  247. package/dist/lib/input-modality.js.map +1 -0
  248. package/dist/lib/key-event.d.ts +11 -0
  249. package/dist/lib/key-event.js +16 -0
  250. package/dist/lib/key-event.js.map +1 -0
  251. package/{lib → dist/lib}/path.js +4 -2
  252. package/dist/lib/path.js.map +1 -0
  253. package/{lib → dist/lib}/schema.d.ts +34 -3
  254. package/{lib → dist/lib}/schema.js +110 -13
  255. package/dist/lib/schema.js.map +1 -0
  256. package/{lib → dist/lib}/utils.js +1 -1
  257. package/dist/lib/utils.js.map +1 -0
  258. package/{lib → dist/lib}/validate.d.ts +11 -1
  259. package/{lib → dist/lib}/validate.js +85 -11
  260. package/dist/lib/validate.js.map +1 -0
  261. package/dist/library/analysis.d.ts +23 -0
  262. package/dist/library/analysis.js +160 -0
  263. package/dist/library/analysis.js.map +1 -0
  264. package/dist/library/catalog.d.ts +57 -0
  265. package/dist/library/catalog.js +307 -0
  266. package/dist/library/catalog.js.map +1 -0
  267. package/dist/library/coreNotes.d.ts +8 -0
  268. package/dist/library/coreNotes.js +111 -0
  269. package/dist/library/coreNotes.js.map +1 -0
  270. package/dist/library/coverage.d.ts +40 -0
  271. package/dist/library/coverage.js +59 -0
  272. package/dist/library/coverage.js.map +1 -0
  273. package/dist/library/entries/advanced.entries.d.ts +2 -0
  274. package/dist/library/entries/advanced.entries.js +6579 -0
  275. package/dist/library/entries/advanced.entries.js.map +1 -0
  276. package/dist/library/entries/commerce.entries.d.ts +2 -0
  277. package/dist/library/entries/commerce.entries.js +4140 -0
  278. package/dist/library/entries/commerce.entries.js.map +1 -0
  279. package/dist/library/entries/company.entries.d.ts +2 -0
  280. package/dist/library/entries/company.entries.js +2731 -0
  281. package/dist/library/entries/company.entries.js.map +1 -0
  282. package/dist/library/entries/conversion.entries.d.ts +2 -0
  283. package/dist/library/entries/conversion.entries.js +3707 -0
  284. package/dist/library/entries/conversion.entries.js.map +1 -0
  285. package/dist/library/entries/data.entries.d.ts +7 -0
  286. package/dist/library/entries/data.entries.js +4613 -0
  287. package/dist/library/entries/data.entries.js.map +1 -0
  288. package/dist/library/entries/events.entries.d.ts +2 -0
  289. package/dist/library/entries/events.entries.js +3428 -0
  290. package/dist/library/entries/events.entries.js.map +1 -0
  291. package/dist/library/entries/features.entries.d.ts +2 -0
  292. package/dist/library/entries/features.entries.js +3157 -0
  293. package/dist/library/entries/features.entries.js.map +1 -0
  294. package/dist/library/entries/heroes.entries.d.ts +2 -0
  295. package/dist/library/entries/heroes.entries.js +3401 -0
  296. package/dist/library/entries/heroes.entries.js.map +1 -0
  297. package/dist/library/entries/index.d.ts +3 -0
  298. package/dist/library/entries/index.js +35 -0
  299. package/dist/library/entries/index.js.map +1 -0
  300. package/dist/library/entries/listings.entries.d.ts +2 -0
  301. package/dist/library/entries/listings.entries.js +2976 -0
  302. package/dist/library/entries/listings.entries.js.map +1 -0
  303. package/dist/library/entries/longform.entries.d.ts +2 -0
  304. package/dist/library/entries/longform.entries.js +4227 -0
  305. package/dist/library/entries/longform.entries.js.map +1 -0
  306. package/dist/library/entries/media.entries.d.ts +2 -0
  307. package/dist/library/entries/media.entries.js +2781 -0
  308. package/dist/library/entries/media.entries.js.map +1 -0
  309. package/dist/library/entries/navigation.entries.d.ts +2 -0
  310. package/dist/library/entries/navigation.entries.js +4011 -0
  311. package/dist/library/entries/navigation.entries.js.map +1 -0
  312. package/dist/library/entries/pricing.entries.d.ts +2 -0
  313. package/dist/library/entries/pricing.entries.js +2383 -0
  314. package/dist/library/entries/pricing.entries.js.map +1 -0
  315. package/dist/library/entries/social-proof.entries.d.ts +2 -0
  316. package/dist/library/entries/social-proof.entries.js +2297 -0
  317. package/dist/library/entries/social-proof.entries.js.map +1 -0
  318. package/dist/library/examples/bento.d.ts +92 -0
  319. package/dist/library/examples/bento.js +201 -0
  320. package/dist/library/examples/bento.js.map +1 -0
  321. package/dist/library/examples/blocks.d.ts +14 -0
  322. package/dist/library/examples/blocks.js +313 -0
  323. package/dist/library/examples/blocks.js.map +1 -0
  324. package/dist/library/examples/faq.d.ts +28 -0
  325. package/dist/library/examples/faq.js +230 -0
  326. package/dist/library/examples/faq.js.map +1 -0
  327. package/dist/library/examples/hero.d.ts +43 -0
  328. package/dist/library/examples/hero.js +222 -0
  329. package/dist/library/examples/hero.js.map +1 -0
  330. package/dist/library/examples/index.d.ts +36 -0
  331. package/dist/library/examples/index.js +109 -0
  332. package/dist/library/examples/index.js.map +1 -0
  333. package/dist/library/examples/journalStory.d.ts +93 -0
  334. package/dist/library/examples/journalStory.js +338 -0
  335. package/dist/library/examples/journalStory.js.map +1 -0
  336. package/dist/library/examples/megaMenu.d.ts +134 -0
  337. package/dist/library/examples/megaMenu.js +442 -0
  338. package/dist/library/examples/megaMenu.js.map +1 -0
  339. package/dist/library/examples/pricing.d.ts +103 -0
  340. package/dist/library/examples/pricing.js +479 -0
  341. package/dist/library/examples/pricing.js.map +1 -0
  342. package/dist/library/examples/tabs.d.ts +87 -0
  343. package/dist/library/examples/tabs.js +180 -0
  344. package/dist/library/examples/tabs.js.map +1 -0
  345. package/dist/library/export.d.ts +42 -0
  346. package/dist/library/export.js +80 -0
  347. package/dist/library/export.js.map +1 -0
  348. package/dist/library/index.d.ts +13 -0
  349. package/dist/library/index.js +6 -0
  350. package/dist/library/kit-catalog.json +1511 -0
  351. package/dist/library/types.d.ts +42 -0
  352. package/dist/library/types.js +0 -0
  353. package/{schema → dist/schema}/adapters.js +1 -2
  354. package/dist/schema/adapters.js.map +1 -0
  355. package/{schema → dist/schema}/help.d.ts +2 -0
  356. package/{schema → dist/schema}/help.js +6 -4
  357. package/dist/schema/help.js.map +1 -0
  358. package/{schema → dist/schema}/scale.js +1 -1
  359. package/dist/schema/scale.js.map +1 -0
  360. package/{schema → dist/schema}/sources.js +1 -1
  361. package/dist/schema/sources.js.map +1 -0
  362. package/{schema → dist/schema}/table.js +11 -10
  363. package/dist/schema/table.js.map +1 -0
  364. package/{schema → dist/schema}/types.d.ts +36 -1
  365. package/{schema → dist/schema}/types.js +1 -1
  366. package/dist/schema/types.js.map +1 -0
  367. package/dist/styles.css +2 -0
  368. package/dist/table/table-view.d.ts +14 -0
  369. package/dist/table/table-view.js +140 -0
  370. package/dist/table/table-view.js.map +1 -0
  371. package/dist/table/table.css +73 -0
  372. package/dist/testing/corpus.d.ts +63 -0
  373. package/dist/testing/corpus.js +129 -0
  374. package/dist/testing/corpus.js.map +1 -0
  375. package/dist/testing/test-form.d.ts +11 -0
  376. package/dist/testing/test-form.js +38 -0
  377. package/dist/testing/test-form.js.map +1 -0
  378. package/dist/theme.css +345 -0
  379. package/dist/theme.d.ts +22 -0
  380. package/dist/theme.js +43 -0
  381. package/dist/theme.js.map +1 -0
  382. package/dist/tokens.css +542 -0
  383. package/dist/types.js +0 -0
  384. package/{ui → dist/ui}/action-tray.d.ts +1 -1
  385. package/{ui → dist/ui}/action-tray.js +20 -19
  386. package/dist/ui/action-tray.js.map +1 -0
  387. package/dist/ui/autocomplete.d.ts +58 -0
  388. package/dist/ui/autocomplete.js +194 -0
  389. package/dist/ui/autocomplete.js.map +1 -0
  390. package/{ui → dist/ui}/button.d.ts +3 -3
  391. package/{ui → dist/ui}/button.js +8 -11
  392. package/dist/ui/button.js.map +1 -0
  393. package/{ui → dist/ui}/choice-switch.js +1 -1
  394. package/dist/ui/choice-switch.js.map +1 -0
  395. package/{ui → dist/ui}/controls.js +51 -39
  396. package/dist/ui/controls.js.map +1 -0
  397. package/{ui → dist/ui}/display.d.ts +10 -3
  398. package/{ui → dist/ui}/display.js +57 -46
  399. package/dist/ui/display.js.map +1 -0
  400. package/{ui → dist/ui}/expanded-editor-modal.d.ts +2 -2
  401. package/{ui → dist/ui}/expanded-editor-modal.js +6 -6
  402. package/dist/ui/expanded-editor-modal.js.map +1 -0
  403. package/{ui → dist/ui}/field-context.js +1 -1
  404. package/dist/ui/field-context.js.map +1 -0
  405. package/{ui → dist/ui}/floating-panel.d.ts +1 -1
  406. package/{ui → dist/ui}/floating-panel.js +28 -12
  407. package/dist/ui/floating-panel.js.map +1 -0
  408. package/{ui → dist/ui}/index.d.ts +4 -0
  409. package/dist/ui/index.js +18 -0
  410. package/{ui → dist/ui}/input.d.ts +1 -1
  411. package/{ui → dist/ui}/input.js +9 -9
  412. package/dist/ui/input.js.map +1 -0
  413. package/{ui → dist/ui}/mode-bar.js +3 -3
  414. package/dist/ui/mode-bar.js.map +1 -0
  415. package/{ui → dist/ui}/overlay.d.ts +77 -5
  416. package/dist/ui/overlay.js +697 -0
  417. package/dist/ui/overlay.js.map +1 -0
  418. package/{ui → dist/ui}/path-crumbs.js +37 -3
  419. package/dist/ui/path-crumbs.js.map +1 -0
  420. package/{ui → dist/ui}/presence.js +2 -2
  421. package/dist/ui/presence.js.map +1 -0
  422. package/{ui → dist/ui}/select.js +89 -87
  423. package/dist/ui/select.js.map +1 -0
  424. package/{ui → dist/ui}/shortcut-hint.js +1 -1
  425. package/dist/ui/shortcut-hint.js.map +1 -0
  426. package/dist/ui/spinner.d.ts +24 -0
  427. package/dist/ui/spinner.js +42 -0
  428. package/dist/ui/spinner.js.map +1 -0
  429. package/dist/ui/split-button.d.ts +32 -0
  430. package/dist/ui/split-button.js +60 -0
  431. package/dist/ui/split-button.js.map +1 -0
  432. package/{ui → dist/ui}/surfaces.js +1 -1
  433. package/dist/ui/surfaces.js.map +1 -0
  434. package/dist/ui/tab.d.ts +38 -0
  435. package/dist/ui/tab.js +87 -0
  436. package/dist/ui/tab.js.map +1 -0
  437. package/dist/ui/toast.d.ts +20 -0
  438. package/dist/ui/toast.js +115 -0
  439. package/dist/ui/toast.js.map +1 -0
  440. package/{ui → dist/ui}/tooltip-root.d.ts +4 -3
  441. package/{ui → dist/ui}/tooltip-root.js +9 -8
  442. package/dist/ui/tooltip-root.js.map +1 -0
  443. package/{ui → dist/ui}/variants.js +1 -1
  444. package/dist/ui/variants.js.map +1 -0
  445. package/package.json +83 -23
  446. package/adapters/icons.js.map +0 -1
  447. package/adapters/lossy.js +0 -233
  448. package/adapters/lossy.js.map +0 -1
  449. package/adapters/prod-types.js.map +0 -1
  450. package/adapters/schema.js.map +0 -1
  451. package/adapters/values.js.map +0 -1
  452. package/brand/logo.js +0 -9
  453. package/brand/logo.js.map +0 -1
  454. package/context.js.map +0 -1
  455. package/controls/button.js.map +0 -1
  456. package/controls/c1.js.map +0 -1
  457. package/controls/c2.js.map +0 -1
  458. package/controls/choice.js.map +0 -1
  459. package/controls/code-register.js.map +0 -1
  460. package/controls/code.js.map +0 -1
  461. package/controls/color.js.map +0 -1
  462. package/controls/date-register.js.map +0 -1
  463. package/controls/date-zone.js.map +0 -1
  464. package/controls/date.js.map +0 -1
  465. package/controls/form-picker-register.d.ts +0 -1
  466. package/controls/form-picker-register.js.map +0 -1
  467. package/controls/form-picker.js.map +0 -1
  468. package/controls/icon-register.js.map +0 -1
  469. package/controls/icon.js.map +0 -1
  470. package/controls/index.js.map +0 -1
  471. package/controls/json-register.js.map +0 -1
  472. package/controls/json.js.map +0 -1
  473. package/controls/link.js.map +0 -1
  474. package/controls/location-register.js.map +0 -1
  475. package/controls/location.js.map +0 -1
  476. package/controls/media-register.js.map +0 -1
  477. package/controls/media.js.map +0 -1
  478. package/controls/number.js.map +0 -1
  479. package/controls/reference-register.js.map +0 -1
  480. package/controls/reference.js.map +0 -1
  481. package/controls/rich-text/blocks.d.ts +0 -28
  482. package/controls/rich-text/blocks.js.map +0 -1
  483. package/controls/rich-text/catalog.js.map +0 -1
  484. package/controls/rich-text/codec.js.map +0 -1
  485. package/controls/rich-text/component-card.js.map +0 -1
  486. package/controls/rich-text/control.js.map +0 -1
  487. package/controls/rich-text/dom.js.map +0 -1
  488. package/controls/rich-text/editor.js.map +0 -1
  489. package/controls/rich-text/floating.js.map +0 -1
  490. package/controls/rich-text/index.js.map +0 -1
  491. package/controls/rich-text/link-form.js +0 -111
  492. package/controls/rich-text/link-form.js.map +0 -1
  493. package/controls/rich-text/markdown.js.map +0 -1
  494. package/controls/rich-text/ops.js.map +0 -1
  495. package/controls/rich-text/toolbar.js.map +0 -1
  496. package/controls/scale.js.map +0 -1
  497. package/controls/slot-register.d.ts +0 -1
  498. package/controls/slot-register.js.map +0 -1
  499. package/controls/slot-services.js +0 -38
  500. package/controls/slot-services.js.map +0 -1
  501. package/controls/slot.js.map +0 -1
  502. package/controls/table/index.js.map +0 -1
  503. package/controls/table/prod.js.map +0 -1
  504. package/controls/table/refs.js.map +0 -1
  505. package/controls/table/stored.js.map +0 -1
  506. package/controls/table/table-editor.js.map +0 -1
  507. package/controls/table/table-link.js.map +0 -1
  508. package/controls/table/table.js.map +0 -1
  509. package/controls/text.js.map +0 -1
  510. package/engine/array.js.map +0 -1
  511. package/engine/bits.js.map +0 -1
  512. package/engine/breadcrumb.js.map +0 -1
  513. package/engine/expand.js.map +0 -1
  514. package/engine/field-list.js.map +0 -1
  515. package/engine/field-shell.js.map +0 -1
  516. package/engine/frame.js.map +0 -1
  517. package/engine/group-summary.js.map +0 -1
  518. package/engine/grouping.js.map +0 -1
  519. package/engine/item-list.js.map +0 -1
  520. package/engine/kit-field.js.map +0 -1
  521. package/engine/schema-form.js.map +0 -1
  522. package/engine/slot.js.map +0 -1
  523. package/index.js +0 -55
  524. package/index.js.map +0 -1
  525. package/lib/cn.js.map +0 -1
  526. package/lib/columns.js.map +0 -1
  527. package/lib/frames.js.map +0 -1
  528. package/lib/icons.js.map +0 -1
  529. package/lib/path.js.map +0 -1
  530. package/lib/schema.js.map +0 -1
  531. package/lib/utils.js.map +0 -1
  532. package/lib/validate.js.map +0 -1
  533. package/schema/adapters.js.map +0 -1
  534. package/schema/help.js.map +0 -1
  535. package/schema/scale.js.map +0 -1
  536. package/schema/sources.js.map +0 -1
  537. package/schema/table.js.map +0 -1
  538. package/schema/types.js.map +0 -1
  539. package/ui/action-tray.js.map +0 -1
  540. package/ui/button.js.map +0 -1
  541. package/ui/choice-switch.js.map +0 -1
  542. package/ui/controls.js.map +0 -1
  543. package/ui/display.js.map +0 -1
  544. package/ui/expanded-editor-modal.js.map +0 -1
  545. package/ui/field-context.js.map +0 -1
  546. package/ui/floating-panel.js.map +0 -1
  547. package/ui/index.js +0 -13
  548. package/ui/input.js.map +0 -1
  549. package/ui/mode-bar.js.map +0 -1
  550. package/ui/overlay.js +0 -378
  551. package/ui/overlay.js.map +0 -1
  552. package/ui/path-crumbs.js.map +0 -1
  553. package/ui/presence.js.map +0 -1
  554. package/ui/select.js.map +0 -1
  555. package/ui/shortcut-hint.js.map +0 -1
  556. package/ui/surfaces.js.map +0 -1
  557. package/ui/tooltip-root.js.map +0 -1
  558. package/ui/variants.js.map +0 -1
  559. /package/{_virtual → dist/_virtual}/_rolldown/runtime.js +0 -0
  560. /package/{adapters → dist/adapters}/icons.d.ts +0 -0
  561. /package/{brand → dist/brand}/logo.d.ts +0 -0
  562. /package/{controls → dist/controls}/c1.d.ts +0 -0
  563. /package/{controls → dist/controls}/c2.d.ts +0 -0
  564. /package/{controls → dist/controls}/code-register.d.ts +0 -0
  565. /package/{controls → dist/controls}/code.d.ts +0 -0
  566. /package/{controls → dist/controls}/color.d.ts +0 -0
  567. /package/{controls → dist/controls}/date-register.d.ts +0 -0
  568. /package/{controls → dist/controls}/date-zone.d.ts +0 -0
  569. /package/{controls → dist/controls}/date.d.ts +0 -0
  570. /package/{controls → dist/controls}/form-picker.d.ts +0 -0
  571. /package/{controls → dist/controls}/icon-register.d.ts +0 -0
  572. /package/{controls → dist/controls}/json-register.d.ts +0 -0
  573. /package/{controls → dist/controls}/json.d.ts +0 -0
  574. /package/{controls → dist/controls}/link.d.ts +0 -0
  575. /package/{controls → dist/controls}/location-register.d.ts +0 -0
  576. /package/{controls → dist/controls}/location.d.ts +0 -0
  577. /package/{controls → dist/controls}/media-register.d.ts +0 -0
  578. /package/{controls → dist/controls}/number.d.ts +0 -0
  579. /package/{controls → dist/controls}/reference-register.d.ts +0 -0
  580. /package/{controls → dist/controls}/rich-text/index.d.ts +0 -0
  581. /package/{controls → dist/controls}/rich-text/markdown.d.ts +0 -0
  582. /package/{controls → dist/controls}/rich-text/ops.d.ts +0 -0
  583. /package/{controls → dist/controls}/scale.d.ts +0 -0
  584. /package/{controls → dist/controls}/slot.d.ts +0 -0
  585. /package/{controls → dist/controls}/table/index.d.ts +0 -0
  586. /package/{controls → dist/controls}/table/prod.d.ts +0 -0
  587. /package/{controls → dist/controls}/table/refs.d.ts +0 -0
  588. /package/{controls → dist/controls}/table/stored.d.ts +0 -0
  589. /package/{controls → dist/controls}/table/table-editor.d.ts +0 -0
  590. /package/{controls → dist/controls}/table/table-link.d.ts +0 -0
  591. /package/{controls → dist/controls}/table/table.d.ts +0 -0
  592. /package/{engine → dist/engine}/array.d.ts +0 -0
  593. /package/{engine → dist/engine}/bits.d.ts +0 -0
  594. /package/{engine → dist/engine}/field-list.d.ts +0 -0
  595. /package/{engine → dist/engine}/field-shell.d.ts +0 -0
  596. /package/{engine → dist/engine}/kit-field.d.ts +0 -0
  597. /package/{engine → dist/engine}/slot.d.ts +0 -0
  598. /package/{index.d.ts → dist/index.d.ts} +0 -0
  599. /package/{lib → dist/lib}/cn.d.ts +0 -0
  600. /package/{lib → dist/lib}/columns.d.ts +0 -0
  601. /package/{lib → dist/lib}/frames.d.ts +0 -0
  602. /package/{lib → dist/lib}/icons.d.ts +0 -0
  603. /package/{lib → dist/lib}/path.d.ts +0 -0
  604. /package/{lib → dist/lib}/utils.d.ts +0 -0
  605. /package/{schema → dist/schema}/adapters.d.ts +0 -0
  606. /package/{schema → dist/schema}/scale.d.ts +0 -0
  607. /package/{schema → dist/schema}/sources.d.ts +0 -0
  608. /package/{schema → dist/schema}/table.d.ts +0 -0
  609. /package/{types.d.ts → dist/types.d.ts} +0 -0
  610. /package/{ui → dist/ui}/choice-switch.d.ts +0 -0
  611. /package/{ui → dist/ui}/controls.d.ts +0 -0
  612. /package/{ui → dist/ui}/field-context.d.ts +0 -0
  613. /package/{ui → dist/ui}/mode-bar.d.ts +0 -0
  614. /package/{ui → dist/ui}/path-crumbs.d.ts +0 -0
  615. /package/{ui → dist/ui}/presence.d.ts +0 -0
  616. /package/{ui → dist/ui}/select.d.ts +0 -0
  617. /package/{ui → dist/ui}/shortcut-hint.d.ts +0 -0
  618. /package/{ui → dist/ui}/surfaces.d.ts +0 -0
  619. /package/{ui → dist/ui}/variants.d.ts +0 -0
@@ -1,11 +1,11 @@
1
1
  import { Sparkle } from "../../ui/button.js";
2
2
  import { Menu, MenuContent, MenuItem, MenuTrigger } from "../../ui/overlay.js";
3
3
  import { StyleMenu, ToolButton, stylesFor } from "./toolbar.js";
4
- import { IconBold, IconCode, IconItalic, IconLink, IconMessage, IconStrikethrough, IconUnderline } from "@tabler/icons-react";
4
+ import * as React from "react";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
- import { motion } from "framer-motion";
6
+ import { IconBold, IconCode, IconItalic, IconLink, IconMessage, IconStrikethrough, IconSubscript, IconSuperscript, IconUnderline } from "@tabler/icons-react";
7
7
  import { createPortal } from "react-dom";
8
- //#region src/kit/controls/rich-text/floating.tsx
8
+ //#region src/controls/rich-text/floating.tsx
9
9
  /**
10
10
  * RICH TEXT · the selection bubble: AI rewrite, style, marks, link (V2 HEAD controls/rich-text/floating.tsx).
11
11
  * V2's inline "Ask AI" prompt took free text; the host's AI service rewrites by preset only, so it is not drawn.
@@ -33,26 +33,28 @@ function SelectionBubble({ rect, fmt, allows, saveSel, onAi, onStyle, onMark, on
33
33
  const above = rect.top - 44;
34
34
  const top = above < 8 || !!avoid && above < avoid.bottom + 4 && above + 36 > avoid.top ? rect.bottom + 8 : above;
35
35
  const styles = stylesFor(allows);
36
- return createPortal(/* @__PURE__ */ jsxs(motion.div, {
37
- initial: {
38
- opacity: 0,
39
- y: 4
40
- },
41
- animate: {
42
- opacity: 1,
43
- y: 0
44
- },
45
- transition: { duration: .14 },
36
+ const ref = React.useRef(null);
37
+ const [w, setW] = React.useState(460);
38
+ React.useLayoutEffect(() => {
39
+ if (ref.current) setW(ref.current.offsetWidth);
40
+ }, [
41
+ fmt.block,
42
+ !!onAi,
43
+ !!onComment
44
+ ]);
45
+ return createPortal(/* @__PURE__ */ jsxs("div", {
46
46
  onMouseDown: (e) => {
47
47
  if (!e.target.closest("button")) e.preventDefault();
48
48
  },
49
+ ref,
49
50
  style: {
50
51
  top,
51
- left: Math.min(window.innerWidth - 400, Math.max(8, rect.left + rect.width / 2 - 190))
52
+ boxShadow: "var(--kit-shadow-sm)",
53
+ left: Math.min(window.innerWidth - w - 8, Math.max(8, rect.left + rect.width / 2 - w / 2))
52
54
  },
53
55
  "data-floating-layer": "",
54
56
  "data-kit-scope": "",
55
- className: "pointer-events-auto fixed z-[85] flex h-9 items-center gap-0.5 rounded-kit-lg border border-kit-line bg-kit-surface px-1 text-kit-fg shadow-kit-sm [.dark_&]:border-kit-line-strong [.dark_&]:bg-[#252528]",
57
+ className: "glass-strong pointer-events-auto fixed z-[calc(var(--kit-z-popover,84)_+_1)] flex h-9 items-center gap-0.5 rounded-kit-lg border border-kit-line px-1",
56
58
  role: "toolbar",
57
59
  "aria-label": "Selection formatting",
58
60
  children: [
@@ -110,6 +112,18 @@ function SelectionBubble({ rect, fmt, allows, saveSel, onAi, onStyle, onMark, on
110
112
  active: fmt.strike,
111
113
  onClick: () => onMark("strikeThrough")
112
114
  }) : null,
115
+ allows("sup") ? /* @__PURE__ */ jsx(ToolButton, {
116
+ label: "Superscript",
117
+ icon: /* @__PURE__ */ jsx(IconSuperscript, { stroke: 1.5 }),
118
+ active: fmt.sup,
119
+ onClick: () => onMark("superscript")
120
+ }) : null,
121
+ allows("sub") ? /* @__PURE__ */ jsx(ToolButton, {
122
+ label: "Subscript",
123
+ icon: /* @__PURE__ */ jsx(IconSubscript, { stroke: 1.5 }),
124
+ active: fmt.sub,
125
+ onClick: () => onMark("subscript")
126
+ }) : null,
113
127
  allows("code") ? /* @__PURE__ */ jsx(ToolButton, {
114
128
  label: "Inline code",
115
129
  icon: /* @__PURE__ */ jsx(IconCode, { stroke: 1.5 }),
@@ -123,15 +137,18 @@ function SelectionBubble({ rect, fmt, allows, saveSel, onAi, onStyle, onMark, on
123
137
  active: fmt.onLink,
124
138
  onClick: onLink
125
139
  }) : null,
126
- onComment ? /* @__PURE__ */ jsx(ToolButton, {
140
+ onComment ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
141
+ "aria-hidden": true,
142
+ className: "mx-0.5 h-4 w-px bg-kit-line"
143
+ }), /* @__PURE__ */ jsx(ToolButton, {
127
144
  label: "Comment",
128
145
  icon: /* @__PURE__ */ jsx(IconMessage, { stroke: 1.5 }),
129
146
  onClick: onComment
130
- }) : null
147
+ })] }) : null
131
148
  ]
132
149
  }), document.body);
133
150
  }
134
151
  //#endregion
135
- export { SelectionBubble };
152
+ export { BUBBLE_AI, SelectionBubble };
136
153
 
137
154
  //# sourceMappingURL=floating.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating.js","names":[],"sources":["../../../src/controls/rich-text/floating.tsx"],"sourcesContent":["/**\n * RICH TEXT · the selection bubble: AI rewrite, style, marks, link (V2 HEAD controls/rich-text/floating.tsx).\n * V2's inline \"Ask AI\" prompt took free text; the host's AI service rewrites by preset only, so it is not drawn.\n */\nimport * as React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { IconBold, IconCode, IconItalic, IconLink, IconMessage, IconStrikethrough, IconSubscript, IconSuperscript, IconUnderline } from \"@tabler/icons-react\";\nimport { Sparkle } from \"../../ui/button\";\nimport { Menu, MenuContent, MenuItem, MenuTrigger } from \"../../ui/overlay\";\nimport type { AiPreset } from \"../../context\";\nimport type { RichTextFeature } from \"./codec\";\nimport { StyleMenu, ToolButton, stylesFor, type Fmt, type MarkCmd } from \"./toolbar\";\n\n/** The bubble's rewrite directions (V2: improve, shorter, punchier, grammar), as the host service's presets. */\nexport const BUBBLE_AI: { id: AiPreset; label: string }[] = [\n { id: \"improve\", label: \"Improve writing\" },\n { id: \"shorter\", label: \"Make shorter\" },\n { id: \"simplify\", label: \"Simplify\" },\n { id: \"grammar\", label: \"Fix spelling and grammar\" },\n];\n\nexport function SelectionBubble({\n rect,\n fmt,\n allows,\n saveSel,\n onAi,\n onStyle,\n onMark,\n onInlineCode,\n onLink,\n onComment,\n avoid,\n}: {\n rect: DOMRect;\n /** The editor's own toolbar row (when it is open): the bubble never sits on top of it. */\n avoid?: DOMRect | null;\n fmt: Fmt;\n allows: (f: RichTextFeature) => boolean;\n saveSel: () => void;\n /** Absent when the person has no AI (D58: ai.use) or the host has no AI service: the AI menu and its divider are not drawn. */\n onAi?: (preset: AiPreset) => void;\n onStyle: (tag: string) => void;\n onMark: (cmd: MarkCmd) => void;\n onInlineCode: () => void;\n onLink: () => void;\n onComment?: () => void;\n}) {\n // Above the selection by default; flips below it when above would cover the editor's toolbar or leave the viewport.\n const above = rect.top - 44;\n const blocked = above < 8 || (!!avoid && above < avoid.bottom + 4 && above + 36 > avoid.top);\n const top = blocked ? rect.bottom + 8 : above;\n const styles = stylesFor(allows);\n // centre on the selection with the bubble's real width (it grows with AI, style and comment), never past either edge\n const ref = React.useRef<HTMLDivElement>(null);\n const [w, setW] = React.useState(460);\n React.useLayoutEffect(() => {\n if (ref.current) setW(ref.current.offsetWidth);\n }, [fmt.block, !!onAi, !!onComment]);\n return createPortal(\n // No entrance motion: the bubble shows on every text selection, a 100+/day action.\n <div\n onMouseDown={(e) => {\n if (!(e.target as HTMLElement).closest(\"button\")) e.preventDefault();\n }}\n ref={ref}\n style={{ top, boxShadow: \"var(--kit-shadow-sm)\", left: Math.min(window.innerWidth - w - 8, Math.max(8, rect.left + rect.width / 2 - w / 2)) }}\n data-floating-layer=\"\"\n data-kit-scope=\"\"\n /* V2 floating.tsx:57-59: glass-strong for the raised fill and hairline; the tight shadow-sm (inline, so it beats the\n glass drop) keeps the shadow off the selected text right under the bubble */\n className=\"glass-strong pointer-events-auto fixed z-[calc(var(--kit-z-popover,84)_+_1)] flex h-9 items-center gap-0.5 rounded-kit-lg border border-kit-line px-1\"\n role=\"toolbar\"\n aria-label=\"Selection formatting\"\n >\n {onAi ? (\n <>\n <Menu>\n <MenuTrigger\n onMouseDown={(e) => {\n e.preventDefault();\n saveSel();\n }}\n className=\"flex h-7 items-center gap-1.5 rounded-kit-md px-2 text-kit-sm text-kit-fg hover:bg-kit-hover data-[popup-open]:bg-kit-hover\"\n >\n <Sparkle size={14} /> Improve writing\n </MenuTrigger>\n <MenuContent className=\"w-52\" finalFocus={false}>\n {BUBBLE_AI.map((p) => (\n <MenuItem key={p.id} icon={<Sparkle size={16} />} onClick={() => onAi(p.id)}>\n {p.label}\n </MenuItem>\n ))}\n </MenuContent>\n </Menu>\n <span aria-hidden className=\"mx-0.5 h-4 w-px bg-kit-line\" />\n </>\n ) : null}\n {fmt.block !== \"island\" && styles.length > 1 ? (\n <>\n <StyleMenu block={fmt.block} styles={styles} onPick={onStyle} />\n <span aria-hidden className=\"mx-0.5 h-4 w-px bg-kit-line\" />\n </>\n ) : null}\n {allows(\"bold\") ? <ToolButton label=\"Bold\" icon={<IconBold stroke={1.5} />} shortcut=\"⌘B\" active={fmt.bold} onClick={() => onMark(\"bold\")} /> : null}\n {allows(\"italic\") ? <ToolButton label=\"Italic\" icon={<IconItalic stroke={1.5} />} shortcut=\"⌘I\" active={fmt.italic} onClick={() => onMark(\"italic\")} /> : null}\n {allows(\"underline\") ? <ToolButton label=\"Underline\" icon={<IconUnderline stroke={1.5} />} shortcut=\"⌘U\" active={fmt.underline} onClick={() => onMark(\"underline\")} /> : null}\n {allows(\"strike\") ? <ToolButton label=\"Strikethrough\" icon={<IconStrikethrough stroke={1.5} />} active={fmt.strike} onClick={() => onMark(\"strikeThrough\")} /> : null}\n {/* x² and x₂: one at a time (picking one inside the other swaps them) */}\n {allows(\"sup\") ? <ToolButton label=\"Superscript\" icon={<IconSuperscript stroke={1.5} />} active={fmt.sup} onClick={() => onMark(\"superscript\")} /> : null}\n {allows(\"sub\") ? <ToolButton label=\"Subscript\" icon={<IconSubscript stroke={1.5} />} active={fmt.sub} onClick={() => onMark(\"subscript\")} /> : null}\n {allows(\"code\") ? <ToolButton label=\"Inline code\" icon={<IconCode stroke={1.5} />} shortcut=\"⌘E\" onClick={onInlineCode} /> : null}\n {allows(\"link\") ? <ToolButton label=\"Link\" icon={<IconLink stroke={1.5} />} shortcut=\"⌘K\" active={fmt.onLink} onClick={onLink} /> : null}\n {onComment ? (\n <>\n <span aria-hidden className=\"mx-0.5 h-4 w-px bg-kit-line\" />\n <ToolButton label=\"Comment\" icon={<IconMessage stroke={1.5} />} onClick={onComment} />\n </>\n ) : null}\n </div>,\n document.body,\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export declare const FN_MARK = "sup[data-rt=fn]";
2
+ /** The toast when a footnote cannot go where the caret is (V2 rich-text-editor.tsx:613). */
3
+ export declare const FOOTNOTE_REFUSED: {
4
+ readonly title: "Put the caret in the text first";
5
+ readonly description: "Footnotes number the story's own text, not text inside a block.";
6
+ };
7
+ /** The popover's chrome (V2 rich-text-editor.tsx:1650). */
8
+ export declare const FOOTNOTE_POPOVER_CLASS = "w-[320px] rounded-kit-lg p-3";
9
+ /** The body's own markers in text order (markers inside a rich block are not the body's). */
10
+ export declare const footnoteMarkers: (root: HTMLElement) => HTMLElement[];
11
+ /** Numbers the markers 1…n in text order; returns them with their notes, for the list. */
12
+ export declare function renumberFootnotes(root: HTMLElement): {
13
+ el: HTMLElement;
14
+ note: string;
15
+ }[];
16
+ /** A new, empty marker at the caret. Null when the caret is outside the body's text (a rich block, code, elsewhere). */
17
+ export declare function insertFootnote(root: HTMLElement): HTMLElement | null;
18
+ /** The caret right after a marker, in the body. */
19
+ export declare function caretAfterMarker(root: HTMLElement, m: HTMLElement): void;
20
+ /** "Back to the text": scroll the marker to the centre, caret after it, and flash it (1200ms). */
21
+ export declare function backToMarker(root: HTMLElement, m: HTMLElement): void;
22
+ /** The note of one footnote: one setting, edited in a popover at its marker (V2 D54 / D55). */
23
+ export declare function FootnoteEditor({ n, note, onChange, onRemove, onDone }: {
24
+ n: number;
25
+ note: string;
26
+ onChange: (v: string) => void;
27
+ onRemove: () => void;
28
+ onDone: () => void;
29
+ }): import("react/jsx-runtime").JSX.Element;
30
+ /** The notes under the body, numbered in text order, each with a way back to its marker. Renders nothing when empty. */
31
+ export declare function FootnotesList({ notes, readOnly, density, onEdit, onBack, }: {
32
+ notes: {
33
+ el: HTMLElement;
34
+ note: string;
35
+ }[];
36
+ readOnly?: boolean;
37
+ /** the editor's spacing: bare (no chrome), dense (panel), default */
38
+ density?: "bare" | "dense" | "default";
39
+ onEdit: (el: HTMLElement) => void;
40
+ onBack: (el: HTMLElement) => void;
41
+ }): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,185 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { Button } from "../../ui/button.js";
3
+ import { Tooltip } from "../../ui/overlay.js";
4
+ import { Textarea } from "../../ui/input.js";
5
+ import * as React from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { IconTrash } from "@tabler/icons-react";
8
+ //#region src/controls/rich-text/footnote.tsx
9
+ /**
10
+ * RICH TEXT · Footnotes (kit-richtext-ui-spec.md §1): V2's inline footnote, stored as the PT inline object
11
+ * `{ _type: "footnote", note }`, written in the editor as `<sup data-rt="fn" data-note contenteditable="false">N</sup>`.
12
+ * The number, the notes list and the way back are derived from the markers' text order, never stored.
13
+ *
14
+ * Editor chrome, not an island: the editor owns the clicks and the popover's anchor; this module is the V2 parts.
15
+ * insert V2 ops.ts:182-205: at the caret through the browser's insert (⌘Z takes it back), never inside a rich
16
+ * block or code; null then, and the editor toasts FOOTNOTE_REFUSED (V2 rich-text-editor.tsx:610-615)
17
+ * numbers V2 dom.ts:429-436: the body's own markers in text order, 1…n
18
+ * popover V2 FootnoteEditor (rich-text-editor.tsx:1736-1777) at the marker, w-[320px] rounded p-3
19
+ * list V2 notes section (rich-text-editor.tsx:1533-1560): each note a button that edits it, and ↩ back to it
20
+ * back V2 backToMarker (rich-text-editor.tsx:1095-1100): scroll to it, caret after it, a 1200ms accent flash
21
+ */
22
+ var FN_MARK = "sup[data-rt=fn]";
23
+ /** The toast when a footnote cannot go where the caret is (V2 rich-text-editor.tsx:613). */
24
+ var FOOTNOTE_REFUSED = {
25
+ title: "Put the caret in the text first",
26
+ description: "Footnotes number the story's own text, not text inside a block."
27
+ };
28
+ /** The popover's chrome (V2 rich-text-editor.tsx:1650). */
29
+ var FOOTNOTE_POPOVER_CLASS = "w-[320px] rounded-kit-lg p-3";
30
+ /** The body's own markers in text order (markers inside a rich block are not the body's). */
31
+ var footnoteMarkers = (root) => Array.from(root.querySelectorAll(FN_MARK)).filter((m) => !m.closest("[data-rt-island],[data-rt-isolate]"));
32
+ /** Numbers the markers 1…n in text order; returns them with their notes, for the list. */
33
+ function renumberFootnotes(root) {
34
+ return footnoteMarkers(root).map((m, i) => {
35
+ if (m.textContent !== String(i + 1)) m.textContent = String(i + 1);
36
+ return {
37
+ el: m,
38
+ note: m.getAttribute("data-note") ?? ""
39
+ };
40
+ });
41
+ }
42
+ /** A new, empty marker at the caret. Null when the caret is outside the body's text (a rich block, code, elsewhere). */
43
+ function insertFootnote(root) {
44
+ const s = window.getSelection();
45
+ if (!s || !s.rangeCount || !root.contains(s.anchorNode)) return null;
46
+ const at = s.anchorNode?.nodeType === 1 ? s.anchorNode : s.anchorNode?.parentElement;
47
+ if (!at || at.closest("[data-rt-island],[data-rt-isolate]") || at.closest("pre")) return null;
48
+ root.focus({ preventScroll: true });
49
+ if (typeof document.execCommand === "function") document.execCommand("insertHTML", false, `<sup data-rt="fn" data-note="" contenteditable="false" data-fn-new="">1</sup>​`);
50
+ let sup = root.querySelector("sup[data-fn-new]");
51
+ if (!sup) {
52
+ sup = document.createElement("sup");
53
+ sup.setAttribute("data-rt", "fn");
54
+ sup.setAttribute("data-note", "");
55
+ sup.setAttribute("contenteditable", "false");
56
+ sup.textContent = "1";
57
+ const r = s.getRangeAt(0);
58
+ r.collapse(false);
59
+ r.insertNode(sup);
60
+ const after = document.createTextNode("​");
61
+ sup.after(after);
62
+ const c = document.createRange();
63
+ c.setStart(after, after.length);
64
+ c.collapse(true);
65
+ s.removeAllRanges();
66
+ s.addRange(c);
67
+ }
68
+ sup.removeAttribute("data-fn-new");
69
+ renumberFootnotes(root);
70
+ return sup;
71
+ }
72
+ /** The caret right after a marker, in the body. */
73
+ function caretAfterMarker(root, m) {
74
+ const s = window.getSelection();
75
+ if (!s || !m.isConnected) return;
76
+ root.focus({ preventScroll: true });
77
+ const r = document.createRange();
78
+ r.setStartAfter(m);
79
+ r.collapse(true);
80
+ s.removeAllRanges();
81
+ s.addRange(r);
82
+ }
83
+ /** "Back to the text": scroll the marker to the centre, caret after it, and flash it (1200ms). */
84
+ function backToMarker(root, m) {
85
+ if (!m.isConnected) return;
86
+ m.scrollIntoView?.({
87
+ block: "center",
88
+ behavior: "smooth"
89
+ });
90
+ caretAfterMarker(root, m);
91
+ m.animate?.([{ boxShadow: "0 0 0 3px var(--kit-accent-soft)" }, { boxShadow: "0 0 0 0 transparent" }], { duration: 1200 });
92
+ }
93
+ /** The note of one footnote: one setting, edited in a popover at its marker (V2 D54 / D55). */
94
+ function FootnoteEditor({ n, note, onChange, onRemove, onDone }) {
95
+ const [v, setV] = React.useState(note);
96
+ const id = React.useId();
97
+ return /* @__PURE__ */ jsxs("form", {
98
+ className: "flex flex-col gap-2",
99
+ onSubmit: (e) => {
100
+ e.preventDefault();
101
+ onDone();
102
+ },
103
+ children: [
104
+ /* @__PURE__ */ jsxs("label", {
105
+ htmlFor: id,
106
+ className: "text-kit-xs font-medium text-kit-fg-2",
107
+ children: ["Footnote ", n]
108
+ }),
109
+ /* @__PURE__ */ jsx(Textarea, {
110
+ id,
111
+ autoFocus: true,
112
+ rows: 3,
113
+ value: v,
114
+ placeholder: "Write the note",
115
+ onChange: (e) => {
116
+ setV(e.target.value);
117
+ onChange(e.target.value);
118
+ },
119
+ onKeyDown: (e) => {
120
+ if (e.key === "Enter" && !e.shiftKey) {
121
+ e.preventDefault();
122
+ onDone();
123
+ }
124
+ }
125
+ }),
126
+ /* @__PURE__ */ jsxs("div", {
127
+ className: "flex items-center justify-between",
128
+ children: [/* @__PURE__ */ jsx(Button, {
129
+ size: "xs",
130
+ variant: "ghost",
131
+ leftIcon: /* @__PURE__ */ jsx(IconTrash, { stroke: 1.5 }),
132
+ onClick: onRemove,
133
+ className: "hover:text-kit-danger-fg",
134
+ children: "Remove"
135
+ }), /* @__PURE__ */ jsx(Button, {
136
+ size: "xs",
137
+ variant: "primary",
138
+ type: "submit",
139
+ children: "Done"
140
+ })]
141
+ })
142
+ ]
143
+ });
144
+ }
145
+ /** The notes under the body, numbered in text order, each with a way back to its marker. Renders nothing when empty. */
146
+ function FootnotesList({ notes, readOnly, density = "default", onEdit, onBack }) {
147
+ if (!notes.length) return null;
148
+ return /* @__PURE__ */ jsx("section", {
149
+ "aria-label": "Footnotes",
150
+ className: cn("border-t border-kit-line-subtle text-kit-sm text-kit-fg-2", density === "bare" ? "mt-4 pt-2" : density === "dense" ? "mx-2.5 mb-2 pt-2" : "mx-4 mb-3 pt-2.5"),
151
+ children: /* @__PURE__ */ jsx("ol", {
152
+ className: "m-0 flex list-decimal flex-col gap-1 pl-5 marker:text-kit-fg-3",
153
+ children: notes.map((n, i) => /* @__PURE__ */ jsx("li", {
154
+ className: "pl-1",
155
+ children: /* @__PURE__ */ jsxs("span", {
156
+ className: "flex items-start gap-1",
157
+ children: [/* @__PURE__ */ jsx("button", {
158
+ type: "button",
159
+ disabled: readOnly,
160
+ "aria-label": `Footnote ${i + 1}: ${n.note || "empty"}. Edit`,
161
+ onClick: () => onEdit(n.el),
162
+ className: "min-w-0 flex-1 rounded-kit-sm text-left leading-relaxed enabled:hover:text-kit-fg",
163
+ children: n.note || /* @__PURE__ */ jsx("span", {
164
+ className: "text-kit-warning-fg",
165
+ children: "Empty note"
166
+ })
167
+ }), /* @__PURE__ */ jsx(Tooltip, {
168
+ content: "Back to the text",
169
+ children: /* @__PURE__ */ jsx("button", {
170
+ type: "button",
171
+ "aria-label": `Back to reference ${i + 1}`,
172
+ onClick: () => onBack(n.el),
173
+ className: "shrink-0 rounded-kit-sm px-1 text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg",
174
+ children: "↩"
175
+ })
176
+ })]
177
+ })
178
+ }, i))
179
+ })
180
+ });
181
+ }
182
+ //#endregion
183
+ export { FN_MARK, FOOTNOTE_POPOVER_CLASS, FOOTNOTE_REFUSED, FootnoteEditor, FootnotesList, backToMarker, caretAfterMarker, footnoteMarkers, insertFootnote, renumberFootnotes };
184
+
185
+ //# sourceMappingURL=footnote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"footnote.js","names":[],"sources":["../../../src/controls/rich-text/footnote.tsx"],"sourcesContent":["/**\n * RICH TEXT · Footnotes (kit-richtext-ui-spec.md §1): V2's inline footnote, stored as the PT inline object\n * `{ _type: \"footnote\", note }`, written in the editor as `<sup data-rt=\"fn\" data-note contenteditable=\"false\">N</sup>`.\n * The number, the notes list and the way back are derived from the markers' text order, never stored.\n *\n * Editor chrome, not an island: the editor owns the clicks and the popover's anchor; this module is the V2 parts.\n * insert V2 ops.ts:182-205: at the caret through the browser's insert (⌘Z takes it back), never inside a rich\n * block or code; null then, and the editor toasts FOOTNOTE_REFUSED (V2 rich-text-editor.tsx:610-615)\n * numbers V2 dom.ts:429-436: the body's own markers in text order, 1…n\n * popover V2 FootnoteEditor (rich-text-editor.tsx:1736-1777) at the marker, w-[320px] rounded p-3\n * list V2 notes section (rich-text-editor.tsx:1533-1560): each note a button that edits it, and ↩ back to it\n * back V2 backToMarker (rich-text-editor.tsx:1095-1100): scroll to it, caret after it, a 1200ms accent flash\n */\nimport * as React from \"react\";\nimport { IconTrash } from \"@tabler/icons-react\";\nimport { cn } from \"../../lib/cn\";\nimport { Button } from \"../../ui/button\";\nimport { Textarea } from \"../../ui/input\";\nimport { Tooltip } from \"../../ui/overlay\";\n\nexport const FN_MARK = \"sup[data-rt=fn]\";\n/** The toast when a footnote cannot go where the caret is (V2 rich-text-editor.tsx:613). */\nexport const FOOTNOTE_REFUSED = {\n title: \"Put the caret in the text first\",\n description: \"Footnotes number the story's own text, not text inside a block.\",\n} as const;\n/** The popover's chrome (V2 rich-text-editor.tsx:1650). */\nexport const FOOTNOTE_POPOVER_CLASS = \"w-[320px] rounded-kit-lg p-3\";\n\n/** The body's own markers in text order (markers inside a rich block are not the body's). */\nexport const footnoteMarkers = (root: HTMLElement): HTMLElement[] =>\n Array.from(root.querySelectorAll<HTMLElement>(FN_MARK)).filter((m) => !m.closest(\"[data-rt-island],[data-rt-isolate]\"));\n\n/** Numbers the markers 1…n in text order; returns them with their notes, for the list. */\nexport function renumberFootnotes(root: HTMLElement): { el: HTMLElement; note: string }[] {\n return footnoteMarkers(root).map((m, i) => {\n if (m.textContent !== String(i + 1)) m.textContent = String(i + 1);\n return { el: m, note: m.getAttribute(\"data-note\") ?? \"\" };\n });\n}\n\n/** A new, empty marker at the caret. Null when the caret is outside the body's text (a rich block, code, elsewhere). */\nexport function insertFootnote(root: HTMLElement): HTMLElement | null {\n const s = window.getSelection();\n if (!s || !s.rangeCount || !root.contains(s.anchorNode)) return null;\n const at = s.anchorNode?.nodeType === 1 ? (s.anchorNode as HTMLElement) : s.anchorNode?.parentElement;\n if (!at || at.closest(\"[data-rt-island],[data-rt-isolate]\") || at.closest(\"pre\")) return null;\n root.focus({ preventScroll: true });\n if (typeof document.execCommand === \"function\") document.execCommand(\"insertHTML\", false, `<sup data-rt=\"fn\" data-note=\"\" contenteditable=\"false\" data-fn-new=\"\">1</sup>​`);\n let sup = root.querySelector<HTMLElement>(\"sup[data-fn-new]\");\n if (!sup) {\n // the browser dropped the marker (or has no execCommand): place it by hand\n sup = document.createElement(\"sup\");\n sup.setAttribute(\"data-rt\", \"fn\");\n sup.setAttribute(\"data-note\", \"\");\n sup.setAttribute(\"contenteditable\", \"false\");\n sup.textContent = \"1\";\n const r = s.getRangeAt(0);\n r.collapse(false);\n r.insertNode(sup);\n const after = document.createTextNode(\"​\");\n sup.after(after);\n const c = document.createRange();\n c.setStart(after, after.length);\n c.collapse(true);\n s.removeAllRanges();\n s.addRange(c);\n }\n sup.removeAttribute(\"data-fn-new\");\n renumberFootnotes(root);\n return sup;\n}\n\n/** The caret right after a marker, in the body. */\nexport function caretAfterMarker(root: HTMLElement, m: HTMLElement) {\n const s = window.getSelection();\n if (!s || !m.isConnected) return;\n root.focus({ preventScroll: true });\n const r = document.createRange();\n r.setStartAfter(m);\n r.collapse(true);\n s.removeAllRanges();\n s.addRange(r);\n}\n\n/** \"Back to the text\": scroll the marker to the centre, caret after it, and flash it (1200ms). */\nexport function backToMarker(root: HTMLElement, m: HTMLElement) {\n if (!m.isConnected) return;\n m.scrollIntoView?.({ block: \"center\", behavior: \"smooth\" });\n caretAfterMarker(root, m);\n m.animate?.([{ boxShadow: \"0 0 0 3px var(--kit-accent-soft)\" }, { boxShadow: \"0 0 0 0 transparent\" }], { duration: 1200 });\n}\n\n/** The note of one footnote: one setting, edited in a popover at its marker (V2 D54 / D55). */\nexport function FootnoteEditor({ n, note, onChange, onRemove, onDone }: { n: number; note: string; onChange: (v: string) => void; onRemove: () => void; onDone: () => void }) {\n const [v, setV] = React.useState(note);\n const id = React.useId();\n return (\n <form\n className=\"flex flex-col gap-2\"\n onSubmit={(e) => {\n e.preventDefault();\n onDone();\n }}\n >\n <label htmlFor={id} className=\"text-kit-xs font-medium text-kit-fg-2\">\n Footnote {n}\n </label>\n <Textarea\n id={id}\n autoFocus\n rows={3}\n value={v}\n placeholder=\"Write the note\"\n onChange={(e) => {\n setV(e.target.value);\n onChange(e.target.value);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n onDone();\n }\n }}\n />\n <div className=\"flex items-center justify-between\">\n <Button size=\"xs\" variant=\"ghost\" leftIcon={<IconTrash stroke={1.5} />} onClick={onRemove} className=\"hover:text-kit-danger-fg\">\n Remove\n </Button>\n <Button size=\"xs\" variant=\"primary\" type=\"submit\">\n Done\n </Button>\n </div>\n </form>\n );\n}\n\n/** The notes under the body, numbered in text order, each with a way back to its marker. Renders nothing when empty. */\nexport function FootnotesList({\n notes,\n readOnly,\n density = \"default\",\n onEdit,\n onBack,\n}: {\n notes: { el: HTMLElement; note: string }[];\n readOnly?: boolean;\n /** the editor's spacing: bare (no chrome), dense (panel), default */\n density?: \"bare\" | \"dense\" | \"default\";\n onEdit: (el: HTMLElement) => void;\n onBack: (el: HTMLElement) => void;\n}) {\n if (!notes.length) return null;\n return (\n <section\n aria-label=\"Footnotes\"\n className={cn(\"border-t border-kit-line-subtle text-kit-sm text-kit-fg-2\", density === \"bare\" ? \"mt-4 pt-2\" : density === \"dense\" ? \"mx-2.5 mb-2 pt-2\" : \"mx-4 mb-3 pt-2.5\")}\n >\n <ol className=\"m-0 flex list-decimal flex-col gap-1 pl-5 marker:text-kit-fg-3\">\n {notes.map((n, i) => (\n <li key={i} className=\"pl-1\">\n <span className=\"flex items-start gap-1\">\n <button\n type=\"button\"\n disabled={readOnly}\n aria-label={`Footnote ${i + 1}: ${n.note || \"empty\"}. Edit`}\n onClick={() => onEdit(n.el)}\n className=\"min-w-0 flex-1 rounded-kit-sm text-left leading-relaxed enabled:hover:text-kit-fg\"\n >\n {n.note || <span className=\"text-kit-warning-fg\">Empty note</span>}\n </button>\n <Tooltip content=\"Back to the text\">\n <button type=\"button\" aria-label={`Back to reference ${i + 1}`} onClick={() => onBack(n.el)} className=\"shrink-0 rounded-kit-sm px-1 text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg\">\n ↩\n </button>\n </Tooltip>\n </span>\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,IAAa,UAAU;;AAEvB,IAAa,mBAAmB;CAC9B,OAAO;CACP,aAAa;AACf;;AAEA,IAAa,yBAAyB;;AAGtC,IAAa,mBAAmB,SAC9B,MAAM,KAAK,KAAK,iBAA8B,OAAO,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,EAAE,QAAQ,oCAAoC,CAAC;;AAGxH,SAAgB,kBAAkB,MAAwD;CACxF,OAAO,gBAAgB,IAAI,CAAC,CAAC,KAAK,GAAG,MAAM;EACzC,IAAI,EAAE,gBAAgB,OAAO,IAAI,CAAC,GAAG,EAAE,cAAc,OAAO,IAAI,CAAC;EACjE,OAAO;GAAE,IAAI;GAAG,MAAM,EAAE,aAAa,WAAW,KAAK;EAAG;CAC1D,CAAC;AACH;;AAGA,SAAgB,eAAe,MAAuC;CACpE,MAAM,IAAI,OAAO,aAAa;CAC9B,IAAI,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,KAAK,SAAS,EAAE,UAAU,GAAG,OAAO;CAChE,MAAM,KAAK,EAAE,YAAY,aAAa,IAAK,EAAE,aAA6B,EAAE,YAAY;CACxF,IAAI,CAAC,MAAM,GAAG,QAAQ,oCAAoC,KAAK,GAAG,QAAQ,KAAK,GAAG,OAAO;CACzF,KAAK,MAAM,EAAE,eAAe,KAAK,CAAC;CAClC,IAAI,OAAO,SAAS,gBAAgB,YAAY,SAAS,YAAY,cAAc,OAAO,gFAAgF;CAC1K,IAAI,MAAM,KAAK,cAA2B,kBAAkB;CAC5D,IAAI,CAAC,KAAK;EAER,MAAM,SAAS,cAAc,KAAK;EAClC,IAAI,aAAa,WAAW,IAAI;EAChC,IAAI,aAAa,aAAa,EAAE;EAChC,IAAI,aAAa,mBAAmB,OAAO;EAC3C,IAAI,cAAc;EAClB,MAAM,IAAI,EAAE,WAAW,CAAC;EACxB,EAAE,SAAS,KAAK;EAChB,EAAE,WAAW,GAAG;EAChB,MAAM,QAAQ,SAAS,eAAe,GAAG;EACzC,IAAI,MAAM,KAAK;EACf,MAAM,IAAI,SAAS,YAAY;EAC/B,EAAE,SAAS,OAAO,MAAM,MAAM;EAC9B,EAAE,SAAS,IAAI;EACf,EAAE,gBAAgB;EAClB,EAAE,SAAS,CAAC;CACd;CACA,IAAI,gBAAgB,aAAa;CACjC,kBAAkB,IAAI;CACtB,OAAO;AACT;;AAGA,SAAgB,iBAAiB,MAAmB,GAAgB;CAClE,MAAM,IAAI,OAAO,aAAa;CAC9B,IAAI,CAAC,KAAK,CAAC,EAAE,aAAa;CAC1B,KAAK,MAAM,EAAE,eAAe,KAAK,CAAC;CAClC,MAAM,IAAI,SAAS,YAAY;CAC/B,EAAE,cAAc,CAAC;CACjB,EAAE,SAAS,IAAI;CACf,EAAE,gBAAgB;CAClB,EAAE,SAAS,CAAC;AACd;;AAGA,SAAgB,aAAa,MAAmB,GAAgB;CAC9D,IAAI,CAAC,EAAE,aAAa;CACpB,EAAE,iBAAiB;EAAE,OAAO;EAAU,UAAU;CAAS,CAAC;CAC1D,iBAAiB,MAAM,CAAC;CACxB,EAAE,UAAU,CAAC,EAAE,WAAW,mCAAmC,GAAG,EAAE,WAAW,sBAAsB,CAAC,GAAG,EAAE,UAAU,KAAK,CAAC;AAC3H;;AAGA,SAAgB,eAAe,EAAE,GAAG,MAAM,UAAU,UAAU,UAAgH;CAC5K,MAAM,CAAC,GAAG,QAAQ,MAAM,SAAS,IAAI;CACrC,MAAM,KAAK,MAAM,MAAM;CACvB,OACE,qBAAC,QAAD;EACE,WAAU;EACV,WAAW,MAAM;GACf,EAAE,eAAe;GACjB,OAAO;EACT;EALF,UAAA;GAOE,qBAAC,SAAD;IAAO,SAAS;IAAI,WAAU;IAA9B,UAAA,CAAsE,aAC1D,CACL;;GACP,oBAAC,UAAD;IACM;IACJ,WAAA;IACA,MAAM;IACN,OAAO;IACP,aAAY;IACZ,WAAW,MAAM;KACf,KAAK,EAAE,OAAO,KAAK;KACnB,SAAS,EAAE,OAAO,KAAK;IACzB;IACA,YAAY,MAAM;KAChB,IAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,UAAU;MACpC,EAAE,eAAe;MACjB,OAAO;KACT;IACF;GACD,CAAA;GACD,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,QAAD;KAAQ,MAAK;KAAK,SAAQ;KAAQ,UAAU,oBAAC,WAAD,EAAW,QAAQ,IAAM,CAAA;KAAG,SAAS;KAAU,WAAU;KAA2B,UAAA;IAExH,CAAA,GACR,oBAAC,QAAD;KAAQ,MAAK;KAAK,SAAQ;KAAU,MAAK;KAAS,UAAA;IAE1C,CAAA,CACL;;EACD;;AAEV;;AAGA,SAAgB,cAAc,EAC5B,OACA,UACA,UAAU,WACV,QACA,UAQC;CACD,IAAI,CAAC,MAAM,QAAQ,OAAO;CAC1B,OACE,oBAAC,WAAD;EACE,cAAW;EACX,WAAW,GAAG,6DAA6D,YAAY,SAAS,cAAc,YAAY,UAAU,qBAAqB,kBAAkB;EAE3K,UAAA,oBAAC,MAAD;GAAI,WAAU;GACX,UAAA,MAAM,KAAK,GAAG,MACb,oBAAC,MAAD;IAAY,WAAU;IACpB,UAAA,qBAAC,QAAD;KAAM,WAAU;KAAhB,UAAA,CACE,oBAAC,UAAD;MACE,MAAK;MACL,UAAU;MACV,cAAY,YAAY,IAAI,EAAE,IAAI,EAAE,QAAQ,QAAQ;MACpD,eAAe,OAAO,EAAE,EAAE;MAC1B,WAAU;MAET,UAAA,EAAE,QAAQ,oBAAC,QAAD;OAAM,WAAU;OAAsB,UAAA;MAAgB,CAAA;KAC3D,CAAA,GACR,oBAAC,SAAD;MAAS,SAAQ;MACf,UAAA,oBAAC,UAAD;OAAQ,MAAK;OAAS,cAAY,qBAAqB,IAAI;OAAK,eAAe,OAAO,EAAE,EAAE;OAAG,WAAU;OAAkF,UAAA;MAEjL,CAAA;KACD,CAAA,CACL;;GACJ,GAjBK,CAiBL,CACL;EACC,CAAA;CACG,CAAA;AAEb"}
@@ -0,0 +1,28 @@
1
+ import type { TypeSchema } from "../../schema/types";
2
+ import type { ImageValue } from "../media";
3
+ import type { IslandCtx } from "./blocks";
4
+ import type { IslandEl } from "./dom";
5
+ export interface GalleryImage {
6
+ _key: string;
7
+ image: ImageValue | null;
8
+ caption: string;
9
+ }
10
+ export interface GalleryModel {
11
+ layout: "grid" | "carousel";
12
+ images: GalleryImage[];
13
+ }
14
+ export declare const GALLERY_LABEL = "Gallery";
15
+ export declare const galleryDefault: () => GalleryModel;
16
+ export declare const GALLERY_SCHEMA: TypeSchema;
17
+ export declare function GalleryPreview({ m, onAdd, ro }: {
18
+ m: GalleryModel;
19
+ onAdd: () => void;
20
+ ro: boolean;
21
+ }): import("react/jsx-runtime").JSX.Element;
22
+ export declare function GalleryBlock({ m, set, el, ctx, autoFocus, }: {
23
+ m: GalleryModel;
24
+ set: (fn: (m: GalleryModel) => GalleryModel, label?: string) => void;
25
+ el: IslandEl;
26
+ ctx: IslandCtx;
27
+ autoFocus: boolean;
28
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,167 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { ArticleEmpty, ArticlePanelBlock } from "./article-shell.js";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { IconPhoto } from "@tabler/icons-react";
5
+ //#region src/controls/rich-text/gallery.tsx
6
+ /**
7
+ * RICH TEXT · Gallery (kit-richtext-ui-spec.md §2): V2's article block, stored as the PT block object
8
+ * `{ _type: "gallery", layout: "grid" | "carousel", images: { _key, image, caption? }[] }`; each image is the rich-text
9
+ * image's own shape (src/alt + media id), so media rewrites and alt audits reach it.
10
+ *
11
+ * form V2 article.ts:75-114: Images (a grid list, 2–24, each a required image + caption ≤160), Layout
12
+ * (Grid | Carousel, segmented). A list of objects → the floating properties panel (D54); a fresh insert opens it.
13
+ * preview V2 article-blocks.tsx:451-480: Grid in 2 columns for 2 or 4 images, else 3, square crops; Carousel a
14
+ * 72%-wide scroll-snap row of 4:3 crops with "N images · carousel"; "Add images" when there are none.
15
+ */
16
+ var GALLERY_LABEL = "Gallery";
17
+ var galleryDefault = () => ({
18
+ layout: "grid",
19
+ images: []
20
+ });
21
+ var GALLERY_SCHEMA = {
22
+ name: "gallery",
23
+ title: GALLERY_LABEL,
24
+ kind: "object",
25
+ icon: "photo",
26
+ fields: [{
27
+ name: "images",
28
+ title: "Images",
29
+ type: "array",
30
+ itemNoun: "image",
31
+ arrayLayout: "grid",
32
+ validation: {
33
+ min: 2,
34
+ max: 24
35
+ },
36
+ of: [{
37
+ name: "photo",
38
+ title: "Image",
39
+ type: "object",
40
+ icon: "photo",
41
+ preview: {
42
+ title: "caption",
43
+ media: "image",
44
+ fallback: "Untitled image"
45
+ },
46
+ fields: [{
47
+ name: "image",
48
+ title: "Image",
49
+ type: "image",
50
+ validation: { required: true }
51
+ }, {
52
+ name: "caption",
53
+ title: "Caption",
54
+ type: "string",
55
+ validation: { max: 160 }
56
+ }]
57
+ }]
58
+ }, {
59
+ name: "layout",
60
+ title: "Layout",
61
+ type: "select",
62
+ layout: "segmented",
63
+ initialValue: "grid",
64
+ options: [{
65
+ value: "grid",
66
+ label: "Grid"
67
+ }, {
68
+ value: "carousel",
69
+ label: "Carousel"
70
+ }]
71
+ }]
72
+ };
73
+ function GalleryPreview({ m, onAdd, ro }) {
74
+ const imgs = m.images.filter((x) => x.image?.url);
75
+ if (!imgs.length) return /* @__PURE__ */ jsx(ArticleEmpty, {
76
+ icon: /* @__PURE__ */ jsx(IconPhoto, { stroke: 1.5 }),
77
+ title: GALLERY_LABEL,
78
+ action: "Add images",
79
+ onAction: onAdd,
80
+ ro
81
+ });
82
+ if (m.layout === "carousel") return /* @__PURE__ */ jsxs("figure", {
83
+ className: "m-0",
84
+ "data-field": "images",
85
+ children: [/* @__PURE__ */ jsx("ul", {
86
+ className: "m-0 flex snap-x gap-2 overflow-x-auto p-0 pb-1",
87
+ "aria-label": GALLERY_LABEL,
88
+ children: imgs.map((x) => /* @__PURE__ */ jsxs("li", {
89
+ className: "w-[72%] shrink-0 snap-start list-none",
90
+ children: [/* @__PURE__ */ jsx("img", {
91
+ src: x.image.url,
92
+ alt: x.image.alt ?? "",
93
+ draggable: false,
94
+ className: "block aspect-[4/3] w-full rounded-kit-lg border border-kit-line object-cover"
95
+ }), x.caption ? /* @__PURE__ */ jsx("p", {
96
+ className: "mt-1 truncate text-kit-xs text-kit-fg-3",
97
+ children: x.caption
98
+ }) : null]
99
+ }, x._key))
100
+ }), /* @__PURE__ */ jsxs("figcaption", {
101
+ className: "mt-1 text-kit-2xs text-kit-fg-3",
102
+ children: [
103
+ imgs.length,
104
+ " ",
105
+ imgs.length === 1 ? "image" : "images",
106
+ " · carousel"
107
+ ]
108
+ })]
109
+ });
110
+ return /* @__PURE__ */ jsx("figure", {
111
+ className: "m-0",
112
+ "data-field": "images",
113
+ children: /* @__PURE__ */ jsx("ul", {
114
+ className: cn("m-0 grid gap-2 p-0", imgs.length === 2 || imgs.length === 4 ? "grid-cols-2" : "grid-cols-3"),
115
+ "aria-label": GALLERY_LABEL,
116
+ children: imgs.map((x) => /* @__PURE__ */ jsxs("li", {
117
+ className: "list-none",
118
+ children: [/* @__PURE__ */ jsx("img", {
119
+ src: x.image.url,
120
+ alt: x.image.alt ?? "",
121
+ draggable: false,
122
+ className: "block aspect-square w-full rounded-kit-lg border border-kit-line object-cover"
123
+ }), x.caption ? /* @__PURE__ */ jsx("p", {
124
+ className: "mt-1 truncate text-kit-xs text-kit-fg-3",
125
+ children: x.caption
126
+ }) : null]
127
+ }, x._key))
128
+ })
129
+ });
130
+ }
131
+ var asImages = (v) => Array.isArray(v) ? v.map((x, i) => {
132
+ const o = x ?? {};
133
+ return {
134
+ _key: typeof o._key === "string" ? o._key : `g${i}`,
135
+ image: o.image ?? null,
136
+ caption: typeof o.caption === "string" ? o.caption : ""
137
+ };
138
+ }) : [];
139
+ function GalleryBlock({ m, set, el, ctx, autoFocus }) {
140
+ return /* @__PURE__ */ jsx(ArticlePanelBlock, {
141
+ label: GALLERY_LABEL,
142
+ kind: "gallery",
143
+ schema: GALLERY_SCHEMA,
144
+ m,
145
+ set,
146
+ el,
147
+ ctx,
148
+ autoFocus,
149
+ toForm: (x) => ({
150
+ images: x.images,
151
+ layout: x.layout
152
+ }),
153
+ fromForm: (v) => ({
154
+ images: asImages(v.images),
155
+ layout: v.layout === "carousel" ? "carousel" : "grid"
156
+ }),
157
+ children: (open, ro) => /* @__PURE__ */ jsx(GalleryPreview, {
158
+ m,
159
+ onAdd: () => open("images"),
160
+ ro
161
+ })
162
+ });
163
+ }
164
+ //#endregion
165
+ export { GALLERY_LABEL, GALLERY_SCHEMA, GalleryBlock, GalleryPreview, galleryDefault };
166
+
167
+ //# sourceMappingURL=gallery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gallery.js","names":[],"sources":["../../../src/controls/rich-text/gallery.tsx"],"sourcesContent":["/**\n * RICH TEXT · Gallery (kit-richtext-ui-spec.md §2): V2's article block, stored as the PT block object\n * `{ _type: \"gallery\", layout: \"grid\" | \"carousel\", images: { _key, image, caption? }[] }`; each image is the rich-text\n * image's own shape (src/alt + media id), so media rewrites and alt audits reach it.\n *\n * form V2 article.ts:75-114: Images (a grid list, 2–24, each a required image + caption ≤160), Layout\n * (Grid | Carousel, segmented). A list of objects → the floating properties panel (D54); a fresh insert opens it.\n * preview V2 article-blocks.tsx:451-480: Grid in 2 columns for 2 or 4 images, else 3, square crops; Carousel a\n * 72%-wide scroll-snap row of 4:3 crops with \"N images · carousel\"; \"Add images\" when there are none.\n */\nimport { IconPhoto } from \"@tabler/icons-react\";\nimport { cn } from \"../../lib/cn\";\nimport type { TypeSchema } from \"../../schema/types\";\nimport type { ImageValue } from \"../media\";\nimport { ArticleEmpty, ArticlePanelBlock } from \"./article-shell\";\nimport type { IslandCtx } from \"./blocks\";\nimport type { IslandEl } from \"./dom\";\n\nexport interface GalleryImage {\n _key: string;\n image: ImageValue | null;\n caption: string;\n}\nexport interface GalleryModel {\n layout: \"grid\" | \"carousel\";\n images: GalleryImage[];\n}\nexport const GALLERY_LABEL = \"Gallery\";\nexport const galleryDefault = (): GalleryModel => ({ layout: \"grid\", images: [] });\n\nexport const GALLERY_SCHEMA: TypeSchema = {\n name: \"gallery\",\n title: GALLERY_LABEL,\n kind: \"object\",\n icon: \"photo\",\n fields: [\n {\n name: \"images\",\n title: \"Images\",\n type: \"array\",\n itemNoun: \"image\",\n arrayLayout: \"grid\",\n validation: { min: 2, max: 24 },\n of: [\n {\n name: \"photo\",\n title: \"Image\",\n type: \"object\",\n icon: \"photo\",\n preview: { title: \"caption\", media: \"image\", fallback: \"Untitled image\" },\n fields: [\n { name: \"image\", title: \"Image\", type: \"image\", validation: { required: true } },\n { name: \"caption\", title: \"Caption\", type: \"string\", validation: { max: 160 } },\n ],\n },\n ],\n },\n {\n name: \"layout\",\n title: \"Layout\",\n type: \"select\",\n layout: \"segmented\",\n initialValue: \"grid\",\n options: [\n { value: \"grid\", label: \"Grid\" },\n { value: \"carousel\", label: \"Carousel\" },\n ],\n },\n ],\n};\n\nexport function GalleryPreview({ m, onAdd, ro }: { m: GalleryModel; onAdd: () => void; ro: boolean }) {\n const imgs = m.images.filter((x) => x.image?.url);\n if (!imgs.length) return <ArticleEmpty icon={<IconPhoto stroke={1.5} />} title={GALLERY_LABEL} action=\"Add images\" onAction={onAdd} ro={ro} />;\n if (m.layout === \"carousel\")\n return (\n <figure className=\"m-0\" data-field=\"images\">\n <ul className=\"m-0 flex snap-x gap-2 overflow-x-auto p-0 pb-1\" aria-label={GALLERY_LABEL}>\n {imgs.map((x) => (\n <li key={x._key} className=\"w-[72%] shrink-0 snap-start list-none\">\n <img src={x.image!.url} alt={x.image!.alt ?? \"\"} draggable={false} className=\"block aspect-[4/3] w-full rounded-kit-lg border border-kit-line object-cover\" />\n {x.caption ? <p className=\"mt-1 truncate text-kit-xs text-kit-fg-3\">{x.caption}</p> : null}\n </li>\n ))}\n </ul>\n <figcaption className=\"mt-1 text-kit-2xs text-kit-fg-3\">\n {imgs.length} {imgs.length === 1 ? \"image\" : \"images\"} · carousel\n </figcaption>\n </figure>\n );\n return (\n <figure className=\"m-0\" data-field=\"images\">\n <ul className={cn(\"m-0 grid gap-2 p-0\", imgs.length === 2 || imgs.length === 4 ? \"grid-cols-2\" : \"grid-cols-3\")} aria-label={GALLERY_LABEL}>\n {imgs.map((x) => (\n <li key={x._key} className=\"list-none\">\n <img src={x.image!.url} alt={x.image!.alt ?? \"\"} draggable={false} className=\"block aspect-square w-full rounded-kit-lg border border-kit-line object-cover\" />\n {x.caption ? <p className=\"mt-1 truncate text-kit-xs text-kit-fg-3\">{x.caption}</p> : null}\n </li>\n ))}\n </ul>\n </figure>\n );\n}\n\nconst asImages = (v: unknown): GalleryImage[] =>\n Array.isArray(v)\n ? v.map((x, i) => {\n const o = (x ?? {}) as Record<string, unknown>;\n return { _key: typeof o._key === \"string\" ? o._key : `g${i}`, image: (o.image as ImageValue | null) ?? null, caption: typeof o.caption === \"string\" ? o.caption : \"\" };\n })\n : [];\n\nexport function GalleryBlock({\n m, set, el, ctx, autoFocus,\n}: {\n m: GalleryModel;\n set: (fn: (m: GalleryModel) => GalleryModel, label?: string) => void;\n el: IslandEl;\n ctx: IslandCtx;\n autoFocus: boolean;\n}) {\n return (\n <ArticlePanelBlock<GalleryModel>\n label={GALLERY_LABEL}\n kind=\"gallery\"\n schema={GALLERY_SCHEMA}\n m={m}\n set={set}\n el={el}\n ctx={ctx}\n autoFocus={autoFocus}\n toForm={(x) => ({ images: x.images, layout: x.layout })}\n fromForm={(v) => ({ images: asImages(v.images), layout: v.layout === \"carousel\" ? \"carousel\" : \"grid\" })}\n >\n {(open, ro) => <GalleryPreview m={m} onAdd={() => open(\"images\")} ro={ro} />}\n </ArticlePanelBlock>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AA2BA,IAAa,gBAAgB;AAC7B,IAAa,wBAAsC;CAAE,QAAQ;CAAQ,QAAQ,CAAC;AAAE;AAEhF,IAAa,iBAA6B;CACxC,MAAM;CACN,OAAO;CACP,MAAM;CACN,MAAM;CACN,QAAQ,CACN;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,UAAU;EACV,aAAa;EACb,YAAY;GAAE,KAAK;GAAG,KAAK;EAAG;EAC9B,IAAI,CACF;GACE,MAAM;GACN,OAAO;GACP,MAAM;GACN,MAAM;GACN,SAAS;IAAE,OAAO;IAAW,OAAO;IAAS,UAAU;GAAiB;GACxE,QAAQ,CACN;IAAE,MAAM;IAAS,OAAO;IAAS,MAAM;IAAS,YAAY,EAAE,UAAU,KAAK;GAAE,GAC/E;IAAE,MAAM;IAAW,OAAO;IAAW,MAAM;IAAU,YAAY,EAAE,KAAK,IAAI;GAAE,CAChF;EACF,CACF;CACF,GACA;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,QAAQ;EACR,cAAc;EACd,SAAS,CACP;GAAE,OAAO;GAAQ,OAAO;EAAO,GAC/B;GAAE,OAAO;GAAY,OAAO;EAAW,CACzC;CACF,CACF;AACF;AAEA,SAAgB,eAAe,EAAE,GAAG,OAAO,MAA2D;CACpG,MAAM,OAAO,EAAE,OAAO,QAAQ,MAAM,EAAE,OAAO,GAAG;CAChD,IAAI,CAAC,KAAK,QAAQ,OAAO,oBAAC,cAAD;EAAc,MAAM,oBAAC,WAAD,EAAW,QAAQ,IAAM,CAAA;EAAG,OAAO;EAAe,QAAO;EAAa,UAAU;EAAW;CAAK,CAAA;CAC7I,IAAI,EAAE,WAAW,YACf,OACE,qBAAC,UAAD;EAAQ,WAAU;EAAM,cAAW;EAAnC,UAAA,CACE,oBAAC,MAAD;GAAI,WAAU;GAAiD,cAAY;GACxE,UAAA,KAAK,KAAK,MACT,qBAAC,MAAD;IAAiB,WAAU;IAA3B,UAAA,CACE,oBAAC,OAAD;KAAK,KAAK,EAAE,MAAO;KAAK,KAAK,EAAE,MAAO,OAAO;KAAI,WAAW;KAAO,WAAU;IAAgF,CAAA,GAC5J,EAAE,UAAU,oBAAC,KAAD;KAAG,WAAU;KAA2C,UAAA,EAAE;IAAW,CAAA,IAAI,IACpF;GAHK,GAAA,EAAE,IAGP,CACL;EACC,CAAA,GACJ,qBAAC,cAAD;GAAY,WAAU;GAAtB,UAAA;IACG,KAAK;IAAO;IAAE,KAAK,WAAW,IAAI,UAAU;IAAS;GAC5C;EACN,CAAA,CAAA;;CAEZ,OACE,oBAAC,UAAD;EAAQ,WAAU;EAAM,cAAW;EACjC,UAAA,oBAAC,MAAD;GAAI,WAAW,GAAG,sBAAsB,KAAK,WAAW,KAAK,KAAK,WAAW,IAAI,gBAAgB,aAAa;GAAG,cAAY;GAC1H,UAAA,KAAK,KAAK,MACT,qBAAC,MAAD;IAAiB,WAAU;IAA3B,UAAA,CACE,oBAAC,OAAD;KAAK,KAAK,EAAE,MAAO;KAAK,KAAK,EAAE,MAAO,OAAO;KAAI,WAAW;KAAO,WAAU;IAAiF,CAAA,GAC7J,EAAE,UAAU,oBAAC,KAAD;KAAG,WAAU;KAA2C,UAAA,EAAE;IAAW,CAAA,IAAI,IACpF;GAHK,GAAA,EAAE,IAGP,CACL;EACC,CAAA;CACE,CAAA;AAEZ;AAEA,IAAM,YAAY,MAChB,MAAM,QAAQ,CAAC,IACX,EAAE,KAAK,GAAG,MAAM;CACd,MAAM,IAAK,KAAK,CAAC;CACjB,OAAO;EAAE,MAAM,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO,IAAI;EAAK,OAAQ,EAAE,SAA+B;EAAM,SAAS,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;CAAG;AACvK,CAAC,IACD,CAAC;AAEP,SAAgB,aAAa,EAC3B,GAAG,KAAK,IAAI,KAAK,aAOhB;CACD,OACE,oBAAC,mBAAD;EACE,OAAO;EACP,MAAK;EACL,QAAQ;EACL;EACE;EACD;EACC;EACM;EACX,SAAS,OAAO;GAAE,QAAQ,EAAE;GAAQ,QAAQ,EAAE;EAAO;EACrD,WAAW,OAAO;GAAE,QAAQ,SAAS,EAAE,MAAM;GAAG,QAAQ,EAAE,WAAW,aAAa,aAAa;EAAO;EAEpG,WAAA,MAAM,OAAO,oBAAC,gBAAD;GAAmB;GAAG,aAAa,KAAK,QAAQ;GAAO;EAAK,CAAA;CAC1D,CAAA;AAEvB"}
@@ -1,6 +1,6 @@
1
1
  import { ACTIONS, CONTROLS } from "../../engine/kit-field.js";
2
2
  import { RichTextControl, RichTextExpandAction } from "./control.js";
3
- //#region src/kit/controls/rich-text/index.ts
3
+ //#region src/controls/rich-text/index.ts
4
4
  /**
5
5
  * Rich text: registers the control and its label-row action (one line each, so lanes merge cleanly).
6
6
  * Imported for its side effect by whatever loads the kit's controls; import the parts themselves by path.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/controls/rich-text/index.ts"],"sourcesContent":["/**\n * Rich text: registers the control and its label-row action (one line each, so lanes merge cleanly).\n * Imported for its side effect by whatever loads the kit's controls; import the parts themselves by path.\n */\nimport { ACTIONS, CONTROLS } from \"../../engine/kit-field\";\nimport { RichTextControl, RichTextExpandAction } from \"./control\";\n\nCONTROLS.richtext = RichTextControl;\nACTIONS.richtext = RichTextExpandAction;\n"],"mappings":";;;;;;;AAOA,SAAS,WAAW;AACpB,QAAQ,WAAW"}
@@ -4,10 +4,12 @@ export interface TextLink {
4
4
  }
5
5
  /** An address a link may carry: http(s), mailto, tel, a site path or an in-page anchor. */
6
6
  export declare function linkProblem(href: string): string | null;
7
- export declare function LinkForm({ initial, allowNewTab, onSave, onCancel, onDetach, }: {
7
+ export declare function LinkForm({ initial, allowNewTab, onSave, onCancel, onDetach, dirty, }: {
8
8
  initial: TextLink;
9
9
  allowNewTab: boolean;
10
10
  onSave: (v: TextLink) => void;
11
11
  onCancel: () => void;
12
12
  onDetach?: () => void;
13
+ /** something the host draws beside the form changed (a button's label), so Apply has something to save */
14
+ dirty?: boolean;
13
15
  }): import("react/jsx-runtime").JSX.Element;