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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (619) hide show
  1. package/README.md +33 -0
  2. package/dist/adapters/dock-values.d.ts +28 -0
  3. package/dist/adapters/dock-values.js +41 -0
  4. package/dist/adapters/dock-values.js.map +1 -0
  5. package/{adapters → dist/adapters}/icons.js +2 -2
  6. package/dist/adapters/icons.js.map +1 -0
  7. package/{adapters → dist/adapters}/lossy.d.ts +94 -31
  8. package/dist/adapters/lossy.js +419 -0
  9. package/dist/adapters/lossy.js.map +1 -0
  10. package/{adapters → dist/adapters}/prod-types.d.ts +91 -26
  11. package/{adapters → dist/adapters}/prod-types.js +82 -13
  12. package/dist/adapters/prod-types.js.map +1 -0
  13. package/{adapters → dist/adapters}/schema.d.ts +40 -1
  14. package/{adapters → dist/adapters}/schema.js +1038 -204
  15. package/dist/adapters/schema.js.map +1 -0
  16. package/{adapters → dist/adapters}/values.d.ts +26 -5
  17. package/{adapters → dist/adapters}/values.js +87 -17
  18. package/dist/adapters/values.js.map +1 -0
  19. package/dist/brand/logo.js +96 -0
  20. package/dist/brand/logo.js.map +1 -0
  21. package/{context.d.ts → dist/context.d.ts} +131 -2
  22. package/{context.js → dist/context.js} +44 -2
  23. package/dist/context.js.map +1 -0
  24. package/{controls → dist/controls}/button.d.ts +19 -5
  25. package/{controls → dist/controls}/button.js +125 -54
  26. package/dist/controls/button.js.map +1 -0
  27. package/{controls → dist/controls}/c1.js +1 -1
  28. package/dist/controls/c1.js.map +1 -0
  29. package/{controls → dist/controls}/c2.js +1 -1
  30. package/dist/controls/c2.js.map +1 -0
  31. package/{controls → dist/controls}/choice.d.ts +7 -2
  32. package/{controls → dist/controls}/choice.js +71 -18
  33. package/dist/controls/choice.js.map +1 -0
  34. package/{controls → dist/controls}/code-register.js +1 -1
  35. package/dist/controls/code-register.js.map +1 -0
  36. package/{controls → dist/controls}/code.js +10 -9
  37. package/dist/controls/code.js.map +1 -0
  38. package/{controls → dist/controls}/color.js +8 -8
  39. package/dist/controls/color.js.map +1 -0
  40. package/{controls → dist/controls}/component-services.d.ts +42 -0
  41. package/dist/controls/component-services.js +7 -0
  42. package/dist/controls/component-services.js.map +1 -0
  43. package/{controls → dist/controls}/date-register.js +1 -1
  44. package/dist/controls/date-register.js.map +1 -0
  45. package/{controls → dist/controls}/date-zone.js +8 -2
  46. package/dist/controls/date-zone.js.map +1 -0
  47. package/{controls → dist/controls}/date.js +32 -24
  48. package/dist/controls/date.js.map +1 -0
  49. package/dist/controls/form-picker-register.d.ts +7 -0
  50. package/{controls → dist/controls}/form-picker-register.js +2 -6
  51. package/dist/controls/form-picker-register.js.map +1 -0
  52. package/{controls → dist/controls}/form-picker.js +11 -9
  53. package/dist/controls/form-picker.js.map +1 -0
  54. package/{controls → dist/controls}/icon-register.js +1 -1
  55. package/dist/controls/icon-register.js.map +1 -0
  56. package/{controls → dist/controls}/icon.d.ts +4 -2
  57. package/{controls → dist/controls}/icon.js +32 -27
  58. package/dist/controls/icon.js.map +1 -0
  59. package/{controls → dist/controls}/index.d.ts +1 -1
  60. package/{controls → dist/controls}/index.js +4 -3
  61. package/dist/controls/index.js.map +1 -0
  62. package/{controls → dist/controls}/json-register.js +1 -1
  63. package/dist/controls/json-register.js.map +1 -0
  64. package/{controls → dist/controls}/json.js +13 -3
  65. package/dist/controls/json.js.map +1 -0
  66. package/{controls → dist/controls}/link.js +116 -200
  67. package/dist/controls/link.js.map +1 -0
  68. package/{controls → dist/controls}/location-register.js +1 -1
  69. package/dist/controls/location-register.js.map +1 -0
  70. package/{controls → dist/controls}/location.js +59 -40
  71. package/dist/controls/location.js.map +1 -0
  72. package/{controls → dist/controls}/media-register.js +1 -1
  73. package/dist/controls/media-register.js.map +1 -0
  74. package/{controls → dist/controls}/media-services.d.ts +6 -0
  75. package/dist/controls/media-services.js +0 -0
  76. package/{controls → dist/controls}/media.d.ts +21 -4
  77. package/{controls → dist/controls}/media.js +407 -130
  78. package/dist/controls/media.js.map +1 -0
  79. package/{controls → dist/controls}/number.js +10 -9
  80. package/dist/controls/number.js.map +1 -0
  81. package/{controls → dist/controls}/reference-register.js +1 -1
  82. package/dist/controls/reference-register.js.map +1 -0
  83. package/{controls → dist/controls}/reference-services.d.ts +4 -0
  84. package/dist/controls/reference-services.js +0 -0
  85. package/{controls → dist/controls}/reference.d.ts +1 -1
  86. package/{controls → dist/controls}/reference.js +93 -77
  87. package/dist/controls/reference.js.map +1 -0
  88. package/dist/controls/rich-text/article-shell.d.ts +145 -0
  89. package/dist/controls/rich-text/article-shell.js +510 -0
  90. package/dist/controls/rich-text/article-shell.js.map +1 -0
  91. package/dist/controls/rich-text/author.d.ts +25 -0
  92. package/dist/controls/rich-text/author.js +104 -0
  93. package/dist/controls/rich-text/author.js.map +1 -0
  94. package/dist/controls/rich-text/blocks.d.ts +60 -0
  95. package/{controls → dist/controls}/rich-text/blocks.js +164 -389
  96. package/dist/controls/rich-text/blocks.js.map +1 -0
  97. package/dist/controls/rich-text/button.d.ts +23 -0
  98. package/dist/controls/rich-text/button.js +85 -0
  99. package/dist/controls/rich-text/button.js.map +1 -0
  100. package/{controls → dist/controls}/rich-text/catalog.d.ts +7 -4
  101. package/{controls → dist/controls}/rich-text/catalog.js +94 -68
  102. package/dist/controls/rich-text/catalog.js.map +1 -0
  103. package/dist/controls/rich-text/checklist.d.ts +24 -0
  104. package/dist/controls/rich-text/checklist.js +115 -0
  105. package/dist/controls/rich-text/checklist.js.map +1 -0
  106. package/{controls → dist/controls}/rich-text/codec.d.ts +9 -1
  107. package/{controls → dist/controls}/rich-text/codec.js +7 -2
  108. package/dist/controls/rich-text/codec.js.map +1 -0
  109. package/dist/controls/rich-text/columns.d.ts +41 -0
  110. package/dist/controls/rich-text/columns.js +181 -0
  111. package/dist/controls/rich-text/columns.js.map +1 -0
  112. package/{controls → dist/controls}/rich-text/component-card.d.ts +1 -1
  113. package/{controls → dist/controls}/rich-text/component-card.js +417 -99
  114. package/dist/controls/rich-text/component-card.js.map +1 -0
  115. package/dist/controls/rich-text/component-panel.d.ts +47 -0
  116. package/dist/controls/rich-text/component-panel.js +141 -0
  117. package/dist/controls/rich-text/component-panel.js.map +1 -0
  118. package/{controls → dist/controls}/rich-text/control.d.ts +1 -2
  119. package/{controls → dist/controls}/rich-text/control.js +84 -42
  120. package/dist/controls/rich-text/control.js.map +1 -0
  121. package/{controls → dist/controls}/rich-text/dom.d.ts +53 -9
  122. package/{controls → dist/controls}/rich-text/dom.js +388 -50
  123. package/dist/controls/rich-text/dom.js.map +1 -0
  124. package/{controls → dist/controls}/rich-text/editor.d.ts +7 -0
  125. package/{controls → dist/controls}/rich-text/editor.js +226 -44
  126. package/dist/controls/rich-text/editor.js.map +1 -0
  127. package/dist/controls/rich-text/embed.d.ts +28 -0
  128. package/dist/controls/rich-text/embed.js +210 -0
  129. package/dist/controls/rich-text/embed.js.map +1 -0
  130. package/{controls → dist/controls}/rich-text/floating.d.ts +6 -1
  131. package/{controls → dist/controls}/rich-text/floating.js +35 -18
  132. package/dist/controls/rich-text/floating.js.map +1 -0
  133. package/dist/controls/rich-text/footnote.d.ts +41 -0
  134. package/dist/controls/rich-text/footnote.js +185 -0
  135. package/dist/controls/rich-text/footnote.js.map +1 -0
  136. package/dist/controls/rich-text/gallery.d.ts +28 -0
  137. package/dist/controls/rich-text/gallery.js +167 -0
  138. package/dist/controls/rich-text/gallery.js.map +1 -0
  139. package/{controls → dist/controls}/rich-text/index.js +1 -1
  140. package/dist/controls/rich-text/index.js.map +1 -0
  141. package/{controls → dist/controls}/rich-text/link-form.d.ts +3 -1
  142. package/dist/controls/rich-text/link-form.js +147 -0
  143. package/dist/controls/rich-text/link-form.js.map +1 -0
  144. package/{controls → dist/controls}/rich-text/markdown.js +4 -2
  145. package/dist/controls/rich-text/markdown.js.map +1 -0
  146. package/{controls → dist/controls}/rich-text/ops.js +17 -15
  147. package/dist/controls/rich-text/ops.js.map +1 -0
  148. package/dist/controls/rich-text/plain.d.ts +17 -0
  149. package/dist/controls/rich-text/plain.js +44 -0
  150. package/dist/controls/rich-text/plain.js.map +1 -0
  151. package/dist/controls/rich-text/related.d.ts +36 -0
  152. package/dist/controls/rich-text/related.js +213 -0
  153. package/dist/controls/rich-text/related.js.map +1 -0
  154. package/dist/controls/rich-text/toc.d.ts +46 -0
  155. package/dist/controls/rich-text/toc.js +161 -0
  156. package/dist/controls/rich-text/toc.js.map +1 -0
  157. package/{controls → dist/controls}/rich-text/toolbar.d.ts +6 -2
  158. package/{controls → dist/controls}/rich-text/toolbar.js +12 -7
  159. package/dist/controls/rich-text/toolbar.js.map +1 -0
  160. package/{controls → dist/controls}/scale.js +5 -5
  161. package/dist/controls/scale.js.map +1 -0
  162. package/dist/controls/slot-register.d.ts +6 -0
  163. package/{controls → dist/controls}/slot-register.js +2 -5
  164. package/dist/controls/slot-register.js.map +1 -0
  165. package/{controls → dist/controls}/slot-services.d.ts +25 -0
  166. package/dist/controls/slot-services.js +155 -0
  167. package/dist/controls/slot-services.js.map +1 -0
  168. package/{controls → dist/controls}/slot.js +42 -24
  169. package/dist/controls/slot.js.map +1 -0
  170. package/{controls → dist/controls}/table/index.js +1 -1
  171. package/dist/controls/table/index.js.map +1 -0
  172. package/{controls → dist/controls}/table/prod.js +3 -3
  173. package/dist/controls/table/prod.js.map +1 -0
  174. package/{controls → dist/controls}/table/refs.js +13 -2
  175. package/dist/controls/table/refs.js.map +1 -0
  176. package/{controls → dist/controls}/table/stored.js +1 -1
  177. package/dist/controls/table/stored.js.map +1 -0
  178. package/{controls → dist/controls}/table/table-editor.js +51 -48
  179. package/dist/controls/table/table-editor.js.map +1 -0
  180. package/{controls → dist/controls}/table/table-link.js +3 -3
  181. package/dist/controls/table/table-link.js.map +1 -0
  182. package/{controls → dist/controls}/table/table.js +3 -3
  183. package/dist/controls/table/table.js.map +1 -0
  184. package/{controls → dist/controls}/text.d.ts +2 -2
  185. package/{controls → dist/controls}/text.js +78 -43
  186. package/dist/controls/text.js.map +1 -0
  187. package/dist/controls/unknown-value.d.ts +17 -0
  188. package/dist/controls/unknown-value.js +66 -0
  189. package/dist/controls/unknown-value.js.map +1 -0
  190. package/dist/core/core.d.ts +70 -0
  191. package/dist/core/core.js +187 -0
  192. package/dist/core/core.js.map +1 -0
  193. package/dist/core/facets.d.ts +355 -0
  194. package/dist/core/facets.js +342 -0
  195. package/dist/core/facets.js.map +1 -0
  196. package/dist/core/index.d.ts +3 -0
  197. package/dist/core/index.js +3 -0
  198. package/{engine → dist/engine}/array.js +34 -21
  199. package/dist/engine/array.js.map +1 -0
  200. package/{engine → dist/engine}/bits.js +1 -1
  201. package/dist/engine/bits.js.map +1 -0
  202. package/{engine → dist/engine}/breadcrumb.d.ts +3 -3
  203. package/{engine → dist/engine}/breadcrumb.js +12 -36
  204. package/dist/engine/breadcrumb.js.map +1 -0
  205. package/{engine → dist/engine}/expand.d.ts +2 -4
  206. package/{engine → dist/engine}/expand.js +5 -22
  207. package/dist/engine/expand.js.map +1 -0
  208. package/{engine → dist/engine}/field-list.js +1 -1
  209. package/dist/engine/field-list.js.map +1 -0
  210. package/{engine → dist/engine}/field-shell.js +249 -121
  211. package/dist/engine/field-shell.js.map +1 -0
  212. package/{engine → dist/engine}/frame.d.ts +3 -1
  213. package/{engine → dist/engine}/frame.js +16 -14
  214. package/dist/engine/frame.js.map +1 -0
  215. package/{engine → dist/engine}/group-summary.d.ts +2 -1
  216. package/{engine → dist/engine}/group-summary.js +7 -3
  217. package/dist/engine/group-summary.js.map +1 -0
  218. package/{engine → dist/engine}/grouping.d.ts +19 -5
  219. package/{engine → dist/engine}/grouping.js +193 -21
  220. package/dist/engine/grouping.js.map +1 -0
  221. package/{engine → dist/engine}/item-list.d.ts +11 -1
  222. package/{engine → dist/engine}/item-list.js +35 -13
  223. package/dist/engine/item-list.js.map +1 -0
  224. package/{engine → dist/engine}/kit-field.js +45 -10
  225. package/dist/engine/kit-field.js.map +1 -0
  226. package/{engine → dist/engine}/schema-form.d.ts +27 -2
  227. package/{engine → dist/engine}/schema-form.js +182 -40
  228. package/dist/engine/schema-form.js.map +1 -0
  229. package/{engine → dist/engine}/slot.js +5 -15
  230. package/dist/engine/slot.js.map +1 -0
  231. package/dist/index.js +58 -0
  232. package/dist/index.js.map +1 -0
  233. package/{kit.css → dist/kit.css} +19 -0
  234. package/{lib → dist/lib}/cn.js +7 -4
  235. package/dist/lib/cn.js.map +1 -0
  236. package/{lib → dist/lib}/columns.js +4 -1
  237. package/dist/lib/columns.js.map +1 -0
  238. package/{lib → dist/lib}/frames.js +2 -2
  239. package/dist/lib/frames.js.map +1 -0
  240. package/dist/lib/icon-image.d.ts +10 -0
  241. package/dist/lib/icon-image.js +8 -0
  242. package/dist/lib/icon-image.js.map +1 -0
  243. package/{lib → dist/lib}/icons.js +4 -3
  244. package/dist/lib/icons.js.map +1 -0
  245. package/dist/lib/input-modality.d.ts +11 -0
  246. package/dist/lib/input-modality.js +47 -0
  247. package/dist/lib/input-modality.js.map +1 -0
  248. package/dist/lib/key-event.d.ts +11 -0
  249. package/dist/lib/key-event.js +16 -0
  250. package/dist/lib/key-event.js.map +1 -0
  251. package/{lib → dist/lib}/path.js +4 -2
  252. package/dist/lib/path.js.map +1 -0
  253. package/{lib → dist/lib}/schema.d.ts +34 -3
  254. package/{lib → dist/lib}/schema.js +110 -13
  255. package/dist/lib/schema.js.map +1 -0
  256. package/{lib → dist/lib}/utils.js +1 -1
  257. package/dist/lib/utils.js.map +1 -0
  258. package/{lib → dist/lib}/validate.d.ts +11 -1
  259. package/{lib → dist/lib}/validate.js +85 -11
  260. package/dist/lib/validate.js.map +1 -0
  261. package/dist/library/analysis.d.ts +23 -0
  262. package/dist/library/analysis.js +160 -0
  263. package/dist/library/analysis.js.map +1 -0
  264. package/dist/library/catalog.d.ts +57 -0
  265. package/dist/library/catalog.js +307 -0
  266. package/dist/library/catalog.js.map +1 -0
  267. package/dist/library/coreNotes.d.ts +8 -0
  268. package/dist/library/coreNotes.js +111 -0
  269. package/dist/library/coreNotes.js.map +1 -0
  270. package/dist/library/coverage.d.ts +40 -0
  271. package/dist/library/coverage.js +59 -0
  272. package/dist/library/coverage.js.map +1 -0
  273. package/dist/library/entries/advanced.entries.d.ts +2 -0
  274. package/dist/library/entries/advanced.entries.js +6579 -0
  275. package/dist/library/entries/advanced.entries.js.map +1 -0
  276. package/dist/library/entries/commerce.entries.d.ts +2 -0
  277. package/dist/library/entries/commerce.entries.js +4140 -0
  278. package/dist/library/entries/commerce.entries.js.map +1 -0
  279. package/dist/library/entries/company.entries.d.ts +2 -0
  280. package/dist/library/entries/company.entries.js +2731 -0
  281. package/dist/library/entries/company.entries.js.map +1 -0
  282. package/dist/library/entries/conversion.entries.d.ts +2 -0
  283. package/dist/library/entries/conversion.entries.js +3707 -0
  284. package/dist/library/entries/conversion.entries.js.map +1 -0
  285. package/dist/library/entries/data.entries.d.ts +7 -0
  286. package/dist/library/entries/data.entries.js +4613 -0
  287. package/dist/library/entries/data.entries.js.map +1 -0
  288. package/dist/library/entries/events.entries.d.ts +2 -0
  289. package/dist/library/entries/events.entries.js +3428 -0
  290. package/dist/library/entries/events.entries.js.map +1 -0
  291. package/dist/library/entries/features.entries.d.ts +2 -0
  292. package/dist/library/entries/features.entries.js +3157 -0
  293. package/dist/library/entries/features.entries.js.map +1 -0
  294. package/dist/library/entries/heroes.entries.d.ts +2 -0
  295. package/dist/library/entries/heroes.entries.js +3401 -0
  296. package/dist/library/entries/heroes.entries.js.map +1 -0
  297. package/dist/library/entries/index.d.ts +3 -0
  298. package/dist/library/entries/index.js +35 -0
  299. package/dist/library/entries/index.js.map +1 -0
  300. package/dist/library/entries/listings.entries.d.ts +2 -0
  301. package/dist/library/entries/listings.entries.js +2976 -0
  302. package/dist/library/entries/listings.entries.js.map +1 -0
  303. package/dist/library/entries/longform.entries.d.ts +2 -0
  304. package/dist/library/entries/longform.entries.js +4227 -0
  305. package/dist/library/entries/longform.entries.js.map +1 -0
  306. package/dist/library/entries/media.entries.d.ts +2 -0
  307. package/dist/library/entries/media.entries.js +2781 -0
  308. package/dist/library/entries/media.entries.js.map +1 -0
  309. package/dist/library/entries/navigation.entries.d.ts +2 -0
  310. package/dist/library/entries/navigation.entries.js +4011 -0
  311. package/dist/library/entries/navigation.entries.js.map +1 -0
  312. package/dist/library/entries/pricing.entries.d.ts +2 -0
  313. package/dist/library/entries/pricing.entries.js +2383 -0
  314. package/dist/library/entries/pricing.entries.js.map +1 -0
  315. package/dist/library/entries/social-proof.entries.d.ts +2 -0
  316. package/dist/library/entries/social-proof.entries.js +2297 -0
  317. package/dist/library/entries/social-proof.entries.js.map +1 -0
  318. package/dist/library/examples/bento.d.ts +92 -0
  319. package/dist/library/examples/bento.js +201 -0
  320. package/dist/library/examples/bento.js.map +1 -0
  321. package/dist/library/examples/blocks.d.ts +14 -0
  322. package/dist/library/examples/blocks.js +313 -0
  323. package/dist/library/examples/blocks.js.map +1 -0
  324. package/dist/library/examples/faq.d.ts +28 -0
  325. package/dist/library/examples/faq.js +230 -0
  326. package/dist/library/examples/faq.js.map +1 -0
  327. package/dist/library/examples/hero.d.ts +43 -0
  328. package/dist/library/examples/hero.js +222 -0
  329. package/dist/library/examples/hero.js.map +1 -0
  330. package/dist/library/examples/index.d.ts +36 -0
  331. package/dist/library/examples/index.js +109 -0
  332. package/dist/library/examples/index.js.map +1 -0
  333. package/dist/library/examples/journalStory.d.ts +93 -0
  334. package/dist/library/examples/journalStory.js +338 -0
  335. package/dist/library/examples/journalStory.js.map +1 -0
  336. package/dist/library/examples/megaMenu.d.ts +134 -0
  337. package/dist/library/examples/megaMenu.js +442 -0
  338. package/dist/library/examples/megaMenu.js.map +1 -0
  339. package/dist/library/examples/pricing.d.ts +103 -0
  340. package/dist/library/examples/pricing.js +479 -0
  341. package/dist/library/examples/pricing.js.map +1 -0
  342. package/dist/library/examples/tabs.d.ts +87 -0
  343. package/dist/library/examples/tabs.js +180 -0
  344. package/dist/library/examples/tabs.js.map +1 -0
  345. package/dist/library/export.d.ts +42 -0
  346. package/dist/library/export.js +80 -0
  347. package/dist/library/export.js.map +1 -0
  348. package/dist/library/index.d.ts +13 -0
  349. package/dist/library/index.js +6 -0
  350. package/dist/library/kit-catalog.json +1511 -0
  351. package/dist/library/types.d.ts +42 -0
  352. package/dist/library/types.js +0 -0
  353. package/{schema → dist/schema}/adapters.js +1 -2
  354. package/dist/schema/adapters.js.map +1 -0
  355. package/{schema → dist/schema}/help.d.ts +2 -0
  356. package/{schema → dist/schema}/help.js +6 -4
  357. package/dist/schema/help.js.map +1 -0
  358. package/{schema → dist/schema}/scale.js +1 -1
  359. package/dist/schema/scale.js.map +1 -0
  360. package/{schema → dist/schema}/sources.js +1 -1
  361. package/dist/schema/sources.js.map +1 -0
  362. package/{schema → dist/schema}/table.js +11 -10
  363. package/dist/schema/table.js.map +1 -0
  364. package/{schema → dist/schema}/types.d.ts +36 -1
  365. package/{schema → dist/schema}/types.js +1 -1
  366. package/dist/schema/types.js.map +1 -0
  367. package/dist/styles.css +2 -0
  368. package/dist/table/table-view.d.ts +14 -0
  369. package/dist/table/table-view.js +140 -0
  370. package/dist/table/table-view.js.map +1 -0
  371. package/dist/table/table.css +73 -0
  372. package/dist/testing/corpus.d.ts +63 -0
  373. package/dist/testing/corpus.js +129 -0
  374. package/dist/testing/corpus.js.map +1 -0
  375. package/dist/testing/test-form.d.ts +11 -0
  376. package/dist/testing/test-form.js +38 -0
  377. package/dist/testing/test-form.js.map +1 -0
  378. package/dist/theme.css +345 -0
  379. package/dist/theme.d.ts +22 -0
  380. package/dist/theme.js +43 -0
  381. package/dist/theme.js.map +1 -0
  382. package/dist/tokens.css +542 -0
  383. package/dist/types.js +0 -0
  384. package/{ui → dist/ui}/action-tray.d.ts +1 -1
  385. package/{ui → dist/ui}/action-tray.js +20 -19
  386. package/dist/ui/action-tray.js.map +1 -0
  387. package/dist/ui/autocomplete.d.ts +58 -0
  388. package/dist/ui/autocomplete.js +194 -0
  389. package/dist/ui/autocomplete.js.map +1 -0
  390. package/{ui → dist/ui}/button.d.ts +3 -3
  391. package/{ui → dist/ui}/button.js +8 -11
  392. package/dist/ui/button.js.map +1 -0
  393. package/{ui → dist/ui}/choice-switch.js +1 -1
  394. package/dist/ui/choice-switch.js.map +1 -0
  395. package/{ui → dist/ui}/controls.js +51 -39
  396. package/dist/ui/controls.js.map +1 -0
  397. package/{ui → dist/ui}/display.d.ts +10 -3
  398. package/{ui → dist/ui}/display.js +57 -46
  399. package/dist/ui/display.js.map +1 -0
  400. package/{ui → dist/ui}/expanded-editor-modal.d.ts +2 -2
  401. package/{ui → dist/ui}/expanded-editor-modal.js +6 -6
  402. package/dist/ui/expanded-editor-modal.js.map +1 -0
  403. package/{ui → dist/ui}/field-context.js +1 -1
  404. package/dist/ui/field-context.js.map +1 -0
  405. package/{ui → dist/ui}/floating-panel.d.ts +1 -1
  406. package/{ui → dist/ui}/floating-panel.js +28 -12
  407. package/dist/ui/floating-panel.js.map +1 -0
  408. package/{ui → dist/ui}/index.d.ts +4 -0
  409. package/dist/ui/index.js +18 -0
  410. package/{ui → dist/ui}/input.d.ts +1 -1
  411. package/{ui → dist/ui}/input.js +9 -9
  412. package/dist/ui/input.js.map +1 -0
  413. package/{ui → dist/ui}/mode-bar.js +3 -3
  414. package/dist/ui/mode-bar.js.map +1 -0
  415. package/{ui → dist/ui}/overlay.d.ts +77 -5
  416. package/dist/ui/overlay.js +697 -0
  417. package/dist/ui/overlay.js.map +1 -0
  418. package/{ui → dist/ui}/path-crumbs.js +37 -3
  419. package/dist/ui/path-crumbs.js.map +1 -0
  420. package/{ui → dist/ui}/presence.js +2 -2
  421. package/dist/ui/presence.js.map +1 -0
  422. package/{ui → dist/ui}/select.js +89 -87
  423. package/dist/ui/select.js.map +1 -0
  424. package/{ui → dist/ui}/shortcut-hint.js +1 -1
  425. package/dist/ui/shortcut-hint.js.map +1 -0
  426. package/dist/ui/spinner.d.ts +24 -0
  427. package/dist/ui/spinner.js +42 -0
  428. package/dist/ui/spinner.js.map +1 -0
  429. package/dist/ui/split-button.d.ts +32 -0
  430. package/dist/ui/split-button.js +60 -0
  431. package/dist/ui/split-button.js.map +1 -0
  432. package/{ui → dist/ui}/surfaces.js +1 -1
  433. package/dist/ui/surfaces.js.map +1 -0
  434. package/dist/ui/tab.d.ts +38 -0
  435. package/dist/ui/tab.js +87 -0
  436. package/dist/ui/tab.js.map +1 -0
  437. package/dist/ui/toast.d.ts +20 -0
  438. package/dist/ui/toast.js +115 -0
  439. package/dist/ui/toast.js.map +1 -0
  440. package/{ui → dist/ui}/tooltip-root.d.ts +4 -3
  441. package/{ui → dist/ui}/tooltip-root.js +9 -8
  442. package/dist/ui/tooltip-root.js.map +1 -0
  443. package/{ui → dist/ui}/variants.js +1 -1
  444. package/dist/ui/variants.js.map +1 -0
  445. package/package.json +83 -23
  446. package/adapters/icons.js.map +0 -1
  447. package/adapters/lossy.js +0 -233
  448. package/adapters/lossy.js.map +0 -1
  449. package/adapters/prod-types.js.map +0 -1
  450. package/adapters/schema.js.map +0 -1
  451. package/adapters/values.js.map +0 -1
  452. package/brand/logo.js +0 -9
  453. package/brand/logo.js.map +0 -1
  454. package/context.js.map +0 -1
  455. package/controls/button.js.map +0 -1
  456. package/controls/c1.js.map +0 -1
  457. package/controls/c2.js.map +0 -1
  458. package/controls/choice.js.map +0 -1
  459. package/controls/code-register.js.map +0 -1
  460. package/controls/code.js.map +0 -1
  461. package/controls/color.js.map +0 -1
  462. package/controls/date-register.js.map +0 -1
  463. package/controls/date-zone.js.map +0 -1
  464. package/controls/date.js.map +0 -1
  465. package/controls/form-picker-register.d.ts +0 -1
  466. package/controls/form-picker-register.js.map +0 -1
  467. package/controls/form-picker.js.map +0 -1
  468. package/controls/icon-register.js.map +0 -1
  469. package/controls/icon.js.map +0 -1
  470. package/controls/index.js.map +0 -1
  471. package/controls/json-register.js.map +0 -1
  472. package/controls/json.js.map +0 -1
  473. package/controls/link.js.map +0 -1
  474. package/controls/location-register.js.map +0 -1
  475. package/controls/location.js.map +0 -1
  476. package/controls/media-register.js.map +0 -1
  477. package/controls/media.js.map +0 -1
  478. package/controls/number.js.map +0 -1
  479. package/controls/reference-register.js.map +0 -1
  480. package/controls/reference.js.map +0 -1
  481. package/controls/rich-text/blocks.d.ts +0 -28
  482. package/controls/rich-text/blocks.js.map +0 -1
  483. package/controls/rich-text/catalog.js.map +0 -1
  484. package/controls/rich-text/codec.js.map +0 -1
  485. package/controls/rich-text/component-card.js.map +0 -1
  486. package/controls/rich-text/control.js.map +0 -1
  487. package/controls/rich-text/dom.js.map +0 -1
  488. package/controls/rich-text/editor.js.map +0 -1
  489. package/controls/rich-text/floating.js.map +0 -1
  490. package/controls/rich-text/index.js.map +0 -1
  491. package/controls/rich-text/link-form.js +0 -111
  492. package/controls/rich-text/link-form.js.map +0 -1
  493. package/controls/rich-text/markdown.js.map +0 -1
  494. package/controls/rich-text/ops.js.map +0 -1
  495. package/controls/rich-text/toolbar.js.map +0 -1
  496. package/controls/scale.js.map +0 -1
  497. package/controls/slot-register.d.ts +0 -1
  498. package/controls/slot-register.js.map +0 -1
  499. package/controls/slot-services.js +0 -38
  500. package/controls/slot-services.js.map +0 -1
  501. package/controls/slot.js.map +0 -1
  502. package/controls/table/index.js.map +0 -1
  503. package/controls/table/prod.js.map +0 -1
  504. package/controls/table/refs.js.map +0 -1
  505. package/controls/table/stored.js.map +0 -1
  506. package/controls/table/table-editor.js.map +0 -1
  507. package/controls/table/table-link.js.map +0 -1
  508. package/controls/table/table.js.map +0 -1
  509. package/controls/text.js.map +0 -1
  510. package/engine/array.js.map +0 -1
  511. package/engine/bits.js.map +0 -1
  512. package/engine/breadcrumb.js.map +0 -1
  513. package/engine/expand.js.map +0 -1
  514. package/engine/field-list.js.map +0 -1
  515. package/engine/field-shell.js.map +0 -1
  516. package/engine/frame.js.map +0 -1
  517. package/engine/group-summary.js.map +0 -1
  518. package/engine/grouping.js.map +0 -1
  519. package/engine/item-list.js.map +0 -1
  520. package/engine/kit-field.js.map +0 -1
  521. package/engine/schema-form.js.map +0 -1
  522. package/engine/slot.js.map +0 -1
  523. package/index.js +0 -55
  524. package/index.js.map +0 -1
  525. package/lib/cn.js.map +0 -1
  526. package/lib/columns.js.map +0 -1
  527. package/lib/frames.js.map +0 -1
  528. package/lib/icons.js.map +0 -1
  529. package/lib/path.js.map +0 -1
  530. package/lib/schema.js.map +0 -1
  531. package/lib/utils.js.map +0 -1
  532. package/lib/validate.js.map +0 -1
  533. package/schema/adapters.js.map +0 -1
  534. package/schema/help.js.map +0 -1
  535. package/schema/scale.js.map +0 -1
  536. package/schema/sources.js.map +0 -1
  537. package/schema/table.js.map +0 -1
  538. package/schema/types.js.map +0 -1
  539. package/ui/action-tray.js.map +0 -1
  540. package/ui/button.js.map +0 -1
  541. package/ui/choice-switch.js.map +0 -1
  542. package/ui/controls.js.map +0 -1
  543. package/ui/display.js.map +0 -1
  544. package/ui/expanded-editor-modal.js.map +0 -1
  545. package/ui/field-context.js.map +0 -1
  546. package/ui/floating-panel.js.map +0 -1
  547. package/ui/index.js +0 -13
  548. package/ui/input.js.map +0 -1
  549. package/ui/mode-bar.js.map +0 -1
  550. package/ui/overlay.js +0 -378
  551. package/ui/overlay.js.map +0 -1
  552. package/ui/path-crumbs.js.map +0 -1
  553. package/ui/presence.js.map +0 -1
  554. package/ui/select.js.map +0 -1
  555. package/ui/shortcut-hint.js.map +0 -1
  556. package/ui/surfaces.js.map +0 -1
  557. package/ui/tooltip-root.js.map +0 -1
  558. package/ui/variants.js.map +0 -1
  559. /package/{_virtual → dist/_virtual}/_rolldown/runtime.js +0 -0
  560. /package/{adapters → dist/adapters}/icons.d.ts +0 -0
  561. /package/{brand → dist/brand}/logo.d.ts +0 -0
  562. /package/{controls → dist/controls}/c1.d.ts +0 -0
  563. /package/{controls → dist/controls}/c2.d.ts +0 -0
  564. /package/{controls → dist/controls}/code-register.d.ts +0 -0
  565. /package/{controls → dist/controls}/code.d.ts +0 -0
  566. /package/{controls → dist/controls}/color.d.ts +0 -0
  567. /package/{controls → dist/controls}/date-register.d.ts +0 -0
  568. /package/{controls → dist/controls}/date-zone.d.ts +0 -0
  569. /package/{controls → dist/controls}/date.d.ts +0 -0
  570. /package/{controls → dist/controls}/form-picker.d.ts +0 -0
  571. /package/{controls → dist/controls}/icon-register.d.ts +0 -0
  572. /package/{controls → dist/controls}/json-register.d.ts +0 -0
  573. /package/{controls → dist/controls}/json.d.ts +0 -0
  574. /package/{controls → dist/controls}/link.d.ts +0 -0
  575. /package/{controls → dist/controls}/location-register.d.ts +0 -0
  576. /package/{controls → dist/controls}/location.d.ts +0 -0
  577. /package/{controls → dist/controls}/media-register.d.ts +0 -0
  578. /package/{controls → dist/controls}/number.d.ts +0 -0
  579. /package/{controls → dist/controls}/reference-register.d.ts +0 -0
  580. /package/{controls → dist/controls}/rich-text/index.d.ts +0 -0
  581. /package/{controls → dist/controls}/rich-text/markdown.d.ts +0 -0
  582. /package/{controls → dist/controls}/rich-text/ops.d.ts +0 -0
  583. /package/{controls → dist/controls}/scale.d.ts +0 -0
  584. /package/{controls → dist/controls}/slot.d.ts +0 -0
  585. /package/{controls → dist/controls}/table/index.d.ts +0 -0
  586. /package/{controls → dist/controls}/table/prod.d.ts +0 -0
  587. /package/{controls → dist/controls}/table/refs.d.ts +0 -0
  588. /package/{controls → dist/controls}/table/stored.d.ts +0 -0
  589. /package/{controls → dist/controls}/table/table-editor.d.ts +0 -0
  590. /package/{controls → dist/controls}/table/table-link.d.ts +0 -0
  591. /package/{controls → dist/controls}/table/table.d.ts +0 -0
  592. /package/{engine → dist/engine}/array.d.ts +0 -0
  593. /package/{engine → dist/engine}/bits.d.ts +0 -0
  594. /package/{engine → dist/engine}/field-list.d.ts +0 -0
  595. /package/{engine → dist/engine}/field-shell.d.ts +0 -0
  596. /package/{engine → dist/engine}/kit-field.d.ts +0 -0
  597. /package/{engine → dist/engine}/slot.d.ts +0 -0
  598. /package/{index.d.ts → dist/index.d.ts} +0 -0
  599. /package/{lib → dist/lib}/cn.d.ts +0 -0
  600. /package/{lib → dist/lib}/columns.d.ts +0 -0
  601. /package/{lib → dist/lib}/frames.d.ts +0 -0
  602. /package/{lib → dist/lib}/icons.d.ts +0 -0
  603. /package/{lib → dist/lib}/path.d.ts +0 -0
  604. /package/{lib → dist/lib}/utils.d.ts +0 -0
  605. /package/{schema → dist/schema}/adapters.d.ts +0 -0
  606. /package/{schema → dist/schema}/scale.d.ts +0 -0
  607. /package/{schema → dist/schema}/sources.d.ts +0 -0
  608. /package/{schema → dist/schema}/table.d.ts +0 -0
  609. /package/{types.d.ts → dist/types.d.ts} +0 -0
  610. /package/{ui → dist/ui}/choice-switch.d.ts +0 -0
  611. /package/{ui → dist/ui}/controls.d.ts +0 -0
  612. /package/{ui → dist/ui}/field-context.d.ts +0 -0
  613. /package/{ui → dist/ui}/mode-bar.d.ts +0 -0
  614. /package/{ui → dist/ui}/path-crumbs.d.ts +0 -0
  615. /package/{ui → dist/ui}/presence.d.ts +0 -0
  616. /package/{ui → dist/ui}/select.d.ts +0 -0
  617. /package/{ui → dist/ui}/shortcut-hint.d.ts +0 -0
  618. /package/{ui → dist/ui}/surfaces.d.ts +0 -0
  619. /package/{ui → dist/ui}/variants.d.ts +0 -0
@@ -0,0 +1,58 @@
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
+ /** decorative icon before the input */
22
+ leading?: React.ReactNode;
23
+ /** an interactive control inside the field before the input (the link-type menu); rendered as is */
24
+ leadingSlot?: React.ReactNode;
25
+ loading?: boolean;
26
+ invalid?: boolean;
27
+ disabled?: boolean;
28
+ /** open the suggestions when the field takes focus (default true, as V2) */
29
+ openOnFocus?: boolean;
30
+ /** controlled open; the list shows while open and it has rows or a note */
31
+ open?: boolean;
32
+ onOpenChange?: (open: boolean) => void;
33
+ /** render the list in the flow under the field instead of a floating popup (panels, popovers) */
34
+ inlineList?: boolean;
35
+ /** a status row shown, with the list kept open, when no row matches */
36
+ emptyNote?: React.ReactNode;
37
+ /** a status row under the rows when there are rows (a partial-load error) */
38
+ listNote?: React.ReactNode;
39
+ /** highlight row 0 on every keystroke that leaves text, so Enter picks it; empty text highlights nothing */
40
+ highlightFirst?: boolean;
41
+ /** emphasise the query inside row labels (default true; V2's link rows draw the plain title) */
42
+ highlightMatches?: boolean;
43
+ /** the listbox's accessible name */
44
+ listLabel?: string;
45
+ /** a pick also writes the row's label into the text (default true); false = a pick only calls onSelect */
46
+ fillOnSelect?: boolean;
47
+ /** replaces the built-in clear (setText("")) on the X */
48
+ onClear?: () => void;
49
+ /** a control inside the field after the clear button (the file-library button) */
50
+ trailingSlot?: React.ReactNode;
51
+ /** data-* attributes on the list's layer (the floating positioner, or the inline wrapper) */
52
+ listAttrs?: Record<`data-${string}`, string>;
53
+ inputRef?: React.Ref<HTMLInputElement>;
54
+ onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
55
+ className?: string;
56
+ menuClassName?: string;
57
+ }
58
+ export declare function Autocomplete({ id, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, value, defaultValue, onValueChange, options, onSelect, onEnter, filter, placeholder, size, leading, leadingSlot, loading, invalid, disabled, openOnFocus, open: openProp, onOpenChange, inlineList, emptyNote, listNote, highlightFirst, highlightMatches, listLabel, fillOnSelect, onClear, trailingSlot, listAttrs, inputRef, onBlur, className, menuClassName, }: AutocompleteProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,194 @@
1
+ import { cn } from "../lib/cn.js";
2
+ import { useFieldDescribedBy, useFieldId, useFieldLabelledBy, useLabelFor } from "./field-context.js";
3
+ import { Spinner } from "./spinner.js";
4
+ import { KIT_SCOPE } from "./surfaces.js";
5
+ import { IconButton } from "./button.js";
6
+ import { Highlight, filterOptions, nodeText } from "./select.js";
7
+ import * as React from "react";
8
+ import { Fragment, 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
+ var NOTE = "px-2 py-1.5 text-kit-xs text-kit-fg-3";
18
+ function Autocomplete({ id, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, value, defaultValue = "", onValueChange, options, onSelect, onEnter, filter = filterOptions, placeholder, size = "md", leading, leadingSlot, loading, invalid, disabled, openOnFocus = true, open: openProp, onOpenChange, inlineList = false, emptyNote, listNote, highlightFirst = false, highlightMatches = true, listLabel, fillOnSelect = true, onClear, trailingSlot, listAttrs, inputRef, onBlur, className, menuClassName }) {
19
+ const fieldId = useFieldId();
20
+ const labelledBy = useFieldLabelledBy();
21
+ const labelFor = useLabelFor(id ?? fieldId);
22
+ const describedBy = useFieldDescribedBy();
23
+ const [inner, setInner] = React.useState(defaultValue);
24
+ const text = value ?? inner;
25
+ const setText = (t) => {
26
+ if (value === void 0) setInner(t);
27
+ onValueChange?.(t);
28
+ };
29
+ const [innerOpen, setInnerOpen] = React.useState(false);
30
+ const open = openProp ?? innerOpen;
31
+ const setOpen = (o) => {
32
+ if (openProp === void 0) setInnerOpen(o);
33
+ onOpenChange?.(o);
34
+ };
35
+ const [highlighted, setHighlighted] = React.useState(void 0);
36
+ const shown = React.useMemo(() => filter ? filter(options, text) : options, [
37
+ filter,
38
+ options,
39
+ text
40
+ ]);
41
+ const hasEmptyNote = emptyNote != null && emptyNote !== false;
42
+ const visible = open && (shown.length > 0 || hasEmptyNote);
43
+ const firstStandsIn = highlightFirst && visible && text.trim() !== "" && !highlighted && shown.length > 0 && !shown[0].disabled;
44
+ const pick = (o) => {
45
+ onSelect?.(o);
46
+ if (fillOnSelect) setText(nodeText(o.label));
47
+ setOpen(false);
48
+ };
49
+ const named = id ?? fieldId ?? ariaLabel;
50
+ const rows = /* @__PURE__ */ jsxs(Fragment, { children: [
51
+ /* @__PURE__ */ jsx(Autocomplete$1.List, {
52
+ "aria-label": listLabel,
53
+ className: "max-h-72 overflow-y-auto overscroll-contain empty:hidden",
54
+ children: shown.map((o, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [o.group && (i === 0 || shown[i - 1].group !== o.group) ? /* @__PURE__ */ jsx("div", {
55
+ role: "presentation",
56
+ className: "px-2 pb-1 pt-2 text-kit-xs font-medium text-kit-fg-3 first:pt-1",
57
+ children: o.group
58
+ }) : null, /* @__PURE__ */ jsxs(Autocomplete$1.Item, {
59
+ value: o,
60
+ disabled: o.disabled,
61
+ onClick: () => onSelect?.(o),
62
+ "data-first-active": firstStandsIn && i === 0 ? "" : void 0,
63
+ 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 data-[first-active]:bg-kit-hover",
64
+ children: [
65
+ o.icon ? /* @__PURE__ */ jsx("span", {
66
+ "aria-hidden": true,
67
+ className: "flex shrink-0 text-kit-fg-3 [&_svg]:size-4",
68
+ children: o.icon
69
+ }) : null,
70
+ /* @__PURE__ */ jsx("span", {
71
+ className: "min-w-0 shrink truncate text-kit-fg",
72
+ children: highlightMatches && typeof o.label === "string" ? /* @__PURE__ */ jsx(Highlight, {
73
+ text: o.label,
74
+ query: text
75
+ }) : o.label
76
+ }),
77
+ o.description ? /* @__PURE__ */ jsx("span", {
78
+ className: "min-w-0 flex-1 truncate text-kit-xs text-kit-fg-3",
79
+ children: o.description
80
+ }) : /* @__PURE__ */ jsx("span", { className: "flex-1" }),
81
+ o.meta ? /* @__PURE__ */ jsx("span", {
82
+ className: "shrink-0 text-kit-2xs text-kit-fg-3",
83
+ children: o.meta
84
+ }) : null
85
+ ]
86
+ })] }, o.value))
87
+ }),
88
+ shown.length === 0 && hasEmptyNote ? /* @__PURE__ */ jsx("p", {
89
+ role: "status",
90
+ className: NOTE,
91
+ children: emptyNote
92
+ }) : null,
93
+ shown.length > 0 && listNote != null && listNote !== false ? /* @__PURE__ */ jsx("p", {
94
+ role: "status",
95
+ className: NOTE,
96
+ children: listNote
97
+ }) : null
98
+ ] });
99
+ return /* @__PURE__ */ jsxs(Autocomplete$1.Root, {
100
+ items: shown,
101
+ filter: null,
102
+ mode: "list",
103
+ value: text,
104
+ onValueChange: (t, details) => {
105
+ if (!fillOnSelect && details.reason === "item-press") return;
106
+ setText(t);
107
+ },
108
+ itemToStringValue: (o) => nodeText(o.label),
109
+ open: visible,
110
+ onOpenChange: setOpen,
111
+ inline: inlineList,
112
+ autoHighlight: highlightFirst,
113
+ onItemHighlighted: (o) => setHighlighted(o),
114
+ openOnInputClick: true,
115
+ loopFocus: true,
116
+ disabled,
117
+ children: [/* @__PURE__ */ jsxs("div", {
118
+ 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),
119
+ children: [
120
+ leadingSlot,
121
+ leading ? /* @__PURE__ */ jsx("span", {
122
+ "aria-hidden": true,
123
+ className: "ml-2.5 flex shrink-0 text-kit-fg-3 [&_svg]:size-4",
124
+ children: leading
125
+ }) : null,
126
+ /* @__PURE__ */ jsx(Autocomplete$1.Input, {
127
+ ref: inputRef,
128
+ id: id ?? fieldId,
129
+ "aria-label": ariaLabel,
130
+ "aria-labelledby": ariaLabel ? void 0 : labelFor ?? (named ? void 0 : labelledBy),
131
+ "aria-describedby": [ariaDescribedBy, describedBy].filter(Boolean).join(" ") || void 0,
132
+ "aria-invalid": invalid || void 0,
133
+ placeholder,
134
+ autoComplete: "off",
135
+ spellCheck: false,
136
+ onFocus: () => openOnFocus && setOpen(true),
137
+ onBlur,
138
+ onKeyDownCapture: (e) => {
139
+ if (e.key === "Escape" && visible) {
140
+ e.preventDefault();
141
+ e.stopPropagation();
142
+ setOpen(false);
143
+ }
144
+ },
145
+ onKeyDown: (e) => {
146
+ if (e.key !== "Enter") return;
147
+ if (firstStandsIn) {
148
+ e.preventDefault();
149
+ pick(shown[0]);
150
+ } else if (!highlighted || !visible) onEnter?.(text);
151
+ },
152
+ 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"
153
+ }),
154
+ loading ? /* @__PURE__ */ jsx(Spinner, {
155
+ size: "sm",
156
+ tone: "muted",
157
+ label: "Loading suggestions",
158
+ className: "mr-2"
159
+ }) : text && !disabled ? /* @__PURE__ */ jsx(IconButton, {
160
+ label: "Clear",
161
+ size: "xs",
162
+ variant: "ghost",
163
+ className: "mr-1",
164
+ onMouseDown: (e) => e.preventDefault(),
165
+ onClick: () => onClear ? onClear() : setText(""),
166
+ children: /* @__PURE__ */ jsx(IconX, { stroke: 1.5 })
167
+ }) : null,
168
+ trailingSlot
169
+ ]
170
+ }), inlineList ? visible ? /* @__PURE__ */ jsx("div", {
171
+ ...listAttrs,
172
+ className: cn("mt-1 rounded-kit-md border border-kit-line bg-kit-surface p-1", menuClassName),
173
+ onMouseDown: (e) => e.preventDefault(),
174
+ children: rows
175
+ }) : null : /* @__PURE__ */ jsx(Autocomplete$1.Portal, { children: /* @__PURE__ */ jsx(Autocomplete$1.Positioner, {
176
+ align: "start",
177
+ side: "bottom",
178
+ sideOffset: 4,
179
+ collisionPadding: 12,
180
+ className: "z-[var(--kit-z-menu,80)]",
181
+ "data-floating-layer": "",
182
+ ...KIT_SCOPE,
183
+ ...listAttrs,
184
+ children: /* @__PURE__ */ jsx(Autocomplete$1.Popup, {
185
+ 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),
186
+ children: rows
187
+ })
188
+ }) })]
189
+ });
190
+ }
191
+ //#endregion
192
+ export { Autocomplete };
193
+
194
+ //# 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 The link field (LinkPicker) opts into V2 link.tsx's extras: an in-flow list (inlineList), a status note when nothing\n matches (emptyNote) or under the rows (listNote), the link-type menu inside the field (leadingSlot), row 0 highlighted\n while typing (highlightFirst), a controlled open, plain row titles (highlightMatches={false}), and Escape that closes\n only the list while it is open (link.tsx:603-618). */\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 /** decorative icon before the input */\n leading?: React.ReactNode;\n /** an interactive control inside the field before the input (the link-type menu); rendered as is */\n leadingSlot?: 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 /** controlled open; the list shows while open and it has rows or a note */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** render the list in the flow under the field instead of a floating popup (panels, popovers) */\n inlineList?: boolean;\n /** a status row shown, with the list kept open, when no row matches */\n emptyNote?: React.ReactNode;\n /** a status row under the rows when there are rows (a partial-load error) */\n listNote?: React.ReactNode;\n /** highlight row 0 on every keystroke that leaves text, so Enter picks it; empty text highlights nothing */\n highlightFirst?: boolean;\n /** emphasise the query inside row labels (default true; V2's link rows draw the plain title) */\n highlightMatches?: boolean;\n /** the listbox's accessible name */\n listLabel?: string;\n /** a pick also writes the row's label into the text (default true); false = a pick only calls onSelect */\n fillOnSelect?: boolean;\n /** replaces the built-in clear (setText(\"\")) on the X */\n onClear?: () => void;\n /** a control inside the field after the clear button (the file-library button) */\n trailingSlot?: React.ReactNode;\n /** data-* attributes on the list's layer (the floating positioner, or the inline wrapper) */\n listAttrs?: Record<`data-${string}`, string>;\n inputRef?: React.Ref<HTMLInputElement>;\n onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;\n className?: string;\n menuClassName?: string;\n}\n\nconst H = { sm: \"h-7\", md: \"h-8\", lg: \"h-9\" } as const;\n/* V2 link.tsx:507-509 */\nconst NOTE = \"px-2 py-1.5 text-kit-xs text-kit-fg-3\";\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 leadingSlot,\n loading,\n invalid,\n disabled,\n openOnFocus = true,\n open: openProp,\n onOpenChange,\n inlineList = false,\n emptyNote,\n listNote,\n highlightFirst = false,\n highlightMatches = true,\n listLabel,\n fillOnSelect = true,\n onClear,\n trailingSlot,\n listAttrs,\n inputRef,\n onBlur,\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 [innerOpen, setInnerOpen] = React.useState(false);\n const open = openProp ?? innerOpen;\n const setOpen = (o: boolean) => {\n if (openProp === undefined) setInnerOpen(o);\n onOpenChange?.(o);\n };\n const [highlighted, setHighlighted] = React.useState<SelectOption | undefined>(undefined);\n const shown = React.useMemo(() => (filter ? filter(options, text) : options), [filter, options, text]);\n const hasEmptyNote = emptyNote != null && emptyNote !== false;\n const visible = open && (shown.length > 0 || hasEmptyNote);\n /* highlightFirst: row 0 stands in as the active row while text is typed and nothing else is highlighted (V2\n link.tsx sets its own active index to 0 on each keystroke); Base UI's autoHighlight normally does the same. */\n const firstStandsIn = highlightFirst && visible && text.trim() !== \"\" && !highlighted && shown.length > 0 && !shown[0].disabled;\n const pick = (o: SelectOption) => {\n onSelect?.(o);\n if (fillOnSelect) setText(nodeText(o.label));\n setOpen(false);\n };\n const named = id ?? fieldId ?? ariaLabel;\n\n const rows = (\n <>\n <AutocompletePrimitive.List aria-label={listLabel} className=\"max-h-72 overflow-y-auto overscroll-contain empty:hidden\">\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 data-first-active={firstStandsIn && i === 0 ? \"\" : undefined}\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 data-[first-active]: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 {highlightMatches && 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 {shown.length === 0 && hasEmptyNote ? (\n <p role=\"status\" className={NOTE}>\n {emptyNote}\n </p>\n ) : null}\n {shown.length > 0 && listNote != null && listNote !== false ? (\n <p role=\"status\" className={NOTE}>\n {listNote}\n </p>\n ) : null}\n </>\n );\n\n return (\n <AutocompletePrimitive.Root\n items={shown}\n filter={null}\n mode=\"list\"\n value={text}\n onValueChange={(t, details) => {\n // Base UI writes a pressed row's label into the input; a host that swaps the field for a chip opts out\n if (!fillOnSelect && details.reason === \"item-press\") return;\n setText(t);\n }}\n itemToStringValue={(o: SelectOption) => nodeText(o.label)}\n open={visible}\n onOpenChange={setOpen}\n inline={inlineList}\n // highlight row 0 while typing; Base UI highlights nothing for empty text, so Enter there commits it (onEnter)\n autoHighlight={highlightFirst}\n onItemHighlighted={(o) => setHighlighted(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 {leadingSlot}\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 ref={inputRef}\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 onBlur={onBlur}\n onKeyDownCapture={(e) => {\n // V2 link.tsx:603-618: while the list shows, Escape closes only the list; the next one reaches the panel\n if (e.key === \"Escape\" && visible) {\n e.preventDefault();\n e.stopPropagation();\n setOpen(false);\n }\n }}\n onKeyDown={(e) => {\n if (e.key !== \"Enter\") return;\n if (firstStandsIn) {\n e.preventDefault();\n pick(shown[0]);\n } else if (!highlighted || !visible) 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={() => (onClear ? onClear() : setText(\"\"))}>\n <IconX stroke={1.5} />\n </IconButton>\n ) : null}\n {trailingSlot}\n </div>\n {inlineList ? (\n visible ? (\n /* V2 link.tsx:646-649: the in-flow list under the field */\n <div {...listAttrs} className={cn(\"mt-1 rounded-kit-md border border-kit-line bg-kit-surface p-1\", menuClassName)} onMouseDown={(e) => e.preventDefault()}>\n {rows}\n </div>\n ) : null\n ) : (\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} {...listAttrs}>\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 {rows}\n </AutocompletePrimitive.Popup>\n </AutocompletePrimitive.Positioner>\n </AutocompletePrimitive.Portal>\n )}\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
  /**
@@ -1,12 +1,13 @@
1
1
  import { cn } from "../lib/cn.js";
2
2
  import { SPARKLE_PATH } from "../brand/logo.js";
3
+ import { Spinner } from "./spinner.js";
3
4
  import { TooltipLayer, TooltipRoot } from "./tooltip-root.js";
4
5
  import { variants } from "./variants.js";
5
6
  import * as React from "react";
6
- import { IconLoader2, IconPlus } from "@tabler/icons-react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { IconPlus } from "@tabler/icons-react";
8
9
  import { Tooltip } from "@base-ui/react/tooltip";
9
- //#region src/kit/ui/button.tsx
10
+ //#region src/ui/button.tsx
10
11
  /**
11
12
  * Button: the only button in the kit.
12
13
  * Heights: xs 24 · sm 28 · md 32 (default) · lg 36 · xl 40. Radius 6.
@@ -17,8 +18,8 @@ import { Tooltip } from "@base-ui/react/tooltip";
17
18
  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
19
  variants: {
19
20
  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",
21
+ primary: "bg-kit-inverse text-kit-fg-inverse shadow-kit-button-primary hover:bg-kit-inverse-hover active:bg-kit-inverse btn-solid",
22
+ accent: "bg-kit-accent text-kit-accent-on shadow-kit-xs hover:bg-kit-accent-hover btn-solid",
22
23
  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
24
  ghost: "text-kit-fg-2 hover:bg-kit-hover hover:text-kit-fg active:bg-kit-selected",
24
25
  soft: "bg-kit-muted text-kit-fg hover:bg-kit-selected",
@@ -44,7 +45,6 @@ var buttonVariants = variants("relative inline-flex items-center justify-center
44
45
  size: "md"
45
46
  }
46
47
  });
47
- var SOLID_DISABLED = "[.dark_&]:disabled:bg-[#2a2a2d] [.dark_&]:disabled:text-[#9e9ea1] [.dark_&]:disabled:opacity-100 [.dark_&]:disabled:shadow-none";
48
48
  function mergeRefs(...refs) {
49
49
  return (node) => {
50
50
  for (const ref of refs) if (typeof ref === "function") ref(node);
@@ -55,7 +55,7 @@ var Button = React.forwardRef(({ className, variant, size, asChild, loading, lef
55
55
  const classes = cn(buttonVariants({
56
56
  variant,
57
57
  size
58
- }), (variant === "primary" || variant === "accent") && SOLID_DISABLED, className);
58
+ }), className);
59
59
  if (asChild && React.isValidElement(children)) return React.cloneElement(children, {
60
60
  ...props,
61
61
  ...children.props,
@@ -70,10 +70,7 @@ var Button = React.forwardRef(({ className, variant, size, asChild, loading, lef
70
70
  className: classes,
71
71
  ...props,
72
72
  children: [
73
- loading ? /* @__PURE__ */ jsx(IconLoader2, {
74
- className: "animate-spin",
75
- "aria-hidden": true
76
- }) : leftIcon,
73
+ loading ? /* @__PURE__ */ jsx(Spinner, {}) : leftIcon,
77
74
  variant === "ai" && !leftIcon && !loading ? /* @__PURE__ */ jsx(Sparkle, {}) : null,
78
75
  children,
79
76
  rightIcon
@@ -82,7 +79,7 @@ var Button = React.forwardRef(({ className, variant, size, asChild, loading, lef
82
79
  });
83
80
  Button.displayName = "Button";
84
81
  /** 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", {
82
+ 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
83
  variants: {
87
84
  size: {
88
85
  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 { IconPlus } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { SPARKLE_PATH } from \"../brand/logo\";\nimport { Spinner } from \"./spinner\";\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 {/* the kit Spinner (decorative: the button says it is busy); the size variant's [&_svg] rule sizes its glyph */}\n {loading ? <Spinner /> : 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