@bettercms-ai/kit 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) 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 +90 -31
  8. package/dist/adapters/lossy.js +414 -0
  9. package/dist/adapters/lossy.js.map +1 -0
  10. package/{adapters → dist/adapters}/prod-types.d.ts +82 -4
  11. package/{adapters → dist/adapters}/prod-types.js +71 -3
  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 +996 -179
  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} +92 -2
  22. package/{context.js → dist/context.js} +5 -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/{controls → dist/controls}/form-picker-register.js +1 -1
  50. package/dist/controls/form-picker-register.js.map +1 -0
  51. package/{controls → dist/controls}/form-picker.js +11 -9
  52. package/dist/controls/form-picker.js.map +1 -0
  53. package/{controls → dist/controls}/icon-register.js +1 -1
  54. package/dist/controls/icon-register.js.map +1 -0
  55. package/{controls → dist/controls}/icon.d.ts +4 -2
  56. package/{controls → dist/controls}/icon.js +32 -27
  57. package/dist/controls/icon.js.map +1 -0
  58. package/{controls → dist/controls}/index.d.ts +1 -1
  59. package/{controls → dist/controls}/index.js +4 -3
  60. package/dist/controls/index.js.map +1 -0
  61. package/{controls → dist/controls}/json-register.js +1 -1
  62. package/dist/controls/json-register.js.map +1 -0
  63. package/{controls → dist/controls}/json.js +13 -3
  64. package/dist/controls/json.js.map +1 -0
  65. package/{controls → dist/controls}/link.js +6 -6
  66. package/dist/controls/link.js.map +1 -0
  67. package/{controls → dist/controls}/location-register.js +1 -1
  68. package/dist/controls/location-register.js.map +1 -0
  69. package/{controls → dist/controls}/location.js +64 -40
  70. package/dist/controls/location.js.map +1 -0
  71. package/{controls → dist/controls}/media-register.js +1 -1
  72. package/dist/controls/media-register.js.map +1 -0
  73. package/{controls → dist/controls}/media-services.d.ts +6 -0
  74. package/dist/controls/media-services.js +0 -0
  75. package/{controls → dist/controls}/media.d.ts +35 -4
  76. package/{controls → dist/controls}/media.js +491 -171
  77. package/dist/controls/media.js.map +1 -0
  78. package/{controls → dist/controls}/number.js +10 -9
  79. package/dist/controls/number.js.map +1 -0
  80. package/{controls → dist/controls}/reference-register.js +1 -1
  81. package/dist/controls/reference-register.js.map +1 -0
  82. package/{controls → dist/controls}/reference-services.d.ts +4 -0
  83. package/dist/controls/reference-services.js +0 -0
  84. package/{controls → dist/controls}/reference.d.ts +1 -1
  85. package/{controls → dist/controls}/reference.js +93 -77
  86. package/dist/controls/reference.js.map +1 -0
  87. package/dist/controls/rich-text/blocks.d.ts +49 -0
  88. package/{controls → dist/controls}/rich-text/blocks.js +471 -144
  89. package/dist/controls/rich-text/blocks.js.map +1 -0
  90. package/{controls → dist/controls}/rich-text/catalog.d.ts +4 -1
  91. package/{controls → dist/controls}/rich-text/catalog.js +75 -65
  92. package/dist/controls/rich-text/catalog.js.map +1 -0
  93. package/{controls → dist/controls}/rich-text/codec.d.ts +9 -1
  94. package/{controls → dist/controls}/rich-text/codec.js +3 -1
  95. package/dist/controls/rich-text/codec.js.map +1 -0
  96. package/{controls → dist/controls}/rich-text/component-card.d.ts +1 -1
  97. package/{controls → dist/controls}/rich-text/component-card.js +417 -99
  98. package/dist/controls/rich-text/component-card.js.map +1 -0
  99. package/dist/controls/rich-text/component-panel.d.ts +47 -0
  100. package/dist/controls/rich-text/component-panel.js +141 -0
  101. package/dist/controls/rich-text/component-panel.js.map +1 -0
  102. package/{controls → dist/controls}/rich-text/control.d.ts +1 -2
  103. package/{controls → dist/controls}/rich-text/control.js +84 -42
  104. package/dist/controls/rich-text/control.js.map +1 -0
  105. package/{controls → dist/controls}/rich-text/dom.d.ts +52 -9
  106. package/{controls → dist/controls}/rich-text/dom.js +379 -50
  107. package/dist/controls/rich-text/dom.js.map +1 -0
  108. package/{controls → dist/controls}/rich-text/editor.d.ts +7 -0
  109. package/{controls → dist/controls}/rich-text/editor.js +148 -48
  110. package/dist/controls/rich-text/editor.js.map +1 -0
  111. package/{controls → dist/controls}/rich-text/floating.d.ts +6 -1
  112. package/{controls → dist/controls}/rich-text/floating.js +35 -18
  113. package/dist/controls/rich-text/floating.js.map +1 -0
  114. package/{controls → dist/controls}/rich-text/index.js +1 -1
  115. package/dist/controls/rich-text/index.js.map +1 -0
  116. package/dist/controls/rich-text/link-form.js +147 -0
  117. package/dist/controls/rich-text/link-form.js.map +1 -0
  118. package/{controls → dist/controls}/rich-text/markdown.js +4 -2
  119. package/dist/controls/rich-text/markdown.js.map +1 -0
  120. package/{controls → dist/controls}/rich-text/ops.js +17 -15
  121. package/dist/controls/rich-text/ops.js.map +1 -0
  122. package/dist/controls/rich-text/plain.d.ts +17 -0
  123. package/dist/controls/rich-text/plain.js +44 -0
  124. package/dist/controls/rich-text/plain.js.map +1 -0
  125. package/{controls → dist/controls}/rich-text/toolbar.d.ts +6 -2
  126. package/{controls → dist/controls}/rich-text/toolbar.js +12 -7
  127. package/dist/controls/rich-text/toolbar.js.map +1 -0
  128. package/{controls → dist/controls}/scale.js +5 -5
  129. package/dist/controls/scale.js.map +1 -0
  130. package/{controls → dist/controls}/slot-register.js +1 -1
  131. package/dist/controls/slot-register.js.map +1 -0
  132. package/{controls → dist/controls}/slot-services.d.ts +25 -0
  133. package/dist/controls/slot-services.js +155 -0
  134. package/dist/controls/slot-services.js.map +1 -0
  135. package/{controls → dist/controls}/slot.js +42 -24
  136. package/dist/controls/slot.js.map +1 -0
  137. package/{controls → dist/controls}/table/index.js +1 -1
  138. package/dist/controls/table/index.js.map +1 -0
  139. package/{controls → dist/controls}/table/prod.js +3 -3
  140. package/dist/controls/table/prod.js.map +1 -0
  141. package/{controls → dist/controls}/table/refs.js +13 -2
  142. package/dist/controls/table/refs.js.map +1 -0
  143. package/{controls → dist/controls}/table/stored.js +1 -1
  144. package/dist/controls/table/stored.js.map +1 -0
  145. package/{controls → dist/controls}/table/table-editor.js +51 -48
  146. package/dist/controls/table/table-editor.js.map +1 -0
  147. package/{controls → dist/controls}/table/table-link.js +3 -3
  148. package/dist/controls/table/table-link.js.map +1 -0
  149. package/{controls → dist/controls}/table/table.js +3 -3
  150. package/dist/controls/table/table.js.map +1 -0
  151. package/{controls → dist/controls}/text.d.ts +2 -2
  152. package/{controls → dist/controls}/text.js +78 -43
  153. package/dist/controls/text.js.map +1 -0
  154. package/dist/controls/unknown-value.d.ts +17 -0
  155. package/dist/controls/unknown-value.js +66 -0
  156. package/dist/controls/unknown-value.js.map +1 -0
  157. package/dist/core/core.d.ts +63 -0
  158. package/dist/core/core.js +171 -0
  159. package/dist/core/core.js.map +1 -0
  160. package/dist/core/facets.d.ts +347 -0
  161. package/dist/core/facets.js +334 -0
  162. package/dist/core/facets.js.map +1 -0
  163. package/dist/core/index.d.ts +3 -0
  164. package/dist/core/index.js +3 -0
  165. package/{engine → dist/engine}/array.js +34 -21
  166. package/dist/engine/array.js.map +1 -0
  167. package/{engine → dist/engine}/bits.js +1 -1
  168. package/dist/engine/bits.js.map +1 -0
  169. package/{engine → dist/engine}/breadcrumb.d.ts +3 -3
  170. package/{engine → dist/engine}/breadcrumb.js +12 -36
  171. package/dist/engine/breadcrumb.js.map +1 -0
  172. package/{engine → dist/engine}/expand.d.ts +2 -4
  173. package/{engine → dist/engine}/expand.js +5 -22
  174. package/dist/engine/expand.js.map +1 -0
  175. package/{engine → dist/engine}/field-list.js +1 -1
  176. package/dist/engine/field-list.js.map +1 -0
  177. package/{engine → dist/engine}/field-shell.js +249 -121
  178. package/dist/engine/field-shell.js.map +1 -0
  179. package/{engine → dist/engine}/frame.d.ts +3 -1
  180. package/{engine → dist/engine}/frame.js +16 -14
  181. package/dist/engine/frame.js.map +1 -0
  182. package/{engine → dist/engine}/group-summary.d.ts +2 -1
  183. package/{engine → dist/engine}/group-summary.js +7 -3
  184. package/dist/engine/group-summary.js.map +1 -0
  185. package/{engine → dist/engine}/grouping.d.ts +19 -5
  186. package/{engine → dist/engine}/grouping.js +193 -21
  187. package/dist/engine/grouping.js.map +1 -0
  188. package/{engine → dist/engine}/item-list.d.ts +11 -1
  189. package/{engine → dist/engine}/item-list.js +35 -13
  190. package/dist/engine/item-list.js.map +1 -0
  191. package/{engine → dist/engine}/kit-field.js +45 -10
  192. package/dist/engine/kit-field.js.map +1 -0
  193. package/{engine → dist/engine}/schema-form.d.ts +27 -2
  194. package/{engine → dist/engine}/schema-form.js +182 -40
  195. package/dist/engine/schema-form.js.map +1 -0
  196. package/{engine → dist/engine}/slot.js +5 -15
  197. package/dist/engine/slot.js.map +1 -0
  198. package/dist/index.js +47 -0
  199. package/dist/index.js.map +1 -0
  200. package/{kit.css → dist/kit.css} +19 -0
  201. package/{lib → dist/lib}/cn.js +7 -4
  202. package/dist/lib/cn.js.map +1 -0
  203. package/{lib → dist/lib}/columns.js +4 -1
  204. package/dist/lib/columns.js.map +1 -0
  205. package/{lib → dist/lib}/frames.js +2 -2
  206. package/dist/lib/frames.js.map +1 -0
  207. package/dist/lib/icon-image.d.ts +10 -0
  208. package/dist/lib/icon-image.js +8 -0
  209. package/dist/lib/icon-image.js.map +1 -0
  210. package/{lib → dist/lib}/icons.js +4 -3
  211. package/dist/lib/icons.js.map +1 -0
  212. package/dist/lib/input-modality.d.ts +11 -0
  213. package/dist/lib/input-modality.js +47 -0
  214. package/dist/lib/input-modality.js.map +1 -0
  215. package/dist/lib/key-event.d.ts +11 -0
  216. package/dist/lib/key-event.js +16 -0
  217. package/dist/lib/key-event.js.map +1 -0
  218. package/{lib → dist/lib}/path.js +4 -2
  219. package/dist/lib/path.js.map +1 -0
  220. package/{lib → dist/lib}/schema.d.ts +34 -3
  221. package/{lib → dist/lib}/schema.js +110 -13
  222. package/dist/lib/schema.js.map +1 -0
  223. package/{lib → dist/lib}/utils.js +1 -1
  224. package/dist/lib/utils.js.map +1 -0
  225. package/{lib → dist/lib}/validate.d.ts +11 -1
  226. package/{lib → dist/lib}/validate.js +85 -11
  227. package/dist/lib/validate.js.map +1 -0
  228. package/dist/library/analysis.d.ts +23 -0
  229. package/dist/library/analysis.js +160 -0
  230. package/dist/library/analysis.js.map +1 -0
  231. package/dist/library/catalog.d.ts +57 -0
  232. package/dist/library/catalog.js +307 -0
  233. package/dist/library/catalog.js.map +1 -0
  234. package/dist/library/coreNotes.d.ts +8 -0
  235. package/dist/library/coreNotes.js +111 -0
  236. package/dist/library/coreNotes.js.map +1 -0
  237. package/dist/library/coverage.d.ts +40 -0
  238. package/dist/library/coverage.js +59 -0
  239. package/dist/library/coverage.js.map +1 -0
  240. package/dist/library/entries/advanced.entries.d.ts +2 -0
  241. package/dist/library/entries/advanced.entries.js +6579 -0
  242. package/dist/library/entries/advanced.entries.js.map +1 -0
  243. package/dist/library/entries/commerce.entries.d.ts +2 -0
  244. package/dist/library/entries/commerce.entries.js +4140 -0
  245. package/dist/library/entries/commerce.entries.js.map +1 -0
  246. package/dist/library/entries/company.entries.d.ts +2 -0
  247. package/dist/library/entries/company.entries.js +2731 -0
  248. package/dist/library/entries/company.entries.js.map +1 -0
  249. package/dist/library/entries/conversion.entries.d.ts +2 -0
  250. package/dist/library/entries/conversion.entries.js +3707 -0
  251. package/dist/library/entries/conversion.entries.js.map +1 -0
  252. package/dist/library/entries/data.entries.d.ts +7 -0
  253. package/dist/library/entries/data.entries.js +4613 -0
  254. package/dist/library/entries/data.entries.js.map +1 -0
  255. package/dist/library/entries/events.entries.d.ts +2 -0
  256. package/dist/library/entries/events.entries.js +3428 -0
  257. package/dist/library/entries/events.entries.js.map +1 -0
  258. package/dist/library/entries/features.entries.d.ts +2 -0
  259. package/dist/library/entries/features.entries.js +3157 -0
  260. package/dist/library/entries/features.entries.js.map +1 -0
  261. package/dist/library/entries/heroes.entries.d.ts +2 -0
  262. package/dist/library/entries/heroes.entries.js +3401 -0
  263. package/dist/library/entries/heroes.entries.js.map +1 -0
  264. package/dist/library/entries/index.d.ts +3 -0
  265. package/dist/library/entries/index.js +35 -0
  266. package/dist/library/entries/index.js.map +1 -0
  267. package/dist/library/entries/listings.entries.d.ts +2 -0
  268. package/dist/library/entries/listings.entries.js +2976 -0
  269. package/dist/library/entries/listings.entries.js.map +1 -0
  270. package/dist/library/entries/longform.entries.d.ts +2 -0
  271. package/dist/library/entries/longform.entries.js +4227 -0
  272. package/dist/library/entries/longform.entries.js.map +1 -0
  273. package/dist/library/entries/media.entries.d.ts +2 -0
  274. package/dist/library/entries/media.entries.js +2781 -0
  275. package/dist/library/entries/media.entries.js.map +1 -0
  276. package/dist/library/entries/navigation.entries.d.ts +2 -0
  277. package/dist/library/entries/navigation.entries.js +4011 -0
  278. package/dist/library/entries/navigation.entries.js.map +1 -0
  279. package/dist/library/entries/pricing.entries.d.ts +2 -0
  280. package/dist/library/entries/pricing.entries.js +2383 -0
  281. package/dist/library/entries/pricing.entries.js.map +1 -0
  282. package/dist/library/entries/social-proof.entries.d.ts +2 -0
  283. package/dist/library/entries/social-proof.entries.js +2297 -0
  284. package/dist/library/entries/social-proof.entries.js.map +1 -0
  285. package/dist/library/examples/bento.d.ts +92 -0
  286. package/dist/library/examples/bento.js +201 -0
  287. package/dist/library/examples/bento.js.map +1 -0
  288. package/dist/library/examples/blocks.d.ts +14 -0
  289. package/dist/library/examples/blocks.js +313 -0
  290. package/dist/library/examples/blocks.js.map +1 -0
  291. package/dist/library/examples/faq.d.ts +28 -0
  292. package/dist/library/examples/faq.js +230 -0
  293. package/dist/library/examples/faq.js.map +1 -0
  294. package/dist/library/examples/hero.d.ts +43 -0
  295. package/dist/library/examples/hero.js +222 -0
  296. package/dist/library/examples/hero.js.map +1 -0
  297. package/dist/library/examples/index.d.ts +36 -0
  298. package/dist/library/examples/index.js +109 -0
  299. package/dist/library/examples/index.js.map +1 -0
  300. package/dist/library/examples/journalStory.d.ts +93 -0
  301. package/dist/library/examples/journalStory.js +338 -0
  302. package/dist/library/examples/journalStory.js.map +1 -0
  303. package/dist/library/examples/megaMenu.d.ts +134 -0
  304. package/dist/library/examples/megaMenu.js +442 -0
  305. package/dist/library/examples/megaMenu.js.map +1 -0
  306. package/dist/library/examples/pricing.d.ts +103 -0
  307. package/dist/library/examples/pricing.js +479 -0
  308. package/dist/library/examples/pricing.js.map +1 -0
  309. package/dist/library/examples/tabs.d.ts +87 -0
  310. package/dist/library/examples/tabs.js +180 -0
  311. package/dist/library/examples/tabs.js.map +1 -0
  312. package/dist/library/export.d.ts +42 -0
  313. package/dist/library/export.js +80 -0
  314. package/dist/library/export.js.map +1 -0
  315. package/dist/library/index.d.ts +13 -0
  316. package/dist/library/index.js +6 -0
  317. package/dist/library/kit-catalog.json +1510 -0
  318. package/dist/library/types.d.ts +42 -0
  319. package/dist/library/types.js +0 -0
  320. package/{schema → dist/schema}/adapters.js +1 -2
  321. package/dist/schema/adapters.js.map +1 -0
  322. package/{schema → dist/schema}/help.d.ts +2 -0
  323. package/{schema → dist/schema}/help.js +6 -4
  324. package/dist/schema/help.js.map +1 -0
  325. package/{schema → dist/schema}/scale.js +1 -1
  326. package/dist/schema/scale.js.map +1 -0
  327. package/{schema → dist/schema}/sources.js +1 -1
  328. package/dist/schema/sources.js.map +1 -0
  329. package/{schema → dist/schema}/table.js +11 -10
  330. package/dist/schema/table.js.map +1 -0
  331. package/{schema → dist/schema}/types.d.ts +29 -1
  332. package/{schema → dist/schema}/types.js +1 -1
  333. package/dist/schema/types.js.map +1 -0
  334. package/dist/styles.css +2 -0
  335. package/dist/table/table-view.d.ts +14 -0
  336. package/dist/table/table-view.js +140 -0
  337. package/dist/table/table-view.js.map +1 -0
  338. package/dist/table/table.css +73 -0
  339. package/dist/testing/corpus.d.ts +63 -0
  340. package/dist/testing/corpus.js +129 -0
  341. package/dist/testing/corpus.js.map +1 -0
  342. package/dist/testing/test-form.d.ts +11 -0
  343. package/dist/testing/test-form.js +38 -0
  344. package/dist/testing/test-form.js.map +1 -0
  345. package/dist/theme.css +345 -0
  346. package/dist/theme.d.ts +22 -0
  347. package/dist/theme.js +43 -0
  348. package/dist/theme.js.map +1 -0
  349. package/dist/tokens.css +542 -0
  350. package/dist/types.js +0 -0
  351. package/{ui → dist/ui}/action-tray.d.ts +1 -1
  352. package/{ui → dist/ui}/action-tray.js +20 -19
  353. package/dist/ui/action-tray.js.map +1 -0
  354. package/dist/ui/autocomplete.d.ts +30 -0
  355. package/dist/ui/autocomplete.js +139 -0
  356. package/dist/ui/autocomplete.js.map +1 -0
  357. package/{ui → dist/ui}/button.d.ts +3 -3
  358. package/{ui → dist/ui}/button.js +6 -7
  359. package/dist/ui/button.js.map +1 -0
  360. package/{ui → dist/ui}/choice-switch.js +1 -1
  361. package/dist/ui/choice-switch.js.map +1 -0
  362. package/{ui → dist/ui}/controls.js +51 -39
  363. package/dist/ui/controls.js.map +1 -0
  364. package/{ui → dist/ui}/display.d.ts +10 -3
  365. package/{ui → dist/ui}/display.js +57 -46
  366. package/dist/ui/display.js.map +1 -0
  367. package/{ui → dist/ui}/expanded-editor-modal.d.ts +2 -2
  368. package/{ui → dist/ui}/expanded-editor-modal.js +6 -6
  369. package/dist/ui/expanded-editor-modal.js.map +1 -0
  370. package/{ui → dist/ui}/field-context.js +1 -1
  371. package/dist/ui/field-context.js.map +1 -0
  372. package/{ui → dist/ui}/floating-panel.d.ts +1 -1
  373. package/{ui → dist/ui}/floating-panel.js +28 -12
  374. package/dist/ui/floating-panel.js.map +1 -0
  375. package/{ui → dist/ui}/index.d.ts +4 -0
  376. package/dist/ui/index.js +18 -0
  377. package/{ui → dist/ui}/input.d.ts +1 -1
  378. package/{ui → dist/ui}/input.js +9 -9
  379. package/dist/ui/input.js.map +1 -0
  380. package/{ui → dist/ui}/mode-bar.js +3 -3
  381. package/dist/ui/mode-bar.js.map +1 -0
  382. package/{ui → dist/ui}/overlay.d.ts +77 -5
  383. package/dist/ui/overlay.js +697 -0
  384. package/dist/ui/overlay.js.map +1 -0
  385. package/{ui → dist/ui}/path-crumbs.js +37 -3
  386. package/dist/ui/path-crumbs.js.map +1 -0
  387. package/{ui → dist/ui}/presence.js +2 -2
  388. package/dist/ui/presence.js.map +1 -0
  389. package/{ui → dist/ui}/select.js +89 -87
  390. package/dist/ui/select.js.map +1 -0
  391. package/{ui → dist/ui}/shortcut-hint.js +1 -1
  392. package/dist/ui/shortcut-hint.js.map +1 -0
  393. package/dist/ui/spinner.d.ts +24 -0
  394. package/dist/ui/spinner.js +42 -0
  395. package/dist/ui/spinner.js.map +1 -0
  396. package/dist/ui/split-button.d.ts +32 -0
  397. package/dist/ui/split-button.js +60 -0
  398. package/dist/ui/split-button.js.map +1 -0
  399. package/{ui → dist/ui}/surfaces.js +1 -1
  400. package/dist/ui/surfaces.js.map +1 -0
  401. package/dist/ui/tab.d.ts +38 -0
  402. package/dist/ui/tab.js +87 -0
  403. package/dist/ui/tab.js.map +1 -0
  404. package/dist/ui/toast.d.ts +20 -0
  405. package/dist/ui/toast.js +115 -0
  406. package/dist/ui/toast.js.map +1 -0
  407. package/{ui → dist/ui}/tooltip-root.d.ts +4 -3
  408. package/{ui → dist/ui}/tooltip-root.js +9 -8
  409. package/dist/ui/tooltip-root.js.map +1 -0
  410. package/{ui → dist/ui}/variants.js +1 -1
  411. package/dist/ui/variants.js.map +1 -0
  412. package/package.json +77 -23
  413. package/adapters/icons.js.map +0 -1
  414. package/adapters/lossy.js +0 -233
  415. package/adapters/lossy.js.map +0 -1
  416. package/adapters/prod-types.js.map +0 -1
  417. package/adapters/schema.js.map +0 -1
  418. package/adapters/values.js.map +0 -1
  419. package/brand/logo.js +0 -9
  420. package/brand/logo.js.map +0 -1
  421. package/context.js.map +0 -1
  422. package/controls/button.js.map +0 -1
  423. package/controls/c1.js.map +0 -1
  424. package/controls/c2.js.map +0 -1
  425. package/controls/choice.js.map +0 -1
  426. package/controls/code-register.js.map +0 -1
  427. package/controls/code.js.map +0 -1
  428. package/controls/color.js.map +0 -1
  429. package/controls/date-register.js.map +0 -1
  430. package/controls/date-zone.js.map +0 -1
  431. package/controls/date.js.map +0 -1
  432. package/controls/form-picker-register.js.map +0 -1
  433. package/controls/form-picker.js.map +0 -1
  434. package/controls/icon-register.js.map +0 -1
  435. package/controls/icon.js.map +0 -1
  436. package/controls/index.js.map +0 -1
  437. package/controls/json-register.js.map +0 -1
  438. package/controls/json.js.map +0 -1
  439. package/controls/link.js.map +0 -1
  440. package/controls/location-register.js.map +0 -1
  441. package/controls/location.js.map +0 -1
  442. package/controls/media-register.js.map +0 -1
  443. package/controls/media.js.map +0 -1
  444. package/controls/number.js.map +0 -1
  445. package/controls/reference-register.js.map +0 -1
  446. package/controls/reference.js.map +0 -1
  447. package/controls/rich-text/blocks.d.ts +0 -28
  448. package/controls/rich-text/blocks.js.map +0 -1
  449. package/controls/rich-text/catalog.js.map +0 -1
  450. package/controls/rich-text/codec.js.map +0 -1
  451. package/controls/rich-text/component-card.js.map +0 -1
  452. package/controls/rich-text/control.js.map +0 -1
  453. package/controls/rich-text/dom.js.map +0 -1
  454. package/controls/rich-text/editor.js.map +0 -1
  455. package/controls/rich-text/floating.js.map +0 -1
  456. package/controls/rich-text/index.js.map +0 -1
  457. package/controls/rich-text/link-form.js +0 -111
  458. package/controls/rich-text/link-form.js.map +0 -1
  459. package/controls/rich-text/markdown.js.map +0 -1
  460. package/controls/rich-text/ops.js.map +0 -1
  461. package/controls/rich-text/toolbar.js.map +0 -1
  462. package/controls/scale.js.map +0 -1
  463. package/controls/slot-register.js.map +0 -1
  464. package/controls/slot-services.js +0 -38
  465. package/controls/slot-services.js.map +0 -1
  466. package/controls/slot.js.map +0 -1
  467. package/controls/table/index.js.map +0 -1
  468. package/controls/table/prod.js.map +0 -1
  469. package/controls/table/refs.js.map +0 -1
  470. package/controls/table/stored.js.map +0 -1
  471. package/controls/table/table-editor.js.map +0 -1
  472. package/controls/table/table-link.js.map +0 -1
  473. package/controls/table/table.js.map +0 -1
  474. package/controls/text.js.map +0 -1
  475. package/engine/array.js.map +0 -1
  476. package/engine/bits.js.map +0 -1
  477. package/engine/breadcrumb.js.map +0 -1
  478. package/engine/expand.js.map +0 -1
  479. package/engine/field-list.js.map +0 -1
  480. package/engine/field-shell.js.map +0 -1
  481. package/engine/frame.js.map +0 -1
  482. package/engine/group-summary.js.map +0 -1
  483. package/engine/grouping.js.map +0 -1
  484. package/engine/item-list.js.map +0 -1
  485. package/engine/kit-field.js.map +0 -1
  486. package/engine/schema-form.js.map +0 -1
  487. package/engine/slot.js.map +0 -1
  488. package/index.js +0 -55
  489. package/index.js.map +0 -1
  490. package/lib/cn.js.map +0 -1
  491. package/lib/columns.js.map +0 -1
  492. package/lib/frames.js.map +0 -1
  493. package/lib/icons.js.map +0 -1
  494. package/lib/path.js.map +0 -1
  495. package/lib/schema.js.map +0 -1
  496. package/lib/utils.js.map +0 -1
  497. package/lib/validate.js.map +0 -1
  498. package/schema/adapters.js.map +0 -1
  499. package/schema/help.js.map +0 -1
  500. package/schema/scale.js.map +0 -1
  501. package/schema/sources.js.map +0 -1
  502. package/schema/table.js.map +0 -1
  503. package/schema/types.js.map +0 -1
  504. package/ui/action-tray.js.map +0 -1
  505. package/ui/button.js.map +0 -1
  506. package/ui/choice-switch.js.map +0 -1
  507. package/ui/controls.js.map +0 -1
  508. package/ui/display.js.map +0 -1
  509. package/ui/expanded-editor-modal.js.map +0 -1
  510. package/ui/field-context.js.map +0 -1
  511. package/ui/floating-panel.js.map +0 -1
  512. package/ui/index.js +0 -13
  513. package/ui/input.js.map +0 -1
  514. package/ui/mode-bar.js.map +0 -1
  515. package/ui/overlay.js +0 -378
  516. package/ui/overlay.js.map +0 -1
  517. package/ui/path-crumbs.js.map +0 -1
  518. package/ui/presence.js.map +0 -1
  519. package/ui/select.js.map +0 -1
  520. package/ui/shortcut-hint.js.map +0 -1
  521. package/ui/surfaces.js.map +0 -1
  522. package/ui/tooltip-root.js.map +0 -1
  523. package/ui/variants.js.map +0 -1
  524. /package/{_virtual → dist/_virtual}/_rolldown/runtime.js +0 -0
  525. /package/{adapters → dist/adapters}/icons.d.ts +0 -0
  526. /package/{brand → dist/brand}/logo.d.ts +0 -0
  527. /package/{controls → dist/controls}/c1.d.ts +0 -0
  528. /package/{controls → dist/controls}/c2.d.ts +0 -0
  529. /package/{controls → dist/controls}/code-register.d.ts +0 -0
  530. /package/{controls → dist/controls}/code.d.ts +0 -0
  531. /package/{controls → dist/controls}/color.d.ts +0 -0
  532. /package/{controls → dist/controls}/date-register.d.ts +0 -0
  533. /package/{controls → dist/controls}/date-zone.d.ts +0 -0
  534. /package/{controls → dist/controls}/date.d.ts +0 -0
  535. /package/{controls → dist/controls}/form-picker-register.d.ts +0 -0
  536. /package/{controls → dist/controls}/form-picker.d.ts +0 -0
  537. /package/{controls → dist/controls}/icon-register.d.ts +0 -0
  538. /package/{controls → dist/controls}/json-register.d.ts +0 -0
  539. /package/{controls → dist/controls}/json.d.ts +0 -0
  540. /package/{controls → dist/controls}/link.d.ts +0 -0
  541. /package/{controls → dist/controls}/location-register.d.ts +0 -0
  542. /package/{controls → dist/controls}/location.d.ts +0 -0
  543. /package/{controls → dist/controls}/media-register.d.ts +0 -0
  544. /package/{controls → dist/controls}/number.d.ts +0 -0
  545. /package/{controls → dist/controls}/reference-register.d.ts +0 -0
  546. /package/{controls → dist/controls}/rich-text/index.d.ts +0 -0
  547. /package/{controls → dist/controls}/rich-text/link-form.d.ts +0 -0
  548. /package/{controls → dist/controls}/rich-text/markdown.d.ts +0 -0
  549. /package/{controls → dist/controls}/rich-text/ops.d.ts +0 -0
  550. /package/{controls → dist/controls}/scale.d.ts +0 -0
  551. /package/{controls → dist/controls}/slot-register.d.ts +0 -0
  552. /package/{controls → dist/controls}/slot.d.ts +0 -0
  553. /package/{controls → dist/controls}/table/index.d.ts +0 -0
  554. /package/{controls → dist/controls}/table/prod.d.ts +0 -0
  555. /package/{controls → dist/controls}/table/refs.d.ts +0 -0
  556. /package/{controls → dist/controls}/table/stored.d.ts +0 -0
  557. /package/{controls → dist/controls}/table/table-editor.d.ts +0 -0
  558. /package/{controls → dist/controls}/table/table-link.d.ts +0 -0
  559. /package/{controls → dist/controls}/table/table.d.ts +0 -0
  560. /package/{engine → dist/engine}/array.d.ts +0 -0
  561. /package/{engine → dist/engine}/bits.d.ts +0 -0
  562. /package/{engine → dist/engine}/field-list.d.ts +0 -0
  563. /package/{engine → dist/engine}/field-shell.d.ts +0 -0
  564. /package/{engine → dist/engine}/kit-field.d.ts +0 -0
  565. /package/{engine → dist/engine}/slot.d.ts +0 -0
  566. /package/{index.d.ts → dist/index.d.ts} +0 -0
  567. /package/{lib → dist/lib}/cn.d.ts +0 -0
  568. /package/{lib → dist/lib}/columns.d.ts +0 -0
  569. /package/{lib → dist/lib}/frames.d.ts +0 -0
  570. /package/{lib → dist/lib}/icons.d.ts +0 -0
  571. /package/{lib → dist/lib}/path.d.ts +0 -0
  572. /package/{lib → dist/lib}/utils.d.ts +0 -0
  573. /package/{schema → dist/schema}/adapters.d.ts +0 -0
  574. /package/{schema → dist/schema}/scale.d.ts +0 -0
  575. /package/{schema → dist/schema}/sources.d.ts +0 -0
  576. /package/{schema → dist/schema}/table.d.ts +0 -0
  577. /package/{types.d.ts → dist/types.d.ts} +0 -0
  578. /package/{ui → dist/ui}/choice-switch.d.ts +0 -0
  579. /package/{ui → dist/ui}/controls.d.ts +0 -0
  580. /package/{ui → dist/ui}/field-context.d.ts +0 -0
  581. /package/{ui → dist/ui}/mode-bar.d.ts +0 -0
  582. /package/{ui → dist/ui}/path-crumbs.d.ts +0 -0
  583. /package/{ui → dist/ui}/presence.d.ts +0 -0
  584. /package/{ui → dist/ui}/select.d.ts +0 -0
  585. /package/{ui → dist/ui}/shortcut-hint.d.ts +0 -0
  586. /package/{ui → dist/ui}/surfaces.d.ts +0 -0
  587. /package/{ui → dist/ui}/variants.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.js","names":[],"sources":["../../src/controls/color.tsx"],"sourcesContent":["/**\n * COLOR — site-palette swatches first, then a custom colour (V2 HEAD 9829bf1 kit/controls/misc.tsx, DESIGN §8.13).\n *\n * Stored shape (prod `color`): a hex string the backend accepts — #RGB, #RRGGBB or #RRGGBBAA — or null when cleared.\n * The hex box keeps what you type as a draft and writes it only once it is a hex colour; while it is not, the box is\n * marked invalid and says why, so a half-typed \"#12\" never reaches the save (the API would refuse it).\n * The palette is the host's (`env.palette`, the project's brand colours); with none, the popover offers the custom\n * picker alone.\n */\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { useKitEnv } from \"../context\";\nimport { Input } from \"../ui/input\";\nimport { Popover, PopoverContent, PopoverTrigger, Tooltip } from \"../ui/overlay\";\nimport type { ControlProps } from \"../types\";\nimport { str, TEXT_FOCUS } from \"./text\";\n\nexport const HEX_COLOR = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;\n/** #RGB / #RRGGBBAA → #RRGGBB for the native picker, which takes only six digits. */\nexport function pickerHex(v: string): string {\n if (!HEX_COLOR.test(v)) return \"#000000\";\n const h = v.slice(1);\n const six = h.length === 3 ? h.split(\"\").map((c) => c + c).join(\"\") : h.slice(0, 6);\n return `#${six.toLowerCase()}`;\n}\n\nexport function ColorControl({ field, value, onChange, readOnly, id, invalid, onBlur }: ControlProps) {\n const { palette } = useKitEnv();\n const v = str(value);\n const [draft, setDraft] = React.useState<string | null>(null);\n const shown = draft ?? v;\n const bad = draft !== null && draft.trim() !== \"\" && !HEX_COLOR.test(draft.trim());\n const sw = palette.find((p) => p.value.toLowerCase() === v.toLowerCase());\n const errId = React.useId();\n const write = (next: string | null) => {\n setDraft(null);\n onChange(next);\n };\n return (\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex items-center gap-2\">\n <Popover>\n <PopoverTrigger\n disabled={readOnly}\n aria-label={`Choose a colour for ${field.title}`}\n render={\n <button\n type=\"button\"\n className=\"flex h-8 min-w-0 flex-1 items-center gap-2 rounded-kit-md border border-kit-line-strong bg-kit-field-bg pl-1 pr-2.5 text-left text-kit-sm hover:border-kit-line-strong data-[popup-open]:border-kit-line-strong data-[popup-open]:bg-kit-field-bg\"\n />\n }\n >\n <span className=\"size-6 shrink-0 rounded-kit-md border border-kit-swatch-ring shadow-kit-xs\" style={{ background: v || \"transparent\" }} />\n <span className={cn(\"min-w-0 flex-1 truncate\", v ? \"text-kit-fg\" : \"text-kit-fg-3\")}>{sw ? sw.name : v ? \"Custom\" : \"No colour\"}</span>\n {sw?.token ? <span className=\"truncate font-kit-mono text-kit-2xs text-kit-fg-3\">{sw.token}</span> : null}\n </PopoverTrigger>\n <PopoverContent className=\"w-64\">\n {palette.length ? (\n <>\n <div className=\"mb-2 text-kit-xs text-kit-fg-3\">Site palette</div>\n <div className=\"grid grid-cols-5 gap-2\">\n {palette.map((s) => (\n <Tooltip key={s.value} content={`${s.name}${s.token ? ` · ${s.token}` : \"\"}`}>\n <button\n type=\"button\"\n aria-label={s.name}\n aria-pressed={s.value.toLowerCase() === v.toLowerCase()}\n onClick={() => write(s.value)}\n className={cn(\n // 1–2% hover scale, only for a hovering pointer (canvas revamp V463)\n \"relative size-9 rounded-kit-md border border-kit-swatch-ring transition-transform duration-150 ease-out motion-reduce:transition-none can-hover:hover:scale-[1.02]\",\n s.value.toLowerCase() === v.toLowerCase() && \"ring-2 ring-kit-fg ring-offset-2 ring-offset-kit-surface\",\n )}\n style={{ background: s.value }}\n />\n </Tooltip>\n ))}\n </div>\n </>\n ) : null}\n <label className={cn(\"mt-3 flex items-center gap-2 border-t border-kit-line pt-3 text-kit-xs text-kit-fg-3\", !palette.length && \"mt-0 border-t-0 pt-0\")}>\n Custom\n <input\n type=\"color\"\n value={pickerHex(v)}\n onChange={(e) => write(e.target.value.toUpperCase())}\n className=\"h-7 w-full cursor-pointer rounded-kit-md border border-kit-line bg-transparent\"\n />\n </label>\n {v ? (\n <button type=\"button\" onClick={() => write(null)} className=\"mt-2 w-full rounded-kit-md px-1.5 py-1 text-left text-kit-xs text-kit-fg-2 hover:bg-kit-hover hover:text-kit-fg\">\n No colour\n </button>\n ) : null}\n </PopoverContent>\n </Popover>\n <Input\n id={id}\n value={shown}\n readOnly={readOnly}\n aria-invalid={invalid || bad}\n aria-describedby={bad ? errId : undefined}\n placeholder=\"#RRGGBB\"\n spellCheck={false}\n onChange={(e) => {\n const t = e.target.value.trim();\n if (t === \"\") write(null);\n else if (HEX_COLOR.test(t)) write(t);\n else setDraft(e.target.value);\n }}\n onBlur={onBlur}\n className={cn(TEXT_FOCUS, \"w-28 shrink-0 font-kit-mono [&_input]:font-kit-mono\")}\n />\n </div>\n {bad ? (\n <p id={errId} role=\"alert\" className=\"text-kit-xs text-kit-danger-fg\">\n “{draft!.trim()}” isn't a hex color, so it isn't saved. Use #RGB or #RRGGBB.\n </p>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -13,6 +13,13 @@ export interface KitComponentField {
13
13
  label: string;
14
14
  /** the component's own value for it (its default), before this place's overrides */
15
15
  value?: unknown;
16
+ /** a choice field's options: the card lists the chosen option's LABEL, never its stored value (an id) */
17
+ options?: {
18
+ value: string;
19
+ label: string;
20
+ }[];
21
+ /** the component expects every place to fill it (an editor hint): an empty one marks the card's scope chip */
22
+ required?: boolean;
16
23
  }
17
24
  export interface KitComponentInfo {
18
25
  /** the component's current name */
@@ -23,6 +30,8 @@ export interface KitComponentInfo {
23
30
  places?: number;
24
31
  /** its content fields in order; an override counts as "Edited here" only when its key is one of these */
25
32
  fields?: KitComponentField[];
33
+ /** its block icon (V2 instance card BlockIcon), a name the host's IconGlyph draws; absent → the components glyph */
34
+ icon?: string;
26
35
  /** a picture of the component as readers see it (the host's snapshot of it) */
27
36
  image?: string | null;
28
37
  /**
@@ -78,6 +87,12 @@ declare module "../context" {
78
87
  overrides: Record<string, unknown>;
79
88
  variant?: string;
80
89
  }) => Promise<KitComponentCopy>;
90
+ /**
91
+ * The component that IS `variant` of `ref`'s section family (a variant is its own component): an embedded instance
92
+ * with a per-instance layout reads as that member, so the card draws the variant itself (V2 instance card draws
93
+ * `r.variant`). Undefined → `ref` has no family member for it, and the card names the layout instead.
94
+ */
95
+ componentVariantMember?: (ref: string, variant: string) => string | undefined;
81
96
  /**
82
97
  * A React HOOK (one identity for the life of the form): the components the rich-text field at `at` may embed,
83
98
  * already narrowed to the ones its config accepts. `error` is a whole sentence. Absent → the "/" menu offers no
@@ -99,8 +114,35 @@ declare module "../context" {
99
114
  * Absent → the card shows the host's snapshot where the place shows exactly the component, else its values.
100
115
  */
101
116
  ComponentPreview?: import("react").ComponentType<KitComponentPreviewProps>;
117
+ /**
118
+ * The per-placement settings form an embedded instance's panel shows (V2 instance panel): inherited values muted,
119
+ * fields edited here with a Reset, the Layout variant. Absent → the card offers no "Edit properties".
120
+ */
121
+ ComponentSettings?: import("react").ComponentType<KitComponentSettingsProps>;
122
+ /** "Edit for all N places": open the shared component itself. Absent → the item is not offered. */
123
+ openComponent?: (ref: string) => void;
124
+ /** "Copy link" to this place. Undefined → the item is not offered. */
125
+ componentHref?: (ref: string, instanceId?: string) => string | undefined;
102
126
  }
103
127
  }
128
+ /** What the host's settings form edits for ONE place of a shared component. */
129
+ export interface KitComponentSettingsProps {
130
+ componentId: string;
131
+ /** Only the fields this place changed (everything else follows the component). */
132
+ overrides: Record<string, unknown>;
133
+ variant?: string;
134
+ /** A separate copy: its own full props, no longer following the component. */
135
+ detached?: {
136
+ props: Record<string, unknown>;
137
+ };
138
+ readOnly?: boolean;
139
+ /** Focus this field when the panel opens (a click on it in the preview). */
140
+ focusKey?: string | null;
141
+ onOverrides: (next: Record<string, unknown>) => void;
142
+ onVariant?: (variant: string | undefined) => void;
143
+ }
144
+ /** V2's insert toast: an embedded component is shared, edits here change only this place. */
145
+ export declare const COMPONENT_INSERT_TOAST = "Shared: it follows the block. Fields you edit here change only this place.";
104
146
  /**
105
147
  * One step of the host's history (KitServices.historyStep). The host's toolbar can undo and redo it too, so `next`
106
148
  * says where it stands NOW: the host's next undo, its next redo, or neither (other changes come first, or it is gone).
@@ -0,0 +1,7 @@
1
+ //#region src/controls/component-services.ts
2
+ /** V2's insert toast: an embedded component is shared, edits here change only this place. */
3
+ var COMPONENT_INSERT_TOAST = "Shared: it follows the block. Fields you edit here change only this place.";
4
+ //#endregion
5
+ export { COMPONENT_INSERT_TOAST };
6
+
7
+ //# sourceMappingURL=component-services.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-services.js","names":[],"sources":["../../src/controls/component-services.ts"],"sourcesContent":["/**\n * The component lookup a rich-text body's embedded component card reads (V2 instance-card.tsx), declared as an\n * augmentation of KitServices. The host answers from its own components library:\n *\n * the dock → the project's components (GET /components) and its usage map (GET /projects/:id/component-usage)\n * the sandbox → V2's demo component library (/style-guide/kit fixtures)\n *\n * Absent → the card stays the compact \"Linked component\" row: no state, no count, no preview is ever made up.\n */\nimport type { RichTextAt } from \"./rich-text/codec\";\n\nexport interface KitComponentField {\n key: string;\n label: string;\n /** the component's own value for it (its default), before this place's overrides */\n value?: unknown;\n /** a choice field's options: the card lists the chosen option's LABEL, never its stored value (an id) */\n options?: { value: string; label: string }[];\n /** the component expects every place to fill it (an editor hint): an empty one marks the card's scope chip */\n required?: boolean;\n}\n\nexport interface KitComponentInfo {\n /** the component's current name */\n name: string;\n /** true: the library has no component with this id (it was deleted) */\n missing?: boolean;\n /** how many places link to it; absent → not measured, and the card says \"Shared\" without a number */\n places?: number;\n /** its content fields in order; an override counts as \"Edited here\" only when its key is one of these */\n fields?: KitComponentField[];\n /** its block icon (V2 instance card BlockIcon), a name the host's IconGlyph draws; absent → the components glyph */\n icon?: string;\n /** a picture of the component as readers see it (the host's snapshot of it) */\n image?: string | null;\n /**\n * the version readers see now (the component's last publish); a separate copy taken from an older one shows\n * \"Shared version changed\". Absent → not known, and no copy is ever called out of date.\n */\n publishedAt?: string | null;\n}\n\n/** A separate copy of a component (V2 instances.ts `detach`): what this place keeps when it stops following it. */\nexport interface KitComponentCopy {\n /** the values readers see, now this place's own (V2 `props`) */\n props: Record<string, unknown>;\n /** whatever the host stores beside them to draw the copy (production: the frozen block tree, as JSON) */\n blocks?: string;\n /** the version of the component it was taken from */\n sourcePublishedAt?: string;\n}\n\n/**\n * The component drawn live in its card (V2 instance card), with THIS place's values: a linked place's defaults with its\n * overrides, a separate copy's own values. Read-only, the card's width. `fallback(reason)` is what the card shows when\n * the host cannot draw it (not validated, no runtime here, an error), with the reason in words.\n */\nexport interface KitComponentPreviewProps {\n componentId: string;\n title: string;\n props: Record<string, unknown>;\n fallback: (reason: string) => import(\"react\").ReactNode;\n}\n\n/** A component a rich-text body can embed (the \"/\" menu's More components). */\nexport interface KitInsertableComponent {\n id: string;\n name: string;\n description?: string;\n}\n\ndeclare module \"../context\" {\n interface KitServices {\n /**\n * A React HOOK (called on every render of a component card, so the host passes one function for the life of the\n * form): what the library knows about the component an embedded instance links to. `info` undefined while it\n * loads; `error` is a whole sentence (\"Components couldn't be loaded: …\").\n */\n useComponentInfo?: (ref: string) => { info?: KitComponentInfo; loading?: boolean; error?: string };\n /**\n * Make this place a separate copy (V2 \"Keep as a separate copy\" / \"Make a separate copy\"): what readers see now,\n * with this place's overrides. Rejects with a whole sentence the card shows (\"“Card” has never been published…\").\n * Absent → the card offers no separate copy.\n */\n copyComponent?: (ref: string, input: { overrides: Record<string, unknown>; variant?: string }) => Promise<KitComponentCopy>;\n /**\n * The component that IS `variant` of `ref`'s section family (a variant is its own component): an embedded instance\n * with a per-instance layout reads as that member, so the card draws the variant itself (V2 instance card draws\n * `r.variant`). Undefined → `ref` has no family member for it, and the card names the layout instead.\n */\n componentVariantMember?: (ref: string, variant: string) => string | undefined;\n /**\n * A React HOOK (one identity for the life of the form): the components the rich-text field at `at` may embed,\n * already narrowed to the ones its config accepts. `error` is a whole sentence. Absent → the \"/\" menu offers no\n * components.\n */\n useInsertableComponents?: (at: RichTextAt) => { components: KitInsertableComponent[]; loading?: boolean; error?: string };\n /**\n * The host's own undo history (the dock: the Visual Editor's toolbar Undo). Runs `write` (synchronously) as ONE\n * step of it and answers that step (KitHistoryStep). Null: the host recorded no step (it keeps no history here),\n * so the editor's own history takes the step.\n */\n historyStep?: (write: () => void) => KitHistoryStep | null;\n /**\n * Draws an embedded component live in its card (KitComponentPreviewProps). Mounted only once the card is on screen.\n * Absent → the card shows the host's snapshot where the place shows exactly the component, else its values.\n */\n ComponentPreview?: import(\"react\").ComponentType<KitComponentPreviewProps>;\n /**\n * The per-placement settings form an embedded instance's panel shows (V2 instance panel): inherited values muted,\n * fields edited here with a Reset, the Layout variant. Absent → the card offers no \"Edit properties\".\n */\n ComponentSettings?: import(\"react\").ComponentType<KitComponentSettingsProps>;\n /** \"Edit for all N places\": open the shared component itself. Absent → the item is not offered. */\n openComponent?: (ref: string) => void;\n /** \"Copy link\" to this place. Undefined → the item is not offered. */\n componentHref?: (ref: string, instanceId?: string) => string | undefined;\n }\n}\n\n/** What the host's settings form edits for ONE place of a shared component. */\nexport interface KitComponentSettingsProps {\n componentId: string;\n /** Only the fields this place changed (everything else follows the component). */\n overrides: Record<string, unknown>;\n variant?: string;\n /** A separate copy: its own full props, no longer following the component. */\n detached?: { props: Record<string, unknown> };\n readOnly?: boolean;\n /** Focus this field when the panel opens (a click on it in the preview). */\n focusKey?: string | null;\n onOverrides: (next: Record<string, unknown>) => void;\n onVariant?: (variant: string | undefined) => void;\n}\n\n/** V2's insert toast: an embedded component is shared, edits here change only this place. */\nexport const COMPONENT_INSERT_TOAST = \"Shared: it follows the block. Fields you edit here change only this place.\";\n\n/**\n * One step of the host's history (KitServices.historyStep). The host's toolbar can undo and redo it too, so `next`\n * says where it stands NOW: the host's next undo, its next redo, or neither (other changes come first, or it is gone).\n * `undo` / `redo` answer true or the sentence saying why nothing changed.\n */\nexport interface KitHistoryStep {\n undo: () => true | string;\n redo: () => true | string;\n next: () => \"undo\" | \"redo\" | null;\n}\n\nexport {};\n"],"mappings":";;AAwIA,IAAa,yBAAyB"}
@@ -1,6 +1,6 @@
1
1
  import { CONTROLS } from "../engine/kit-field.js";
2
2
  import { DateControl } from "./date.js";
3
- //#region src/kit/controls/date-register.ts
3
+ //#region src/controls/date-register.ts
4
4
  /** Lane C3: date and datetime in the engine's dispatch table (one line per type; merge with other lanes by line). */
5
5
  CONTROLS.date = DateControl;
6
6
  CONTROLS.datetime = DateControl;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-register.js","names":[],"sources":["../../src/controls/date-register.ts"],"sourcesContent":["/** Lane C3: date and datetime in the engine's dispatch table (one line per type; merge with other lanes by line). */\nimport { CONTROLS } from \"../engine/kit-field\";\nimport { DateControl } from \"./date\";\n\nCONTROLS.date = DateControl;\nCONTROLS.datetime = DateControl;\n"],"mappings":";;;;AAIA,SAAS,OAAO;AAChB,SAAS,WAAW"}
@@ -1,6 +1,6 @@
1
1
  import { useKitServices } from "../context.js";
2
2
  import * as React from "react";
3
- //#region src/kit/controls/date-zone.ts
3
+ //#region src/controls/date-zone.ts
4
4
  /**
5
5
  * DATE / DATETIME values and time zones (DESIGN 6.4, D43), ported from V2 controls/date.tsx and fitted to what the
6
6
  * backend and the value adapters keep (adapters/values.ts datetimeToProd / datetimeFromProd, backend
@@ -186,6 +186,12 @@ function parseStored(v) {
186
186
  readable: true
187
187
  };
188
188
  }
189
+ /** A stored value as a JS Date (drops the [Zone] annotation, which `new Date()` can't read). */
190
+ function storedToDate(v) {
191
+ if (typeof v !== "string" || !v) return null;
192
+ const d = new Date(v.replace(/\[[^\]]*\]$/, ""));
193
+ return Number.isNaN(d.getTime()) ? null : d;
194
+ }
189
195
  /** Every IANA zone this runtime knows, UTC included. */
190
196
  var ALL_ZONES = (() => {
191
197
  const list = typeof Intl.supportedValuesOf === "function" ? Intl.supportedValuesOf("timeZone").map(modernZone) : [];
@@ -267,6 +273,6 @@ function todayIn(zone, now = /* @__PURE__ */ new Date()) {
267
273
  return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
268
274
  }
269
275
  //#endregion
270
- export { ALL_ZONES, browserZone, parseStored, resolveShown, todayIn, useDefaultZone, validZone, wallInstant, writeValue, zoneCity, zoneLabel, zonePolicy, zoneShortOffset };
276
+ export { ALL_ZONES, browserZone, instantToWall, modernZone, offsetIso, offsetMinutes, parseStored, resolveShown, storedToDate, todayIn, useDefaultZone, validZone, wallInstant, wallOffset, writeValue, zoneCity, zoneLabel, zonePolicy, zoneShortOffset, zoneWithOffset };
271
277
 
272
278
  //# sourceMappingURL=date-zone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-zone.js","names":[],"sources":["../../src/controls/date-zone.ts"],"sourcesContent":["/**\n * DATE / DATETIME values and time zones (DESIGN 6.4, D43), ported from V2 controls/date.tsx and fitted to what the\n * backend and the value adapters keep (adapters/values.ts datetimeToProd / datetimeFromProd, backend\n * parseDateField / parseDatetimeField).\n *\n * What the control writes, per field (`zonePolicy`):\n *\n * date (any timezone) \"2026-10-14\" a prod `date` without includeTime refuses a \"T\"\n * datetime, timezone false \"2026-10-14T09:00:00\" floating wall time\n * datetime, true / unset \"2026-10-14T09:00:00+05:30\" the zone the editor picked lives in the offset:\n * datetime, \"site\" \"2026-10-14T09:00:00-07:00\" prod keeps no [Zone] (the adapter names a kept\n * one as lost and the dock refuses the write)\n * datetime, \"fixed:<IANA>\" \"2026-10-14T09:00:00-04:00[America/New_York]\" the adapter checks the zone against\n * config.timezone, stores the instant, and\n * reads it back with the same [Zone]\n *\n * Seconds are always written (prod refuses a seconds-less datetime; the adapter names it \"format\"). The offset is the\n * zone's offset AT the wall time the author typed (two passes, so it is right on both sides of a clock change), and a\n * wall time that a clock change skips is refused with a named reason, never shifted silently.\n */\nimport * as React from \"react\";\nimport { useKitServices } from \"../context\";\nimport type { FieldSchema } from \"../schema/types\";\n\n/* ── The site zone (a host service) ───────────────────────────────────── */\ndeclare module \"../context\" {\n interface KitServices {\n /**\n * The site's IANA zone (Project.localeConfig.timeZone, Settings › General): where a new date/time value starts and\n * what timezone \"site\" locks to. The dock passes `useSiteTimeZone().zone` when its source is \"site\". Absent or not\n * a zone → the viewer's browser zone, which the picker names \"Your time zone\".\n */\n siteTimeZone?: string;\n }\n}\n\nexport type ZoneSource = \"site\" | \"browser\";\n\nexport function validZone(z: unknown): z is string {\n if (typeof z !== \"string\" || !z) return false;\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: z });\n return true;\n } catch {\n return false;\n }\n}\n\n/** ICU still lists some zones under their old names; people read the current ones (Kolkata, not Calcutta). */\nconst MODERN: Readonly<Record<string, string>> = {\n \"Asia/Calcutta\": \"Asia/Kolkata\",\n \"Asia/Katmandu\": \"Asia/Kathmandu\",\n \"Asia/Saigon\": \"Asia/Ho_Chi_Minh\",\n \"Asia/Rangoon\": \"Asia/Yangon\",\n \"Europe/Kiev\": \"Europe/Kyiv\",\n \"America/Godthab\": \"America/Nuuk\",\n \"Atlantic/Faeroe\": \"Atlantic/Faroe\",\n \"America/Buenos_Aires\": \"America/Argentina/Buenos_Aires\",\n};\nexport const modernZone = (z: string) => (MODERN[z] && validZone(MODERN[z]) ? MODERN[z] : z);\n\nexport function browserZone(): string {\n try {\n return modernZone(Intl.DateTimeFormat().resolvedOptions().timeZone || \"UTC\");\n } catch {\n return \"UTC\";\n }\n}\n\n/** The zone a new value starts in: the site's, else the browser's. `source` names which one. */\nexport function useDefaultZone(): { zone: string; source: ZoneSource } {\n const site = useKitServices().siteTimeZone;\n return React.useMemo(() => (validZone(site) ? { zone: site, source: \"site\" as const } : { zone: browserZone(), source: \"browser\" as const }), [site]);\n}\n\n/* ── Policy ───────────────────────────────────────────────────────────── */\nexport type ZoneMode = \"pick\" | \"site\" | \"fixed\" | \"none\";\n/**\n * What the schema allows. A `date` never carries a zone here: prod stores a date as \"YYYY-MM-DD\" and refuses a time on\n * a date field without includeTime, so a zoned date (V2 allowed one) would be refused at save.\n */\nexport function zonePolicy(field: Pick<FieldSchema, \"type\" | \"timezone\">): { mode: ZoneMode; zone?: string } {\n if (field.type !== \"datetime\") return { mode: \"none\" };\n const t = field.timezone ?? true;\n if (t === false) return { mode: \"none\" };\n if (t === \"site\") return { mode: \"site\" };\n if (typeof t === \"string\" && t.startsWith(\"fixed:\")) {\n const z = t.slice(6);\n return validZone(z) ? { mode: \"fixed\", zone: z } : { mode: \"site\" };\n }\n return { mode: \"pick\" };\n}\n\n/* ── Offsets ──────────────────────────────────────────────────────────── */\nconst pad = (n: number) => String(Math.abs(Math.trunc(n))).padStart(2, \"0\");\n\n/** The zone's UTC offset in minutes at an instant (+330 for Kolkata). */\nexport function offsetMinutes(zone: string, at: Date): number {\n try {\n const name = new Intl.DateTimeFormat(\"en-US\", { timeZone: zone, timeZoneName: \"longOffset\" }).formatToParts(at).find((p) => p.type === \"timeZoneName\")?.value ?? \"GMT\";\n const m = /GMT([+\\-−])(\\d{1,2})(?::?(\\d{2}))?/.exec(name);\n if (!m) return 0;\n const sign = m[1] === \"+\" ? 1 : -1;\n return sign * (Number(m[2]) * 60 + Number(m[3] ?? 0));\n } catch {\n return 0;\n }\n}\n\n/** +330 → \"+05:30\"; 0 → \"+00:00\". */\nexport const offsetIso = (min: number) => `${min < 0 ? \"-\" : \"+\"}${pad(Math.floor(Math.abs(min) / 60))}:${pad(Math.abs(min) % 60)}`;\n\n/** \"GMT+5:30\", \"GMT−7\", \"GMT\" — the short form people read (with a true minus sign). */\nexport function zoneShortOffset(zone: string, at = new Date()): string {\n const min = offsetMinutes(zone, at);\n if (min === 0) return \"GMT\";\n const h = Math.floor(Math.abs(min) / 60);\n const m = Math.abs(min) % 60;\n return `GMT${min < 0 ? \"−\" : \"+\"}${h}${m ? `:${pad(m)}` : \"\"}`;\n}\n\nexport const zoneCity = (z: string) => (z === \"UTC\" || z === \"Etc/UTC\" ? \"UTC\" : (z.split(\"/\").pop() ?? z).replace(/_/g, \" \"));\n/** \"GMT+5:30 · Kolkata\" */\nexport const zoneLabel = (zone: string, at?: Date) => `${zoneShortOffset(zone, at)} · ${zoneCity(zone)}`;\n\n/* ── Wall time ↔ instant ──────────────────────────────────────────────── */\nexport interface Wall {\n /** \"YYYY-MM-DD\" */\n ymd: string;\n /** \"HH:mm\" */\n time: string;\n}\nconst ymdParts = (ymd: string) => ymd.split(\"-\").map(Number) as [number, number, number];\nconst hmParts = (time: string) => time.split(\":\").map(Number) as [number, number];\nconst wallUtc = ({ ymd, time }: Wall) => {\n const [y, mo, d] = ymdParts(ymd);\n const [h, mi] = hmParts(time);\n return Date.UTC(y, mo - 1, d, h, mi);\n};\n\n/** The wall clock an instant shows in a zone. */\nexport function instantToWall(instant: Date, zone: string): Wall {\n const parts = new Intl.DateTimeFormat(\"en-CA\", { timeZone: zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\", hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\" }).formatToParts(instant);\n const get = (t: string) => parts.find((p) => p.type === t)?.value ?? \"00\";\n return { ymd: `${get(\"year\")}-${get(\"month\")}-${get(\"day\")}`, time: `${get(\"hour\")}:${get(\"minute\")}` };\n}\n\n/**\n * The offset of a wall time in a zone, or null when a clock change skips that wall time (it names no instant there).\n * Two passes: the offset at the naive instant, then at the instant that offset gives.\n */\nexport function wallOffset(zone: string, wall: Wall): number | null {\n const naive = wallUtc(wall);\n const first = offsetMinutes(zone, new Date(naive));\n const second = offsetMinutes(zone, new Date(naive - first * 60_000));\n for (const off of second === first ? [first] : [second, first]) {\n const back = instantToWall(new Date(naive - off * 60_000), zone);\n if (back.ymd === wall.ymd && back.time === wall.time) return off;\n }\n return null;\n}\n\n/** The instant a wall time names in a zone (the earlier one when a clock change skips it). */\nexport const wallInstant = (zone: string, wall: Wall) => new Date(wallUtc(wall) - (wallOffset(zone, wall) ?? offsetMinutes(zone, new Date(wallUtc(wall)))) * 60_000);\n\n/* ── Stored value → parts ─────────────────────────────────────────────── */\nexport interface ParsedValue {\n /** the day as stored (wall clock), or null when empty */\n wall: Wall | null;\n hasTime: boolean;\n /** the stated offset in minutes (\"Z\" → 0); undefined for a floating time */\n offset?: number;\n /** an RFC 9557 [Zone] suffix, when valid */\n zone?: string;\n /** false: a value this control cannot read (an object, a word); it is shown and never overwritten by accident */\n readable: boolean;\n}\n\nconst STORED = /^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::\\d{2}(?:\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})?)?(?:\\[([^\\]]+)\\])?$/;\nconst EMPTY: ParsedValue = { wall: null, hasTime: false, readable: true };\n\nexport function parseStored(v: unknown): ParsedValue {\n if (v == null || v === \"\") return EMPTY;\n if (typeof v !== \"string\") return { ...EMPTY, readable: false };\n const m = STORED.exec(v.trim());\n if (!m) return { ...EMPTY, readable: false };\n const [, y, mo, d, h, mi, off, zone] = m;\n const date = new Date(Date.UTC(Number(y), Number(mo) - 1, Number(d)));\n if (date.getUTCMonth() !== Number(mo) - 1 || date.getUTCDate() !== Number(d)) return { ...EMPTY, readable: false };\n let offset: number | undefined;\n if (off === \"Z\") offset = 0;\n else if (off) {\n const om = /([+-])(\\d{2}):?(\\d{2})/.exec(off)!;\n offset = (om[1] === \"-\" ? -1 : 1) * (Number(om[2]) * 60 + Number(om[3]));\n }\n return { wall: { ymd: `${y}-${mo}-${d}`, time: h ? `${h}:${mi}` : \"09:00\" }, hasTime: !!h, offset, zone: validZone(zone) ? zone : undefined, readable: true };\n}\n\n/** A stored value as a JS Date (drops the [Zone] annotation, which `new Date()` can't read). */\nexport function storedToDate(v: unknown): Date | null {\n if (typeof v !== \"string\" || !v) return null;\n const d = new Date(v.replace(/\\[[^\\]]*\\]$/, \"\"));\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\n/* ── Zones ────────────────────────────────────────────────────────────── */\n/** Every IANA zone this runtime knows, UTC included. */\nexport const ALL_ZONES: readonly string[] = (() => {\n const list = typeof Intl.supportedValuesOf === \"function\" ? Intl.supportedValuesOf(\"timeZone\").map(modernZone) : [];\n return Array.from(new Set(list.includes(\"UTC\") ? list : [...list, \"UTC\"]));\n})();\n\n/** The first zone (in order) whose offset at the instant is `offset`; undefined when none is. */\nexport function zoneWithOffset(offset: number, instant: Date, candidates: readonly (string | undefined)[]): string | undefined {\n for (const z of candidates) if (z && validZone(z) && offsetMinutes(z, instant) === offset) return z;\n return undefined;\n}\n\n/**\n * What the control shows for a stored value: the wall time and the zone it lives in.\n *\n * - none: the stored wall time, as typed.\n * - site / fixed: that zone. A stored instant with another offset is shown as THAT instant's wall time in the zone,\n * so the shown and the saved time never disagree.\n * - pick: the stored [Zone]; else the zone the editor picked this session, the default, the browser's, then any\n * zone whose offset matches the stored one (a \"+05:30\" reads back as Kolkata). A floating time reads in the default.\n */\nexport function resolveShown(parsed: ParsedValue, mode: ZoneMode, zones: { fixed?: string; def: string; picked?: string }): { wall: Wall | null; zone: string } {\n const lockedZone = mode === \"fixed\" ? zones.fixed! : zones.def;\n if (!parsed.wall) return { wall: null, zone: mode === \"pick\" ? (zones.picked ?? zones.def) : lockedZone };\n if (mode === \"none\" || parsed.offset === undefined) {\n const zone = mode === \"pick\" ? (parsed.zone ?? zones.picked ?? zones.def) : lockedZone;\n return { wall: parsed.wall, zone };\n }\n const instant = new Date(wallUtc(parsed.wall) - parsed.offset * 60_000);\n if (mode === \"pick\") {\n const zone = (parsed.zone && offsetMinutes(parsed.zone, instant) === parsed.offset ? parsed.zone : undefined) ?? zoneWithOffset(parsed.offset, instant, [zones.picked, zones.def, browserZone(), ...ALL_ZONES]);\n if (zone) return { wall: parsed.wall, zone };\n return { wall: instantToWall(instant, zones.def), zone: zones.def };\n }\n return { wall: offsetMinutes(lockedZone, instant) === parsed.offset ? parsed.wall : instantToWall(instant, lockedZone), zone: lockedZone };\n}\n\n/* ── Parts → stored value ─────────────────────────────────────────────── */\nexport type WriteResult = { ok: true; value: string } | { ok: false; reason: string };\n\n/** The stored string for a wall time under the field's policy (file header). */\nexport function writeValue(o: { withTime: boolean; mode: ZoneMode; wall: Wall; zone: string }): WriteResult {\n const { withTime, mode, wall, zone } = o;\n if (!withTime) return { ok: true, value: wall.ymd };\n const local = `${wall.ymd}T${wall.time}:00`;\n if (mode === \"none\") return { ok: true, value: local };\n const off = wallOffset(zone, wall);\n if (off === null) return { ok: false, reason: `That local time doesn't exist in ${zoneCity(zone)} (clocks change). Pick another time.` };\n return { ok: true, value: `${local}${offsetIso(off)}${mode === \"fixed\" ? `[${zone}]` : \"\"}` };\n}\n\n/** Today in a zone (the browser's local day for a floating field). */\nexport function todayIn(zone: string | undefined, now = new Date()): string {\n if (zone) return instantToWall(now, zone).ymd;\n return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;\n}\n"],"mappings":"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"}
@@ -5,9 +5,9 @@ import { Popover, PopoverContent, PopoverTrigger, Tooltip } from "../ui/overlay.
5
5
  import { Select } from "../ui/select.js";
6
6
  import { ALL_ZONES, browserZone, parseStored, resolveShown, todayIn, useDefaultZone, validZone, wallInstant, writeValue, zoneCity, zoneLabel, zonePolicy, zoneShortOffset } from "./date-zone.js";
7
7
  import * as React from "react";
8
- import { IconAlertTriangle, IconCalendar, IconChevronDown, IconChevronLeft, IconChevronRight, IconClock, IconLock, IconWorld } from "@tabler/icons-react";
9
8
  import { jsx, jsxs } from "react/jsx-runtime";
10
- //#region src/kit/controls/date.tsx
9
+ import { IconAlertTriangle, IconCalendar, IconChevronDown, IconChevronLeft, IconChevronRight, IconClock, IconLock, IconWorld } from "@tabler/icons-react";
10
+ //#region src/controls/date.tsx
11
11
  /**
12
12
  * DATE / DATETIME — one picker for date, time and time zone (DESIGN 8.9, CPO D43). V2 controls/date.tsx, with the
13
13
  * stored shapes prod keeps (date-zone.ts header) and a calendar you can drive from the keyboard:
@@ -171,7 +171,7 @@ function MiniCalendar({ value, today, onSelect }) {
171
171
  day: "numeric",
172
172
  year: "numeric"
173
173
  }),
174
- className: cn("flex size-8 items-center justify-center rounded-kit-md text-kit-sm tabular-nums transition-colors", sel ? "bg-kit-inverse font-medium text-kit-fg-inverse" : out ? "text-kit-fg-4 hover:bg-kit-hover" : "text-kit-fg hover:bg-kit-hover", !sel && d === today && "ring-1 ring-inset ring-kit-line-strong"),
174
+ className: cn("tabular-nums flex size-8 items-center justify-center rounded-kit-md text-kit-sm transition-colors", sel ? "bg-kit-inverse font-medium text-kit-fg-inverse" : out ? "text-kit-fg-4 hover:bg-kit-hover" : "text-kit-fg hover:bg-kit-hover", !sel && d === today && "ring-1 ring-inset ring-kit-line-strong"),
175
175
  children: Number(d.slice(8))
176
176
  }, d);
177
177
  })]
@@ -205,6 +205,11 @@ function zoneOptions(current, def, at) {
205
205
  return [...suggested, ...ALL_ZONES.filter((z) => !seen.has(z)).map((z) => option(z, z.includes("/") ? z.split("/")[0] : "Other"))];
206
206
  }
207
207
  function ZoneSelect({ zone, def, at, disabled, onPick }) {
208
+ const options = React.useMemo(() => zoneOptions(zone, def, at), [
209
+ zone,
210
+ def,
211
+ at
212
+ ]);
208
213
  return /* @__PURE__ */ jsx(Select, {
209
214
  "aria-label": "Time zone",
210
215
  size: "md",
@@ -214,11 +219,7 @@ function ZoneSelect({ zone, def, at, disabled, onPick }) {
214
219
  menuClassName: "w-[300px]",
215
220
  value: zone,
216
221
  onValueChange: onPick,
217
- options: React.useMemo(() => zoneOptions(zone, def, at), [
218
- zone,
219
- def,
220
- at
221
- ]),
222
+ options,
222
223
  disabled
223
224
  });
224
225
  }
@@ -293,7 +294,7 @@ function DateControl({ field, value, onChange, readOnly, id, invalid }) {
293
294
  disabled: readOnly,
294
295
  "aria-invalid": invalid || void 0,
295
296
  "aria-label": wall ? `${field.title}: ${full}. Change` : `${field.title}: pick a date`,
296
- className: cn("@container/date flex w-full min-w-0 items-center gap-2 rounded-kit-md border bg-kit-field-bg px-2.5 text-left text-kit-sm text-kit-fg shadow-kit-field outline-none transition-colors disabled:opacity-60", invalid ? "border-[var(--kit-field-invalid)]" : "border-kit-field-border hover:border-kit-field-border-hover data-[popup-open]:border-kit-field-border-focus focus-visible:border-kit-field-border-focus", variant === "document" ? "h-9" : "h-8")
297
+ className: cn("@container/date flex w-full min-w-0 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 transition-colors hover:border-kit-field-border-hover data-[popup-open]:border-kit-field-border-focus", variant === "document" ? "h-9" : "h-8", invalid && "border-[var(--kit-field-invalid)]")
297
298
  }),
298
299
  children: [
299
300
  /* @__PURE__ */ jsx(IconCalendar, {
@@ -348,20 +349,27 @@ function DateControl({ field, value, onChange, readOnly, id, invalid }) {
348
349
  className: "mt-3 flex w-[248px] flex-col gap-2 border-t border-kit-line pt-3",
349
350
  children: [/* @__PURE__ */ jsxs("label", {
350
351
  className: "flex items-center gap-2",
351
- children: [/* @__PURE__ */ jsx(IconClock, {
352
- className: "size-4 shrink-0 text-kit-fg-3",
353
- stroke: 1.5,
354
- "aria-hidden": true
355
- }), /* @__PURE__ */ jsx("input", {
356
- type: "time",
357
- value: time,
358
- onChange: (e) => e.target.value && commit({
359
- ymd: wall?.ymd ?? today,
360
- time: e.target.value
352
+ children: [
353
+ /* @__PURE__ */ jsx(IconClock, {
354
+ className: "size-4 shrink-0 text-kit-fg-3",
355
+ stroke: 1.5,
356
+ "aria-hidden": true
361
357
  }),
362
- className: "h-8 min-w-0 flex-1 rounded-kit-md border border-kit-field-border bg-kit-field-bg px-2 text-kit-sm text-kit-fg outline-none hover:border-kit-field-border-hover focus:border-kit-field-border-focus",
363
- "aria-label": "Time"
364
- })]
358
+ /* @__PURE__ */ jsx("span", {
359
+ className: "sr-only",
360
+ children: "Time"
361
+ }),
362
+ /* @__PURE__ */ jsx("input", {
363
+ type: "time",
364
+ value: time,
365
+ onChange: (e) => e.target.value && commit({
366
+ ymd: wall?.ymd ?? today,
367
+ time: e.target.value
368
+ }),
369
+ className: "h-8 min-w-0 flex-1 rounded-kit-md border border-kit-field-border bg-kit-field-bg px-2 text-kit-sm text-kit-fg outline-none hover:border-kit-field-border-hover focus:border-kit-field-border-focus",
370
+ "aria-label": "Time"
371
+ })
372
+ ]
365
373
  }), zoned ? /* @__PURE__ */ jsxs("div", {
366
374
  className: "flex items-center gap-2",
367
375
  children: [/* @__PURE__ */ jsx(IconWorld, {
@@ -381,7 +389,7 @@ function DateControl({ field, value, onChange, readOnly, id, invalid }) {
381
389
  content: policy.mode === "site" ? "Uses the site's time zone (Site settings › General)." : "Set by the developer for this field.",
382
390
  children: /* @__PURE__ */ jsxs("span", {
383
391
  tabIndex: 0,
384
- className: "flex h-8 min-w-0 flex-1 items-center gap-1.5 rounded-kit-md bg-kit-subtle px-2 text-kit-sm text-kit-fg-2 outline-none focus-visible:outline-2 focus-visible:outline-kit-focus-ring",
392
+ className: "flex h-8 min-w-0 flex-1 items-center gap-1.5 rounded-kit-md bg-kit-subtle px-2 text-kit-sm text-kit-fg-2 outline-none",
385
393
  children: [/* @__PURE__ */ jsx("span", {
386
394
  className: "min-w-0 flex-1 truncate",
387
395
  children: zoneLabel(zone, at)
@@ -453,6 +461,6 @@ function Unreadable({ id, title, value }) {
453
461
  });
454
462
  }
455
463
  //#endregion
456
- export { DateControl };
464
+ export { DateControl, MiniCalendar };
457
465
 
458
466
  //# sourceMappingURL=date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.js","names":[],"sources":["../../src/controls/date.tsx"],"sourcesContent":["/**\n * DATE / DATETIME — one picker for date, time and time zone (DESIGN 8.9, CPO D43). V2 controls/date.tsx, with the\n * stored shapes prod keeps (date-zone.ts header) and a calendar you can drive from the keyboard:\n *\n * arrows move a day / a week · Home / End go to the week's start / end · Page Up / Down move a month (Shift: a year)\n * Enter or Space picks · the calendar is one tab stop (the picked day, else today, else the 1st)\n *\n * A value this picker cannot read (an object, a word) is shown with its reason and never overwritten by a stray\n * click. A wall time a clock change skips is refused with the reason, not shifted.\n */\nimport * as React from \"react\";\nimport { IconAlertTriangle, IconCalendar, IconChevronDown, IconChevronLeft, IconChevronRight, IconClock, IconLock, IconWorld } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { useKitEnv } from \"../context\";\nimport type { ControlProps } from \"../types\";\nimport { Button } from \"../ui/button\";\nimport { Popover, PopoverContent, PopoverTrigger, Tooltip } from \"../ui/overlay\";\nimport { Select, type SelectOption } from \"../ui/select\";\nimport {\n ALL_ZONES, browserZone, parseStored, resolveShown, todayIn, useDefaultZone, validZone, wallInstant, writeValue, zoneCity, zoneLabel,\n zonePolicy, zoneShortOffset, type Wall,\n} from \"./date-zone\";\n\n/* ── Day arithmetic on \"YYYY-MM-DD\" (UTC, so no local zone leaks in) ──── */\nconst pad = (n: number) => String(n).padStart(2, \"0\");\nconst toUtc = (ymd: string) => {\n const [y, m, d] = ymd.split(\"-\").map(Number);\n return new Date(Date.UTC(y, m - 1, d));\n};\nconst fromUtc = (d: Date) => `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())}`;\nconst addDays = (ymd: string, n: number) => {\n const d = toUtc(ymd);\n d.setUTCDate(d.getUTCDate() + n);\n return fromUtc(d);\n};\nconst addMonths = (ymd: string, n: number) => {\n const d = toUtc(ymd);\n const day = d.getUTCDate();\n const t = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + n, 1));\n const last = new Date(Date.UTC(t.getUTCFullYear(), t.getUTCMonth() + 1, 0)).getUTCDate();\n t.setUTCDate(Math.min(day, last));\n return fromUtc(t);\n};\nconst monthOf = (ymd: string) => ymd.slice(0, 7);\nconst fmt = (ymd: string, o: Intl.DateTimeFormatOptions) => toUtc(ymd).toLocaleDateString(\"en-US\", { ...o, timeZone: \"UTC\" });\nconst fmtTime = (hm: string) => {\n const [h, m] = hm.split(\":\").map(Number);\n return new Date(Date.UTC(2000, 0, 1, h, m)).toLocaleTimeString(\"en-US\", { hour: \"numeric\", minute: \"2-digit\", timeZone: \"UTC\" });\n};\n\n/* ── Calendar ─────────────────────────────────────────────────────────── */\nconst WD = [\"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\", \"Su\"];\nexport function MiniCalendar({ value, today, onSelect }: { value: string | null; today: string; onSelect: (ymd: string) => void }) {\n const [view, setView] = React.useState(() => `${monthOf(value ?? today)}-01`);\n const [cursor, setCursor] = React.useState<string>(value ?? today);\n const grid = React.useRef<HTMLDivElement>(null);\n const refocus = React.useRef(false);\n const viewMonth = monthOf(view);\n /* the one tab stop: the cursor when it is in view, else the picked day, today, or the 1st */\n const stop = [cursor, value, today].find((d) => d && monthOf(d) === viewMonth) ?? view;\n const lead = (toUtc(view).getUTCDay() + 6) % 7;\n const cells = Array.from({ length: 42 }, (_, i) => addDays(view, i - lead));\n\n React.useEffect(() => {\n if (!refocus.current) return;\n refocus.current = false;\n grid.current?.querySelector<HTMLButtonElement>(`[data-day=\"${cursor}\"]`)?.focus();\n }, [cursor, view]);\n\n const go = (ymd: string) => {\n refocus.current = true;\n setCursor(ymd);\n if (monthOf(ymd) !== viewMonth) setView(`${monthOf(ymd)}-01`);\n };\n const onKeyDown = (e: React.KeyboardEvent) => {\n const from = (e.target as HTMLElement).dataset.day;\n if (!from) return;\n const dow = (toUtc(from).getUTCDay() + 6) % 7;\n const to = ({\n ArrowLeft: () => addDays(from, -1),\n ArrowRight: () => addDays(from, 1),\n ArrowUp: () => addDays(from, -7),\n ArrowDown: () => addDays(from, 7),\n Home: () => addDays(from, -dow),\n End: () => addDays(from, 6 - dow),\n PageUp: () => addMonths(from, e.shiftKey ? -12 : -1),\n PageDown: () => addMonths(from, e.shiftKey ? 12 : 1),\n } as Record<string, () => string>)[e.key];\n if (!to) return;\n e.preventDefault();\n go(to());\n };\n const page = (n: number) => {\n const next = addMonths(view, n);\n setView(next);\n setCursor(next);\n };\n\n return (\n <div className=\"w-[248px]\">\n <div className=\"mb-2 flex items-center justify-between\">\n <button type=\"button\" aria-label=\"Previous month\" onClick={() => page(-1)} className=\"flex size-7 items-center justify-center rounded-kit-md text-kit-fg-2 hover:bg-kit-hover\">\n <IconChevronLeft className=\"size-4\" stroke={1.5} />\n </button>\n <span className=\"text-kit-sm font-medium text-kit-fg\" aria-live=\"polite\">{fmt(view, { month: \"long\", year: \"numeric\" })}</span>\n <button type=\"button\" aria-label=\"Next month\" onClick={() => page(1)} className=\"flex size-7 items-center justify-center rounded-kit-md text-kit-fg-2 hover:bg-kit-hover\">\n <IconChevronRight className=\"size-4\" stroke={1.5} />\n </button>\n </div>\n <div ref={grid} role=\"group\" aria-label={fmt(view, { month: \"long\", year: \"numeric\" })} className=\"grid grid-cols-7 gap-0.5 text-center\" onKeyDown={onKeyDown}>\n {WD.map((d) => (\n <span key={d} aria-hidden className=\"pb-1 text-kit-2xs text-kit-fg-3\">{d}</span>\n ))}\n {cells.map((d) => {\n const out = monthOf(d) !== viewMonth;\n const sel = d === value;\n return (\n <button\n key={d}\n type=\"button\"\n data-day={d}\n tabIndex={d === stop ? 0 : -1}\n onClick={() => {\n setCursor(d);\n onSelect(d);\n }}\n aria-pressed={sel}\n aria-current={d === today ? \"date\" : undefined}\n aria-label={fmt(d, { weekday: \"long\", month: \"long\", day: \"numeric\", year: \"numeric\" })}\n className={cn(\n \"tabular-nums flex size-8 items-center justify-center rounded-kit-md text-kit-sm transition-colors\",\n sel ? \"bg-kit-inverse font-medium text-kit-fg-inverse\" : out ? \"text-kit-fg-4 hover:bg-kit-hover\" : \"text-kit-fg hover:bg-kit-hover\",\n !sel && d === today && \"ring-1 ring-inset ring-kit-line-strong\",\n )}\n >\n {Number(d.slice(8))}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\n/* ── Zone list ────────────────────────────────────────────────────────── */\n/** One searchable list: Suggested (the default zone, your zone, the value's zone) first, then every IANA zone by region. */\nfunction zoneOptions(current: string, def: { zone: string; source: string }, at: Date): SelectOption[] {\n const suggested: SelectOption[] = [];\n const seen = new Set<string>();\n const option = (z: string, group: string, description?: string): SelectOption => ({\n value: z,\n label: zoneLabel(z, at),\n description,\n group,\n keywords: [z, zoneCity(z), zoneShortOffset(z, at), ...(description ? [description] : [])],\n });\n const push = (z: string, note: string) => {\n if (seen.has(z) || !validZone(z)) return;\n seen.add(z);\n suggested.push(option(z, \"Suggested\", note));\n };\n push(def.zone, def.source === \"site\" ? \"Site time zone\" : \"Your time zone\");\n push(browserZone(), \"Your time zone\");\n push(current, \"Current\");\n return [...suggested, ...ALL_ZONES.filter((z) => !seen.has(z)).map((z) => option(z, z.includes(\"/\") ? z.split(\"/\")[0] : \"Other\"))];\n}\n\nfunction ZoneSelect({ zone, def, at, disabled, onPick }: { zone: string; def: { zone: string; source: string }; at: Date; disabled: boolean; onPick: (z: string) => void }) {\n const options = React.useMemo(() => zoneOptions(zone, def, at), [zone, def, at]);\n return (\n <Select\n aria-label=\"Time zone\"\n size=\"md\"\n className=\"min-w-0 flex-1\"\n searchable\n searchPlaceholder=\"Search city, region or offset\"\n menuClassName=\"w-[300px]\"\n value={zone}\n onValueChange={onPick}\n options={options}\n disabled={disabled}\n />\n );\n}\n\n/* ── The control ──────────────────────────────────────────────────────── */\nexport function DateControl({ field, value, onChange, readOnly, id, invalid }: ControlProps) {\n const { variant } = useKitEnv();\n const withTime = field.type === \"datetime\";\n const policy = zonePolicy(field);\n const def = useDefaultZone();\n const [picked, setPicked] = React.useState<string>();\n const [open, setOpen] = React.useState(false);\n const [problem, setProblem] = React.useState<string | null>(null);\n const parsed = React.useMemo(() => parseStored(value), [value]);\n const { wall, zone } = React.useMemo(() => resolveShown(parsed, policy.mode, { fixed: policy.zone, def: def.zone, picked }), [parsed, policy.mode, policy.zone, def.zone, picked]);\n const zoned = policy.mode !== \"none\";\n const time = wall?.time ?? \"09:00\";\n const today = todayIn(zoned ? zone : undefined);\n const at = React.useMemo(() => (wall ? wallInstant(zone, wall) : new Date()), [wall, zone]);\n\n if (!parsed.readable) return <Unreadable id={id} title={field.title} value={value} />;\n\n const commit = (next: Wall, z = zone) => {\n const r = writeValue({ withTime, mode: policy.mode, wall: next, zone: z });\n if (!r.ok) {\n setProblem(r.reason);\n return false;\n }\n setProblem(null);\n onChange(r.value);\n return true;\n };\n const pickDay = (ymd: string) => {\n if (commit({ ymd, time }) && !withTime) setOpen(false);\n };\n\n const timeText = withTime && wall ? fmtTime(wall.time) : \"\";\n const showZone = zoned && withTime;\n const full = wall ? `${fmt(wall.ymd, { weekday: \"long\", month: \"long\", day: \"numeric\", year: \"numeric\" })}${timeText ? ` at ${timeText}` : \"\"}${showZone ? ` (${zoneLabel(zone, at)})` : \"\"}` : \"\";\n\n return (\n <Popover\n open={open}\n onOpenChange={(o) => {\n setOpen(o);\n if (!o) setProblem(null);\n }}\n >\n <PopoverTrigger\n render={\n <button\n id={id}\n type=\"button\"\n disabled={readOnly}\n aria-invalid={invalid || undefined}\n aria-label={wall ? `${field.title}: ${full}. Change` : `${field.title}: pick a date`}\n className={cn(\n \"@container/date flex w-full min-w-0 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 transition-colors hover:border-kit-field-border-hover data-[popup-open]:border-kit-field-border-focus\",\n variant === \"document\" ? \"h-9\" : \"h-8\",\n invalid && \"border-[var(--kit-field-invalid)]\",\n )}\n />\n }\n >\n <IconCalendar className=\"size-4 shrink-0 text-kit-fg-3\" stroke={1.5} aria-hidden />\n {wall ? (\n /* never truncate the date itself: drop the weekday first, then the zone (it stays in the label and popover) */\n <span className=\"flex min-w-0 flex-1 items-baseline gap-1.5 whitespace-nowrap\" data-slot=\"date-text\">\n <span className=\"shrink-0\">\n <span className=\"hidden @[260px]/date:inline\">{fmt(wall.ymd, { weekday: \"short\" })}, </span>\n {fmt(wall.ymd, { month: \"short\", day: \"numeric\", year: \"numeric\" })}\n {timeText ? <span className=\"text-kit-fg-2\"> · {timeText}</span> : null}\n </span>\n {showZone ? <span className=\"hidden min-w-0 truncate text-kit-xs text-kit-fg-3 @[200px]/date:inline\">{zoneShortOffset(zone, at)}</span> : null}\n </span>\n ) : (\n <span className=\"min-w-0 flex-1 truncate text-kit-fg-3\">{withTime ? \"Pick a date and time\" : \"Pick a date\"}</span>\n )}\n <IconChevronDown className=\"size-3.5 shrink-0 text-kit-fg-3\" stroke={1.5} aria-hidden />\n </PopoverTrigger>\n <PopoverContent className=\"w-auto\" aria-label={withTime ? `${field.title}: date and time` : `${field.title}: date`}>\n <MiniCalendar value={wall?.ymd ?? null} today={today} onSelect={pickDay} />\n {withTime ? (\n <div className=\"mt-3 flex w-[248px] flex-col gap-2 border-t border-kit-line pt-3\">\n <label className=\"flex items-center gap-2\">\n <IconClock className=\"size-4 shrink-0 text-kit-fg-3\" stroke={1.5} aria-hidden />\n <span className=\"sr-only\">Time</span>\n <input\n type=\"time\"\n value={time}\n onChange={(e) => e.target.value && commit({ ymd: wall?.ymd ?? today, time: e.target.value })}\n className=\"h-8 min-w-0 flex-1 rounded-kit-md border border-kit-field-border bg-kit-field-bg px-2 text-kit-sm text-kit-fg outline-none hover:border-kit-field-border-hover focus:border-kit-field-border-focus\"\n aria-label=\"Time\"\n />\n </label>\n {zoned ? (\n <div className=\"flex items-center gap-2\">\n <IconWorld className=\"size-4 shrink-0 text-kit-fg-3\" stroke={1.5} aria-hidden />\n {policy.mode === \"pick\" ? (\n <ZoneSelect\n zone={zone}\n def={def}\n at={at}\n disabled={!wall}\n onPick={(z) => {\n if (!wall) return;\n // keep the wall time the author typed; the instant moves with the zone (6.4)\n if (commit(wall, z)) setPicked(z);\n }}\n />\n ) : (\n <Tooltip content={policy.mode === \"site\" ? \"Uses the site's time zone (Site settings › General).\" : \"Set by the developer for this field.\"}>\n <span tabIndex={0} className=\"flex h-8 min-w-0 flex-1 items-center gap-1.5 rounded-kit-md bg-kit-subtle px-2 text-kit-sm text-kit-fg-2 outline-none\">\n <span className=\"min-w-0 flex-1 truncate\">{zoneLabel(zone, at)}</span>\n <IconLock className=\"size-3.5 shrink-0 text-kit-fg-3\" stroke={1.5} role=\"img\" aria-label={policy.mode === \"site\" ? \"Site time zone\" : \"Fixed time zone\"} />\n </span>\n </Tooltip>\n )}\n </div>\n ) : null}\n </div>\n ) : null}\n {problem ? (\n <p role=\"alert\" className=\"mt-2 flex w-[248px] items-start gap-1.5 text-kit-xs text-kit-danger-fg\">\n <IconAlertTriangle className=\"mt-0.5 size-3.5 shrink-0\" stroke={1.5} aria-hidden />\n {problem}\n </p>\n ) : null}\n <div className=\"mt-2 flex justify-between\">\n <Button size=\"xs\" variant=\"ghost\" onClick={() => pickDay(today)}>\n Today\n </Button>\n {wall ? (\n <Button\n size=\"xs\"\n variant=\"ghost\"\n onClick={() => {\n // null, not \"\": the backend skips an empty value but refuses \"\" as \"not a valid date\"\n onChange(null);\n setProblem(null);\n setOpen(false);\n }}\n >\n Clear\n </Button>\n ) : null}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\n/** A stored value this picker cannot read: shown with the reason, kept as it is, never replaced by a stray pick. */\nfunction Unreadable({ id, title, value }: { id: string; title: string; value: unknown }) {\n const raw = typeof value === \"string\" ? value : JSON.stringify(value);\n return (\n <output\n id={id}\n tabIndex={0}\n data-slot=\"date-unreadable\"\n className=\"flex min-w-0 items-start gap-2 rounded-kit-md border border-dashed border-kit-line-strong bg-kit-subtle px-2.5 py-2 text-kit-xs text-kit-fg-2 outline-none focus-visible:outline-2 focus-visible:outline-kit-focus-ring\"\n >\n <IconAlertTriangle className=\"mt-0.5 size-3.5 shrink-0 text-kit-warning-fg\" stroke={1.5} aria-hidden />\n <span className=\"min-w-0\">\n {title} holds a value this picker can't read, so it is kept as it is:{\" \"}\n <span className=\"break-all font-kit-mono text-kit-fg\">{raw}</span>\n </span>\n </output>\n );\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { CONTROLS } from "../engine/kit-field.js";
3
3
  import { ReferenceControl } from "./reference.js";
4
4
  import { FormPickerControl, isFormOnly } from "./form-picker.js";
5
5
  import { createElement } from "react";
6
- //#region src/kit/controls/form-picker-register.ts
6
+ //#region src/controls/form-picker-register.ts
7
7
  /**
8
8
  * Lane L3: a reference to forms only (`reference: { to: ["form"] }`, a component's `form` prop) draws the form picker
9
9
  * when the host provides the project's forms; any other reference keeps the reference control. Imported after
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-picker-register.js","names":[],"sources":["../../src/controls/form-picker-register.ts"],"sourcesContent":["/**\n * Lane L3: a reference to forms only (`reference: { to: [\"form\"] }`, a component's `form` prop) draws the form picker\n * when the host provides the project's forms; any other reference keeps the reference control. Imported after\n * reference-register (kit barrel), so it wraps the registered reference control.\n */\nimport { createElement } from \"react\";\nimport type { ControlProps } from \"../types\";\nimport { useKitServices } from \"../context\";\nimport { CONTROLS } from \"../engine/kit-field\";\nimport { ReferenceControl } from \"./reference\";\nimport { FormPickerControl, isFormOnly } from \"./form-picker\";\n\nconst Reference = CONTROLS.reference ?? ReferenceControl;\nCONTROLS.reference = function ReferenceOrFormControl(props: ControlProps) {\n const { forms, useFormOptions } = useKitServices();\n return createElement(isFormOnly(props.field) && (forms || useFormOptions) ? FormPickerControl : Reference, props);\n};\n"],"mappings":";;;;;;;;;;;AAYA,IAAM,YAAY,SAAS,aAAa;AACxC,SAAS,YAAY,SAAS,uBAAuB,OAAqB;CACxE,MAAM,EAAE,OAAO,mBAAmB,eAAe;CACjD,OAAO,cAAc,WAAW,MAAM,KAAK,MAAM,SAAS,kBAAkB,oBAAoB,WAAW,KAAK;AAClH"}
@@ -2,7 +2,7 @@ import { KitServicesProvider, useKitEnv, useKitServices } from "../context.js";
2
2
  import { ReferenceControl } from "./reference.js";
3
3
  import * as React from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
- //#region src/kit/controls/form-picker.tsx
5
+ //#region src/controls/form-picker.tsx
6
6
  /**
7
7
  * FORM PICKER — a reference to the project's forms (`reference: { to: ["form"] }`; a component's `form` prop), drawn as
8
8
  * V2 draws it: the reference control's card and 300px search popover, its rows the host's forms (V2 read them from
@@ -62,19 +62,21 @@ function FormPickerControl(props) {
62
62
  };
63
63
  const formId = typeof props.value === "string" && props.value ? props.value : null;
64
64
  const Details = services.FormDetails;
65
+ const control = /* @__PURE__ */ jsx(KitServicesProvider, {
66
+ value,
67
+ children: /* @__PURE__ */ jsx(ReferenceControl, {
68
+ ...props,
69
+ onChange: (v) => props.onChange(v == null || v === "" ? void 0 : v)
70
+ })
71
+ });
72
+ if (!formId || !Details) return control;
65
73
  return /* @__PURE__ */ jsxs("div", {
66
74
  className: "flex min-w-0 flex-col gap-2",
67
- children: [/* @__PURE__ */ jsx(KitServicesProvider, {
68
- value,
69
- children: /* @__PURE__ */ jsx(ReferenceControl, {
70
- ...props,
71
- onChange: (v) => props.onChange(v == null || v === "" ? void 0 : v)
72
- })
73
- }), formId && Details ? /* @__PURE__ */ jsx(Details, {
75
+ children: [control, /* @__PURE__ */ jsx(Details, {
74
76
  formId,
75
77
  readOnly: props.readOnly,
76
78
  onPick: (id) => props.onChange(id)
77
- }) : null]
79
+ })]
78
80
  });
79
81
  }
80
82
  //#endregion
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-picker.js","names":[],"sources":["../../src/controls/form-picker.tsx"],"sourcesContent":["/**\n * FORM PICKER — a reference to the project's forms (`reference: { to: [\"form\"] }`; a component's `form` prop), drawn as\n * V2 draws it: the reference control's card and 300px search popover, its rows the host's forms (V2 read them from\n * `services.forms`, with \"{n} fields · {n} submissions\" under each name).\n *\n * The rows come from the host, never a seed: `forms` (V2's synchronous list) or `useFormOptions`, a React HOOK for a host\n * that loads them (the dock: GET /forms). While they load, the saved form shows its id; a failed load is said in words\n * on the card and in the picker. D58: submission counts are form data, so a viewer without `forms.submissions` sees\n * them dropped from the subtitle (V2 rule).\n *\n * Remove clears the value (`undefined`): a form prop stores `{ formId }` or nothing, never a null envelope.\n * `FormDetails`, when the host has one, draws under a chosen form (where the form renders on the site, editing its fields).\n */\nimport * as React from \"react\";\nimport { KitServicesProvider, useKitEnv, useKitServices, type KitServices } from \"../context\";\nimport type { FieldSchema } from \"../schema/types\";\nimport type { ControlProps } from \"../types\";\nimport { ReferenceControl } from \"./reference\";\nimport type { KitReferenceOption, KitReferenceQuery } from \"./reference-services\";\n\nexport interface KitFormOption {\n id: string;\n title: string;\n /** \"5 fields · 128 submissions\" */\n subtitle?: string;\n /** \"draft\" shows the Draft chip (a draft form refuses submissions) */\n status?: string | null;\n}\n\ndeclare module \"../context\" {\n interface KitServices {\n /** A React HOOK: the project's forms, for a host that loads them. One identity for the life of the form. */\n useFormOptions?: () => { forms: KitFormOption[]; loading?: boolean; error?: string };\n /** Drawn under a chosen form: the host's own detail for it (where it renders, its fields). */\n FormDetails?: React.ComponentType<{ formId: string; readOnly?: boolean; onPick?: (formId: string) => void }>;\n }\n}\n\n/** A reference whose only target is forms (no filter: a filtered one stays on the reference search). */\nexport const isFormOnly = (field: FieldSchema) => {\n const to = field.reference?.to ?? [];\n return to.length === 1 && to[0] === \"form\" && !field.reference?.filter;\n};\n\nconst SUBMISSIONS = / · [\\d,]+ submissions?$/;\n\nfunction useFormRows(services: KitServices): { forms: KitFormOption[] | null; error?: string } {\n const loaded = services.useFormOptions ? services.useFormOptions() : null;\n if (loaded) return { forms: loaded.loading ? null : loaded.forms, error: loaded.error };\n return { forms: services.forms?.() ?? [] };\n}\n\nexport function FormPickerControl(props: ControlProps) {\n const services = useKitServices();\n const subs = useKitEnv().can(\"forms.submissions\");\n const { forms, error } = useFormRows(services);\n // by content: `forms()` may hand back a new list on every render, and the search must keep one identity (the picker\n // searches again whenever it changes)\n const rowsKey = JSON.stringify(forms);\n const options = React.useMemo<KitReferenceOption[] | null>(\n () =>\n forms?.map((f) => ({ id: f.id, kind: \"form\" as const, title: f.title, subtitle: (subs ? f.subtitle : f.subtitle?.replace(SUBMISSIONS, \"\")) || null, status: f.status ?? null })) ?? null,\n [rowsKey, subs], // eslint-disable-line react-hooks/exhaustive-deps\n );\n // the reference control over these rows: search by name, read the saved id back. While the forms load there is no\n // lookup, so the card shows the saved id (never a \"Missing\" that is only \"not loaded yet\").\n const reads = React.useMemo(() => {\n const fail = () => Promise.reject(new Error(error));\n return {\n searchReferences: error\n ? fail\n : async (q: KitReferenceQuery) => {\n const t = q.q.trim().toLowerCase();\n const rows = (options ?? []).filter((o) => o.id !== q.excludeId && (!t || o.title.toLowerCase().includes(t)));\n return { options: rows.slice(0, q.limit), truncated: false };\n },\n lookupReferences: error ? fail : options ? async (ids: string[]) => options.filter((o) => ids.includes(o.id)) : undefined,\n };\n }, [options, error]);\n const value: KitServices = { ...services, ...reads, createReference: undefined };\n const formId = typeof props.value === \"string\" && props.value ? props.value : null;\n const Details = services.FormDetails;\n const control = (\n <KitServicesProvider value={value}>\n <ReferenceControl {...props} onChange={(v) => props.onChange(v == null || v === \"\" ? undefined : v)} />\n </KitServicesProvider>\n );\n // V2 draws the reference control alone; only the host's details under a chosen form need the stack\n if (!formId || !Details) return control;\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n {control}\n <Details formId={formId} readOnly={props.readOnly} onPick={(id) => props.onChange(id)} />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAuCA,IAAa,cAAc,UAAuB;CAChD,MAAM,KAAK,MAAM,WAAW,MAAM,CAAC;CACnC,OAAO,GAAG,WAAW,KAAK,GAAG,OAAO,UAAU,CAAC,MAAM,WAAW;AAClE;AAEA,IAAM,cAAc;AAEpB,SAAS,YAAY,UAA0E;CAC7F,MAAM,SAAS,SAAS,iBAAiB,SAAS,eAAe,IAAI;CACrE,IAAI,QAAQ,OAAO;EAAE,OAAO,OAAO,UAAU,OAAO,OAAO;EAAO,OAAO,OAAO;CAAM;CACtF,OAAO,EAAE,OAAO,SAAS,QAAQ,KAAK,CAAC,EAAE;AAC3C;AAEA,SAAgB,kBAAkB,OAAqB;CACrD,MAAM,WAAW,eAAe;CAChC,MAAM,OAAO,UAAU,CAAC,CAAC,IAAI,mBAAmB;CAChD,MAAM,EAAE,OAAO,UAAU,YAAY,QAAQ;CAG7C,MAAM,UAAU,KAAK,UAAU,KAAK;CACpC,MAAM,UAAU,MAAM,cAElB,OAAO,KAAK,OAAO;EAAE,IAAI,EAAE;EAAI,MAAM;EAAiB,OAAO,EAAE;EAAO,WAAW,OAAO,EAAE,WAAW,EAAE,UAAU,QAAQ,aAAa,EAAE,MAAM;EAAM,QAAQ,EAAE,UAAU;CAAK,EAAE,KAAK,MACtL,CAAC,SAAS,IAAI,CAChB;CAGA,MAAM,QAAQ,MAAM,cAAc;EAChC,MAAM,aAAa,QAAQ,OAAO,IAAI,MAAM,KAAK,CAAC;EAClD,OAAO;GACL,kBAAkB,QACd,OACA,OAAO,MAAyB;IAC9B,MAAM,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,YAAY;IAEjC,OAAO;KAAE,UADK,WAAW,CAAC,EAAA,CAAG,QAAQ,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,MAAM,YAAY,CAAC,CAAC,SAAS,CAAC,EACxF,CAAA,CAAK,MAAM,GAAG,EAAE,KAAK;KAAG,WAAW;IAAM;GAC7D;GACJ,kBAAkB,QAAQ,OAAO,UAAU,OAAO,QAAkB,QAAQ,QAAQ,MAAM,IAAI,SAAS,EAAE,EAAE,CAAC,IAAI,KAAA;EAClH;CACF,GAAG,CAAC,SAAS,KAAK,CAAC;CACnB,MAAM,QAAqB;EAAE,GAAG;EAAU,GAAG;EAAO,iBAAiB,KAAA;CAAU;CAC/E,MAAM,SAAS,OAAO,MAAM,UAAU,YAAY,MAAM,QAAQ,MAAM,QAAQ;CAC9E,MAAM,UAAU,SAAS;CACzB,MAAM,UACJ,oBAAC,qBAAD;EAA4B;EAC1B,UAAA,oBAAC,kBAAD;GAAkB,GAAI;GAAO,WAAW,MAAM,MAAM,SAAS,KAAK,QAAQ,MAAM,KAAK,KAAA,IAAY,CAAC;EAAI,CAAA;CACnF,CAAA;CAGvB,IAAI,CAAC,UAAU,CAAC,SAAS,OAAO;CAChC,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACG,SACD,oBAAC,SAAD;GAAiB;GAAQ,UAAU,MAAM;GAAU,SAAS,OAAO,MAAM,SAAS,EAAE;EAAI,CAAA,CACrF;;AAET"}
@@ -1,6 +1,6 @@
1
1
  import { CONTROLS } from "../engine/kit-field.js";
2
2
  import { IconControl } from "./icon.js";
3
- //#region src/kit/controls/icon-register.ts
3
+ //#region src/controls/icon-register.ts
4
4
  /** Lane C3: the icon field in the engine's dispatch table (one line per type; merge with other lanes by line). */
5
5
  CONTROLS.icon = IconControl;
6
6
  //#endregion
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon-register.js","names":[],"sources":["../../src/controls/icon-register.ts"],"sourcesContent":["/** Lane C3: the icon field in the engine's dispatch table (one line per type; merge with other lanes by line). */\nimport { CONTROLS } from \"../engine/kit-field\";\nimport { IconControl } from \"./icon\";\n\nCONTROLS.icon = IconControl;\n"],"mappings":";;;;AAIA,SAAS,OAAO"}
@@ -29,10 +29,12 @@ declare module "../context" {
29
29
  }>;
30
30
  }
31
31
  }
32
- /** The picker: search, Recent, then the whole set ("No icon" first). Search spans the name and its Tabler twin. */
33
- export declare function IconPicker({ value, onPick, onChooseMedia }: {
32
+ /** The picker: search, Recent, then the whole set ("No icon" first). Search spans the name and its Tabler twin.
33
+ * `field`: the icon field's popover (V2 IconFieldPicker, a 22rem list); otherwise the app-UI grid (V2 IconPickerGrid, max-h-56). */
34
+ export declare function IconPicker({ value, onPick, onChooseMedia, field }: {
34
35
  value?: string;
35
36
  onPick: (name: string | null) => void;
36
37
  onChooseMedia?: () => void;
38
+ field?: boolean;
37
39
  }): import("react/jsx-runtime").JSX.Element;
38
40
  export declare function IconControl({ field, value, onChange, readOnly, id, invalid }: ControlProps): import("react/jsx-runtime").JSX.Element;