@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,30 @@
1
+ import * as React from "react";
2
+ import { type SelectOption } from "./select";
3
+ export interface AutocompleteProps {
4
+ id?: string;
5
+ "aria-label"?: string;
6
+ "aria-describedby"?: string;
7
+ /** the text (controlled) */
8
+ value?: string;
9
+ defaultValue?: string;
10
+ /** every keystroke, and the label of a picked suggestion */
11
+ onValueChange?: (text: string) => void;
12
+ options: SelectOption[];
13
+ /** a suggestion was picked (click, or Enter on a highlighted row) */
14
+ onSelect?: (option: SelectOption) => void;
15
+ /** Enter with no suggestion highlighted: commit the typed text */
16
+ onEnter?: (text: string) => void;
17
+ /** default: Select's ranking; null = the caller already filtered (async options) */
18
+ filter?: ((options: SelectOption[], query: string) => SelectOption[]) | null;
19
+ placeholder?: string;
20
+ size?: "sm" | "md" | "lg";
21
+ leading?: React.ReactNode;
22
+ loading?: boolean;
23
+ invalid?: boolean;
24
+ disabled?: boolean;
25
+ /** open the suggestions when the field takes focus (default true, as V2) */
26
+ openOnFocus?: boolean;
27
+ className?: string;
28
+ menuClassName?: string;
29
+ }
30
+ export declare function Autocomplete({ id, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, value, defaultValue, onValueChange, options, onSelect, onEnter, filter, placeholder, size, leading, loading, invalid, disabled, openOnFocus, className, menuClassName, }: AutocompleteProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,139 @@
1
+ import { cn } from "../lib/cn.js";
2
+ import { useFieldDescribedBy, useFieldId, useFieldLabelledBy, useLabelFor } from "./field-context.js";
3
+ import { KIT_SCOPE } from "./surfaces.js";
4
+ import { IconButton } from "./button.js";
5
+ import { Highlight, filterOptions, nodeText } from "./select.js";
6
+ import { Spinner } from "./spinner.js";
7
+ import * as React from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { IconX } from "@tabler/icons-react";
10
+ import { Autocomplete as Autocomplete$1 } from "@base-ui/react/autocomplete";
11
+ //#region src/ui/autocomplete.tsx
12
+ var H = {
13
+ sm: "h-7",
14
+ md: "h-8",
15
+ lg: "h-9"
16
+ };
17
+ function Autocomplete({ id, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, value, defaultValue = "", onValueChange, options, onSelect, onEnter, filter = filterOptions, placeholder, size = "md", leading, loading, invalid, disabled, openOnFocus = true, className, menuClassName }) {
18
+ const fieldId = useFieldId();
19
+ const labelledBy = useFieldLabelledBy();
20
+ const labelFor = useLabelFor(id ?? fieldId);
21
+ const describedBy = useFieldDescribedBy();
22
+ const [inner, setInner] = React.useState(defaultValue);
23
+ const text = value ?? inner;
24
+ const setText = (t) => {
25
+ if (value === void 0) setInner(t);
26
+ onValueChange?.(t);
27
+ };
28
+ const [open, setOpen] = React.useState(false);
29
+ const highlighted = React.useRef(void 0);
30
+ const shown = React.useMemo(() => filter ? filter(options, text) : options, [
31
+ filter,
32
+ options,
33
+ text
34
+ ]);
35
+ const named = id ?? fieldId ?? ariaLabel;
36
+ return /* @__PURE__ */ jsxs(Autocomplete$1.Root, {
37
+ items: shown,
38
+ filter: null,
39
+ mode: "list",
40
+ value: text,
41
+ onValueChange: (t) => setText(t),
42
+ itemToStringValue: (o) => nodeText(o.label),
43
+ open: open && shown.length > 0,
44
+ onOpenChange: setOpen,
45
+ onItemHighlighted: (o) => highlighted.current = o,
46
+ openOnInputClick: true,
47
+ loopFocus: true,
48
+ disabled,
49
+ children: [/* @__PURE__ */ jsxs("div", {
50
+ className: cn("flex min-w-0 items-center rounded-kit-md border border-kit-field-border bg-kit-field-bg shadow-kit-field transition-[border-color,box-shadow] duration-150 hover:border-kit-field-border-hover focus-within:border-kit-field-border-focus focus-within:shadow-kit-ring-field", invalid && "border-[var(--kit-field-invalid)] hover:border-[var(--kit-field-invalid)]", disabled && "cursor-not-allowed bg-kit-subtle opacity-60", H[size], className),
51
+ children: [
52
+ leading ? /* @__PURE__ */ jsx("span", {
53
+ "aria-hidden": true,
54
+ className: "ml-2.5 flex shrink-0 text-kit-fg-3 [&_svg]:size-4",
55
+ children: leading
56
+ }) : null,
57
+ /* @__PURE__ */ jsx(Autocomplete$1.Input, {
58
+ id: id ?? fieldId,
59
+ "aria-label": ariaLabel,
60
+ "aria-labelledby": ariaLabel ? void 0 : labelFor ?? (named ? void 0 : labelledBy),
61
+ "aria-describedby": [ariaDescribedBy, describedBy].filter(Boolean).join(" ") || void 0,
62
+ "aria-invalid": invalid || void 0,
63
+ placeholder,
64
+ autoComplete: "off",
65
+ spellCheck: false,
66
+ onFocus: () => openOnFocus && setOpen(true),
67
+ onKeyDown: (e) => {
68
+ if (e.key === "Enter" && !highlighted.current) onEnter?.(text);
69
+ },
70
+ className: "h-full min-w-0 flex-1 bg-transparent px-2 text-kit-sm text-kit-fg outline-none placeholder:text-kit-fg-3 disabled:cursor-not-allowed"
71
+ }),
72
+ loading ? /* @__PURE__ */ jsx(Spinner, {
73
+ size: "sm",
74
+ tone: "muted",
75
+ label: "Loading suggestions",
76
+ className: "mr-2"
77
+ }) : text && !disabled ? /* @__PURE__ */ jsx(IconButton, {
78
+ label: "Clear",
79
+ size: "xs",
80
+ variant: "ghost",
81
+ className: "mr-1",
82
+ onMouseDown: (e) => e.preventDefault(),
83
+ onClick: () => setText(""),
84
+ children: /* @__PURE__ */ jsx(IconX, { stroke: 1.5 })
85
+ }) : null
86
+ ]
87
+ }), /* @__PURE__ */ jsx(Autocomplete$1.Portal, { children: /* @__PURE__ */ jsx(Autocomplete$1.Positioner, {
88
+ align: "start",
89
+ side: "bottom",
90
+ sideOffset: 4,
91
+ collisionPadding: 12,
92
+ className: "z-[var(--kit-z-menu,80)]",
93
+ "data-floating-layer": "",
94
+ ...KIT_SCOPE,
95
+ children: /* @__PURE__ */ jsx(Autocomplete$1.Popup, {
96
+ className: cn("w-[max(var(--anchor-width),280px)] max-w-[min(420px,calc(100vw-24px))] rounded-kit-lg border bg-kit-surface p-1 text-kit-fg shadow-lg outline-none data-[open]:animate-kit-pop-in", menuClassName),
97
+ children: /* @__PURE__ */ jsx(Autocomplete$1.List, {
98
+ className: "max-h-72 overflow-y-auto overscroll-contain",
99
+ children: shown.map((o, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [o.group && (i === 0 || shown[i - 1].group !== o.group) ? /* @__PURE__ */ jsx("div", {
100
+ role: "presentation",
101
+ className: "px-2 pb-1 pt-2 text-kit-xs font-medium text-kit-fg-3 first:pt-1",
102
+ children: o.group
103
+ }) : null, /* @__PURE__ */ jsxs(Autocomplete$1.Item, {
104
+ value: o,
105
+ disabled: o.disabled,
106
+ onClick: () => onSelect?.(o),
107
+ className: "flex h-8 cursor-pointer select-none items-center gap-2 rounded-kit-md px-2 text-kit-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-40 data-[highlighted]:bg-kit-hover",
108
+ children: [
109
+ o.icon ? /* @__PURE__ */ jsx("span", {
110
+ "aria-hidden": true,
111
+ className: "flex shrink-0 text-kit-fg-3 [&_svg]:size-4",
112
+ children: o.icon
113
+ }) : null,
114
+ /* @__PURE__ */ jsx("span", {
115
+ className: "min-w-0 shrink truncate text-kit-fg",
116
+ children: typeof o.label === "string" ? /* @__PURE__ */ jsx(Highlight, {
117
+ text: o.label,
118
+ query: text
119
+ }) : o.label
120
+ }),
121
+ o.description ? /* @__PURE__ */ jsx("span", {
122
+ className: "min-w-0 flex-1 truncate text-kit-xs text-kit-fg-3",
123
+ children: o.description
124
+ }) : /* @__PURE__ */ jsx("span", { className: "flex-1" }),
125
+ o.meta ? /* @__PURE__ */ jsx("span", {
126
+ className: "shrink-0 text-kit-2xs text-kit-fg-3",
127
+ children: o.meta
128
+ }) : null
129
+ ]
130
+ })] }, o.value))
131
+ })
132
+ })
133
+ }) })]
134
+ });
135
+ }
136
+ //#endregion
137
+ export { Autocomplete };
138
+
139
+ //# sourceMappingURL=autocomplete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autocomplete.js","names":[],"sources":["../../src/ui/autocomplete.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Autocomplete as AutocompletePrimitive } from \"@base-ui/react/autocomplete\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { IconButton } from \"./button\";\nimport { useFieldDescribedBy, useFieldId, useFieldLabelledBy, useLabelFor } from \"./field-context\";\nimport { filterOptions, Highlight, nodeText, type SelectOption } from \"./select\";\nimport { Spinner } from \"./spinner\";\nimport { KIT_SCOPE } from \"./surfaces\";\n\n/* ── Autocomplete ────────────────────────────────────────────────────────\n Free text with suggestions: the value is whatever is typed; a suggestion fills it in. Select only picks fixed options.\n V2 has no component, only the pattern (kit controls link.tsx:504-650, invite-flow.tsx:197); kit-ports-spec.md §2.\n Field = the Input look; the list opens on focus or typing, only while it has rows (free text is a valid value, so\n there is no \"No matches\"); nothing is highlighted until the arrows move, so Enter commits the typed text (onEnter).\n Ranking is Select's filterOptions + Highlight. */\n\nexport interface AutocompleteProps {\n id?: string;\n \"aria-label\"?: string;\n \"aria-describedby\"?: string;\n /** the text (controlled) */\n value?: string;\n defaultValue?: string;\n /** every keystroke, and the label of a picked suggestion */\n onValueChange?: (text: string) => void;\n options: SelectOption[];\n /** a suggestion was picked (click, or Enter on a highlighted row) */\n onSelect?: (option: SelectOption) => void;\n /** Enter with no suggestion highlighted: commit the typed text */\n onEnter?: (text: string) => void;\n /** default: Select's ranking; null = the caller already filtered (async options) */\n filter?: ((options: SelectOption[], query: string) => SelectOption[]) | null;\n placeholder?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n leading?: React.ReactNode;\n loading?: boolean;\n invalid?: boolean;\n disabled?: boolean;\n /** open the suggestions when the field takes focus (default true, as V2) */\n openOnFocus?: boolean;\n className?: string;\n menuClassName?: string;\n}\n\nconst H = { sm: \"h-7\", md: \"h-8\", lg: \"h-9\" } as const;\n\nexport function Autocomplete({\n id,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n value,\n defaultValue = \"\",\n onValueChange,\n options,\n onSelect,\n onEnter,\n filter = filterOptions,\n placeholder,\n size = \"md\",\n leading,\n loading,\n invalid,\n disabled,\n openOnFocus = true,\n className,\n menuClassName,\n}: AutocompleteProps) {\n const fieldId = useFieldId();\n const labelledBy = useFieldLabelledBy();\n const labelFor = useLabelFor(id ?? fieldId);\n const describedBy = useFieldDescribedBy();\n const [inner, setInner] = React.useState(defaultValue);\n const text = value ?? inner;\n const setText = (t: string) => {\n if (value === undefined) setInner(t);\n onValueChange?.(t);\n };\n const [open, setOpen] = React.useState(false);\n const highlighted = React.useRef<SelectOption | undefined>(undefined);\n const shown = React.useMemo(() => (filter ? filter(options, text) : options), [filter, options, text]);\n const named = id ?? fieldId ?? ariaLabel;\n\n return (\n <AutocompletePrimitive.Root\n items={shown}\n filter={null}\n mode=\"list\"\n value={text}\n onValueChange={(t) => setText(t)}\n itemToStringValue={(o: SelectOption) => nodeText(o.label)}\n open={open && shown.length > 0}\n onOpenChange={setOpen}\n onItemHighlighted={(o) => (highlighted.current = o as SelectOption | undefined)}\n openOnInputClick\n loopFocus\n disabled={disabled}\n >\n <div\n className={cn(\n \"flex min-w-0 items-center rounded-kit-md border border-kit-field-border bg-kit-field-bg shadow-kit-field transition-[border-color,box-shadow] duration-150 hover:border-kit-field-border-hover focus-within:border-kit-field-border-focus focus-within:shadow-kit-ring-field\",\n invalid && \"border-[var(--kit-field-invalid)] hover:border-[var(--kit-field-invalid)]\",\n disabled && \"cursor-not-allowed bg-kit-subtle opacity-60\",\n H[size],\n className,\n )}\n >\n {leading ? (\n <span aria-hidden className=\"ml-2.5 flex shrink-0 text-kit-fg-3 [&_svg]:size-4\">\n {leading}\n </span>\n ) : null}\n <AutocompletePrimitive.Input\n id={id ?? fieldId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabel ? undefined : (labelFor ?? (named ? undefined : labelledBy))}\n aria-describedby={[ariaDescribedBy, describedBy].filter(Boolean).join(\" \") || undefined}\n aria-invalid={invalid || undefined}\n placeholder={placeholder}\n autoComplete=\"off\"\n spellCheck={false}\n onFocus={() => openOnFocus && setOpen(true)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !highlighted.current) onEnter?.(text);\n }}\n className=\"h-full min-w-0 flex-1 bg-transparent px-2 text-kit-sm text-kit-fg outline-none placeholder:text-kit-fg-3 disabled:cursor-not-allowed\"\n />\n {loading ? (\n <Spinner size=\"sm\" tone=\"muted\" label=\"Loading suggestions\" className=\"mr-2\" />\n ) : text && !disabled ? (\n <IconButton label=\"Clear\" size=\"xs\" variant=\"ghost\" className=\"mr-1\" onMouseDown={(e) => e.preventDefault()} onClick={() => setText(\"\")}>\n <IconX stroke={1.5} />\n </IconButton>\n ) : null}\n </div>\n <AutocompletePrimitive.Portal>\n <AutocompletePrimitive.Positioner align=\"start\" side=\"bottom\" sideOffset={4} collisionPadding={12} className=\"z-[var(--kit-z-menu,80)]\" data-floating-layer=\"\" {...KIT_SCOPE}>\n <AutocompletePrimitive.Popup\n className={cn(\n \"w-[max(var(--anchor-width),280px)] max-w-[min(420px,calc(100vw-24px))] rounded-kit-lg border bg-kit-surface p-1 text-kit-fg shadow-lg outline-none data-[open]:animate-kit-pop-in\",\n menuClassName,\n )}\n >\n <AutocompletePrimitive.List className=\"max-h-72 overflow-y-auto overscroll-contain\">\n {shown.map((o, i) => (\n <React.Fragment key={o.value}>\n {o.group && (i === 0 || shown[i - 1].group !== o.group) ? (\n <div role=\"presentation\" className=\"px-2 pb-1 pt-2 text-kit-xs font-medium text-kit-fg-3 first:pt-1\">\n {o.group}\n </div>\n ) : null}\n <AutocompletePrimitive.Item\n value={o}\n disabled={o.disabled}\n onClick={() => onSelect?.(o)}\n className=\"flex h-8 cursor-pointer select-none items-center gap-2 rounded-kit-md px-2 text-kit-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-40 data-[highlighted]:bg-kit-hover\"\n >\n {o.icon ? (\n <span aria-hidden className=\"flex shrink-0 text-kit-fg-3 [&_svg]:size-4\">\n {o.icon}\n </span>\n ) : null}\n <span className=\"min-w-0 shrink truncate text-kit-fg\">\n {typeof o.label === \"string\" ? <Highlight text={o.label} query={text} /> : o.label}\n </span>\n {o.description ? <span className=\"min-w-0 flex-1 truncate text-kit-xs text-kit-fg-3\">{o.description}</span> : <span className=\"flex-1\" />}\n {o.meta ? <span className=\"shrink-0 text-kit-2xs text-kit-fg-3\">{o.meta}</span> : null}\n </AutocompletePrimitive.Item>\n </React.Fragment>\n ))}\n </AutocompletePrimitive.List>\n </AutocompletePrimitive.Popup>\n </AutocompletePrimitive.Positioner>\n </AutocompletePrimitive.Portal>\n </AutocompletePrimitive.Root>\n );\n}\n"],"mappings":"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"}
@@ -8,8 +8,8 @@ import { type VariantProps } from "./variants";
8
8
  * The keyboard focus ring is the global :focus-visible outline, suppressed under pointer modality (DESIGN.md 3.7).
9
9
  */
10
10
  export declare const buttonVariants: (props?: {
11
- variant?: "accent" | "link" | "primary" | "secondary" | "ghost" | "soft" | "danger" | "danger-ghost" | "ai" | null | undefined;
12
- size?: "xs" | "sm" | "md" | "lg" | "xl" | null | undefined;
11
+ variant?: "link" | "ai" | "primary" | "secondary" | "accent" | "ghost" | "soft" | "danger" | "danger-ghost" | null | undefined;
12
+ size?: "sm" | "md" | "lg" | "xs" | "xl" | null | undefined;
13
13
  } | undefined) => string;
14
14
  export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
15
15
  /** Render the single child element (a link, say) with the button's classes and props. */
@@ -21,7 +21,7 @@ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElemen
21
21
  export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
22
22
  /** Square icon-only button. Always pass `label` (used for aria-label + tooltip). */
23
23
  export declare const iconButtonVariants: (props?: {
24
- size?: "xs" | "sm" | "md" | "lg" | null | undefined;
24
+ size?: "sm" | "md" | "lg" | "xs" | null | undefined;
25
25
  variant?: "outline" | "ghost" | "soft" | null | undefined;
26
26
  } | undefined) => string;
27
27
  /**
@@ -3,10 +3,10 @@ import { SPARKLE_PATH } from "../brand/logo.js";
3
3
  import { TooltipLayer, TooltipRoot } from "./tooltip-root.js";
4
4
  import { variants } from "./variants.js";
5
5
  import * as React from "react";
6
- import { IconLoader2, IconPlus } from "@tabler/icons-react";
7
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { IconLoader2, IconPlus } from "@tabler/icons-react";
8
8
  import { Tooltip } from "@base-ui/react/tooltip";
9
- //#region src/kit/ui/button.tsx
9
+ //#region src/ui/button.tsx
10
10
  /**
11
11
  * Button: the only button in the kit.
12
12
  * Heights: xs 24 · sm 28 · md 32 (default) · lg 36 · xl 40. Radius 6.
@@ -17,8 +17,8 @@ import { Tooltip } from "@base-ui/react/tooltip";
17
17
  var buttonVariants = variants("relative inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium tracking-[-0.01em] select-none transition-[background-color,border-color,color,box-shadow,opacity] duration-150 ease-out disabled:pointer-events-none disabled:opacity-45 [&_svg]:shrink-0 [&_svg]:opacity-90", {
18
18
  variants: {
19
19
  variant: {
20
- primary: "bg-kit-inverse text-kit-fg-inverse shadow-[var(--kit-shadow-button-primary)] hover:bg-kit-inverse-hover active:bg-kit-inverse",
21
- accent: "bg-kit-accent text-kit-accent-on shadow-kit-xs hover:bg-kit-accent-hover",
20
+ primary: "bg-kit-inverse text-kit-fg-inverse shadow-kit-button-primary hover:bg-kit-inverse-hover active:bg-kit-inverse btn-solid",
21
+ accent: "bg-kit-accent text-kit-accent-on shadow-kit-xs hover:bg-kit-accent-hover btn-solid",
22
22
  secondary: "border border-kit-line-strong bg-kit-control-bg text-kit-fg shadow-kit-xs hover:bg-kit-subtle active:bg-kit-hover",
23
23
  ghost: "text-kit-fg-2 hover:bg-kit-hover hover:text-kit-fg active:bg-kit-selected",
24
24
  soft: "bg-kit-muted text-kit-fg hover:bg-kit-selected",
@@ -44,7 +44,6 @@ var buttonVariants = variants("relative inline-flex items-center justify-center
44
44
  size: "md"
45
45
  }
46
46
  });
47
- var SOLID_DISABLED = "[.dark_&]:disabled:bg-[#2a2a2d] [.dark_&]:disabled:text-[#9e9ea1] [.dark_&]:disabled:opacity-100 [.dark_&]:disabled:shadow-none";
48
47
  function mergeRefs(...refs) {
49
48
  return (node) => {
50
49
  for (const ref of refs) if (typeof ref === "function") ref(node);
@@ -55,7 +54,7 @@ var Button = React.forwardRef(({ className, variant, size, asChild, loading, lef
55
54
  const classes = cn(buttonVariants({
56
55
  variant,
57
56
  size
58
- }), (variant === "primary" || variant === "accent") && SOLID_DISABLED, className);
57
+ }), className);
59
58
  if (asChild && React.isValidElement(children)) return React.cloneElement(children, {
60
59
  ...props,
61
60
  ...children.props,
@@ -82,7 +81,7 @@ var Button = React.forwardRef(({ className, variant, size, asChild, loading, lef
82
81
  });
83
82
  Button.displayName = "Button";
84
83
  /** Square icon-only button. Always pass `label` (used for aria-label + tooltip). */
85
- var iconButtonVariants = variants("relative inline-flex items-center justify-center shrink-0 text-kit-fg-2 transition-colors duration-150 hover:bg-kit-hover hover:text-kit-fg active:scale-[0.96] disabled:opacity-40 disabled:pointer-events-none data-[active=true]:bg-kit-selected data-[active=true]:text-kit-fg data-[popup-open]:bg-kit-selected data-[popup-open]:text-kit-fg", {
84
+ var iconButtonVariants = variants("relative inline-flex items-center justify-center shrink-0 text-kit-fg-2 transition-colors duration-150 hover:bg-kit-hover hover:text-kit-fg active:scale-[0.96] disabled:opacity-40 disabled:pointer-events-none data-[active=true]:bg-kit-selected data-[active=true]:text-kit-fg", {
86
85
  variants: {
87
86
  size: {
88
87
  xs: "size-6 rounded-kit-md [&_svg]:size-3.5",
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.js","names":[],"sources":["../../src/ui/button.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\";\nimport { IconLoader2, IconPlus } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { SPARKLE_PATH } from \"../brand/logo\";\nimport { TooltipLayer, TooltipRoot } from \"./tooltip-root\";\nimport { variants, type VariantProps } from \"./variants\";\n\n/**\n * Button: the only button in the kit.\n * Heights: xs 24 · sm 28 · md 32 (default) · lg 36 · xl 40. Radius 6.\n * Variants: primary (ink) · accent (violet, reserved for the ONE create action per screen)\n * secondary (bordered) · ghost · soft · danger · danger-ghost · link · ai (gradient sparkle)\n * The keyboard focus ring is the global :focus-visible outline, suppressed under pointer modality (DESIGN.md 3.7).\n */\nexport const buttonVariants = variants(\n \"relative inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium tracking-[-0.01em] select-none transition-[background-color,border-color,color,box-shadow,opacity] duration-150 ease-out disabled:pointer-events-none disabled:opacity-45 [&_svg]:shrink-0 [&_svg]:opacity-90\",\n {\n variants: {\n variant: {\n // .btn-solid: in dark a disabled primary/accent takes the solid --kit-disabled-bg / --kit-disabled-fg pair; light keeps the opacity dim.\n primary: \"bg-kit-inverse text-kit-fg-inverse shadow-kit-button-primary hover:bg-kit-inverse-hover active:bg-kit-inverse btn-solid\",\n accent: \"bg-kit-accent text-kit-accent-on shadow-kit-xs hover:bg-kit-accent-hover btn-solid\",\n secondary: \"border border-kit-line-strong bg-kit-control-bg text-kit-fg shadow-kit-xs hover:bg-kit-subtle active:bg-kit-hover\",\n ghost: \"text-kit-fg-2 hover:bg-kit-hover hover:text-kit-fg active:bg-kit-selected\",\n soft: \"bg-kit-muted text-kit-fg hover:bg-kit-selected\",\n danger: \"bg-kit-danger text-kit-danger-on shadow-kit-xs hover:brightness-95\",\n \"danger-ghost\": \"text-kit-danger-fg hover:bg-kit-danger-soft\",\n link: \"text-kit-accent-fg underline-offset-4 hover:underline px-0 h-auto active:scale-100\",\n ai: \"border border-kit-line bg-kit-control-bg text-kit-fg shadow-kit-xs hover:border-kit-accent-line hover:bg-kit-accent-softer\",\n },\n size: {\n xs: \"h-6 rounded-kit-md px-2 text-kit-xs [&_svg]:size-3.5\",\n sm: \"h-7 rounded-kit-md px-2.5 text-kit-sm [&_svg]:size-3.5\",\n md: \"h-8 rounded-kit-md px-3 text-kit-sm [&_svg]:size-4\",\n lg: \"h-9 rounded-kit-md px-3.5 text-kit-base [&_svg]:size-4\",\n xl: \"h-10 rounded-kit-md px-4 text-kit-base [&_svg]:size-[18px]\",\n },\n },\n compoundVariants: [{ variant: \"link\", className: \"h-auto px-0\" }],\n defaultVariants: { variant: \"secondary\", size: \"md\" },\n },\n);\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {\n /** Render the single child element (a link, say) with the button's classes and props. */\n asChild?: boolean;\n loading?: boolean;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n}\n\ntype ChildProps = { className?: string; ref?: React.Ref<unknown> };\n\nfunction mergeRefs<T>(...refs: (React.Ref<T> | undefined)[]) {\n return (node: T | null) => {\n for (const ref of refs) {\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.RefObject<T | null>).current = node;\n }\n };\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild, loading, leftIcon, rightIcon, children, disabled, ...props }, ref) => {\n const classes = cn(buttonVariants({ variant, size }), className);\n if (asChild && React.isValidElement<ChildProps>(children)) {\n return React.cloneElement(children, {\n ...props,\n ...children.props,\n className: cn(classes, children.props.className),\n ref: mergeRefs(ref as React.Ref<unknown>, children.props.ref),\n });\n }\n return (\n <button ref={ref} type={props.type ?? \"button\"} disabled={disabled || loading} aria-busy={loading || undefined} className={classes} {...props}>\n {loading ? <IconLoader2 className=\"animate-spin\" aria-hidden /> : leftIcon}\n {variant === \"ai\" && !leftIcon && !loading ? <Sparkle /> : null}\n {children}\n {rightIcon}\n </button>\n );\n },\n);\nButton.displayName = \"Button\";\n\n/** Square icon-only button. Always pass `label` (used for aria-label + tooltip). */\nexport const iconButtonVariants = variants(\n \"relative inline-flex items-center justify-center shrink-0 text-kit-fg-2 transition-colors duration-150 hover:bg-kit-hover hover:text-kit-fg active:scale-[0.96] disabled:opacity-40 disabled:pointer-events-none data-[active=true]:bg-kit-selected data-[active=true]:text-kit-fg\",\n {\n variants: {\n size: {\n xs: \"size-6 rounded-kit-md [&_svg]:size-3.5\",\n sm: \"size-7 rounded-kit-md [&_svg]:size-4\",\n md: \"size-8 rounded-kit-md [&_svg]:size-4\",\n lg: \"size-9 rounded-kit-md [&_svg]:size-[18px]\",\n },\n variant: {\n ghost: \"\",\n outline: \"border border-kit-line bg-kit-control-bg shadow-kit-xs hover:border-kit-line-strong\",\n soft: \"bg-kit-muted\",\n },\n },\n defaultVariants: { size: \"md\", variant: \"ghost\" },\n },\n);\n\n/**\n * a11y: true while rendering inside a tooltip (or a surface that manages its own hints), so an IconButton nested\n * there doesn't add a second tooltip. Provided by HintTooltip and overlay.tsx's <Tooltip>.\n */\nexport const TooltipScope = React.createContext(false);\n\n/**\n * The plain ink hint (DESIGN.md 8.23: top, 6px offset, 8px collision padding, portalled, z 90, 350ms). The child\n * element is the trigger and must take a ref and DOM props. input, display and action-tray use it so they never\n * import overlay.tsx; overlay's <Tooltip> adds the shortcut slot on top of the same layer.\n */\nexport function HintTooltip({\n content,\n side = \"top\",\n delay = 350,\n children,\n}: {\n content: React.ReactNode;\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n delay?: number;\n children: React.ReactElement;\n}) {\n return (\n <TooltipScope.Provider value>\n <TooltipRoot>\n <TooltipPrimitive.Trigger delay={delay} render={children} />\n <TooltipLayer side={side}>\n <span className=\"line-clamp-[8] min-w-0 whitespace-normal [overflow-wrap:anywhere]\">{content}</span>\n </TooltipLayer>\n </TooltipRoot>\n </TooltipScope.Provider>\n );\n}\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof iconButtonVariants> {\n label: string;\n active?: boolean;\n /** Hover/focus hint. Defaults to `label`; pass `false` to opt out, or a node to customise. */\n tooltip?: React.ReactNode | false;\n tooltipSide?: \"top\" | \"bottom\" | \"left\" | \"right\";\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ className, size, variant, label, active, children, tooltip, tooltipSide = \"top\", ...props }, ref) => {\n const inTooltip = React.useContext(TooltipScope);\n const btn = (\n <button\n ref={ref}\n type=\"button\"\n aria-label={label}\n data-active={active ? \"true\" : undefined}\n className={cn(iconButtonVariants({ size, variant }), className)}\n {...props}\n >\n {children}\n </button>\n );\n // Every icon-only button gets a visible hint on hover AND keyboard focus (brief §11), unless a\n // parent tooltip already provides one or the caller opted out.\n if (inTooltip || tooltip === false || !label) return btn;\n return (\n <HintTooltip content={tooltip ?? label} side={tooltipSide}>\n {btn}\n </HintTooltip>\n );\n },\n);\nIconButton.displayName = \"IconButton\";\n\n/** The AI sparkle in the official brand gradient. Used everywhere AI appears. */\nexport function Sparkle({ className, size = 16 }: { className?: string; size?: number }) {\n const id = React.useId().replace(/:/g, \"\");\n return (\n <svg width={size} height={size} viewBox=\"2 2 16 16\" className={cn(\"shrink-0\", className)} aria-hidden>\n <defs>\n <linearGradient id={`sp${id}`} x1=\"6.89\" y1=\"4.59\" x2=\"18\" y2=\"23.67\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0.0817\" style={{ stopColor: \"var(--kit-brand-violet)\" }} />\n <stop offset=\"0.4667\" style={{ stopColor: \"var(--kit-brand-coral)\" }} />\n <stop offset=\"1\" style={{ stopColor: \"var(--kit-brand-rose)\" }} />\n </linearGradient>\n </defs>\n <path d={SPARKLE_PATH} fill={`url(#sp${id})`} />\n </svg>\n );\n}\n\n/** D15 progressive disclosure: \"+ Add a message\" / \"+ Limit to specific sites\": reveals an optional input. */\nexport function RevealLink({ className, children, ...props }: React.ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <button\n type=\"button\"\n className={cn(\n \"inline-flex h-7 items-center gap-1 rounded-kit-md text-kit-sm font-medium text-kit-fg-2 transition-colors hover:text-kit-fg [&_svg]:size-3.5\",\n className,\n )}\n {...props}\n >\n <IconPlus stroke={2} aria-hidden />\n {children}\n </button>\n );\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ import { Segmented } from "./controls.js";
2
2
  import { Select, nodeText } from "./select.js";
3
3
  import "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
- //#region src/kit/ui/choice-switch.tsx
5
+ //#region src/ui/choice-switch.tsx
6
6
  /** Most options a segmented switch may hold. */
7
7
  var SEGMENTED_MAX = 3;
8
8
  /**
@@ -0,0 +1 @@
1
+ {"version":3,"file":"choice-switch.js","names":[],"sources":["../../src/ui/choice-switch.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Segmented } from \"./controls\";\nimport { Select, nodeText } from \"./select\";\n\n/* ── Pickers: segmented vs dropdown (D46) ──────────────────────────────────\n A tab-style switch is for 2–3 short options people flip often. Four or more options, or labels that would wrap or\n truncate in a 340px inspector, become a dropdown (the D34 Select, with a one-line description where an option\n isn't self-explanatory). `fitsSegmented` is the single test; `ChoiceSwitch` applies it for dynamic lists\n (variants, schema options, presets) so call sites never have to count. */\n\n/** Most options a segmented switch may hold. */\nexport const SEGMENTED_MAX = 3;\n/**\n * Longest label (characters) that stays on one line when the row shares a 340px inspector:\n * two options get ~134px each (about 18 characters at 13px), three get ~84px (about 12).\n */\nexport const SEGMENTED_MAX_LABEL = { 2: 18, 3: 12 } as const;\n\nexport function fitsSegmented(labels: React.ReactNode[]): boolean {\n const n = labels.length;\n if (n < 2 || n > SEGMENTED_MAX) return false;\n const max = SEGMENTED_MAX_LABEL[n as 2 | 3];\n return labels.every((l) => nodeText(l).trim().length <= max);\n}\n\nexport interface ChoiceSwitchItem<T extends string> {\n value: T;\n label: React.ReactNode;\n /** one line under the option in the dropdown; ignored while it renders as a segmented switch */\n description?: string;\n icon?: React.ReactNode;\n disabled?: boolean;\n}\n\nexport function ChoiceSwitch<T extends string>({\n value,\n onChange,\n items,\n \"aria-label\": ariaLabel,\n size = \"sm\",\n layout = \"auto\",\n disabled,\n className,\n segmentedClassName,\n selectClassName,\n layoutId,\n placeholder,\n}: {\n value: T;\n onChange: (v: T) => void;\n items: ChoiceSwitchItem<T>[];\n \"aria-label\"?: string;\n size?: \"sm\" | \"md\";\n /** \"auto\" applies D46; force a look only when a design reason overrides the rule */\n layout?: \"auto\" | \"segmented\" | \"dropdown\";\n disabled?: boolean;\n /** applied to whichever control renders */\n className?: string;\n segmentedClassName?: string;\n selectClassName?: string;\n layoutId?: string;\n placeholder?: string;\n}) {\n const segmented = layout === \"segmented\" || (layout === \"auto\" && fitsSegmented(items.map((i) => i.label)));\n if (segmented)\n return (\n <Segmented<T>\n size={size}\n aria-label={ariaLabel}\n value={value}\n onChange={(v) => !disabled && onChange(v)}\n layoutId={layoutId}\n className={[className, segmentedClassName].filter(Boolean).join(\" \") || undefined}\n items={items.map((i) => ({ value: i.value, label: i.label, icon: i.icon, disabled: disabled || i.disabled }))}\n />\n );\n return (\n <Select\n size={size}\n aria-label={ariaLabel}\n value={value || undefined}\n disabled={disabled}\n placeholder={placeholder}\n onValueChange={(v) => onChange(v as T)}\n className={[className, selectClassName].filter(Boolean).join(\" \") || undefined}\n options={items.map((i) => ({ value: i.value, label: i.label, description: i.description, icon: i.icon, disabled: i.disabled }))}\n />\n );\n}\n"],"mappings":";;;;;;AAWA,IAAa,gBAAgB;;;;;AAK7B,IAAa,sBAAsB;CAAE,GAAG;CAAI,GAAG;AAAG;AAElD,SAAgB,cAAc,QAAoC;CAChE,MAAM,IAAI,OAAO;CACjB,IAAI,IAAI,KAAK,IAAA,GAAmB,OAAO;CACvC,MAAM,MAAM,oBAAoB;CAChC,OAAO,OAAO,OAAO,MAAM,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG;AAC7D;AAWA,SAAgB,aAA+B,EAC7C,OACA,UACA,OACA,cAAc,WACd,OAAO,MACP,SAAS,QACT,UACA,WACA,oBACA,iBACA,UACA,eAgBC;CAED,IADkB,WAAW,eAAgB,WAAW,UAAU,cAAc,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC,GAEvG,OACE,oBAAC,WAAD;EACQ;EACN,cAAY;EACL;EACP,WAAW,MAAM,CAAC,YAAY,SAAS,CAAC;EAC9B;EACV,WAAW,CAAC,WAAW,kBAAkB,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA;EACxE,OAAO,MAAM,KAAK,OAAO;GAAE,OAAO,EAAE;GAAO,OAAO,EAAE;GAAO,MAAM,EAAE;GAAM,UAAU,YAAY,EAAE;EAAS,EAAE;CAC7G,CAAA;CAEL,OACE,oBAAC,QAAD;EACQ;EACN,cAAY;EACZ,OAAO,SAAS,KAAA;EACN;EACG;EACb,gBAAgB,MAAM,SAAS,CAAM;EACrC,WAAW,CAAC,WAAW,eAAe,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA;EACrE,SAAS,MAAM,KAAK,OAAO;GAAE,OAAO,EAAE;GAAO,OAAO,EAAE;GAAO,aAAa,EAAE;GAAa,MAAM,EAAE;GAAM,UAAU,EAAE;EAAS,EAAE;CAC/H,CAAA;AAEL"}
@@ -1,50 +1,49 @@
1
1
  import { cn } from "../lib/cn.js";
2
2
  import { useFieldLabelledBy, useLabelFor } from "./field-context.js";
3
- import { INK_ACTIVE } from "./surfaces.js";
4
3
  import { TooltipLayer, TooltipRoot } from "./tooltip-root.js";
5
4
  import { TooltipScope } from "./button.js";
6
5
  import { useShortcutHints } from "./shortcut-hint.js";
7
6
  import * as React from "react";
8
- import { IconCheck, IconMinus } from "@tabler/icons-react";
9
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { IconCheck, IconMinus } from "@tabler/icons-react";
10
9
  import { AnimatePresence, motion, useReducedMotion } from "framer-motion";
11
- import { Switch } from "@base-ui/react/switch";
12
- import { Checkbox } from "@base-ui/react/checkbox";
13
- import { RadioGroup } from "@base-ui/react/radio-group";
14
- import { Radio } from "@base-ui/react/radio";
10
+ import { Switch as Switch$1 } from "@base-ui/react/switch";
11
+ import { Checkbox as Checkbox$1 } from "@base-ui/react/checkbox";
12
+ import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
13
+ import { Radio as Radio$1 } from "@base-ui/react/radio";
15
14
  import { Tooltip } from "@base-ui/react/tooltip";
16
- import { Slider } from "@base-ui/react/slider";
17
- import { ToggleGroup } from "@base-ui/react/toggle-group";
15
+ import { Slider as Slider$1 } from "@base-ui/react/slider";
16
+ import { ToggleGroup as ToggleGroup$1 } from "@base-ui/react/toggle-group";
18
17
  import { Toggle } from "@base-ui/react/toggle";
19
- import { Progress } from "@base-ui/react/progress";
20
- //#region src/kit/ui/controls.tsx
18
+ import { Progress as Progress$1 } from "@base-ui/react/progress";
19
+ //#region src/ui/controls.tsx
21
20
  var PILL_SPRING = {
22
21
  type: "spring",
23
22
  stiffness: 520,
24
23
  damping: 42
25
24
  };
26
- function Switch$1({ className, size = "md", ...props }) {
25
+ function Switch({ className, size = "md", ...props }) {
27
26
  const sm = size === "sm";
28
27
  const labelledBy = useFieldLabelledBy();
29
28
  const labelFor = useLabelFor(props.id);
30
- return /* @__PURE__ */ jsx(Switch.Root, {
29
+ return /* @__PURE__ */ jsx(Switch$1.Root, {
31
30
  className: cn("group relative inline-flex shrink-0 items-center rounded-full bg-kit-switch-off transition-colors duration-200 data-[checked]:bg-kit-success data-[disabled]:opacity-40", sm ? "h-4 w-7" : "h-5 w-9", className),
32
31
  "aria-labelledby": props["aria-labelledby"] ?? (props["aria-label"] ? void 0 : labelFor ?? (props.id ? void 0 : labelledBy)),
33
32
  ...props,
34
- children: /* @__PURE__ */ jsx(Switch.Thumb, { className: cn("pointer-events-none block rounded-full bg-kit-control-thumb shadow-kit-sm transition-transform duration-200 ease-kit-spring", sm ? "size-3 translate-x-0.5 data-[checked]:translate-x-[14px]" : "size-4 translate-x-0.5 data-[checked]:translate-x-[18px]") })
33
+ children: /* @__PURE__ */ jsx(Switch$1.Thumb, { className: cn("pointer-events-none block rounded-full bg-kit-control-thumb shadow-kit-sm transition-transform duration-200 ease-[var(--kit-ease-spring)]", sm ? "size-3 translate-x-0.5 data-[checked]:translate-x-[14px]" : "size-4 translate-x-0.5 data-[checked]:translate-x-[18px]") })
35
34
  });
36
35
  }
37
36
  /** `checked` keeps V2's tri-state value: true, false or "indeterminate". */
38
- function Checkbox$1({ className, checked, ...props }) {
37
+ function Checkbox({ className, checked, ...props }) {
39
38
  const indeterminate = checked === "indeterminate";
40
39
  const labelFor = useLabelFor(props.id);
41
- return /* @__PURE__ */ jsx(Checkbox.Root, {
40
+ return /* @__PURE__ */ jsx(Checkbox$1.Root, {
42
41
  "aria-labelledby": props["aria-labelledby"] ?? (props["aria-label"] ? void 0 : labelFor),
43
- className: cn("peer flex size-4 shrink-0 items-center justify-center rounded-kit-sm border border-kit-line-strong bg-kit-control-bg shadow-kit-xs transition-colors hover:border-[var(--kit-emphasis-line)] data-[checked]:border-kit-inverse data-[checked]:bg-kit-inverse data-[indeterminate]:border-kit-inverse data-[indeterminate]:bg-kit-inverse data-[disabled]:opacity-40", className),
42
+ className: cn("peer flex size-4 shrink-0 items-center justify-center rounded-kit-sm border border-kit-line-strong bg-kit-control-bg shadow-kit-xs transition-colors hover:border-[var(--kit-emphasis-line)] data-[checked]:border-kit-inverse data-[checked]:bg-kit-inverse data-[indeterminate]:border-kit-inverse data-[indeterminate]:bg-kit-inverse", className),
44
43
  checked: checked === void 0 ? void 0 : checked === true,
45
44
  indeterminate,
46
45
  ...props,
47
- children: /* @__PURE__ */ jsx(Checkbox.Indicator, {
46
+ children: /* @__PURE__ */ jsx(Checkbox$1.Indicator, {
48
47
  className: "text-kit-fg-inverse",
49
48
  children: indeterminate ? /* @__PURE__ */ jsx(IconMinus, {
50
49
  className: "size-3",
@@ -56,12 +55,12 @@ function Checkbox$1({ className, checked, ...props }) {
56
55
  })
57
56
  });
58
57
  }
59
- var RadioGroup$1 = RadioGroup;
60
- function Radio$1({ className, ...props }) {
61
- return /* @__PURE__ */ jsx(Radio.Root, {
62
- className: cn("flex size-4 shrink-0 items-center justify-center rounded-full border border-kit-line-strong bg-kit-control-bg shadow-kit-xs transition-colors hover:border-[var(--kit-emphasis-line)] data-[checked]:border-kit-accent data-[disabled]:opacity-40", className),
58
+ var RadioGroup = RadioGroup$1;
59
+ function Radio({ className, ...props }) {
60
+ return /* @__PURE__ */ jsx(Radio$1.Root, {
61
+ className: cn("flex size-4 shrink-0 items-center justify-center rounded-full border border-kit-line-strong bg-kit-control-bg shadow-kit-xs transition-colors hover:border-[var(--kit-emphasis-line)] data-[checked]:border-kit-accent", className),
63
62
  ...props,
64
- children: /* @__PURE__ */ jsx(Radio.Indicator, { className: "block size-2 rounded-full bg-kit-accent" })
63
+ children: /* @__PURE__ */ jsx(Radio$1.Indicator, { className: "block size-2 rounded-full bg-kit-accent" })
65
64
  });
66
65
  }
67
66
  /** Large selectable card used for choices (plans, project kinds, roles). */
@@ -70,7 +69,7 @@ function ChoiceCard({ selected, onSelect, icon, title, description, badge, class
70
69
  type: "button",
71
70
  onClick: onSelect,
72
71
  "aria-pressed": selected,
73
- className: cn("group relative flex w-full flex-col gap-1.5 rounded-kit-lg border bg-kit-control-bg px-3 py-2.5 text-left transition-[border-color,box-shadow,background-color] duration-150 focus-visible:outline-offset-[-2px]", selected ? "border-[var(--kit-emphasis-line)] shadow-kit-ring-field" : "border-kit-line hover:border-kit-line-strong hover:shadow-kit-sm", className),
72
+ className: cn("focus-inset group relative flex w-full flex-col gap-1.5 rounded-kit-lg border bg-kit-control-bg px-3 py-2.5 text-left transition-[border-color,box-shadow,background-color] duration-150", selected ? "border-[var(--kit-emphasis-line)] shadow-kit-ring-field" : "border-kit-line hover:border-kit-line-strong hover:shadow-kit-sm", className),
74
73
  children: [/* @__PURE__ */ jsxs("div", {
75
74
  className: "flex items-start gap-3",
76
75
  children: [
@@ -108,19 +107,19 @@ function ChoiceList({ className, children, ...props }) {
108
107
  children
109
108
  });
110
109
  }
111
- function Slider$1({ className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, label, ...props }) {
110
+ function Slider({ className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, label, ...props }) {
112
111
  const name = ariaLabel ?? label;
113
112
  const v = props.value ?? props.defaultValue ?? [0];
114
113
  const thumbs = Array.isArray(v) ? v.length : 1;
115
- return /* @__PURE__ */ jsx(Slider.Root, {
114
+ return /* @__PURE__ */ jsx(Slider$1.Root, {
116
115
  className: cn("w-full", className),
117
116
  ...props,
118
- children: /* @__PURE__ */ jsxs(Slider.Control, {
117
+ children: /* @__PURE__ */ jsxs(Slider$1.Control, {
119
118
  className: "relative flex h-5 w-full touch-none select-none items-center",
120
- children: [/* @__PURE__ */ jsx(Slider.Track, {
119
+ children: [/* @__PURE__ */ jsx(Slider$1.Track, {
121
120
  className: "relative h-1 w-full grow overflow-hidden rounded-full bg-[var(--kit-track-line)]",
122
- children: /* @__PURE__ */ jsx(Slider.Indicator, { className: "absolute h-full bg-kit-fg-2" })
123
- }), Array.from({ length: thumbs }, (_, i) => /* @__PURE__ */ jsx(Slider.Thumb, {
121
+ children: /* @__PURE__ */ jsx(Slider$1.Indicator, { className: "absolute h-full bg-kit-fg-2" })
122
+ }), Array.from({ length: thumbs }, (_, i) => /* @__PURE__ */ jsx(Slider$1.Thumb, {
124
123
  index: thumbs > 1 ? i : void 0,
125
124
  getAriaLabel: name ? () => name : void 0,
126
125
  "aria-labelledby": name ? void 0 : ariaLabelledby,
@@ -143,7 +142,7 @@ function SegmentTooltip({ content, shortcut, children }) {
143
142
  children: content
144
143
  }), shortcut && hints ? /* @__PURE__ */ jsx("kbd", {
145
144
  "data-hint": "shortcuts",
146
- className: cn("mt-px shrink-0 rounded-kit-sm px-1 font-kit-sans text-kit-2xs", INK_ACTIVE),
145
+ className: "mt-px shrink-0 rounded-kit-sm bg-kit-ink-active px-1 font-kit-sans text-kit-2xs",
147
146
  children: shortcut
148
147
  }) : null]
149
148
  })] })
@@ -281,14 +280,27 @@ function Segmented({ value, onChange, items, size = "md", className, layoutId, i
281
280
  })
282
281
  });
283
282
  }
284
- function ToggleGroup$1({ className, ...props }) {
285
- return /* @__PURE__ */ jsx(ToggleGroup, {
286
- className: cn("inline-flex items-center gap-px rounded-kit-md border border-kit-line bg-kit-field-bg p-[2px]", className),
287
- ...props
283
+ var ToggleGroupSingle = React.createContext(false);
284
+ function ToggleGroup({ className, ...props }) {
285
+ const single = !props.multiple;
286
+ return /* @__PURE__ */ jsx(ToggleGroupSingle.Provider, {
287
+ value: single,
288
+ children: /* @__PURE__ */ jsx(ToggleGroup$1, {
289
+ className: cn("inline-flex items-center gap-px rounded-kit-md border border-kit-line bg-kit-field-bg p-[2px]", className),
290
+ ...single ? { role: "radiogroup" } : {},
291
+ ...props
292
+ })
288
293
  });
289
294
  }
290
295
  function ToggleItem({ className, ...props }) {
296
+ const single = React.useContext(ToggleGroupSingle);
291
297
  return /* @__PURE__ */ jsx(Toggle, {
298
+ ...single ? { render: (p, state) => /* @__PURE__ */ jsx("button", {
299
+ ...p,
300
+ role: "radio",
301
+ "aria-checked": state.pressed,
302
+ "aria-pressed": void 0
303
+ }) } : {},
292
304
  className: cn("inline-flex h-6 min-w-6 items-center justify-center gap-1 rounded-kit-sm px-1.5 text-kit-xs font-medium text-kit-fg-3 transition-colors hover:bg-kit-hover hover:text-kit-fg data-[pressed]:bg-kit-selected data-[pressed]:text-kit-fg [&_svg]:size-3.5", className),
293
305
  ...props
294
306
  });
@@ -301,19 +313,19 @@ var progressTones = {
301
313
  ink: "bg-[var(--kit-bar-fill)]",
302
314
  brand: "bg-[var(--kit-bar-fill)]"
303
315
  };
304
- function Progress$1({ value, className, tone = "success", size = "md", label = "Progress" }) {
316
+ function Progress({ value, className, tone = "success", size = "md", label = "Progress" }) {
305
317
  const pct = Math.min(100, Math.max(0, value));
306
- return /* @__PURE__ */ jsx(Progress.Root, {
318
+ return /* @__PURE__ */ jsx(Progress$1.Root, {
307
319
  value: pct,
308
320
  "aria-label": label,
309
321
  className: cn("relative w-full overflow-hidden rounded-full bg-[var(--kit-track)]", size === "sm" ? "h-1" : "h-1.5", className),
310
- children: /* @__PURE__ */ jsx(Progress.Indicator, {
311
- className: cn("block h-full rounded-full transition-[width] duration-500 ease-kit-out-soft", progressTones[tone]),
322
+ children: /* @__PURE__ */ jsx(Progress$1.Indicator, {
323
+ className: cn("h-full rounded-full transition-[width] duration-500 ease-[var(--kit-ease-out-soft)]", progressTones[tone]),
312
324
  style: { width: `${pct}%` }
313
325
  })
314
326
  });
315
327
  }
316
328
  //#endregion
317
- export { Checkbox$1 as Checkbox, ChoiceCard, ChoiceList, Progress$1 as Progress, Radio$1 as Radio, RadioGroup$1 as RadioGroup, Segmented, Slider$1 as Slider, Switch$1 as Switch, ToggleGroup$1 as ToggleGroup, ToggleItem };
329
+ export { Checkbox, ChoiceCard, ChoiceList, Progress, Radio, RadioGroup, Segmented, Slider, Switch, ToggleGroup, ToggleItem };
318
330
 
319
331
  //# sourceMappingURL=controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controls.js","names":[],"sources":["../../src/ui/controls.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Switch as SwitchPrimitive } from \"@base-ui/react/switch\";\nimport { Checkbox as CheckboxPrimitive } from \"@base-ui/react/checkbox\";\nimport { RadioGroup as RadioGroupPrimitive } from \"@base-ui/react/radio-group\";\nimport { Radio as RadioPrimitive } from \"@base-ui/react/radio\";\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\";\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\";\nimport { ToggleGroup as ToggleGroupPrimitive } from \"@base-ui/react/toggle-group\";\nimport { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\";\nimport { Progress as ProgressPrimitive } from \"@base-ui/react/progress\";\nimport { IconCheck, IconMinus } from \"@tabler/icons-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport { cn } from \"../lib/cn\";\nimport { useFieldLabelledBy, useLabelFor } from \"./field-context\";\nimport { TooltipScope } from \"./button\";\nimport { useShortcutHints } from \"./shortcut-hint\";\nimport { TooltipLayer, TooltipRoot } from \"./tooltip-root\";\n\n/* Underlines and selected pills share one spring (DESIGN.md 3.6). */\nconst PILL_SPRING = { type: \"spring\", stiffness: 520, damping: 42 } as const;\n\n/* ── Switch ─────────────────────────────────────────────────────────────── */\nexport function Switch({\n className,\n size = \"md\",\n ...props\n}: SwitchPrimitive.Root.Props & { size?: \"sm\" | \"md\" }) {\n const sm = size === \"sm\";\n const labelledBy = useFieldLabelledBy();\n const labelFor = useLabelFor(props.id);\n return (\n <SwitchPrimitive.Root\n className={cn(\n \"group relative inline-flex shrink-0 items-center rounded-full bg-kit-switch-off transition-colors duration-200 data-[checked]:bg-kit-success data-[disabled]:opacity-40\",\n sm ? \"h-4 w-7\" : \"h-5 w-9\",\n className,\n )}\n aria-labelledby={props[\"aria-labelledby\"] ?? (props[\"aria-label\"] ? undefined : (labelFor ?? (props.id ? undefined : labelledBy)))}\n {...props}\n >\n <SwitchPrimitive.Thumb\n className={cn(\n \"pointer-events-none block rounded-full bg-kit-control-thumb shadow-kit-sm transition-transform duration-200 ease-[var(--kit-ease-spring)]\",\n sm ? \"size-3 translate-x-0.5 data-[checked]:translate-x-[14px]\" : \"size-4 translate-x-0.5 data-[checked]:translate-x-[18px]\",\n )}\n />\n </SwitchPrimitive.Root>\n );\n}\n\n/* ── Checkbox ───────────────────────────────────────────────────────────── */\n/** `checked` keeps V2's tri-state value: true, false or \"indeterminate\". */\nexport function Checkbox({\n className,\n checked,\n ...props\n}: Omit<CheckboxPrimitive.Root.Props, \"checked\" | \"indeterminate\"> & { checked?: boolean | \"indeterminate\" }) {\n const indeterminate = checked === \"indeterminate\";\n const labelFor = useLabelFor(props.id);\n return (\n <CheckboxPrimitive.Root\n aria-labelledby={props[\"aria-labelledby\"] ?? (props[\"aria-label\"] ? undefined : labelFor)}\n className={cn(\n \"peer flex size-4 shrink-0 items-center justify-center rounded-kit-sm border border-kit-line-strong bg-kit-control-bg shadow-kit-xs transition-colors hover:border-[var(--kit-emphasis-line)] data-[checked]:border-kit-inverse data-[checked]:bg-kit-inverse data-[indeterminate]:border-kit-inverse data-[indeterminate]:bg-kit-inverse\",\n className,\n )}\n checked={checked === undefined ? undefined : checked === true}\n indeterminate={indeterminate}\n {...props}\n >\n <CheckboxPrimitive.Indicator className=\"text-kit-fg-inverse\">\n {indeterminate ? <IconMinus className=\"size-3\" stroke={3} /> : <IconCheck className=\"size-3\" stroke={3} />}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\n/* ── Radio ──────────────────────────────────────────────────────────────── */\nexport const RadioGroup = RadioGroupPrimitive;\nexport function Radio({ className, ...props }: RadioPrimitive.Root.Props) {\n return (\n <RadioPrimitive.Root\n className={cn(\n \"flex size-4 shrink-0 items-center justify-center rounded-full border border-kit-line-strong bg-kit-control-bg shadow-kit-xs transition-colors hover:border-[var(--kit-emphasis-line)] data-[checked]:border-kit-accent\",\n className,\n )}\n {...props}\n >\n <RadioPrimitive.Indicator className=\"block size-2 rounded-full bg-kit-accent\" />\n </RadioPrimitive.Root>\n );\n}\n\n/** Large selectable card used for choices (plans, project kinds, roles). */\nexport function ChoiceCard({\n selected,\n onSelect,\n icon,\n title,\n description,\n badge,\n className,\n children,\n}: {\n selected: boolean;\n onSelect: () => void;\n icon?: React.ReactNode;\n title: React.ReactNode;\n description?: React.ReactNode;\n badge?: React.ReactNode;\n className?: string;\n children?: React.ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onSelect}\n aria-pressed={selected}\n className={cn(\n \"focus-inset group relative flex w-full flex-col gap-1.5 rounded-kit-lg border bg-kit-control-bg px-3 py-2.5 text-left transition-[border-color,box-shadow,background-color] duration-150\", // inset: option cards often sit in a clipped, gapless list\n selected\n ? \"border-[var(--kit-emphasis-line)] shadow-kit-ring-field\"\n : \"border-kit-line hover:border-kit-line-strong hover:shadow-kit-sm\",\n className,\n )}\n >\n <div className=\"flex items-start gap-3\">\n {icon ? (\n <span className={cn(\"mt-0.5 flex shrink-0 items-center justify-center text-kit-fg-2 [&_svg]:size-4\", selected && \"text-kit-fg\")}>\n {icon}\n </span>\n ) : null}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2 text-kit-sm font-medium text-kit-fg\">\n {title}\n {badge}\n </div>\n {description ? <p className=\"mt-0.5 text-[13px] leading-[18px] text-kit-fg-2\">{description}</p> : null}\n </div>\n <span\n className={cn(\n \"mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full border transition-colors\",\n selected ? \"border-kit-inverse bg-kit-inverse text-kit-fg-inverse\" : \"border-kit-line-strong\",\n )}\n >\n {selected ? <IconCheck className=\"size-2.5\" stroke={3.5} /> : null}\n </span>\n </div>\n {children}\n </button>\n );\n}\n\n/** D15: 2–4 choices → one hairline list of compact rows. Wrap <ChoiceCard>s in it; they lose their own card chrome. */\nexport function ChoiceList({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n role=\"group\"\n className={cn(\n \"flex flex-col divide-y divide-kit-line-subtle overflow-hidden rounded-kit-lg border border-kit-line\",\n \"[&>*]:rounded-none [&>*]:border-0 [&>*]:shadow-none [&>*]:hover:shadow-none [&>*]:hover:bg-kit-hover [&>[aria-pressed=true]]:bg-kit-selected [&>[aria-pressed=true]]:shadow-none\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n}\n\n/* ── Slider ─────────────────────────────────────────────────────────────── */\nexport function Slider({\n className,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledby,\n label,\n ...props\n}: Omit<SliderPrimitive.Root.Props<number | readonly number[]>, \"className\"> & {\n className?: string;\n /** accessible name for the thumb(s) */\n label?: string;\n}) {\n const name = ariaLabel ?? label;\n const v = props.value ?? props.defaultValue ?? [0];\n const thumbs = Array.isArray(v) ? v.length : 1;\n return (\n <SliderPrimitive.Root className={cn(\"w-full\", className)} {...props}>\n <SliderPrimitive.Control className=\"relative flex h-5 w-full touch-none select-none items-center\">\n {/* Figma §4.3 slider: 4px track, --fg-2 fill, 12px light thumb with a border (control-thumb lifts off the dark track) */}\n <SliderPrimitive.Track className=\"relative h-1 w-full grow overflow-hidden rounded-full bg-[var(--kit-track-line)]\">\n <SliderPrimitive.Indicator className=\"absolute h-full bg-kit-fg-2\" />\n </SliderPrimitive.Track>\n {Array.from({ length: thumbs }, (_, i) => (\n <SliderPrimitive.Thumb\n key={i}\n index={thumbs > 1 ? i : undefined}\n getAriaLabel={name ? () => name : undefined}\n aria-labelledby={name ? undefined : ariaLabelledby}\n className=\"block size-3 rounded-full border border-kit-line-strong bg-kit-control-thumb shadow-kit-md transition-transform hover:scale-110 has-[:focus-visible]:scale-110 has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-kit-focus-ring has-[:focus-visible]:[outline-style:solid]\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n );\n}\n\n/* V2's overlay <Tooltip> (side bottom, 350ms) for collapsed and icon-only segments, built on the shared ink layer. */\nfunction SegmentTooltip({ content, shortcut, children }: { content: React.ReactNode; shortcut?: string; children: React.ReactElement }) {\n const hints = useShortcutHints();\n return (\n <TooltipScope.Provider value>\n <TooltipRoot>\n <TooltipPrimitive.Trigger delay={350} render={children} />\n <TooltipLayer side=\"bottom\">\n <span className=\"line-clamp-[8] min-w-0 whitespace-normal [overflow-wrap:anywhere]\">{content}</span>\n {shortcut && hints ? (\n <kbd data-hint=\"shortcuts\" className=\"mt-px shrink-0 rounded-kit-sm bg-kit-ink-active px-1 font-kit-sans text-kit-2xs\">\n {shortcut}\n </kbd>\n ) : null}\n </TooltipLayer>\n </TooltipRoot>\n </TooltipScope.Provider>\n );\n}\n\n/* ── Segmented ───────────────────────────────────────────────────────────\n Two deliberate looks (founder: no \"AI-sloppy\" grey pills with counts inside):\n • variant=\"tabs\" (opt-in) — quiet text tabs, muted tabular count, 1.5px animated underline.\n Use for filters, view sections, panel tabs.\n • variant=\"toggle\" (default) — slim hairline-bordered control, subtle selected fill, no shadow.\n Use for binary/ternary switches: list|grid, light|dark, desktop|tablet|mobile.\n Pass `count` on items instead of baking numbers into labels. */\nexport type SegmentedItem<T extends string> = {\n value: T;\n label: React.ReactNode;\n icon?: React.ReactNode;\n disabled?: boolean;\n count?: number;\n tooltip?: React.ReactNode;\n shortcut?: string;\n name?: string;\n};\n\nexport function Segmented<T extends string>({\n value,\n onChange,\n items,\n size = \"md\",\n className,\n layoutId,\n iconOnly,\n collapseInactive,\n variant,\n bordered,\n \"aria-label\": ariaLabel,\n}: {\n \"aria-label\"?: string;\n value: T;\n onChange: (v: T) => void;\n items: SegmentedItem<T>[];\n /** Toggle variant: only the selected item shows its label; the others collapse to icon + tooltip. */\n collapseInactive?: boolean;\n size?: \"sm\" | \"md\";\n className?: string;\n layoutId?: string;\n iconOnly?: boolean;\n variant?: \"tabs\" | \"toggle\";\n /** tabs only: draw a hairline under the whole tab row */\n bordered?: boolean;\n}) {\n const id = React.useId();\n const v = variant ?? \"toggle\";\n const reduceMotion = useReducedMotion();\n const pillTransition = reduceMotion ? { duration: 0 } : PILL_SPRING;\n const onKey = (e: React.KeyboardEvent, i: number) => {\n const enabled = items.filter((x) => !x.disabled);\n const idx = enabled.findIndex((x) => x.value === items[i].value);\n const fwd = e.key === \"ArrowRight\" || e.key === \"ArrowDown\";\n const back = e.key === \"ArrowLeft\" || e.key === \"ArrowUp\";\n const next = fwd\n ? enabled[(idx + 1) % enabled.length]\n : back\n ? enabled[(idx - 1 + enabled.length) % enabled.length]\n : e.key === \"Home\"\n ? enabled[0]\n : e.key === \"End\"\n ? enabled[enabled.length - 1]\n : null;\n if (next) {\n e.preventDefault();\n onChange(next.value);\n // roving tabindex: keep keyboard focus on the newly selected item\n const group = (e.currentTarget as HTMLElement).closest(\"[data-segmented]\");\n requestAnimationFrame(() => group?.querySelector<HTMLElement>(`[data-seg-value=\"${CSS.escape(next.value)}\"]`)?.focus());\n }\n };\n\n if (v === \"tabs\") {\n return (\n <div role=\"tablist\" aria-label={ariaLabel} data-segmented className={cn(\"inline-flex items-center gap-5\", bordered && \"border-b border-kit-line\", className)}>\n {items.map((it, i) => {\n const active = it.value === value;\n return (\n <button\n key={it.value}\n role=\"tab\"\n type=\"button\"\n data-seg-value={it.value}\n aria-selected={active}\n tabIndex={active ? 0 : -1}\n disabled={it.disabled}\n onKeyDown={(e) => onKey(e, i)}\n onClick={() => onChange(it.value)}\n className={cn(\n \"group relative inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium tracking-[-0.01em] transition-colors duration-150 disabled:opacity-40 [&_svg]:size-4\",\n size === \"sm\" ? \"h-7 text-kit-xs [&_svg]:size-3.5\" : \"h-8 text-kit-sm\",\n active ? \"text-kit-fg\" : \"text-kit-fg-3 hover:text-kit-fg-2\",\n )}\n >\n {it.icon}\n {iconOnly ? null : it.label}\n {typeof it.count === \"number\" ? (\n <span className={cn(\"text-kit-xs font-normal tabular-nums\", active ? \"text-kit-fg-2\" : \"text-kit-fg-4\")}>{it.count}</span>\n ) : null}\n {active ? (\n <motion.span\n layoutId={layoutId ?? `tab-${id}`}\n transition={pillTransition}\n data-seg-indicator=\"\"\n className={cn(\"absolute inset-x-0 h-[1.5px] rounded-full bg-kit-fg\", bordered ? \"-bottom-px\" : \"bottom-0\")}\n />\n ) : null}\n </button>\n );\n })}\n </div>\n );\n }\n\n return (\n /* Toggle metrics (D29, founder): container 1px border + 2px padding, 2px between items, pill radius = container (6) − 2.\n md items are 28px tall and icon-only items exactly 28×28; sm items 24px. Collapsing items keep the icon at the same\n inset in both states (6px md / 5px sm) — only the label wrapper animates its width, with the icon→label gap inside it. */\n <div role=\"radiogroup\" aria-label={ariaLabel} data-segmented className={cn(\"inline-flex items-center gap-[2px] rounded-kit-md border border-kit-line bg-kit-field-bg p-[2px]\", className)}>\n {items.map((it, i) => {\n const active = it.value === value;\n const sm = size === \"sm\";\n const hasLabel = !iconOnly && it.label !== \"\" && it.label != null;\n const showLabel = hasLabel && (!collapseInactive || active);\n const btn = (\n <button\n key={it.value}\n role=\"radio\"\n type=\"button\"\n data-seg-value={it.value}\n aria-checked={active}\n aria-label={iconOnly && typeof it.label === \"string\" ? it.label : collapseInactive ? it.name : undefined}\n tabIndex={active ? 0 : -1}\n disabled={it.disabled}\n onKeyDown={(e) => onKey(e, i)}\n onClick={() => onChange(it.value)}\n className={cn(\n \"relative inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-kit-sm font-medium transition-[color,background-color,padding] duration-150 disabled:opacity-40 [&_svg]:size-4 [&_svg]:shrink-0\",\n sm ? \"h-6 text-kit-xs [&_svg]:size-3.5\" : \"h-7 text-kit-sm\",\n iconOnly || !hasLabel\n ? sm ? \"w-6 px-0\" : \"w-7 px-0\"\n : collapseInactive\n ? sm ? (active ? \"pl-[5px] pr-2\" : \"px-[5px]\") : active ? \"pl-1.5 pr-2.5\" : \"px-1.5\"\n : sm ? \"px-2\" : \"px-2.5\",\n active ? \"text-kit-fg\" : \"text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg\",\n )}\n >\n {active ? (\n <motion.span\n layoutId={layoutId ?? `seg-${id}`}\n transition={pillTransition}\n data-seg-indicator=\"\"\n className=\"absolute inset-0 rounded-kit-sm bg-kit-selected\"\n />\n ) : null}\n <span className={cn(\"relative z-[1] inline-flex items-center\", !collapseInactive && \"gap-1.5\")}>\n {it.icon}\n {!hasLabel ? null : collapseInactive ? (\n <AnimatePresence initial={false}>\n {showLabel ? (\n <motion.span\n key=\"label\"\n initial={{ width: 0, opacity: 0 }}\n animate={{ width: \"auto\", opacity: 1 }}\n exit={{ width: 0, opacity: 0 }}\n transition={reduceMotion ? { duration: 0 } : { duration: 0.18, ease: [0.2, 0, 0, 1] }}\n className=\"inline-flex overflow-hidden\"\n >\n <span className={sm ? \"pl-1\" : \"pl-1.5\"}>{it.label}</span>\n </motion.span>\n ) : null}\n </AnimatePresence>\n ) : (\n it.label\n )}\n {typeof it.count === \"number\" ? <span className=\"text-kit-xs font-normal tabular-nums text-kit-fg-3\">{it.count}</span> : null}\n </span>\n </button>\n );\n if (collapseInactive && it.tooltip)\n return (\n <SegmentTooltip key={it.value} content={it.tooltip} shortcut={it.shortcut}>\n {btn}\n </SegmentTooltip>\n );\n return iconOnly && typeof it.label === \"string\" ? (\n <SegmentTooltip key={it.value} content={it.label}>\n {btn}\n </SegmentTooltip>\n ) : (\n btn\n );\n })}\n </div>\n );\n}\n\n/* ── Toggle group (toolbar style) ───────────────────────────────────────\n One choice (the default) is a radio group in WAI-ARIA: role=\"radiogroup\" with role=\"radio\" + aria-checked items, as\n V2's Radix ToggleGroup type=\"single\" renders. `multiple` keeps group + aria-pressed (independent toggles). The arrow\n keys rove the items either way (Base UI's composite). */\nconst ToggleGroupSingle = React.createContext(false);\nexport function ToggleGroup({ className, ...props }: Omit<ToggleGroupPrimitive.Props, \"className\"> & { className?: string }) {\n const single = !props.multiple;\n return (\n <ToggleGroupSingle.Provider value={single}>\n <ToggleGroupPrimitive\n className={cn(\"inline-flex items-center gap-px rounded-kit-md border border-kit-line bg-kit-field-bg p-[2px]\", className)}\n {...(single ? { role: \"radiogroup\" } : {})}\n {...props}\n />\n </ToggleGroupSingle.Provider>\n );\n}\nexport function ToggleItem({ className, ...props }: Omit<TogglePrimitive.Props, \"className\"> & { className?: string }) {\n const single = React.useContext(ToggleGroupSingle);\n return (\n <TogglePrimitive\n {...(single\n ? { render: (p: React.ComponentProps<\"button\">, state: { pressed: boolean }) => <button {...p} role=\"radio\" aria-checked={state.pressed} aria-pressed={undefined} /> }\n : {})}\n className={cn(\n \"inline-flex h-6 min-w-6 items-center justify-center gap-1 rounded-kit-sm px-1.5 text-kit-xs font-medium text-kit-fg-3 transition-colors hover:bg-kit-hover hover:text-kit-fg data-[pressed]:bg-kit-selected data-[pressed]:text-kit-fg [&_svg]:size-3.5\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/* ── Progress ──────────────────────────────────────────────────────────── */\nconst progressTones = {\n success: \"bg-kit-success\",\n accent: \"bg-kit-accent\",\n warning: \"bg-kit-warning\",\n danger: \"bg-kit-danger\",\n // --bar-fill: ink in light, a quiet grey in dark (no near-white glare on a dark track)\n ink: \"bg-[var(--kit-bar-fill)]\",\n brand: \"bg-[var(--kit-bar-fill)]\",\n};\nexport function Progress({\n value,\n className,\n tone = \"success\",\n size = \"md\",\n label = \"Progress\",\n}: {\n value: number;\n className?: string;\n /** accessible name, e.g. \"AI credits used\" */\n label?: string;\n tone?: keyof typeof progressTones;\n size?: \"sm\" | \"md\";\n}) {\n const pct = Math.min(100, Math.max(0, value));\n return (\n <ProgressPrimitive.Root\n value={pct}\n aria-label={label}\n className={cn(\n \"relative w-full overflow-hidden rounded-full bg-[var(--kit-track)]\",\n size === \"sm\" ? \"h-1\" : \"h-1.5\",\n className,\n )}\n >\n <ProgressPrimitive.Indicator\n className={cn(\"h-full rounded-full transition-[width] duration-500 ease-[var(--kit-ease-out-soft)]\", progressTones[tone])}\n style={{ width: `${pct}%` }}\n />\n </ProgressPrimitive.Root>\n );\n}\n"],"mappings":"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"}
@@ -30,12 +30,20 @@ export declare const statusMap: Record<PublishStatus, {
30
30
  label: string;
31
31
  tone: BadgeTone;
32
32
  }>;
33
- export declare function StatusPill({ status, label, className, size, }: {
33
+ export declare function StatusPill({ status, label, tone, className, size, }: {
34
34
  status: PublishStatus;
35
35
  label?: string;
36
+ /** Transition prop: live-preview's pre-D72 `pageStatus.ts` keeps its "Edited" amber pill. Remove when it adopts D72. */
37
+ tone?: BadgeTone;
36
38
  className?: string;
37
39
  size?: BadgeSize;
38
40
  }): import("react/jsx-runtime").JSX.Element;
41
+ export type MarkStatus = "published" | "changed" | "held" | "draft" | "scheduled" | "review" | "archived";
42
+ export declare function StatusMark({ status, at, className }: {
43
+ status: MarkStatus;
44
+ at?: string;
45
+ className?: string;
46
+ }): import("react/jsx-runtime").JSX.Element;
39
47
  export declare function Kbd({ className, ...props }: React.HTMLAttributes<HTMLElement>): import("react/jsx-runtime").JSX.Element;
40
48
  /** The person's avatar colour as a CSS value (the light hex is the fallback outside a kit scope). */
41
49
  export declare function colorFor(seed: string): string;
@@ -91,8 +99,7 @@ export declare function Separator({ vertical, className }: {
91
99
  vertical?: boolean;
92
100
  className?: string;
93
101
  }): import("react/jsx-runtime").JSX.Element;
94
- /** V2 .skeleton: a --skeleton → --skeleton-shine sweep (800px wide, 1.6s linear; keyframe kit-shimmer in kit.css). */
95
- export declare const SKELETON = "bg-[linear-gradient(90deg,var(--kit-skeleton)_0,var(--kit-skeleton-shine)_40%,var(--kit-skeleton)_80%)] bg-[length:800px_100%] animate-[kit-shimmer_1.6s_linear_infinite] motion-reduce:animate-none";
102
+ /** V2 .skeleton: a --kit-skeleton → --kit-skeleton-shine sweep (800px wide, 1.6s linear; keyframe kit-shimmer in kit.css). */
96
103
  export declare function Skeleton({ className }: {
97
104
  className?: string;
98
105
  }): import("react/jsx-runtime").JSX.Element;