@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,17 +1,17 @@
1
+ import { BUTTON_VARIANTS, DOCK_ICON_NAME_SET } from "../adapters/prod-types.js";
1
2
  import { cn } from "../lib/cn.js";
3
+ import { useForm, useKitEnv } from "../context.js";
2
4
  import { isObj } from "../lib/path.js";
3
5
  import { KIT_ICONS, KitIcon, iconLabel } from "../lib/icons.js";
4
- import { BUTTON_VARIANTS, DOCK_ICON_NAME_SET } from "../adapters/prod-types.js";
5
- import { useForm, useKitEnv } from "../context.js";
6
6
  import { Segmented, Switch } from "../ui/controls.js";
7
7
  import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../ui/overlay.js";
8
- import { Input } from "../ui/input.js";
9
8
  import { FieldUnit } from "../engine/grouping.js";
10
- import { LinkForm, LinkLine, LinkQuickEdit, TARGET_KEYS, describeLink, finalizeLink, findTarget, hasLink, normLink, storedLink, useLinkTargets } from "./link.js";
9
+ import { Input } from "../ui/input.js";
10
+ import { LinkForm, LinkLine, LinkQuickEdit, TARGET_KEYS, finalizeLink, findTarget, hasLink, linkText, normLink, storedLink, useLinkTargets } from "./link.js";
11
11
  import * as React from "react";
12
- import { IconArrowRight, IconChevronDown, IconChevronRight, IconSearch } from "@tabler/icons-react";
13
12
  import { jsx, jsxs } from "react/jsx-runtime";
14
- //#region src/kit/controls/button.tsx
13
+ import { IconArrowRight, IconChevronDown, IconChevronRight, IconSearch, IconX } from "@tabler/icons-react";
14
+ //#region src/controls/button.tsx
15
15
  /**
16
16
  * BUTTON — label + link + look as ONE unit (V2 HEAD kit/controls/link.tsx "Button", DESIGN §8.8, CPO D43 · D45 · D46).
17
17
  *
@@ -32,10 +32,10 @@ import { jsx, jsxs } from "react/jsx-runtime";
32
32
  * "Full width" writes `fullWidth: true`, and off writes `false` only where the stored value had the key (as Show arrow);
33
33
  * every renderer draws it (hosted `bcms-btn-full`, the SDKs' and in-place publishing's `data-full-width`).
34
34
  *
35
- * Deviations from V2, each because prod has nothing behind it: an unset look reads "Default" (V2 drew Primary, and guessed Outline for a field named "secondary"); the button
36
- * screen's preview reads the site palette from --kit-preview-paper / -ink / -primary / -primary-on / -line / -filter
37
- * when the host sets them (the Kit library sets V2's demo-site palette) and otherwise draws in neutral kit ink (the
38
- * dock has no project palette yet; the canvas shows the site's own button). The style grid stays in kit ink except Primary, which shows the brand colour as V2's chrome swatch does.
35
+ * Deviation from V2, because prod has nothing behind it: an unset look reads "Default" (V2 drew Primary, and guessed
36
+ * Outline for a field named "secondary"). The preview is V2's: the site palette (--kit-preview-paper / -ink / -primary /
37
+ * -primary-on / -contrast / -contrast-on / -outline, which a host may set to the project's colours) on the paper, and the
38
+ * chrome swatches in the style grid.
39
39
  */
40
40
  var STYLE_ITEMS = [
41
41
  {
@@ -134,7 +134,8 @@ function ButtonStyleGrid({ v, onPick, "aria-label": ariaLabel, size = "md" }) {
134
134
  icon: void 0,
135
135
  arrow: false
136
136
  },
137
- small: true
137
+ small: true,
138
+ chrome: true
138
139
  }), /* @__PURE__ */ jsx("span", {
139
140
  className: "truncate",
140
141
  children: s.label
@@ -144,14 +145,17 @@ function ButtonStyleGrid({ v, onPick, "aria-label": ariaLabel, size = "md" }) {
144
145
  });
145
146
  }
146
147
  /**
147
- * The button as a shape: filled · soft · outlined · underlined. In kit ink by default; `site` draws it in the host's
148
- * site palette (--kit-preview-*), falling back to kit ink for each token the host leaves unset.
148
+ * The site's button as the site draws it (V2 link.tsx ButtonPreview: the site palette, not app tokens). On the preview
149
+ * paper it keeps the site's own colours in both themes; `chrome` = drawn on app chrome (the style grid), where the
150
+ * dark-ink styles flip so they still read on a dark panel. Prod looks beyond the four: brand as primary, dark as
151
+ * secondary, any other in the muted kit fill.
149
152
  */
150
- function ButtonPreview({ v, className, small, site }) {
151
- const style = lookOf(v) ?? "primary";
153
+ function ButtonPreview({ v, className, small, chrome }) {
154
+ const look = lookOf(v) ?? "primary";
155
+ const style = look === "brand" ? "primary" : look === "dark" ? "secondary" : look;
152
156
  const size = small ? "sm" : v.size ?? "md";
153
157
  return /* @__PURE__ */ jsxs("span", {
154
- className: cn("inline-flex max-w-full items-center justify-center gap-1.5 truncate font-medium transition-colors", size === "sm" ? "h-6 rounded-kit-md px-2 text-kit-xs" : size === "lg" ? "h-10 rounded-kit-lg px-4 text-kit-base" : "h-8 rounded-kit-lg px-3 text-kit-sm", site ? siteLook(style) : style === "link" ? "h-auto px-0 text-kit-fg underline underline-offset-4" : style === "outline" ? "border border-kit-line-strong text-kit-fg" : style === "primary" || style === "brand" ? "bg-[color:var(--kit-preview-primary,var(--kit-inverse))] text-[color:var(--kit-preview-primary-on,var(--kit-fg-inverse))]" : style === "dark" ? "bg-kit-inverse text-kit-fg-inverse" : "bg-kit-muted text-kit-fg", className),
158
+ className: cn("inline-flex max-w-full items-center justify-center gap-1.5 truncate font-medium transition-colors", size === "sm" ? "h-6 rounded-kit-md px-2 text-kit-xs" : size === "lg" ? "h-10 rounded-kit-lg px-4 text-kit-base" : "h-8 rounded-kit-lg px-3 text-kit-sm", style === "primary" && "bg-kit-preview-primary text-kit-preview-primary-on", style === "secondary" && (chrome ? "bg-kit-preview-contrast text-kit-preview-contrast-on" : "bg-kit-preview-ink text-kit-preview-paper"), style === "outline" && (chrome ? "border border-kit-preview-outline text-kit-fg" : "border border-kit-preview-ink/25 text-kit-preview-ink"), style === "link" && "h-auto px-0 text-kit-preview-primary underline underline-offset-4", !STYLE_ITEMS.some((x) => x.value === style) && "bg-kit-muted text-kit-fg", v.fullWidth && !small && "w-full", className),
155
159
  children: [
156
160
  v.icon ? /* @__PURE__ */ jsx(KitIcon, {
157
161
  name: v.icon,
@@ -168,14 +172,6 @@ function ButtonPreview({ v, className, small, site }) {
168
172
  ]
169
173
  });
170
174
  }
171
- /** V2's site preview: primary in the brand colour, secondary / dark as ink on paper, outline as an ink hairline. */
172
- function siteLook(style) {
173
- if (style === "link") return "h-auto px-0 text-[color:var(--kit-preview-primary,var(--kit-fg))] underline underline-offset-4";
174
- if (style === "outline") return "border border-[color:var(--kit-preview-line,var(--kit-line-strong))] text-[color:var(--kit-preview-ink,var(--kit-fg))]";
175
- if (style === "primary" || style === "brand") return "bg-[color:var(--kit-preview-primary,var(--kit-inverse))] text-[color:var(--kit-preview-primary-on,var(--kit-fg-inverse))]";
176
- if (style === "dark") return "bg-[color:var(--kit-preview-ink,var(--kit-inverse))] text-[color:var(--kit-preview-paper,var(--kit-fg-inverse))]";
177
- return "bg-[color:var(--kit-preview-ink,var(--kit-muted))] text-[color:var(--kit-preview-paper,var(--kit-fg))]";
178
- }
179
175
  /** A 16px neutral glyph of the style (filled · outlined · underlined) — brand-free, so the field stays calm. */
180
176
  function StyleGlyph({ style, className }) {
181
177
  return /* @__PURE__ */ jsx("span", {
@@ -184,57 +180,70 @@ function StyleGlyph({ style, className }) {
184
180
  children: style === "link" ? /* @__PURE__ */ jsx("span", { className: "h-[2px] w-3.5 rounded-full bg-kit-fg-2" }) : /* @__PURE__ */ jsx("span", { className: cn("h-2.5 w-4 rounded-[3px]", style === "outline" ? "border-[1.5px] border-kit-fg-2" : style === "secondary" || style === "light" || style === "tertiary" ? "bg-kit-fg-3" : "bg-kit-fg") })
185
181
  });
186
182
  }
187
- /** The leading-icon picker: search + grid over BUTTON_ICONS, "No icon" first. */
183
+ /** The leading-icon picker over BUTTON_ICONS, "No icon" first: V2's IconPickerGrid (icon.tsx) — search box, 8-column
184
+ * grid in a 224px scroll. The tiles stay one radiogroup (the dash's semantics; V2 draws a listbox). */
188
185
  function ButtonIconPicker({ value, onPick }) {
189
186
  const [q, setQ] = React.useState("");
190
187
  const query = q.trim().toLowerCase();
191
188
  const shown = query ? BUTTON_ICONS.filter((n) => n.includes(query.replace(/\s+/g, "-"))) : BUTTON_ICONS;
189
+ const tile = (on) => cn("flex aspect-square items-center justify-center rounded-kit-md text-kit-fg-2 transition-colors hover:bg-kit-hover hover:text-kit-fg", on && "bg-kit-selected text-kit-fg ring-1 ring-inset ring-kit-line-strong");
192
190
  return /* @__PURE__ */ jsxs("div", {
191
+ "data-icon-picker": true,
193
192
  className: "flex flex-col gap-2",
194
- children: [
195
- /* @__PURE__ */ jsx(Input, {
196
- size: "sm",
197
- "aria-label": "Search icons",
198
- leading: /* @__PURE__ */ jsx(IconSearch, { stroke: 1.5 }),
193
+ children: [/* @__PURE__ */ jsxs("label", {
194
+ className: "flex h-8 items-center gap-2 rounded-kit-md bg-kit-muted px-2.5 text-kit-fg-3 focus-within:bg-kit-field-bg focus-within:ring-1 focus-within:ring-kit-line-strong",
195
+ children: [/* @__PURE__ */ jsx(IconSearch, {
196
+ className: "size-4 shrink-0",
197
+ stroke: 1.5,
198
+ "aria-hidden": true
199
+ }), /* @__PURE__ */ jsx("input", {
200
+ autoFocus: true,
199
201
  value: q,
200
202
  onChange: (e) => setQ(e.target.value),
201
203
  placeholder: "Search icons",
202
- autoFocus: true
203
- }),
204
- /* @__PURE__ */ jsxs("div", {
204
+ "aria-label": "Search icons",
205
+ className: "h-full min-w-0 flex-1 bg-transparent text-kit-sm text-kit-fg outline-none placeholder:text-kit-fg-3"
206
+ })]
207
+ }), /* @__PURE__ */ jsxs("div", {
208
+ className: "max-h-56 overflow-y-auto pr-0.5",
209
+ children: [/* @__PURE__ */ jsxs("div", {
205
210
  role: "radiogroup",
206
211
  "aria-label": "Leading icon",
207
- className: "grid max-h-56 grid-cols-8 gap-1 overflow-y-auto overscroll-contain",
212
+ className: "grid gap-0.5",
213
+ style: { gridTemplateColumns: "repeat(8, minmax(0, 1fr))" },
208
214
  children: [query ? null : /* @__PURE__ */ jsx("button", {
209
215
  type: "button",
210
216
  role: "radio",
211
217
  "aria-checked": !value,
212
218
  "aria-label": "No icon",
213
219
  onClick: () => onPick(void 0),
214
- className: cn("flex size-8 items-center justify-center rounded-kit-md text-kit-fg-3 hover:bg-kit-hover", !value && "bg-kit-selected"),
215
- children: /* @__PURE__ */ jsx("span", { className: "size-4 rounded-kit-md border border-dashed border-[var(--kit-emphasis-line)]" })
220
+ className: tile(!value),
221
+ children: /* @__PURE__ */ jsx(IconX, {
222
+ className: "size-4",
223
+ stroke: 1.5,
224
+ "aria-hidden": true
225
+ })
216
226
  }), shown.map((n) => /* @__PURE__ */ jsx("button", {
217
227
  type: "button",
218
228
  role: "radio",
219
229
  "aria-checked": value === n,
220
230
  "aria-label": iconLabel(n),
221
231
  onClick: () => onPick(n),
222
- className: cn("flex size-8 items-center justify-center rounded-kit-md text-kit-fg-2 hover:bg-kit-hover hover:text-kit-fg", value === n && "bg-kit-selected text-kit-fg"),
232
+ className: tile(value === n),
223
233
  children: /* @__PURE__ */ jsx(KitIcon, {
224
234
  name: n,
225
- className: "size-4"
235
+ className: "size-[18px]"
226
236
  })
227
237
  }, n))]
228
- }),
229
- shown.length === 0 ? /* @__PURE__ */ jsxs("p", {
230
- className: "px-1 text-kit-xs text-kit-fg-3",
238
+ }), shown.length === 0 ? /* @__PURE__ */ jsxs("p", {
239
+ className: "py-6 text-center text-kit-sm text-kit-fg-3",
231
240
  children: [
232
- "No icon matches “",
233
- q.trim(),
234
- "”."
241
+ "No icons match “",
242
+ q,
243
+ "”"
235
244
  ]
236
- }) : null
237
- ]
245
+ }) : null]
246
+ })]
238
247
  });
239
248
  }
240
249
  /** The ONE button screen: preview · label · link (+ new tab, rel) · appearance (style, size, icon, arrow). */
@@ -251,11 +260,8 @@ function ButtonScreen({ value, onChange, readOnly, title = "Button" }) {
251
260
  children: [
252
261
  /* @__PURE__ */ jsx("div", {
253
262
  "data-button-preview": "",
254
- className: "flex min-h-20 items-center justify-center rounded-kit-lg bg-[color:var(--kit-preview-paper,var(--kit-subtle))] px-4 py-5 [filter:var(--kit-preview-filter,none)]",
255
- children: /* @__PURE__ */ jsx(ButtonPreview, {
256
- v,
257
- site: true
258
- })
263
+ className: "flex min-h-20 items-center justify-center rounded-kit-lg bg-kit-preview-paper px-4 py-5 [filter:var(--kit-paper-filter)]",
264
+ children: /* @__PURE__ */ jsx(ButtonPreview, { v })
259
265
  }),
260
266
  /* @__PURE__ */ jsx(Row, {
261
267
  label: "Label",
@@ -329,7 +335,7 @@ function ButtonScreen({ value, onChange, readOnly, title = "Button" }) {
329
335
  children: [/* @__PURE__ */ jsxs(PopoverTrigger, {
330
336
  render: /* @__PURE__ */ jsx("button", {
331
337
  type: "button",
332
- className: "flex h-8 w-full items-center gap-2 rounded-kit-md border border-kit-field-border bg-kit-field-bg px-2.5 text-left text-kit-sm text-kit-fg shadow-kit-field hover:border-kit-field-border-hover data-[popup-open]:border-kit-field-border-focus"
338
+ className: "flex h-8 w-full items-center gap-2 rounded-kit-md border border-kit-field-border bg-kit-field-bg px-2.5 text-left text-kit-sm text-kit-fg hover:border-kit-field-border-hover"
333
339
  }),
334
340
  children: [
335
341
  v.icon ? /* @__PURE__ */ jsx(KitIcon, {
@@ -472,7 +478,7 @@ function ButtonControl({ value, onChange, readOnly, id, path, field }) {
472
478
  type: "button",
473
479
  disabled: readOnly,
474
480
  onClick: () => setEditingLink(true),
475
- "aria-label": hasLink(v) ? `${field.title} link: ${describeLink(v, target).primary}. Edit link` : `Add a link to ${field.title.toLowerCase()}`,
481
+ "aria-label": hasLink(v) ? `${field.title} link: ${linkText(v)}. Edit link` : `Add a link to ${field.title.toLowerCase()}`,
476
482
  className: cn("flex w-full min-w-0 items-center px-2.5 text-left outline-none transition-colors hover:bg-kit-hover focus-visible:bg-kit-hover disabled:cursor-default disabled:hover:bg-transparent", h),
477
483
  children: /* @__PURE__ */ jsx(LinkLine, {
478
484
  v,
@@ -501,7 +507,72 @@ function ButtonControl({ value, onChange, readOnly, id, path, field }) {
501
507
  })]
502
508
  });
503
509
  }
510
+ function ButtonLinkEditor({ value, onChange, onSubmit, styles = STYLE_ITEMS, labelFirst = true }) {
511
+ const v = normLink(value);
512
+ const labelId = React.useId();
513
+ const setStyle = (s) => onChange({
514
+ ...v,
515
+ style: s,
516
+ variant: s
517
+ });
518
+ return /* @__PURE__ */ jsxs("div", {
519
+ className: "flex flex-col gap-3",
520
+ children: [
521
+ labelFirst ? /* @__PURE__ */ jsxs("div", {
522
+ className: "flex flex-col gap-1.5",
523
+ children: [/* @__PURE__ */ jsx("label", {
524
+ htmlFor: labelId,
525
+ className: "text-kit-xs font-medium text-kit-fg-2",
526
+ children: "Label"
527
+ }), /* @__PURE__ */ jsx(Input, {
528
+ id: labelId,
529
+ size: "sm",
530
+ autoFocus: true,
531
+ value: v.label ?? "",
532
+ onChange: (e) => onChange({
533
+ ...v,
534
+ label: e.target.value
535
+ }),
536
+ onKeyDown: (e) => e.key === "Enter" && (e.preventDefault(), onSubmit?.()),
537
+ placeholder: "Shop cookware"
538
+ })]
539
+ }) : null,
540
+ /* @__PURE__ */ jsxs("div", {
541
+ className: "flex flex-col gap-2.5",
542
+ role: "group",
543
+ "aria-label": "Link",
544
+ children: [/* @__PURE__ */ jsx("span", {
545
+ className: "text-kit-xs font-medium text-kit-fg-2",
546
+ children: "Link"
547
+ }), /* @__PURE__ */ jsx(LinkForm, {
548
+ value: v,
549
+ onChange: (n) => onChange({
550
+ ...v,
551
+ ...n,
552
+ label: v.label,
553
+ style: v.style,
554
+ variant: v.variant
555
+ }),
556
+ onEnter: () => onSubmit?.()
557
+ })]
558
+ }),
559
+ styles ? /* @__PURE__ */ jsxs("div", {
560
+ className: "flex items-center justify-between gap-3 border-t border-kit-line pt-2.5",
561
+ children: [/* @__PURE__ */ jsx("span", {
562
+ className: "text-kit-xs text-kit-fg-2",
563
+ children: "Style"
564
+ }), /* @__PURE__ */ jsx(Segmented, {
565
+ size: "sm",
566
+ "aria-label": "Button style",
567
+ value: v.style ?? "primary",
568
+ onChange: (s) => setStyle(s),
569
+ items: styles
570
+ })]
571
+ }) : null
572
+ ]
573
+ });
574
+ }
504
575
  //#endregion
505
- export { ButtonControl, ButtonScreen };
576
+ export { BUTTON_ICONS, ButtonControl, ButtonIconPicker, ButtonLinkEditor, ButtonPreview, ButtonScreen, ButtonStyleGrid, STYLE_ITEMS, StyleGlyph, lookLabel, lookOf, nextButton };
506
577
 
507
578
  //# sourceMappingURL=button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.js","names":[],"sources":["../../src/controls/button.tsx"],"sourcesContent":["/**\n * BUTTON — label + link + look as ONE unit (V2 HEAD kit/controls/link.tsx \"Button\", DESIGN §8.8, CPO D43 · D45 · D46).\n *\n * - <ButtonControl> at rest: one FieldUnit, two rows. The label row drills into the button screen (form.navigate → the\n * \"button\" frame); the link row edits the link in place (LinkQuickEdit).\n * - <ButtonScreen> the one button screen (the frame body): preview · label · link (LinkForm) · appearance (style grid,\n * size, leading icon, arrow).\n * - <ButtonStyleGrid>, <ButtonPreview>, <StyleGlyph> — the pieces both draw.\n *\n * Stored shape (prod `button`, adapters/values.ts buttonToProd / buttonFromProd; backend buttonValueProblem). The kit\n * value is the flattened V2 button the adapter hands in. What this control writes keeps that value's keys:\n * - the look goes in the key the value already uses — `style` when it has one, else `variant` (what prod renderers\n * read) — and never both (buttonToProd names an equal pair as lost, so the dock would refuse the write);\n * - `rel: \"follow\"` is never written (prod's rel list is nofollow · sponsored · ugc) and `newTab: false`/`target` only\n * where the stored value had that key (storedLink);\n * - `icon` is a dock icon name (DOCK_ICON_NAMES): the picker offers only icons that are dock names.\n *\n * \"Full width\" writes `fullWidth: true`, and off writes `false` only where the stored value had the key (as Show arrow);\n * every renderer draws it (hosted `bcms-btn-full`, the SDKs' and in-place publishing's `data-full-width`).\n *\n * Deviation from V2, because prod has nothing behind it: an unset look reads \"Default\" (V2 drew Primary, and guessed\n * Outline for a field named \"secondary\"). The preview is V2's: the site palette (--kit-preview-paper / -ink / -primary /\n * -primary-on / -contrast / -contrast-on / -outline, which a host may set to the project's colours) on the paper, and the\n * chrome swatches in the style grid.\n */\nimport * as React from \"react\";\nimport { IconArrowRight, IconChevronDown, IconChevronRight, IconSearch, IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { isObj } from \"../lib/path\";\nimport { KIT_ICONS, KitIcon, iconLabel } from \"../lib/icons\";\nimport { BUTTON_VARIANTS, DOCK_ICON_NAME_SET } from \"../adapters/prod-types\";\nimport { useForm, useKitEnv } from \"../context\";\nimport { FieldUnit } from \"../engine/grouping\";\nimport { Input } from \"../ui/input\";\nimport { Segmented, Switch } from \"../ui/controls\";\nimport { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from \"../ui/overlay\";\nimport type { ControlProps } from \"../types\";\nimport { LinkForm, LinkLine, LinkQuickEdit, TARGET_KEYS, finalizeLink, findTarget, hasLink, linkText, normLink, storedLink, useLinkTargets, type ButtonStyle, type LinkValue } from \"./link\";\n\nexport const STYLE_ITEMS: { value: ButtonStyle; label: string }[] = [\n { value: \"primary\", label: \"Primary\" },\n { value: \"secondary\", label: \"Secondary\" },\n { value: \"outline\", label: \"Outline\" },\n { value: \"link\", label: \"Text link\" },\n];\nconst SIZE_LABEL = { sm: \"Small\", md: \"Medium\", lg: \"Large\" } as const;\nconst isVariant = (x: unknown): x is string => typeof x === \"string\" && (BUTTON_VARIANTS as readonly string[]).includes(x);\n\n/** The look prod renders: the first valid of variant, style (buttonToProd's rule). */\nexport function lookOf(v: Pick<LinkValue, \"variant\" | \"style\">): string | undefined {\n return [v.variant, v.style].find(isVariant);\n}\n/** \"Brand\" for a stored look outside the four styles; undefined when unset. */\nexport function lookLabel(look: string | undefined): string {\n if (!look) return \"Default\";\n return STYLE_ITEMS.find((s) => s.value === look)?.label ?? look.charAt(0).toUpperCase() + look.slice(1);\n}\n\n/**\n * The next stored button: `raw` (the value as the field holds it) with `patch` applied, keyed like `raw`. A look in the\n * patch (`style`) lands in the key `raw` uses for it.\n */\nexport function nextButton(raw: unknown, patch: Partial<LinkValue>): LinkValue {\n const base: LinkValue = isObj(raw) ? ({ ...(raw as object) } as LinkValue) : { href: \"\" };\n const { style, ...rest } = patch;\n const out: LinkValue = { ...base, ...rest };\n // prod requires both strings (buttonToProd names a missing one as lost, and the dock refuses the write)\n if (typeof out.href !== \"string\") out.href = \"\";\n if (typeof out.label !== \"string\") out.label = \"\";\n if (style !== undefined) {\n const key = isObj(raw) && raw.style !== undefined ? \"style\" : \"variant\";\n delete out.style;\n delete out.variant;\n out[key] = style;\n }\n return storedLink(out, raw);\n}\n\n/** The icons a button can carry: the kit's drawn icons that are also dock names (the backend checks the name). */\nexport const BUTTON_ICONS: string[] = Object.keys(KIT_ICONS).filter((n) => DOCK_ICON_NAME_SET.has(n));\n\n/** D46: four styles never sit in a row of tabs. The option IS the visual, so it is a 2×2 grid of live previews (one\n * radiogroup: Tab enters on the checked style, arrows move and pick). A stored look outside the four is listed too. */\nexport function ButtonStyleGrid({\n v,\n onPick,\n \"aria-label\": ariaLabel,\n size = \"md\",\n}: {\n v: LinkValue;\n onPick: (s: ButtonStyle) => void;\n \"aria-label\": string;\n size?: \"sm\" | \"md\";\n}) {\n const cur = lookOf(v);\n const items: { value: string; label: string }[] = cur && !STYLE_ITEMS.some((s) => s.value === cur) ? [...STYLE_ITEMS, { value: cur, label: lookLabel(cur) }] : STYLE_ITEMS;\n const onKey = (e: React.KeyboardEvent, i: number) => {\n const d = e.key === \"ArrowRight\" || e.key === \"ArrowDown\" ? 1 : e.key === \"ArrowLeft\" || e.key === \"ArrowUp\" ? -1 : 0;\n if (!d) return;\n e.preventDefault();\n const next = items[(i + d + items.length) % items.length];\n onPick(next.value as ButtonStyle);\n const group = (e.currentTarget as HTMLElement).parentElement;\n requestAnimationFrame(() => group?.querySelector<HTMLElement>(`[data-style=\"${next.value}\"]`)?.focus());\n };\n return (\n <div className=\"grid grid-cols-2 gap-1.5\" role=\"radiogroup\" aria-label={ariaLabel}>\n {items.map((s, i) => {\n const on = cur === s.value;\n return (\n <button\n key={s.value}\n type=\"button\"\n role=\"radio\"\n data-style={s.value}\n aria-checked={on}\n tabIndex={on || (!items.some((x) => x.value === cur) && i === 0) ? 0 : -1}\n onKeyDown={(e) => onKey(e, i)}\n onClick={() => onPick(s.value as ButtonStyle)}\n className={cn(\n \"flex min-w-0 items-center gap-2 rounded-kit-md border px-2 transition-colors\",\n size === \"sm\" ? \"h-8 text-kit-xs\" : \"h-9 text-kit-sm\",\n on ? \"border-[var(--kit-emphasis-line)] bg-kit-selected text-kit-fg\" : \"border-kit-line text-kit-fg-2 hover:border-kit-line-strong hover:text-kit-fg\",\n )}\n >\n <ButtonPreview v={{ ...v, style: s.value as ButtonStyle, variant: undefined, label: \"Aa\", icon: undefined, arrow: false }} small chrome />\n <span className=\"truncate\">{s.label}</span>\n </button>\n );\n })}\n </div>\n );\n}\n\n/**\n * The site's button as the site draws it (V2 link.tsx ButtonPreview: the site palette, not app tokens). On the preview\n * paper it keeps the site's own colours in both themes; `chrome` = drawn on app chrome (the style grid), where the\n * dark-ink styles flip so they still read on a dark panel. Prod looks beyond the four: brand as primary, dark as\n * secondary, any other in the muted kit fill.\n */\nexport function ButtonPreview({ v, className, small, chrome }: { v: LinkValue; className?: string; small?: boolean; chrome?: boolean }) {\n const look = lookOf(v) ?? \"primary\";\n const style = look === \"brand\" ? \"primary\" : look === \"dark\" ? \"secondary\" : look;\n const size = small ? \"sm\" : v.size ?? \"md\";\n return (\n <span\n className={cn(\n \"inline-flex max-w-full items-center justify-center gap-1.5 truncate font-medium transition-colors\",\n size === \"sm\" ? \"h-6 rounded-kit-md px-2 text-kit-xs\" : size === \"lg\" ? \"h-10 rounded-kit-lg px-4 text-kit-base\" : \"h-8 rounded-kit-lg px-3 text-kit-sm\",\n style === \"primary\" && \"bg-kit-preview-primary text-kit-preview-primary-on\",\n style === \"secondary\" && (chrome ? \"bg-kit-preview-contrast text-kit-preview-contrast-on\" : \"bg-kit-preview-ink text-kit-preview-paper\"),\n style === \"outline\" && (chrome ? \"border border-kit-preview-outline text-kit-fg\" : \"border border-kit-preview-ink/25 text-kit-preview-ink\"),\n style === \"link\" && \"h-auto px-0 text-kit-preview-primary underline underline-offset-4\",\n !STYLE_ITEMS.some((x) => x.value === style) && \"bg-kit-muted text-kit-fg\",\n v.fullWidth && !small && \"w-full\",\n className,\n )}\n >\n {v.icon ? <KitIcon name={v.icon} className=\"size-3.5 shrink-0\" /> : null}\n <span className=\"truncate\">{v.label || \"Button\"}</span>\n {v.arrow ? <IconArrowRight className=\"size-3.5 shrink-0\" stroke={1.75} /> : null}\n </span>\n );\n}\n\n/** A 16px neutral glyph of the style (filled · outlined · underlined) — brand-free, so the field stays calm. */\nexport function StyleGlyph({ style, className }: { style?: string; className?: string }) {\n return (\n <span aria-hidden className={cn(\"flex size-4 shrink-0 items-center justify-center\", className)}>\n {style === \"link\" ? (\n <span className=\"h-[2px] w-3.5 rounded-full bg-kit-fg-2\" />\n ) : (\n <span className={cn(\"h-2.5 w-4 rounded-[3px]\", style === \"outline\" ? \"border-[1.5px] border-kit-fg-2\" : style === \"secondary\" || style === \"light\" || style === \"tertiary\" ? \"bg-kit-fg-3\" : \"bg-kit-fg\")} />\n )}\n </span>\n );\n}\n\n/** The leading-icon picker over BUTTON_ICONS, \"No icon\" first: V2's IconPickerGrid (icon.tsx) — search box, 8-column\n * grid in a 224px scroll. The tiles stay one radiogroup (the dash's semantics; V2 draws a listbox). */\nexport function ButtonIconPicker({ value, onPick }: { value?: string; onPick: (icon: string | undefined) => void }) {\n const [q, setQ] = React.useState(\"\");\n const query = q.trim().toLowerCase();\n const shown = query ? BUTTON_ICONS.filter((n) => n.includes(query.replace(/\\s+/g, \"-\"))) : BUTTON_ICONS;\n const tile = (on: boolean) =>\n cn(\"flex aspect-square items-center justify-center rounded-kit-md text-kit-fg-2 transition-colors hover:bg-kit-hover hover:text-kit-fg\", on && \"bg-kit-selected text-kit-fg ring-1 ring-inset ring-kit-line-strong\");\n return (\n <div data-icon-picker className=\"flex flex-col gap-2\">\n <label className=\"flex h-8 items-center gap-2 rounded-kit-md bg-kit-muted px-2.5 text-kit-fg-3 focus-within:bg-kit-field-bg focus-within:ring-1 focus-within:ring-kit-line-strong\">\n <IconSearch className=\"size-4 shrink-0\" stroke={1.5} aria-hidden />\n <input\n autoFocus\n value={q}\n onChange={(e) => setQ(e.target.value)}\n placeholder=\"Search icons\"\n aria-label=\"Search icons\"\n className=\"h-full min-w-0 flex-1 bg-transparent text-kit-sm text-kit-fg outline-none placeholder:text-kit-fg-3\"\n />\n </label>\n <div className=\"max-h-56 overflow-y-auto pr-0.5\">\n <div role=\"radiogroup\" aria-label=\"Leading icon\" className=\"grid gap-0.5\" style={{ gridTemplateColumns: \"repeat(8, minmax(0, 1fr))\" }}>\n {query ? null : (\n <button type=\"button\" role=\"radio\" aria-checked={!value} aria-label=\"No icon\" onClick={() => onPick(undefined)} className={tile(!value)}>\n <IconX className=\"size-4\" stroke={1.5} aria-hidden />\n </button>\n )}\n {shown.map((n) => (\n <button key={n} type=\"button\" role=\"radio\" aria-checked={value === n} aria-label={iconLabel(n)} onClick={() => onPick(n)} className={tile(value === n)}>\n <KitIcon name={n} className=\"size-[18px]\" />\n </button>\n ))}\n </div>\n {shown.length === 0 ? <p className=\"py-6 text-center text-kit-sm text-kit-fg-3\">No icons match “{q}”</p> : null}\n </div>\n </div>\n );\n}\n\n/** The ONE button screen: preview · label · link (+ new tab, rel) · appearance (style, size, icon, arrow). */\nexport function ButtonScreen({ value, onChange, readOnly, title = \"Button\" }: { value: unknown; onChange: (v: LinkValue) => void; readOnly?: boolean; title?: string }) {\n const v = normLink(value);\n const set = (p: Partial<LinkValue>) => onChange(nextButton(value, p));\n const [iconOpen, setIconOpen] = React.useState(false);\n const labelId = React.useId();\n const arrowId = React.useId();\n const fullId = React.useId();\n return (\n <fieldset disabled={readOnly} className=\"flex min-w-0 flex-col gap-5\">\n <div data-button-preview=\"\" className=\"flex min-h-20 items-center justify-center rounded-kit-lg bg-kit-preview-paper px-4 py-5 [filter:var(--kit-paper-filter)]\">\n <ButtonPreview v={v} />\n </div>\n <Row label=\"Label\" htmlFor={labelId}>\n <Input id={labelId} value={v.label ?? \"\"} onChange={(e) => set({ label: e.target.value })} placeholder=\"Shop now\" />\n </Row>\n <div className=\"flex flex-col gap-1.5\" role=\"group\" aria-label={`${title} link`}>\n <span className=\"text-kit-sm font-medium text-kit-fg-2\">Link</span>\n <LinkForm\n readOnly={readOnly}\n value={v}\n onChange={(n) => {\n // a script link is never written; LinkForm says why under the target\n const out = finalizeLink(n);\n if (out) set(linkPart(out));\n }}\n />\n </div>\n <div className=\"flex flex-col gap-4 border-t border-kit-line pt-4\">\n <span className=\"text-kit-xs font-medium text-kit-fg-3\">Appearance</span>\n <Row label=\"Style\">\n <ButtonStyleGrid v={v} aria-label={`${title} style`} onPick={(style) => set({ style })} />\n </Row>\n <Row label=\"Size\">\n <Segmented<\"sm\" | \"md\" | \"lg\">\n aria-label={`${title} size`}\n value={v.size ?? \"md\"}\n onChange={(s) => set({ size: s })}\n items={[\n { value: \"sm\", label: \"Small\" },\n { value: \"md\", label: \"Medium\" },\n { value: \"lg\", label: \"Large\" },\n ]}\n className=\"w-full [&>button]:flex-1\"\n />\n </Row>\n <Row label=\"Leading icon\">\n <Popover open={iconOpen} onOpenChange={setIconOpen}>\n <PopoverTrigger\n render={\n <button\n type=\"button\"\n className=\"flex h-8 w-full items-center gap-2 rounded-kit-md border border-kit-field-border bg-kit-field-bg px-2.5 text-left text-kit-sm text-kit-fg hover:border-kit-field-border-hover\"\n />\n }\n >\n {v.icon ? <KitIcon name={v.icon} className=\"size-4 text-kit-fg-2\" /> : <span className=\"size-4 rounded-kit-md border border-dashed border-[var(--kit-emphasis-line)]\" />}\n <span className={cn(\"flex-1 truncate\", !v.icon && \"text-kit-fg-3\")}>{v.icon ? iconLabel(v.icon) : \"No icon\"}</span>\n <IconChevronDown className=\"size-3.5 text-kit-fg-3\" stroke={1.5} />\n </PopoverTrigger>\n <PopoverContent className=\"w-[300px] p-2\">\n <ButtonIconPicker\n value={v.icon}\n onPick={(k) => {\n set({ icon: k });\n setIconOpen(false);\n }}\n />\n </PopoverContent>\n </Popover>\n </Row>\n <div className=\"flex flex-col gap-2\">\n <label htmlFor={arrowId} className=\"flex min-h-7 cursor-pointer items-center justify-between gap-3\">\n <span className=\"text-kit-sm text-kit-fg-2\">Show arrow</span>\n <Switch disabled={readOnly} id={arrowId} size=\"sm\" checked={!!v.arrow} onCheckedChange={(c) => set({ arrow: c ? true : isObj(value) && \"arrow\" in value ? false : undefined })} />\n </label>\n <label htmlFor={fullId} className=\"flex min-h-7 cursor-pointer items-center justify-between gap-3\">\n <span className=\"text-kit-sm text-kit-fg-2\">Full width</span>\n <Switch\n disabled={readOnly}\n id={fullId}\n size=\"sm\"\n checked={v.fullWidth === true}\n onCheckedChange={(c) => set({ fullWidth: c ? true : isObj(value) && \"fullWidth\" in value ? false : undefined })}\n />\n </label>\n </div>\n </div>\n </fieldset>\n );\n}\n\n/** The link half of a link value (what LinkForm / the quick edit own); the label and the look stay the button's. */\nfunction linkPart(n: LinkValue): Partial<LinkValue> {\n const { label: _l, style: _s, variant: _v, size: _z, arrow: _a, icon: _i, fullWidth: _f, ...link } = n;\n // a key the new link no longer has (a picked page drops the typed email) is cleared, not kept from before\n return { ...TARGET_KEYS, email: undefined, phone: undefined, subject: undefined, ...link };\n}\n\nfunction Row({ label, children, htmlFor }: { label: string; children: React.ReactNode; htmlFor?: string }) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n <label htmlFor={htmlFor} className=\"text-kit-sm font-medium text-kit-fg-2\">\n {label}\n </label>\n {children}\n </div>\n );\n}\n\n/**\n * Button field at rest: ONE unit between two hairlines (fieldset-like).\n * [style glyph] Label ……………… Primary · Medium › → drills into the button screen (\"… › Button\")\n * [page icon] Title /path → edits the link in place\n */\nexport function ButtonControl({ value, onChange, readOnly, id, path, field }: ControlProps) {\n const v = normLink(value);\n const form = useForm();\n const { variant } = useKitEnv();\n const [open, setOpen] = React.useState(false);\n const [editingLink, setEditingLink] = React.useState(false);\n const { targets } = useLinkTargets();\n const target = findTarget(targets, v);\n const linkBtn = React.useRef<HTMLButtonElement>(null);\n const look = lookOf(v);\n const openSettings = () => (form ? form.navigate(path) : setOpen(true));\n const h = variant === \"document\" ? \"h-10\" : \"h-9\";\n const head = (\n <button\n id={id}\n type=\"button\"\n onClick={readOnly && !form ? undefined : openSettings}\n aria-label={`${field.title}: ${v.label || \"no label\"}. Open button settings`}\n className={cn(\"group/bhead flex w-full min-w-0 items-center gap-2.5 px-2.5 text-left outline-none transition-colors hover:bg-kit-hover focus-visible:bg-kit-hover\", h)}\n >\n <StyleGlyph style={look} />\n <span className={cn(\"min-w-0 flex-1 truncate text-kit-sm font-medium\", v.label ? \"text-kit-fg\" : \"text-kit-fg-3\")}>{v.label || \"Add a label\"}</span>\n <span className=\"shrink-0 text-kit-xs text-kit-fg-3\">\n {lookLabel(look)}\n {v.size && v.size !== \"md\" ? ` · ${SIZE_LABEL[v.size]}` : \"\"}\n </span>\n <IconChevronRight className=\"size-4 shrink-0 text-kit-fg-3 transition-transform group-hover/bhead:translate-x-0.5\" stroke={1.5} aria-hidden />\n </button>\n );\n const linkRow =\n editingLink && !readOnly ? (\n <div>\n <LinkQuickEdit\n value={v}\n ariaLabel={`${field.title} link`}\n size=\"sm\"\n bare\n onCommit={(n) => onChange(nextButton(value, n ? linkPart(n) : { ...linkPart({ href: \"\" }), type: \"page\", href: \"\" }))}\n onDone={() => {\n setEditingLink(false);\n requestAnimationFrame(() => linkBtn.current?.focus({ preventScroll: true }));\n }}\n />\n </div>\n ) : (\n <button\n ref={linkBtn}\n type=\"button\"\n disabled={readOnly}\n onClick={() => setEditingLink(true)}\n // V2 link.tsx:1263: the name reads the link's own text (its title, else its address), not the picked target's title\n aria-label={hasLink(v) ? `${field.title} link: ${linkText(v)}. Edit link` : `Add a link to ${field.title.toLowerCase()}`}\n className={cn(\"flex w-full min-w-0 items-center px-2.5 text-left outline-none transition-colors hover:bg-kit-hover focus-visible:bg-kit-hover disabled:cursor-default disabled:hover:bg-transparent\", h)}\n >\n <LinkLine v={v} target={target} />\n </button>\n );\n // CPO D43 + D45: label + link are ONE unit — one border, a hairline between the label row and the link row\n const unit = (\n <FieldUnit data-button-unit=\"\" aria-label={field.title} className=\"overflow-hidden\">\n {head}\n {linkRow}\n </FieldUnit>\n );\n if (form) return unit;\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverAnchor render={unit} />\n <PopoverContent className=\"w-[360px] p-4\" align=\"start\">\n <ButtonScreen value={value} onChange={onChange} readOnly={readOnly} title={field.title} />\n </PopoverContent>\n </Popover>\n );\n}\n\n/* ── Compact button editor for small surfaces (the canvas popover) ──\n * V2 kit/controls/link.tsx ButtonLinkEditor, ported as is: label + the link element (LinkForm, same Type · target ·\n * options as everywhere) as one unit, then the button's Style. Here beside STYLE_ITEMS, which link.tsx cannot import.\n */\nexport function ButtonLinkEditor({\n value,\n onChange,\n onSubmit,\n styles = STYLE_ITEMS,\n labelFirst = true,\n}: {\n value: LinkValue;\n onChange: (v: LinkValue) => void;\n onSubmit?: () => void;\n /** null = a plain text link (nav, footer and legal links): no style row. */\n styles?: { value: ButtonStyle; label: string }[] | null;\n labelFirst?: boolean;\n}) {\n const v = normLink(value);\n const labelId = React.useId();\n const setStyle = (s: ButtonStyle) => onChange({ ...v, style: s, variant: s });\n return (\n <div className=\"flex flex-col gap-3\">\n {labelFirst ? (\n <div className=\"flex flex-col gap-1.5\">\n <label htmlFor={labelId} className=\"text-kit-xs font-medium text-kit-fg-2\">Label</label>\n <Input id={labelId} size=\"sm\" autoFocus value={v.label ?? \"\"} onChange={(e) => onChange({ ...v, label: e.target.value })} onKeyDown={(e) => e.key === \"Enter\" && (e.preventDefault(), onSubmit?.())} placeholder=\"Shop cookware\" />\n </div>\n ) : null}\n <div className=\"flex flex-col gap-2.5\" role=\"group\" aria-label=\"Link\">\n <span className=\"text-kit-xs font-medium text-kit-fg-2\">Link</span>\n <LinkForm value={v} onChange={(n) => onChange({ ...v, ...n, label: v.label, style: v.style, variant: v.variant })} onEnter={() => onSubmit?.()} />\n </div>\n {styles ? (\n <div className=\"flex items-center justify-between gap-3 border-t border-kit-line pt-2.5\">\n <span className=\"text-kit-xs text-kit-fg-2\">Style</span>\n <Segmented size=\"sm\" aria-label=\"Button style\" value={v.style ?? \"primary\"} onChange={(s) => setStyle(s as ButtonStyle)} items={styles} />\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ import { ACTIONS, CONTROLS } from "../engine/kit-field.js";
2
2
  import { EmailControl, SlugControl, SlugGenerate, StringControl, TextControl, UrlControl } from "./text.js";
3
3
  import { ColorControl } from "./color.js";
4
4
  import { NumberControl, RatingControl } from "./number.js";
5
- //#region src/kit/controls/c1.ts
5
+ //#region src/controls/c1.ts
6
6
  var C1_CONTROLS = {
7
7
  string: StringControl,
8
8
  text: TextControl,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c1.js","names":[],"sources":["../../src/controls/c1.ts"],"sourcesContent":["/**\n * Lane C1 (text, slug, email, url, number, rating, color): the controls and label-row actions this lane ports, keyed by\n * kit type, for the engine's CONTROLS / ACTIONS tables. `registerC1Controls()` puts them in; a registered type stops\n * drawing the host's legacy control.\n */\nimport type { ComponentType } from \"react\";\nimport type { SchemaType } from \"../schema/types\";\nimport type { ControlProps } from \"../types\";\nimport { ACTIONS, CONTROLS } from \"../engine/kit-field\";\nimport { ColorControl } from \"./color\";\nimport { NumberControl, RatingControl } from \"./number\";\nimport { EmailControl, SlugControl, SlugGenerate, StringControl, TextControl, UrlControl } from \"./text\";\n\nexport const C1_CONTROLS: Partial<Record<SchemaType, ComponentType<ControlProps>>> = {\n string: StringControl,\n text: TextControl,\n email: EmailControl,\n url: UrlControl,\n slug: SlugControl,\n number: NumberControl,\n rating: RatingControl,\n color: ColorControl,\n};\nexport const C1_ACTIONS: Partial<Record<SchemaType, ComponentType<ControlProps>>> = { slug: SlugGenerate };\n\nexport function registerC1Controls() {\n Object.assign(CONTROLS, C1_CONTROLS);\n Object.assign(ACTIONS, C1_ACTIONS);\n}\n"],"mappings":";;;;;AAaA,IAAa,cAAwE;CACnF,QAAQ;CACR,MAAM;CACN,OAAO;CACP,KAAK;CACL,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,OAAO;AACT;AACA,IAAa,aAAuE,EAAE,MAAM,aAAa;AAEzG,SAAgB,qBAAqB;CACnC,OAAO,OAAO,UAAU,WAAW;CACnC,OAAO,OAAO,SAAS,UAAU;AACnC"}
@@ -2,7 +2,7 @@ import { CONTROLS } from "../engine/kit-field.js";
2
2
  import { NUMBER_SCALE } from "./number.js";
3
3
  import { BooleanControl, MultiSelectControl, SelectControl, TagsControl } from "./choice.js";
4
4
  import { ScaleControl } from "./scale.js";
5
- //#region src/kit/controls/c2.ts
5
+ //#region src/controls/c2.ts
6
6
  var C2_CONTROLS = {
7
7
  boolean: BooleanControl,
8
8
  select: SelectControl,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c2.js","names":[],"sources":["../../src/controls/c2.ts"],"sourcesContent":["/**\n * Lane C2 (boolean, select, multiselect, tags, and the scale capsule for a number with a scale): the controls this lane\n * ports, keyed by kit type, for the engine's CONTROLS table. `registerC2Controls()` puts them in and hands the scale\n * control to the number control (lane C1's NUMBER_SCALE hook); a registered type stops drawing the host's legacy control.\n */\nimport type { ComponentType } from \"react\";\nimport type { SchemaType } from \"../schema/types\";\nimport type { ControlProps } from \"../types\";\nimport { CONTROLS } from \"../engine/kit-field\";\nimport { BooleanControl, MultiSelectControl, SelectControl, TagsControl } from \"./choice\";\nimport { NUMBER_SCALE } from \"./number\";\nimport { ScaleControl } from \"./scale\";\n\nexport const C2_CONTROLS: Partial<Record<SchemaType, ComponentType<ControlProps>>> = {\n boolean: BooleanControl,\n select: SelectControl,\n multiselect: MultiSelectControl,\n tags: TagsControl,\n};\n\nexport function registerC2Controls() {\n Object.assign(CONTROLS, C2_CONTROLS);\n NUMBER_SCALE.control = ScaleControl;\n}\n"],"mappings":";;;;;AAaA,IAAa,cAAwE;CACnF,SAAS;CACT,QAAQ;CACR,aAAa;CACb,MAAM;AACR;AAEA,SAAgB,qBAAqB;CACnC,OAAO,OAAO,UAAU,WAAW;CACnC,aAAa,UAAU;AACzB"}
@@ -31,8 +31,13 @@ export declare function optionIcons(options: Option[], className?: string, Glyph
31
31
  export declare function useOwnDescription(ref: React.RefObject<HTMLElement | null>, ownId: string | null): void;
32
32
  /** Boolean switch (used inside the switch card the shell draws). Commits immediately. */
33
33
  export declare function BooleanControl({ field, value, onChange, readOnly, id }: ControlProps): import("react/jsx-runtime").JSX.Element;
34
- export declare function SelectControl({ field, value, onChange, readOnly, id }: ControlProps): import("react/jsx-runtime").JSX.Element;
35
- export declare function MultiSelectControl({ field, value, onChange, readOnly, id }: ControlProps): import("react/jsx-runtime").JSX.Element;
34
+ /**
35
+ * A stored value none of the options names any more (renamed or removed) is kept and flagged under the control, with
36
+ * change-to and remove (H4). @see UnknownValueNote
37
+ */
38
+ export declare function SelectControl(props: ControlProps): import("react/jsx-runtime").JSX.Element;
39
+ /** As `SelectControl`: each stored choice no option names any more is kept and flagged, with change-to and remove. */
40
+ export declare function MultiSelectControl(props: ControlProps): import("react/jsx-runtime").JSX.Element;
36
41
  /** Why a typed tag is not added, or null when it is (the backend's own checks, said in words). */
37
42
  export declare function tagRefusal(tag: string, list: string[]): string | null;
38
43
  /** Chip input. Says so at its limit, and says why a tag was not added, instead of silently dropping it. */
@@ -1,16 +1,18 @@
1
+ import "../adapters/prod-types.js";
2
+ import { dockIconOf } from "../adapters/icons.js";
1
3
  import { cn } from "../lib/cn.js";
2
- import { KitIcon, iconKey } from "../lib/icons.js";
3
4
  import { useKitEnv, useKitServices } from "../context.js";
5
+ import { KitIcon, iconKey } from "../lib/icons.js";
4
6
  import { shortcutHintsOn } from "../ui/shortcut-hint.js";
5
7
  import { Checkbox, Segmented, Switch } from "../ui/controls.js";
6
8
  import { Popover, PopoverContent, PopoverTrigger } from "../ui/overlay.js";
7
9
  import { Select } from "../ui/select.js";
8
10
  import { fitsSegmented } from "../ui/choice-switch.js";
9
- import { dockIconOf } from "../adapters/icons.js";
11
+ import { UnknownValueNote } from "./unknown-value.js";
10
12
  import * as React from "react";
11
- import { IconCheck, IconPlus, IconX } from "@tabler/icons-react";
12
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
- //#region src/kit/controls/choice.tsx
14
+ import { IconCheck, IconPlus, IconX } from "@tabler/icons-react";
15
+ //#region src/controls/choice.tsx
14
16
  /**
15
17
  * CHOICE — boolean · select · multiselect · tags (V2 HEAD 9829bf1 kit/controls/choice.tsx, DESIGN 8.10–8.12).
16
18
  * Rule (production): few options → segmented, many → dropdown, many values → checkboxes, on/off → switch card.
@@ -101,7 +103,9 @@ function BooleanControl({ field, value, onChange, readOnly, id }) {
101
103
  checked: Boolean(value),
102
104
  disabled: readOnly,
103
105
  onCheckedChange: (c) => onChange(c === true),
104
- "aria-label": field.title
106
+ "aria-label": field.title,
107
+ nativeButton: true,
108
+ render: /* @__PURE__ */ jsx("button", { type: "button" })
105
109
  });
106
110
  return /* @__PURE__ */ jsx(Switch, {
107
111
  id,
@@ -113,7 +117,32 @@ function BooleanControl({ field, value, onChange, readOnly, id }) {
113
117
  render: /* @__PURE__ */ jsx("button", { type: "button" })
114
118
  });
115
119
  }
116
- function SelectControl({ field, value, onChange, readOnly, id }) {
120
+ /**
121
+ * A stored value none of the options names any more (renamed or removed) is kept and flagged under the control, with
122
+ * change-to and remove (H4). @see UnknownValueNote
123
+ */
124
+ function SelectControl(props) {
125
+ const options = opts(props.field.options);
126
+ const v = str(props.value);
127
+ if (v === "" || options.length === 0 || options.some((o) => o.value === v)) return /* @__PURE__ */ jsx(SelectInput, { ...props });
128
+ return /* @__PURE__ */ jsxs("div", {
129
+ className: "flex min-w-0 flex-col gap-1.5",
130
+ children: [/* @__PURE__ */ jsx(SelectInput, { ...props }), /* @__PURE__ */ jsx(UnknownValueNote, {
131
+ items: [{
132
+ key: v,
133
+ label: `“${v}”`,
134
+ options: options.map((o) => ({
135
+ value: o.value,
136
+ label: o.label
137
+ }))
138
+ }],
139
+ onRemap: (_, to) => props.onChange(to),
140
+ onRemove: () => props.onChange(null),
141
+ readOnly: props.readOnly
142
+ })]
143
+ });
144
+ }
145
+ function SelectInput({ field, value, onChange, readOnly, id }) {
117
146
  const { variant } = useKitEnv();
118
147
  const { IconGlyph } = useKitServices();
119
148
  const options = opts(field.options);
@@ -170,7 +199,8 @@ function SelectControl({ field, value, onChange, readOnly, id }) {
170
199
  }, o.value))
171
200
  });
172
201
  if (layout === "cards" || layout === "grid") {
173
- const icons = optionIcons(options, "size-4", IconGlyph);
202
+ const iconsOn = optionIcons(options, "size-4 text-kit-fg", IconGlyph);
203
+ const iconsOff = optionIcons(options, "size-4 text-kit-fg-3", IconGlyph);
174
204
  return /* @__PURE__ */ jsx("div", {
175
205
  role: "radiogroup",
176
206
  id,
@@ -187,12 +217,9 @@ function SelectControl({ field, value, onChange, readOnly, id }) {
187
217
  disabled: readOnly,
188
218
  onClick: () => pick(o.value),
189
219
  onKeyDown: (e) => keys.onKeyDown(e, i),
190
- className: cn("relative flex flex-col items-start gap-1.5 rounded-kit-lg border p-2.5 text-left transition-[border-color,box-shadow] duration-150 focus-visible:outline-offset-[-2px]", on ? "border-[var(--kit-emphasis-line)] bg-kit-control-bg shadow-kit-xs" : "border-kit-line hover:border-kit-line-strong"),
220
+ className: cn("relative flex flex-col items-start gap-1.5 rounded-kit-lg border p-2.5 text-left transition-[border-color,box-shadow] duration-150", on ? "border-[var(--kit-emphasis-line)] bg-kit-control-bg shadow-kit-xs" : "border-kit-line hover:border-kit-line-strong"),
191
221
  children: [
192
- icons[i] ? /* @__PURE__ */ jsx("span", {
193
- className: cn("[&_svg]:size-4", on ? "text-kit-fg" : "text-kit-fg-3"),
194
- children: icons[i]
195
- }) : null,
222
+ (on ? iconsOn : iconsOff)[i] ?? null,
196
223
  /* @__PURE__ */ jsx("span", {
197
224
  className: "text-kit-sm font-medium text-kit-fg",
198
225
  children: o.label
@@ -228,7 +255,30 @@ function SelectControl({ field, value, onChange, readOnly, id }) {
228
255
  }))
229
256
  });
230
257
  }
231
- function MultiSelectControl({ field, value, onChange, readOnly, id }) {
258
+ /** As `SelectControl`: each stored choice no option names any more is kept and flagged, with change-to and remove. */
259
+ function MultiSelectControl(props) {
260
+ const list = Array.isArray(props.value) ? props.value.filter((x) => typeof x === "string") : [];
261
+ const options = opts(props.field.options);
262
+ const unknown = options.length ? list.filter((x) => !options.some((o) => o.value === x)) : [];
263
+ if (unknown.length === 0) return /* @__PURE__ */ jsx(MultiSelectInput, { ...props });
264
+ return /* @__PURE__ */ jsxs("div", {
265
+ className: "flex min-w-0 flex-col gap-1.5",
266
+ children: [/* @__PURE__ */ jsx(MultiSelectInput, { ...props }), /* @__PURE__ */ jsx(UnknownValueNote, {
267
+ items: unknown.map((x) => ({
268
+ key: x,
269
+ label: `“${x}”`,
270
+ options: options.filter((o) => !list.includes(o.value)).map((o) => ({
271
+ value: o.value,
272
+ label: o.label
273
+ }))
274
+ })),
275
+ onRemap: (from, to) => props.onChange(list.map((x) => x === from ? to : x)),
276
+ onRemove: (from) => props.onChange(list.filter((x) => x !== from)),
277
+ readOnly: props.readOnly
278
+ })]
279
+ });
280
+ }
281
+ function MultiSelectInput({ field, value, onChange, readOnly, id }) {
232
282
  const list = Array.isArray(value) ? value.filter((x) => typeof x === "string") : [];
233
283
  const options = opts(field.options);
234
284
  const max = field.validation?.max;
@@ -251,11 +301,13 @@ function MultiSelectControl({ field, value, onChange, readOnly, id }) {
251
301
  children: options.map((o) => {
252
302
  const on = list.includes(o.value);
253
303
  return /* @__PURE__ */ jsxs("label", {
254
- className: cn("flex items-center gap-2.5 rounded-kit-md px-1.5 py-1.5", !on && full ? "cursor-not-allowed" : "cursor-pointer hover:bg-kit-hover"),
304
+ className: cn("flex cursor-pointer items-center gap-2.5 rounded-kit-md px-1.5 py-1.5 hover:bg-kit-hover", !on && full && "cursor-not-allowed hover:bg-transparent"),
255
305
  children: [/* @__PURE__ */ jsx(Checkbox, {
256
306
  checked: on,
257
307
  disabled: readOnly || !on && full,
258
- onCheckedChange: () => toggle(o.value)
308
+ onCheckedChange: () => toggle(o.value),
309
+ nativeButton: true,
310
+ render: /* @__PURE__ */ jsx("button", { type: "button" })
259
311
  }), /* @__PURE__ */ jsx("span", {
260
312
  className: "text-kit-sm text-kit-fg",
261
313
  children: o.label
@@ -296,13 +348,14 @@ function MultiSelectControl({ field, value, onChange, readOnly, id }) {
296
348
  "aria-label": field.title,
297
349
  children: options.map((o) => {
298
350
  const on = list.includes(o.value);
351
+ const blocked = !on && full;
299
352
  return /* @__PURE__ */ jsxs("button", {
300
353
  type: "button",
301
354
  role: "checkbox",
302
355
  "aria-checked": on,
303
- disabled: !on && full,
356
+ disabled: blocked,
304
357
  onClick: () => toggle(o.value),
305
- className: "flex h-8 w-full items-center gap-2 rounded-kit-md px-2 text-left text-kit-sm hover:bg-kit-hover disabled:opacity-40 disabled:hover:bg-transparent",
358
+ className: cn("flex h-8 w-full items-center gap-2 rounded-kit-md px-2 text-left text-kit-sm hover:bg-kit-hover", blocked && "opacity-40 hover:bg-transparent"),
306
359
  children: [/* @__PURE__ */ jsx("span", {
307
360
  className: cn("flex size-4 items-center justify-center rounded-kit-md border", on ? "border-kit-accent bg-kit-accent text-kit-accent-on" : "border-kit-line-strong"),
308
361
  children: on ? /* @__PURE__ */ jsx(IconCheck, {
@@ -405,6 +458,6 @@ function TagsControl({ field, value, onChange, readOnly, id, onBlur }) {
405
458
  });
406
459
  }
407
460
  //#endregion
408
- export { BooleanControl, MultiSelectControl, SelectControl, TagsControl };
461
+ export { BooleanControl, MultiSelectControl, SelectControl, TagsControl, optionIcons, tagRefusal, useOwnDescription };
409
462
 
410
463
  //# sourceMappingURL=choice.js.map