@logicplanes/kaeso-ui 0.4.3 → 0.4.5

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 (490) hide show
  1. package/ai/component-guides.md +279 -98
  2. package/ai/component-registry.json +352 -236
  3. package/ai/component-registry.md +241 -219
  4. package/ai/icons.md +2 -2
  5. package/ai/tokens.md +18 -14
  6. package/dist/blocks/delete-resource.js +3 -3
  7. package/dist/blocks/delete-resource.js.map +1 -1
  8. package/dist/blocks/pages.js +47 -42
  9. package/dist/blocks/pages.js.map +1 -1
  10. package/dist/blocks/resource-list.js +68 -55
  11. package/dist/blocks/resource-list.js.map +1 -1
  12. package/dist/chunks/agent-avatar-DHieggHK.js +188 -0
  13. package/dist/chunks/agent-avatar-DHieggHK.js.map +1 -0
  14. package/dist/chunks/app-frame-DysOel2X.js +232 -0
  15. package/dist/chunks/app-frame-DysOel2X.js.map +1 -0
  16. package/dist/chunks/arrow-focus-B0KdRFX8.js +20 -0
  17. package/dist/chunks/arrow-focus-B0KdRFX8.js.map +1 -0
  18. package/dist/chunks/avatar-CYNMK7uY.js +110 -0
  19. package/dist/chunks/avatar-CYNMK7uY.js.map +1 -0
  20. package/dist/chunks/badge-C0GC3B9X.js +27 -0
  21. package/dist/chunks/badge-C0GC3B9X.js.map +1 -0
  22. package/dist/chunks/banner-B3DGLTBu.js +88 -0
  23. package/dist/chunks/banner-B3DGLTBu.js.map +1 -0
  24. package/dist/chunks/button-IblhXUyZ.js +202 -0
  25. package/dist/chunks/button-IblhXUyZ.js.map +1 -0
  26. package/dist/chunks/{calendar-BWaf2MXc.js → calendar-Dc6_dl0f.js} +4 -4
  27. package/dist/chunks/calendar-Dc6_dl0f.js.map +1 -0
  28. package/dist/chunks/checkbox-9tbimmF3.js +141 -0
  29. package/dist/chunks/checkbox-9tbimmF3.js.map +1 -0
  30. package/dist/chunks/{cn-Dj6sRgkF.js → cn-BjnOAUrA.js} +45 -4
  31. package/dist/chunks/cn-BjnOAUrA.js.map +1 -0
  32. package/dist/chunks/code-block-64e-Cy1S.js +346 -0
  33. package/dist/chunks/code-block-64e-Cy1S.js.map +1 -0
  34. package/dist/chunks/code-block-KIvuE8jg.js +352 -0
  35. package/dist/chunks/code-block-KIvuE8jg.js.map +1 -0
  36. package/dist/chunks/{code-tqj0uhBL.js → code-xqjww4Pv.js} +5 -6
  37. package/dist/chunks/code-xqjww4Pv.js.map +1 -0
  38. package/dist/chunks/combobox-DkcjkWc6.js +352 -0
  39. package/dist/chunks/combobox-DkcjkWc6.js.map +1 -0
  40. package/dist/chunks/command-list-CypqsC4T.js +456 -0
  41. package/dist/chunks/command-list-CypqsC4T.js.map +1 -0
  42. package/dist/chunks/{copy-button-FJvPJn72.js → copy-button-CwU8t_9_.js} +22 -15
  43. package/dist/chunks/copy-button-CwU8t_9_.js.map +1 -0
  44. package/dist/chunks/core-CmK-8ObW.js +505 -0
  45. package/dist/chunks/core-CmK-8ObW.js.map +1 -0
  46. package/dist/chunks/data-table-CqY8_6IS.js +581 -0
  47. package/dist/chunks/data-table-CqY8_6IS.js.map +1 -0
  48. package/dist/chunks/date-popup-DAnjptFt.js +58 -0
  49. package/dist/chunks/date-popup-DAnjptFt.js.map +1 -0
  50. package/dist/chunks/{de-CPXJh9cq.js → de-CqC4aSIV.js} +81 -40
  51. package/dist/chunks/de-CqC4aSIV.js.map +1 -0
  52. package/dist/chunks/{dialog-Cg9A_6SF.js → dialog-2zb6ClNR.js} +156 -134
  53. package/dist/chunks/dialog-2zb6ClNR.js.map +1 -0
  54. package/dist/chunks/disclosure-BtYRTDO3.js +22 -0
  55. package/dist/chunks/disclosure-BtYRTDO3.js.map +1 -0
  56. package/dist/chunks/domain-obd_w9xk.js +28 -0
  57. package/dist/chunks/domain-obd_w9xk.js.map +1 -0
  58. package/dist/chunks/{empty-DvhyMXQq.js → empty-BpiUgGzm.js} +2 -2
  59. package/dist/chunks/{empty-DvhyMXQq.js.map → empty-BpiUgGzm.js.map} +1 -1
  60. package/dist/chunks/{field-TviMvYa2.js → field-D7m-yl-D.js} +37 -34
  61. package/dist/chunks/field-D7m-yl-D.js.map +1 -0
  62. package/dist/chunks/{icon-D7ja-_Yk.js → icon-CBzOwqrX.js} +7 -6
  63. package/dist/chunks/{icon-D7ja-_Yk.js.map → icon-CBzOwqrX.js.map} +1 -1
  64. package/dist/chunks/icon-CPJWE2N-.js +95 -0
  65. package/dist/chunks/{icon-DVooQfk4.js.map → icon-CPJWE2N-.js.map} +1 -1
  66. package/dist/chunks/{icon-button-CrdF_eMG.js → icon-button-Dfwpvmav.js} +7 -6
  67. package/dist/chunks/icon-button-Dfwpvmav.js.map +1 -0
  68. package/dist/chunks/{identity-BmhQ6BQ-.js → identity-3Foi5F8w.js} +7 -7
  69. package/dist/chunks/{identity-BmhQ6BQ-.js.map → identity-3Foi5F8w.js.map} +1 -1
  70. package/dist/chunks/{input-2VJuj_M4.js → input-Bo5-UZg2.js} +15 -9
  71. package/dist/chunks/input-Bo5-UZg2.js.map +1 -0
  72. package/dist/chunks/{input-group-DQ_4DoXg.js → input-group-jPcK9T_a.js} +42 -29
  73. package/dist/chunks/input-group-jPcK9T_a.js.map +1 -0
  74. package/dist/chunks/iso-field-DoqHBg8n.js +52 -0
  75. package/dist/chunks/iso-field-DoqHBg8n.js.map +1 -0
  76. package/dist/chunks/json-view-DZ2nL2Ir.js +253 -0
  77. package/dist/chunks/json-view-DZ2nL2Ir.js.map +1 -0
  78. package/dist/chunks/{kbd-BF1vKXJf.js → kbd-8A0ML_up.js} +30 -28
  79. package/dist/chunks/kbd-8A0ML_up.js.map +1 -0
  80. package/dist/chunks/label-DW24Aj0Z.js +26 -0
  81. package/dist/chunks/label-DW24Aj0Z.js.map +1 -0
  82. package/dist/chunks/{link-KWI7PevW.js → link-CMjkcLQK.js} +14 -14
  83. package/dist/chunks/link-CMjkcLQK.js.map +1 -0
  84. package/dist/chunks/list-B4G-sWwV.js +540 -0
  85. package/dist/chunks/list-B4G-sWwV.js.map +1 -0
  86. package/dist/chunks/{loader-DCfPndXa.js → loader-zo8CCIGJ.js} +2 -2
  87. package/dist/chunks/{loader-DCfPndXa.js.map → loader-zo8CCIGJ.js.map} +1 -1
  88. package/dist/chunks/markdown-C565aBR7.js +338 -0
  89. package/dist/chunks/markdown-C565aBR7.js.map +1 -0
  90. package/dist/chunks/menu-Clvv6ftq.js +485 -0
  91. package/dist/chunks/menu-Clvv6ftq.js.map +1 -0
  92. package/dist/chunks/merge-refs-BN1FyQt9.js +20 -0
  93. package/dist/chunks/merge-refs-BN1FyQt9.js.map +1 -0
  94. package/dist/chunks/meter-CASMHlxl.js +100 -0
  95. package/dist/chunks/meter-CASMHlxl.js.map +1 -0
  96. package/dist/chunks/nav-sheet-Dt6JSvzX.js +67 -0
  97. package/dist/chunks/nav-sheet-Dt6JSvzX.js.map +1 -0
  98. package/dist/chunks/{nav-wordmark-_pjheAsZ.js → nav-wordmark-J4pB_vjr.js} +4 -8
  99. package/dist/chunks/nav-wordmark-J4pB_vjr.js.map +1 -0
  100. package/dist/chunks/page-header-kS5tdmvb.js +45 -0
  101. package/dist/chunks/page-header-kS5tdmvb.js.map +1 -0
  102. package/dist/chunks/pagination-D7fAm8qg.js +147 -0
  103. package/dist/chunks/pagination-D7fAm8qg.js.map +1 -0
  104. package/dist/chunks/picker-popover-1FHb1LQG.js +119 -0
  105. package/dist/chunks/picker-popover-1FHb1LQG.js.map +1 -0
  106. package/dist/chunks/popover-Bl5QYqnh.js +51 -0
  107. package/dist/chunks/popover-Bl5QYqnh.js.map +1 -0
  108. package/dist/chunks/{portal-context-BBbzDKmY.js → portal-context-CTatR2Z8.js} +14 -4
  109. package/dist/chunks/portal-context-CTatR2Z8.js.map +1 -0
  110. package/dist/chunks/{radio-CDDFpdtL.js → radio-C6GtzF_t.js} +38 -23
  111. package/dist/chunks/radio-C6GtzF_t.js.map +1 -0
  112. package/dist/chunks/range-popup-lGiZsG3s.js +160 -0
  113. package/dist/chunks/range-popup-lGiZsG3s.js.map +1 -0
  114. package/dist/chunks/reasoning-frame-C3HdQRRS.js +51 -0
  115. package/dist/chunks/reasoning-frame-C3HdQRRS.js.map +1 -0
  116. package/dist/chunks/release-art-ChiT4T2S.js +582 -0
  117. package/dist/chunks/release-art-ChiT4T2S.js.map +1 -0
  118. package/dist/chunks/rights-B68ocZuq.js +312 -0
  119. package/dist/chunks/rights-B68ocZuq.js.map +1 -0
  120. package/dist/chunks/{scroll-area-D8MD7Vpo.js → scroll-area-_Ljh4-bG.js} +11 -6
  121. package/dist/chunks/scroll-area-_Ljh4-bG.js.map +1 -0
  122. package/dist/chunks/section-CFBYhsUi.js +77 -0
  123. package/dist/chunks/section-CFBYhsUi.js.map +1 -0
  124. package/dist/chunks/section-header-DU1Q4Tdf.js +28 -0
  125. package/dist/chunks/section-header-DU1Q4Tdf.js.map +1 -0
  126. package/dist/chunks/segmented-D9i1avik.js +119 -0
  127. package/dist/chunks/segmented-D9i1avik.js.map +1 -0
  128. package/dist/chunks/select-BqjmQOqx.js +222 -0
  129. package/dist/chunks/select-BqjmQOqx.js.map +1 -0
  130. package/dist/chunks/{separator-D7TzNHmX.js → separator-BNWf6BBj.js} +13 -8
  131. package/dist/chunks/separator-BNWf6BBj.js.map +1 -0
  132. package/dist/chunks/sidebar-Dq7oGOje.js +664 -0
  133. package/dist/chunks/sidebar-Dq7oGOje.js.map +1 -0
  134. package/dist/chunks/{sidebar-menu-BN3jkTlK.js → sidebar-menu-QSSNu1jJ.js} +2 -2
  135. package/dist/chunks/{sidebar-menu-BN3jkTlK.js.map → sidebar-menu-QSSNu1jJ.js.map} +1 -1
  136. package/dist/chunks/{skeleton-Dcz57Zyp.js → skeleton-D-qk3mes.js} +3 -3
  137. package/dist/chunks/skeleton-D-qk3mes.js.map +1 -0
  138. package/dist/chunks/slider-CcE8GtuV.js +58 -0
  139. package/dist/chunks/slider-CcE8GtuV.js.map +1 -0
  140. package/dist/chunks/{status-dot-QJTF0Yv4.js → status-dot-CP6runiC.js} +4 -4
  141. package/dist/chunks/{status-dot-QJTF0Yv4.js.map → status-dot-CP6runiC.js.map} +1 -1
  142. package/dist/chunks/{styles-CVJU9t9v.js → styles-hkFkoBbi.js} +2 -2
  143. package/dist/chunks/{styles-CVJU9t9v.js.map → styles-hkFkoBbi.js.map} +1 -1
  144. package/dist/chunks/{swap-text-Dr0Irxz6.js → swap-text-SlUjrTlG.js} +3 -3
  145. package/dist/chunks/swap-text-SlUjrTlG.js.map +1 -0
  146. package/dist/chunks/switch-ngywMQdl.js +76 -0
  147. package/dist/chunks/switch-ngywMQdl.js.map +1 -0
  148. package/dist/chunks/table-CTK5E0J7.js +102 -0
  149. package/dist/chunks/table-CTK5E0J7.js.map +1 -0
  150. package/dist/chunks/tag-BGr6lTSV.js +100 -0
  151. package/dist/chunks/tag-BGr6lTSV.js.map +1 -0
  152. package/dist/chunks/{text-CIXH8rmT.js → text-DkKdTVUf.js} +9 -9
  153. package/dist/chunks/text-DkKdTVUf.js.map +1 -0
  154. package/dist/chunks/{textarea--4FRL3Pb.js → textarea-CO0HP6fK.js} +47 -36
  155. package/dist/chunks/textarea-CO0HP6fK.js.map +1 -0
  156. package/dist/chunks/timeseries-Ck-q0wWn.js +381 -0
  157. package/dist/chunks/timeseries-Ck-q0wWn.js.map +1 -0
  158. package/dist/chunks/toolbar-u0Gm7Q7-.js +61 -0
  159. package/dist/chunks/toolbar-u0Gm7Q7-.js.map +1 -0
  160. package/dist/chunks/tooltip-Tkm-urbi.js +202 -0
  161. package/dist/chunks/tooltip-Tkm-urbi.js.map +1 -0
  162. package/dist/chunks/tooltip-root-BC_RNNiP.js +70 -0
  163. package/dist/chunks/tooltip-root-BC_RNNiP.js.map +1 -0
  164. package/dist/chunks/truncated-d1afmUJT.js +33 -0
  165. package/dist/chunks/truncated-d1afmUJT.js.map +1 -0
  166. package/dist/chunks/use-coarse-pointer-Ml5oE6oX.js +28 -0
  167. package/dist/chunks/use-coarse-pointer-Ml5oE6oX.js.map +1 -0
  168. package/dist/chunks/use-hydrating-COtYVRo4.js +8 -0
  169. package/dist/chunks/use-hydrating-COtYVRo4.js.map +1 -0
  170. package/dist/chunks/use-scroll-fade-uc8mWSDX.js +30 -0
  171. package/dist/chunks/use-scroll-fade-uc8mWSDX.js.map +1 -0
  172. package/dist/chunks/{zh-CN-29X4CDLE.js → zh-CN-BlpsT6d_.js} +80 -39
  173. package/dist/chunks/zh-CN-BlpsT6d_.js.map +1 -0
  174. package/dist/components/agent-avatar.js +1 -1
  175. package/dist/components/app-frame.js +2 -2
  176. package/dist/components/avatar.js +1 -1
  177. package/dist/components/badge.js +1 -1
  178. package/dist/components/banner.js +1 -1
  179. package/dist/components/button-group.js +22 -22
  180. package/dist/components/button-group.js.map +1 -1
  181. package/dist/components/button.js +1 -1
  182. package/dist/components/calendar.js +1 -1
  183. package/dist/components/charts/bar.js +235 -160
  184. package/dist/components/charts/bar.js.map +1 -1
  185. package/dist/components/charts/donut.js +144 -99
  186. package/dist/components/charts/donut.js.map +1 -1
  187. package/dist/components/charts/gauge.js +61 -49
  188. package/dist/components/charts/gauge.js.map +1 -1
  189. package/dist/components/charts/heatmap.js +179 -70
  190. package/dist/components/charts/heatmap.js.map +1 -1
  191. package/dist/components/charts/sankey.js +144 -77
  192. package/dist/components/charts/sankey.js.map +1 -1
  193. package/dist/components/charts/sparkline.js +54 -38
  194. package/dist/components/charts/sparkline.js.map +1 -1
  195. package/dist/components/charts/timeseries.js +1 -1
  196. package/dist/components/charts.js +2 -2
  197. package/dist/components/checkbox.js +1 -1
  198. package/dist/components/code-block.js +4 -3
  199. package/dist/components/code.js +1 -1
  200. package/dist/components/collapsible.js +77 -1
  201. package/dist/components/collapsible.js.map +1 -0
  202. package/dist/components/combobox.js +1 -1
  203. package/dist/components/command-list.js +2 -2
  204. package/dist/components/command-palette.js +89 -66
  205. package/dist/components/command-palette.js.map +1 -1
  206. package/dist/components/copy-button.js +1 -1
  207. package/dist/components/data-table.js +1 -459
  208. package/dist/components/date-picker.js +162 -151
  209. package/dist/components/date-picker.js.map +1 -1
  210. package/dist/components/dialog.js +74 -63
  211. package/dist/components/dialog.js.map +1 -1
  212. package/dist/components/display-options.js +76 -64
  213. package/dist/components/display-options.js.map +1 -1
  214. package/dist/components/empty.js +1 -1
  215. package/dist/components/field.js +1 -1
  216. package/dist/components/figure.js +2 -2
  217. package/dist/components/filter-chip.js +36 -27
  218. package/dist/components/filter-chip.js.map +1 -1
  219. package/dist/components/filter-row.js +4 -4
  220. package/dist/components/filter-row.js.map +1 -1
  221. package/dist/components/flow.js +94 -63
  222. package/dist/components/flow.js.map +1 -1
  223. package/dist/components/heading.js +1 -1
  224. package/dist/components/icon-button.js +1 -1
  225. package/dist/components/icon.js +2 -2
  226. package/dist/components/input.js +176 -98
  227. package/dist/components/input.js.map +1 -1
  228. package/dist/components/kaeso/conversation.js +51 -46
  229. package/dist/components/kaeso/conversation.js.map +1 -1
  230. package/dist/components/kaeso/identity.js +1 -1
  231. package/dist/components/kaeso/moments.js +23 -20
  232. package/dist/components/kaeso/moments.js.map +1 -1
  233. package/dist/components/kaeso/rights.js +1 -1
  234. package/dist/components/kaeso/usage.js +90 -74
  235. package/dist/components/kaeso/usage.js.map +1 -1
  236. package/dist/components/kaeso.js +200 -187
  237. package/dist/components/kaeso.js.map +1 -1
  238. package/dist/components/kbd.js +1 -1
  239. package/dist/components/key-value.js +32 -47
  240. package/dist/components/key-value.js.map +1 -1
  241. package/dist/components/label.js +1 -25
  242. package/dist/components/layout.js +2 -2
  243. package/dist/components/layout.js.map +1 -1
  244. package/dist/components/link.js +1 -1
  245. package/dist/components/list.js +1 -1
  246. package/dist/components/loader.js +11 -10
  247. package/dist/components/loader.js.map +1 -1
  248. package/dist/components/logo.js +2 -2
  249. package/dist/components/markdown.js +1 -1
  250. package/dist/components/menu.js +2 -2
  251. package/dist/components/meter.js +1 -1
  252. package/dist/components/page-header.js +1 -1
  253. package/dist/components/pagination.js +1 -1
  254. package/dist/components/playground.js +644 -529
  255. package/dist/components/playground.js.map +1 -1
  256. package/dist/components/popover.js +4 -4
  257. package/dist/components/popover.js.map +1 -1
  258. package/dist/components/portal.js +1 -1
  259. package/dist/components/qr-code.js +2 -2
  260. package/dist/components/qr-code.js.map +1 -1
  261. package/dist/components/radio.js +1 -1
  262. package/dist/components/release-art.js +1 -1
  263. package/dist/components/scroll-area.js +1 -1
  264. package/dist/components/section.js +1 -1
  265. package/dist/components/segmented.js +1 -1
  266. package/dist/components/select.js +1 -1
  267. package/dist/components/separator.js +1 -1
  268. package/dist/components/settings.js +39 -46
  269. package/dist/components/settings.js.map +1 -1
  270. package/dist/components/sheet.js +10 -9
  271. package/dist/components/sheet.js.map +1 -1
  272. package/dist/components/sidebar.js +1 -1
  273. package/dist/components/skeleton.js +1 -1
  274. package/dist/components/slider.js +1 -1
  275. package/dist/components/stat.js +98 -84
  276. package/dist/components/stat.js.map +1 -1
  277. package/dist/components/status-dot.js +1 -1
  278. package/dist/components/surface.js +1 -1
  279. package/dist/components/swap-text.js +1 -1
  280. package/dist/components/switch.js +1 -1
  281. package/dist/components/table.js +1 -1
  282. package/dist/components/tabs.js +73 -55
  283. package/dist/components/tabs.js.map +1 -1
  284. package/dist/components/tag.js +1 -1
  285. package/dist/components/text.js +1 -1
  286. package/dist/components/theme-image.js +1 -1
  287. package/dist/components/theme-menu.js +5 -2
  288. package/dist/components/theme-menu.js.map +1 -1
  289. package/dist/components/theme-select.js +1 -1
  290. package/dist/components/thumbnail.js +35 -24
  291. package/dist/components/thumbnail.js.map +1 -1
  292. package/dist/components/timeline.js +51 -35
  293. package/dist/components/timeline.js.map +1 -1
  294. package/dist/components/toast.js +76 -66
  295. package/dist/components/toast.js.map +1 -1
  296. package/dist/components/toc.js +14 -8
  297. package/dist/components/toc.js.map +1 -1
  298. package/dist/components/toolbar.js +1 -1
  299. package/dist/components/tooltip.js +1 -1
  300. package/dist/components/visually-hidden.js +1 -1
  301. package/dist/i18n-provider.js +1 -1
  302. package/dist/index.js +101 -101
  303. package/dist/kaeso.css +605 -67
  304. package/dist/styles.css +1 -1
  305. package/dist/tailwind.css +1 -1
  306. package/dist/types/blocks/delete-resource/delete-resource.d.ts +2 -2
  307. package/dist/types/components/agent-avatar/agent-avatar.d.ts +24 -19
  308. package/dist/types/components/badge/badge.d.ts +3 -3
  309. package/dist/types/components/banner/banner.d.ts +3 -3
  310. package/dist/types/components/button/button.d.ts +2 -2
  311. package/dist/types/components/button-group/button-group.d.ts +1 -1
  312. package/dist/types/components/charts/domain.d.ts +11 -0
  313. package/dist/types/components/charts/marks.d.ts +1 -0
  314. package/dist/types/components/code/code.d.ts +3 -3
  315. package/dist/types/components/code-block/diff-view.d.ts +30 -0
  316. package/dist/types/components/code-block/diff.d.ts +26 -0
  317. package/dist/types/components/code-block/docs.d.ts +14 -0
  318. package/dist/types/components/code-block/index.d.ts +1 -0
  319. package/dist/types/components/code-block/json-view.d.ts +2 -1
  320. package/dist/types/components/code-block/numbers.d.ts +1 -0
  321. package/dist/types/components/collapsible/collapsible.d.ts +2 -2
  322. package/dist/types/components/collapsible/disclosure.d.ts +2 -0
  323. package/dist/types/components/data-table/data-table.d.ts +6 -5
  324. package/dist/types/components/data-table/docs.d.ts +1 -0
  325. package/dist/types/components/data-table/time-columns.d.ts +1 -0
  326. package/dist/types/components/date-picker/focus-day.d.ts +1 -0
  327. package/dist/types/components/date-picker/iso-field.d.ts +8 -1
  328. package/dist/types/components/dialog/dialog.d.ts +7 -7
  329. package/dist/types/components/field/field.d.ts +1 -1
  330. package/dist/types/components/flow/flow.d.ts +1 -1
  331. package/dist/types/components/icon-button/icon-button.d.ts +1 -1
  332. package/dist/types/components/input/input-group.d.ts +2 -0
  333. package/dist/types/components/input/number-input.d.ts +4 -4
  334. package/dist/types/components/input/otp-input.d.ts +3 -3
  335. package/dist/types/components/kaeso/client-button.d.ts +2 -1
  336. package/dist/types/components/kaeso/provider-picker.d.ts +1 -0
  337. package/dist/types/components/kaeso/rights.d.ts +1 -1
  338. package/dist/types/components/kaeso/role-picker.d.ts +1 -0
  339. package/dist/types/components/key-value/key-value.d.ts +2 -2
  340. package/dist/types/components/layout/layout.d.ts +2 -2
  341. package/dist/types/components/link/link.d.ts +4 -4
  342. package/dist/types/components/list/list.d.ts +2 -2
  343. package/dist/types/components/menu/menu.d.ts +2 -1
  344. package/dist/types/components/menu/styles.d.ts +3 -3
  345. package/dist/types/components/meter/meter.d.ts +3 -3
  346. package/dist/types/components/page-header/page-header.d.ts +1 -1
  347. package/dist/types/components/pagination/pagination.d.ts +2 -2
  348. package/dist/types/components/playground/prompt-suggestions.d.ts +1 -0
  349. package/dist/types/components/playground/reasoning-frame.d.ts +14 -0
  350. package/dist/types/components/playground/reasoning.d.ts +1 -0
  351. package/dist/types/components/popover/popover.d.ts +1 -1
  352. package/dist/types/components/scroll-area/scroll-area.d.ts +2 -2
  353. package/dist/types/components/section/section-header.d.ts +6 -0
  354. package/dist/types/components/segmented/segmented.d.ts +1 -0
  355. package/dist/types/components/select/select.d.ts +1 -1
  356. package/dist/types/components/sheet/sheet.d.ts +3 -3
  357. package/dist/types/components/sidebar/sidebar.d.ts +1 -0
  358. package/dist/types/components/slider/slider.d.ts +2 -2
  359. package/dist/types/components/stat/stat.d.ts +1 -1
  360. package/dist/types/components/tabs/tabs.d.ts +6 -4
  361. package/dist/types/components/text/truncated.d.ts +7 -0
  362. package/dist/types/components/timeline/timeline.d.ts +5 -5
  363. package/dist/types/components/toc/toc.d.ts +1 -1
  364. package/dist/types/components/toolbar/toolbar.d.ts +1 -1
  365. package/dist/types/components/tooltip/tooltip.d.ts +2 -2
  366. package/dist/types/components/tooltip/trigger-props.d.ts +1 -0
  367. package/dist/types/hooks/use-coarse-pointer.d.ts +1 -0
  368. package/dist/types/hooks/use-hydrating.d.ts +1 -0
  369. package/dist/types/icons/groups.d.ts +1 -1
  370. package/dist/types/icons/vocabulary.d.ts +5 -0
  371. package/dist/types/utils/arrow-focus.d.ts +4 -1
  372. package/dist/types/utils/cn.d.ts +33 -0
  373. package/dist/types/utils/portal-context.d.ts +7 -1
  374. package/dist/utils.js +2 -2
  375. package/foundations/accessibility.md +3 -2
  376. package/foundations/color.md +5 -1
  377. package/foundations/elevation.md +1 -0
  378. package/foundations/motion.md +1 -1
  379. package/foundations/shape.md +2 -2
  380. package/foundations/typography.md +12 -12
  381. package/package.json +2 -2
  382. package/dist/chunks/agent-avatar-0pdBTWkR.js +0 -171
  383. package/dist/chunks/agent-avatar-0pdBTWkR.js.map +0 -1
  384. package/dist/chunks/app-frame-DogGRmsu.js +0 -221
  385. package/dist/chunks/app-frame-DogGRmsu.js.map +0 -1
  386. package/dist/chunks/arrow-focus-BcySmwwU.js +0 -11
  387. package/dist/chunks/arrow-focus-BcySmwwU.js.map +0 -1
  388. package/dist/chunks/avatar-CWbdwbJv.js +0 -83
  389. package/dist/chunks/avatar-CWbdwbJv.js.map +0 -1
  390. package/dist/chunks/badge-C2KtxCLB.js +0 -26
  391. package/dist/chunks/badge-C2KtxCLB.js.map +0 -1
  392. package/dist/chunks/banner-BA2ALw9M.js +0 -85
  393. package/dist/chunks/banner-BA2ALw9M.js.map +0 -1
  394. package/dist/chunks/button-CzuxqawA.js +0 -164
  395. package/dist/chunks/button-CzuxqawA.js.map +0 -1
  396. package/dist/chunks/calendar-BWaf2MXc.js.map +0 -1
  397. package/dist/chunks/checkbox-CQjwCPkc.js +0 -126
  398. package/dist/chunks/checkbox-CQjwCPkc.js.map +0 -1
  399. package/dist/chunks/cn-Dj6sRgkF.js.map +0 -1
  400. package/dist/chunks/code-block-D5A-CGXG.js +0 -330
  401. package/dist/chunks/code-block-D5A-CGXG.js.map +0 -1
  402. package/dist/chunks/code-tqj0uhBL.js.map +0 -1
  403. package/dist/chunks/collapsible-CKrCX_T9.js +0 -87
  404. package/dist/chunks/collapsible-CKrCX_T9.js.map +0 -1
  405. package/dist/chunks/combobox-DjDI7SUC.js +0 -319
  406. package/dist/chunks/combobox-DjDI7SUC.js.map +0 -1
  407. package/dist/chunks/command-list-C2Y7V_lt.js +0 -418
  408. package/dist/chunks/command-list-C2Y7V_lt.js.map +0 -1
  409. package/dist/chunks/copy-button-FJvPJn72.js.map +0 -1
  410. package/dist/chunks/core-BYns5ytV.js +0 -472
  411. package/dist/chunks/core-BYns5ytV.js.map +0 -1
  412. package/dist/chunks/date-popup-CPA_zt6o.js +0 -35
  413. package/dist/chunks/date-popup-CPA_zt6o.js.map +0 -1
  414. package/dist/chunks/de-CPXJh9cq.js.map +0 -1
  415. package/dist/chunks/dialog-Cg9A_6SF.js.map +0 -1
  416. package/dist/chunks/field-TviMvYa2.js.map +0 -1
  417. package/dist/chunks/hidden-description-B2zSmLcn.js +0 -23
  418. package/dist/chunks/hidden-description-B2zSmLcn.js.map +0 -1
  419. package/dist/chunks/icon-DVooQfk4.js +0 -94
  420. package/dist/chunks/icon-button-CrdF_eMG.js.map +0 -1
  421. package/dist/chunks/input-2VJuj_M4.js.map +0 -1
  422. package/dist/chunks/input-group-DQ_4DoXg.js.map +0 -1
  423. package/dist/chunks/iso-field-B2rTwiBo.js +0 -33
  424. package/dist/chunks/iso-field-B2rTwiBo.js.map +0 -1
  425. package/dist/chunks/json-view-Dqd2TDkc.js +0 -175
  426. package/dist/chunks/json-view-Dqd2TDkc.js.map +0 -1
  427. package/dist/chunks/kbd-BF1vKXJf.js.map +0 -1
  428. package/dist/chunks/link-KWI7PevW.js.map +0 -1
  429. package/dist/chunks/list-M1csq-d4.js +0 -494
  430. package/dist/chunks/list-M1csq-d4.js.map +0 -1
  431. package/dist/chunks/markdown-DULktoTK.js +0 -313
  432. package/dist/chunks/markdown-DULktoTK.js.map +0 -1
  433. package/dist/chunks/menu-DEmBfdPm.js +0 -450
  434. package/dist/chunks/menu-DEmBfdPm.js.map +0 -1
  435. package/dist/chunks/meter-Bj4N3Xuh.js +0 -84
  436. package/dist/chunks/meter-Bj4N3Xuh.js.map +0 -1
  437. package/dist/chunks/nav-sheet-CzgIwgAm.js +0 -60
  438. package/dist/chunks/nav-sheet-CzgIwgAm.js.map +0 -1
  439. package/dist/chunks/nav-wordmark-_pjheAsZ.js.map +0 -1
  440. package/dist/chunks/page-header-DL2y2iZp.js +0 -41
  441. package/dist/chunks/page-header-DL2y2iZp.js.map +0 -1
  442. package/dist/chunks/pagination-Cn_qF4cg.js +0 -86
  443. package/dist/chunks/pagination-Cn_qF4cg.js.map +0 -1
  444. package/dist/chunks/picker-popover-BxyU1U9F.js +0 -106
  445. package/dist/chunks/picker-popover-BxyU1U9F.js.map +0 -1
  446. package/dist/chunks/popover-DNN4S47w.js +0 -50
  447. package/dist/chunks/popover-DNN4S47w.js.map +0 -1
  448. package/dist/chunks/portal-context-BBbzDKmY.js.map +0 -1
  449. package/dist/chunks/radio-CDDFpdtL.js.map +0 -1
  450. package/dist/chunks/range-popup-CRyWYUB1.js +0 -128
  451. package/dist/chunks/range-popup-CRyWYUB1.js.map +0 -1
  452. package/dist/chunks/release-art-ZwfFQImt.js +0 -561
  453. package/dist/chunks/release-art-ZwfFQImt.js.map +0 -1
  454. package/dist/chunks/rights-Cyp0Pzp-.js +0 -279
  455. package/dist/chunks/rights-Cyp0Pzp-.js.map +0 -1
  456. package/dist/chunks/scroll-area-D8MD7Vpo.js.map +0 -1
  457. package/dist/chunks/scroll-parent-WXvzQcUo.js +0 -14
  458. package/dist/chunks/scroll-parent-WXvzQcUo.js.map +0 -1
  459. package/dist/chunks/section-Ce1efbsP.js +0 -87
  460. package/dist/chunks/section-Ce1efbsP.js.map +0 -1
  461. package/dist/chunks/segmented-CErcoxwi.js +0 -114
  462. package/dist/chunks/segmented-CErcoxwi.js.map +0 -1
  463. package/dist/chunks/select-x4XVsdCI.js +0 -210
  464. package/dist/chunks/select-x4XVsdCI.js.map +0 -1
  465. package/dist/chunks/separator-D7TzNHmX.js.map +0 -1
  466. package/dist/chunks/sidebar-3r1ZRXlN.js +0 -621
  467. package/dist/chunks/sidebar-3r1ZRXlN.js.map +0 -1
  468. package/dist/chunks/skeleton-Dcz57Zyp.js.map +0 -1
  469. package/dist/chunks/slider-Ci83PGtj.js +0 -57
  470. package/dist/chunks/slider-Ci83PGtj.js.map +0 -1
  471. package/dist/chunks/swap-text-Dr0Irxz6.js.map +0 -1
  472. package/dist/chunks/switch-BNMq_kGt.js +0 -59
  473. package/dist/chunks/switch-BNMq_kGt.js.map +0 -1
  474. package/dist/chunks/table-BeOSKl_3.js +0 -84
  475. package/dist/chunks/table-BeOSKl_3.js.map +0 -1
  476. package/dist/chunks/tag-D_M1s2qS.js +0 -87
  477. package/dist/chunks/tag-D_M1s2qS.js.map +0 -1
  478. package/dist/chunks/text-CIXH8rmT.js.map +0 -1
  479. package/dist/chunks/textarea--4FRL3Pb.js.map +0 -1
  480. package/dist/chunks/timeseries-D1xjRXfk.js +0 -339
  481. package/dist/chunks/timeseries-D1xjRXfk.js.map +0 -1
  482. package/dist/chunks/toolbar-WA_oZgu-.js +0 -37
  483. package/dist/chunks/toolbar-WA_oZgu-.js.map +0 -1
  484. package/dist/chunks/tooltip-OcwO0VUT.js +0 -154
  485. package/dist/chunks/tooltip-OcwO0VUT.js.map +0 -1
  486. package/dist/chunks/tooltip-root-DzahJDVj.js +0 -60
  487. package/dist/chunks/tooltip-root-DzahJDVj.js.map +0 -1
  488. package/dist/chunks/zh-CN-29X4CDLE.js.map +0 -1
  489. package/dist/components/data-table.js.map +0 -1
  490. package/dist/components/label.js.map +0 -1
@@ -1,29 +1,29 @@
1
1
  # @logicplanes/kaeso-ui component registry
2
2
 
3
- Version 0.4.3. Generated from the component types, their descriptions and variants; do not edit.
3
+ Version 0.4.5. Generated from the component types, their descriptions and variants; do not edit.
4
4
 
5
5
  ## agent-avatar
6
6
 
7
7
  `import { AgentAttribution, AgentAvatar } from "@logicplanes/kaeso-ui/agent-avatar";`
8
8
 
9
- - **size** (agent_attribution): `20` — 20px person, 10px agent badge; `24` (default) — 24px person, 12px agent badge (default); `28` — 28px person, 14px agent badge; `32` — 32px person, 16px agent badge; `40` — 40px person, 20px agent badge
9
+ - **size** (agent_attribution): `20` — 20px person, 8px agent badge; `24` (default) — 24px person, 10px agent badge (default); `28` — 28px person, 12px agent badge; `32` — 32px person, 12px agent badge; `40` — 40px person, 16px agent badge
10
10
  - **size** (agent_avatar): `20` — 20px; `24` (default) — 24px: rows and lists (default); `28` — 28px; `32` — 32px; `40` — 40px: an agent's own page, menus
11
11
 
12
12
  ### AgentAttribution
13
13
 
14
- A person's avatar with the agent that acted for them as a small badge on its corner, for audit rows and activity; it reads as one picture named after both. The badge stays inside the avatar's square, so a table cell never cuts it off.
14
+ A person's avatar with the agent that acted for them as a small round ink badge on its corner, for audit rows and activity; it reads as one picture named after both, and a tooltip says the same to the pointer. The badge is about 40% of the avatar and a 2px gap cut out of the face separates it on any surface; it stays inside the avatar's square, so a table cell never cuts it off.
15
15
 
16
16
  | Prop | Type | Default | Description |
17
17
  |---|---|---|---|
18
18
  | `agent` * | `{ name: string; model: string; }` | | The agent that acted, with its name and model family id from the API; the family is named in the accessible name only. |
19
19
  | `name` * | `string` | | The name of the person the agent acted for; it starts the accessible name, such as `Ada Okafor via Release helper (Claude)`. |
20
20
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
21
- | `size` | `24 \| 20 \| 28 \| 32 \| 40` | `24` | The diameter of the person's avatar in pixels; the agent badge is half of it. |
21
+ | `size` | `24 \| 20 \| 28 \| 32 \| 40` | `24` | The diameter of the person's avatar in pixels; the agent badge is about 40% of it (8 to 16px). |
22
22
  | `src` | `string` | | The person's picture; without one, or when it fails to load, their initials show. |
23
23
 
24
24
  ### AgentAvatar
25
25
 
26
- An agent acting for a person: one bot face on an ink square, the same for every agent; write its model family beside it with useModelName where it matters.
26
+ An agent acting for a person: one bot face on a `fill-3` square, the same for every agent (people are round, agents square); write its model family beside it with useModelName where it matters.
27
27
 
28
28
  | Prop | Type | Default | Description |
29
29
  |---|---|---|---|
@@ -63,7 +63,7 @@ The sidebar as a floating panel from the left edge (a peek): the mobile navigati
63
63
  | `children` * | `ReactNode` | | The navigation, usually the app's `Sidebar`. |
64
64
  | `onOpenChange` * | `(open: boolean) => void` | | Called when the navigation opens or closes. |
65
65
  | `open` * | `boolean` | | Whether the navigation is shown on phones. |
66
- | `peek` | `boolean` | `false` | Slides the sheet in a little, to hint that it can be opened. |
66
+ | `peek` | `boolean` | `false` | Shows the sheet as a preview that doesn't trap focus or dim the page, and closes when the pointer leaves it. |
67
67
  | `returnFocus` | `RefObject<HTMLElement \| null>` | | The element that gets focus back when the sheet closes. |
68
68
 
69
69
  ## avatar
@@ -75,7 +75,7 @@ The sidebar as a floating panel from the left edge (a peek): the mobile navigati
75
75
 
76
76
  ### Avatar
77
77
 
78
- The first letters of the first and last word; `max` 1 keeps only the first.
78
+ The first letters of the first and last word; `max` 1 keeps only the first. A photo gets a hairline so a light picture keeps its edge.
79
79
 
80
80
  | Prop | Type | Default | Description |
81
81
  |---|---|---|---|
@@ -88,25 +88,25 @@ The first letters of the first and last word; `max` 1 keeps only the first.
88
88
 
89
89
  ### AvatarGroup
90
90
 
91
- Overlapping avatars with a 2px panel ring and a "+3".
91
+ Overlapping avatars, each separated from the one under it by a 2px gap cut out of that avatar, so the gap shows whatever surface the group sits on (a hovered row, a card); then a "+3".
92
92
 
93
93
  | Prop | Type | Default | Description |
94
94
  |---|---|---|---|
95
95
  | `people` * | `{ name: string; src?: string \| undefined; }[]` | | The people to show, in order. |
96
96
  | `children` | `ReactNode` | | Content after the avatars, such as a button to invite more people. |
97
97
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
98
- | `max` | `number` | `4` | Show at most this many; the rest become "+3". |
98
+ | `max` | `number` | `4` | Show at most this many; the rest become "+3", which names them in a tooltip. |
99
99
  | `size` | `24 \| 20 \| 28 \| 32 \| 40` | `24` | The diameter of each avatar in pixels. |
100
100
 
101
101
  ## badge
102
102
 
103
103
  `import { Badge } from "@logicplanes/kaeso-ui/badge";`
104
104
 
105
- - **tone** (badge): `neutral` (default) — Neutral (default); `success` — Success; `warning` — Warning; `danger` — Danger; `info` — Information; `outline` — A ring only; `ink` — Inverted, for the one thing that must stand out
105
+ - **tone** (badge): `neutral` (default) — Neutral (default): fill-2, or the control fill on a hovered or selected row; `success` — Success; `warning` — Warning; `danger` — Danger; `info` — Information; `outline` — A ring only; `ink` — Inverted: at most one on a view, for the one thing that must stand out
106
106
 
107
107
  ### Badge
108
108
 
109
- A small pill label: 22px, 12/500. Words carry meaning; color supports them.
109
+ A small read-only pill label: 22px, 12/500, smaller than a Tag (24 or 28px) so a mark never looks like a control. Words carry meaning; color supports them. A label longer than its room ends in an ellipsis and shows in full in a tooltip. `ink` is for at most one badge on a view.
110
110
 
111
111
  | Prop | Type | Default | Description |
112
112
  |---|---|---|---|
@@ -118,20 +118,20 @@ A small pill label: 22px, 12/500. Words carry meaning; color supports them.
118
118
  `import { Banner } from "@logicplanes/kaeso-ui/banner";`
119
119
 
120
120
  - **tone** (banner): `neutral` (default) — A neutral notice (default); `info` — Information; `success` — Something worked; `warning` — Attention needed soon; `danger` — Something failed or will fail
121
- - **layout** (banner): `inline` (default) — Inside content: radius 14 (default); `full` — Across the top of the panel for global notices
121
+ - **layout** (banner): `inline` (default) — Inside content: radius 14, its icon 12px in, at least 56px tall with or without actions (default); `full` — Across the top of the panel for global notices: its icon on the 24px gutter
122
122
 
123
123
  ### Banner
124
124
 
125
- An inline notice: a tint, an icon, an optional title, the text, actions at the end. The banner is its own size container. From 480px inside its padding (the `banner` container size, `@banner:`) the actions sit on the right, centered on the title and text together, and the icon stays on the first line. Narrower (a phone) the actions go under the text, starting where the text starts: their 24px inset is the icon's 16px column and its 8px gap, which in the row is the gap before them.
125
+ An inline notice: a tint, an icon (none for a neutral notice, so it never looks like information), an optional title, the text, actions at the end. Inline, the icon sits 12px in and the banner is at least 56px tall, so banners with and without actions stack evenly; full width, the icon sits on the 24px gutter and the text 24px further in. The banner is its own size container. From 480px inside its padding (the `banner` container size, `@banner:`) the actions sit on the right, centered on the title and text together, and the icon stays on the first line. Narrower (a phone) the actions go under the text, starting where the text starts: their 24px inset is the icon's 16px column and its 8px gap, which in the row is the gap before them.
126
126
 
127
127
  | Prop | Type | Default | Description |
128
128
  |---|---|---|---|
129
129
  | `actions` | `ReactNode` | | sm pills: on the right, centered on the title and text; under the text when the banner is narrow. |
130
130
  | `children` | `ReactNode` | | The message, with actions if it needs them. |
131
131
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
132
- | `icon` | `IconSvgElement` | | An icon in place of the tone's own. |
132
+ | `icon` | `IconSvgElement` | | An icon in place of the tone's own; a neutral banner has none unless you pass one. |
133
133
  | `layout` | `"inline" \| "full"` | `inline` | Inside the content (`inline`) or across the full width of the panel (`full`). |
134
- | `onDismiss` | `(() => void)` | | Only informational banners can be dismissed. |
134
+ | `onDismiss` | `(() => void)` | | Shows a dismiss button on `neutral` and `info` banners. Success, warning and danger banners stay until their cause changes, so they ignore it and warn in development. |
135
135
  | `title` | `ReactNode` | | The banner's heading. |
136
136
  | `tone` | `"neutral" \| "success" \| "warning" \| "danger" \| "info"` | `neutral` | The kind of message, from neutral information to a danger warning. |
137
137
 
@@ -150,10 +150,10 @@ The button. Every one is a pill; icon-only buttons are circles (see `IconButton`
150
150
  | Prop | Type | Default | Description |
151
151
  |---|---|---|---|
152
152
  | `icon` * | `IconSvgElement` | | The only content of an icon button; give it an `aria-label`. |
153
- | `children` | `ReactNode` | | The button's label: a verb first, in sentence case. |
153
+ | `children` | `ReactNode` | | The button's label: a verb first, in sentence case. A label wider than its container is cut with an ellipsis and shown whole in a tooltip. |
154
154
  | `count` | `number` | | A count after the label. |
155
155
  | `data-force` | `string` | | Forces an interaction state for state matrices: `hover`, `pressed`, `focus`, `open`. |
156
- | `disabledReason` | `string` | | Why the button is disabled, shown as a tooltip. The button stays focusable so people can read it. |
156
+ | `disabledReason` | `string` | | Why the button is disabled, shown as a tooltip and read out as the button's description. The button stays focusable so people can reach it. |
157
157
  | `fullWidth` | `boolean` | | Fills the width of its container. |
158
158
  | `href` | `string` | | Renders a link that looks like the button. |
159
159
  | `leadingIcon` | `IconSvgElement` | | An icon before the text. |
@@ -162,7 +162,7 @@ The button. Every one is a pill; icon-only buttons are circles (see `IconButton`
162
162
  | `reserveLabels` | `ReactNode[]` | | Every label this button can show ("Copy key", "Copied"). The button keeps the width of the widest, so a state change never resizes it. |
163
163
  | `shape` | `"pill" \| "circle"` | | Icon-only buttons are circles and need an accessible name. |
164
164
  | `shortcut` | `string[] \| string[][]` | | A shortcut hint after the label (lg and xl, and in menus). |
165
- | `size` | `"md" \| "xs" \| "sm" \| "lg" \| "xl"` | | The height, from `xs` (24px) to `xl` (44px). |
165
+ | `size` | `"md" \| "xs" \| "sm" \| "lg" \| "xl"` | | The height, from `xs` (24px) to `xl` (48px). |
166
166
  | `target` | `string` | | Where the link opens, as on an `a` element. |
167
167
  | `trailingIcon` | `IconSvgElement` | | An icon after the text. |
168
168
  | `variant` | `"danger" \| "link" \| "secondary" \| "primary" \| "ghost" \| "quiet" \| "soft" \| "danger-secondary"` | | `primary` for the one main action of a view, `secondary` for others, `ghost` and `quiet` for toolbars and rows, `danger` for destructive actions. A ghost or quiet button at the end of a settings row's control pulls its padding past the row's edge, so its label ends where an outlined button's ring does. |
@@ -176,7 +176,7 @@ The button. Every one is a pill; icon-only buttons are circles (see `IconButton`
176
176
 
177
177
  ### ButtonGroup
178
178
 
179
- Related actions side by side: connected pills, or spaced with `attached={false}`.
179
+ Related actions side by side: connected pills, or spaced with `attached={false}`. An item with `pressed` is a toggle; pass `false` while it is off, and the selected item turns ink.
180
180
 
181
181
  | Prop | Type | Default | Description |
182
182
  |---|---|---|---|
@@ -224,31 +224,31 @@ The calendar: 36px day circles, today ringed, ranges as a continuous strip with
224
224
 
225
225
  ### BarChart
226
226
 
227
- Bars for comparing values across categories: grouped, stacked, or horizontal for rankings. The category under the pointer, or reached with the arrow keys, shows its tooltip.
227
+ Bars for comparing values across categories: grouped, stacked, or horizontal for rankings. The category under the pointer, or reached with the arrow keys, shows its tooltip; the legend pills show and hide series.
228
228
 
229
229
  | Prop | Type | Default | Description |
230
230
  |---|---|---|---|
231
231
  | `aria-label` * | `string` | | The chart's accessible name ("Requests by model"). |
232
232
  | `categories` * | `string[]` | | The names along the category axis, one per bar group, in order. They also head the tooltip and the data table. |
233
- | `series` * | `BarSeries[]` | | The bars' series, each with an `id`, a `label`, one value per category and an optional `color`. Colors otherwise come from the series order by `id`. |
233
+ | `series` * | `BarSeries[]` | | The bars' series, each with an `id`, a `label`, one value per category and an optional `color`. Colors otherwise come from the series order by `id`; one series takes series 1. Negative values grow down from the zero line. With two or more, the legend shows and hides them. |
234
234
  | `axisLabels` | `string[]` | | Shorter names under the bars, one per category ("3 Aug" for "Week of 3 Aug"); the tooltip, the table and screen readers keep the categories. Name the year where one begins ("Aug", "Dec", "2026", "Feb"), and pass `dates`: where the labels don't all fit, the axis keeps every nth, and keeps that one before the newest (`axisLabelIndexes`). |
235
235
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
236
236
  | `dates` | `readonly AxisDate[]` | | The day each category begins, one per category: a `Date`, or an ISO day ("2026-01-05"). Where the axis thins its labels, it keeps the ones where a year begins (the month after December, the first week in January), read from these, so every language keeps the same labels. |
237
- | `empty` | `boolean` | | Shows the empty state (`emptyText`) in place of the data. Pass it when the period has no data. |
237
+ | `empty` | `boolean` | | Shows the empty state (`emptyText`) in place of the data, over the baseline and the category axis. By default it shows when there is no value at all; zeros are data. |
238
238
  | `emptyText` | `ReactNode` | | What the empty state says. Defaults to "No data for this period" in the provider's language. |
239
- | `error` | `ReactNode` | | The data failed to load: the chart keeps its height, says so quietly and offers Try again. Errors are toasts, so the value isn't shown; toast the message where the request fails. |
240
- | `formatValue` | `((v: number) => string)` | `(v) => formatNumber(v)` | Formats values on the axis and in the tooltip. |
239
+ | `error` | `ReactNode` | | The data failed to load: the chart keeps its height, hides its legend and table toggle, and says so quietly, with Try again when there is `onRetry` and otherwise a hint to reload the page. Errors are toasts, so the value isn't shown; pass `true` and toast the message where the request fails. |
240
+ | `formatValue` | `((v: number) => string)` | | Formats values in the tooltip, the table and beside horizontal bars. Without it, values are written in full and the axis in short form (1.2M); the axis takes the room its widest label needs, and long category names in a ranking end in an ellipsis with the full name on hover. |
241
241
  | `height` | `number` | `240` | The plot's height in px (240 by default). |
242
242
  | `highlight` | `number` | | Highlight a category as the pointer does, with its tooltip: a linked view, or the states pages. |
243
243
  | `layout` | `"horizontal" \| "grouped" \| "stacked"` | `grouped` | `grouped` puts each category's bars side by side (default), `stacked` stacks them, and `horizontal` draws bars across for rankings. |
244
- | `loading` | `boolean` | | The data is loading: the chart keeps its height and shows a quiet loading bar. |
244
+ | `loading` | `boolean` | | The data is loading: the chart keeps its height and is marked busy; data already on screen dims and breathes, and with none yet the plot is a skeleton. |
245
245
  | `onRetry` | `(() => void)` | | Called when Try again is pressed after `error`; without it, the button doesn't show. |
246
- | `partial` | `{ first?: boolean; last?: boolean; ongoing?: boolean \| undefined; } \| undefined` | | Marks the `first` or `last` category as covering only part of its span: its bars are drawn lighter and its tooltip says "partial". `ongoing` marks the last one as still counting, such as today, and says "so far". |
246
+ | `partial` | `{ first?: boolean; last?: boolean; ongoing?: boolean \| undefined; } \| undefined` | | Marks the `first` or `last` category as covering only part of its span: its bars are drawn faint with a dashed edge, like a partial line, and its tooltip says "partial". `ongoing` marks the last one as still counting, such as today, and says "so far". |
247
247
  | `shares` | `boolean` | `true` | Shows each series' share of the category's total in the tooltip (on by default). Turn it off when one series is part of another, such as errors within requests. |
248
248
 
249
249
  ### ChartFrame
250
250
 
251
- The frame every chart draws in: a hidden data table for assistive technology, a "View as table" toggle, and the empty, loading and error states. The toggle sits at the right end of the last line of the legend; when the frame is narrower than 480px (the `chart-legend` container size, a phone), it moves to its own line under the legend, so it never reads as one of the series. Use it to build a chart of your own that behaves like the others.
251
+ The frame every chart draws in: a hidden data table for assistive technology, a "View as table" toggle that shows the table at the chart's height, scrolling inside, and the empty, loading and error states. The toggle sits at the right end of the last line of the legend; when the frame is narrower than 480px (the `chart-legend` container size, a phone), it moves to its own line under the legend, so it never reads as one of the series. Use it to build a chart of your own that behaves like the others.
252
252
 
253
253
  | Prop | Type | Default | Description |
254
254
  |---|---|---|---|
@@ -290,44 +290,44 @@ A ring of shares with the total in the center and a legend beside it, or under i
290
290
  | Prop | Type | Default | Description |
291
291
  |---|---|---|---|
292
292
  | `aria-label` * | `string` | | The chart's accessible name ("Requests by model"). |
293
- | `slices` * | `Slice[]` | | The parts of the whole, each with an `id`, a `label`, a `value` and an optional `color`. Slices under 2% are grouped as Other when there are two or more. |
293
+ | `slices` * | `Slice[]` | | The parts of the whole, each with an `id`, a `label`, a `value` and an optional `color`. Slices under 2% are grouped as Other when there are two or more, and past the eighth slice the rest are grouped too, so no two slices share a color. |
294
294
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
295
- | `empty` | `boolean` | | Shows the empty state (`emptyText`) in place of the data. By default it shows when every value is 0. |
295
+ | `empty` | `boolean` | | Shows the empty state (`emptyText`) in place of the ring and legend. By default it shows when every value is 0, since a ring of nothing has no shares. |
296
296
  | `emptyText` | `ReactNode` | | What the empty state says. Defaults to "No data for this period" in the provider's language. |
297
- | `error` | `ReactNode` | | The data failed to load: the chart keeps its height, says so quietly and offers Try again. Errors are toasts, so the value isn't shown; toast the message where the request fails. |
297
+ | `error` | `ReactNode` | | The data failed to load: the chart keeps its height, hides its legend and table toggle, and says so quietly, with Try again when there is `onRetry` and otherwise a hint to reload the page. Errors are toasts, so the value isn't shown; pass `true` and toast the message where the request fails. |
298
298
  | `formatValue` | `((v: number) => string)` | `(v) => formatNumber(v)` | Formats the total in the center and the values in the legend. Defaults to `formatNumber`. |
299
- | `loading` | `boolean` | | The data is loading: the chart keeps its height and shows a quiet loading bar. |
299
+ | `loading` | `boolean` | | The data is loading: the chart keeps its height and is marked busy; data already on screen dims and breathes, and with none yet the plot is a skeleton. |
300
300
  | `onRetry` | `(() => void)` | | Called when Try again is pressed after `error`; without it, the button doesn't show. |
301
301
  | `size` | `"md" \| "sm" \| "lg"` | `md` | The ring's diameter: `sm` 140px, `md` 160px (default) or `lg` 180px. |
302
- | `total` | `ReactNode` | | Replaces the total in the center, which is otherwise the sum of the slices written with `formatValue`. |
302
+ | `total` | `ReactNode` | | Replaces the total in the center, which is otherwise the sum of the slices written with `formatValue`. A long total steps down a size to fit the ring. |
303
303
  | `totalLabel` | `ReactNode` | | The word under the total. Defaults to "Total" in the provider's language. |
304
304
 
305
305
  ### Gauge
306
306
 
307
- A semicircle meter for one share of a limit, such as "budget used". It turns to warning at the first threshold and to danger at 100%.
307
+ A semicircle meter for one share of a limit, such as "budget used". At the first threshold it says "Near the limit" and turns to warning; at 100% it says "Over the limit" and turns to danger.
308
308
 
309
309
  | Prop | Type | Default | Description |
310
310
  |---|---|---|---|
311
311
  | `aria-label` * | `string` | | The chart's accessible name ("Requests by model"). |
312
- | `value` * | `number` | | The share used, from 0 to 1. Values above 1 fill the arc and turn it to danger. |
312
+ | `value` * | `number` | | The share used, from 0 to 1. Values above 1 fill the arc and turn it to danger; a missing value (NaN) shows a dash and no arc. |
313
313
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
314
- | `label` | `ReactNode` | | A caption under the value ("of $500.00 budget"). |
314
+ | `label` | `ReactNode` | | A caption under the arc ("of $500.00 budget"); it wraps when long. |
315
315
  | `thresholds` | `number[]` | `[0.8]` | Fractions marked as ticks on the arc (`[0.8]` by default). From the lowest one, the arc turns to warning. |
316
- | `valueLabel` | `ReactNode` | | Replaces the value in the center, which is otherwise the percentage. |
316
+ | `valueLabel` | `ReactNode` | | Replaces the value in the center, which is otherwise the percentage. Pass a string so screen readers hear it with the unit. |
317
317
 
318
318
  ### Heatmap
319
319
 
320
- A grid of cells shaded on a five-step ramp, for one value across two dimensions such as hour by weekday.
320
+ A grid of cells shaded on a five-step ramp, for one value across two dimensions such as hour by weekday. One tab stop: the arrow keys move between cells and show each value, the table toggle lists them all, and a grid wider than its column scrolls with a fade at the edge.
321
321
 
322
322
  | Prop | Type | Default | Description |
323
323
  |---|---|---|---|
324
324
  | `aria-label` * | `string` | | The chart's accessible name ("Requests by model"). |
325
325
  | `columns` * | `string[]` | | The column labels, left to right (hours, or weeks). |
326
- | `rows` * | `string[]` | | The row labels, top to bottom (weekdays). |
326
+ | `rows` * | `string[]` | | The row labels, top to bottom (weekdays). With no rows or columns the chart shows its empty state. |
327
327
  | `values` * | `number[][]` | | The values by row, then column: `values[row][column]`. The darkest step is the largest value. |
328
328
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
329
329
  | `columnLabelEvery` | `number` | `3` | Labels every nth column, starting with the first (3 by default), so dense columns stay readable. |
330
- | `formatValue` | `((v: number) => string)` | `(v) => formatNumber(v)` | Formats a cell's value for its tooltip and screen readers. Defaults to `formatNumber`. |
330
+ | `formatValue` | `((v: number) => string)` | `(v) => formatNumber(v)` | Formats a cell's value for its tooltip, the table and screen readers. Defaults to `formatNumber`. |
331
331
 
332
332
  ### Legend
333
333
 
@@ -348,21 +348,21 @@ The same component as `Donut` under another name, with the same props.
348
348
  | Prop | Type | Default | Description |
349
349
  |---|---|---|---|
350
350
  | `aria-label` * | `string` | | The chart's accessible name ("Requests by model"). |
351
- | `slices` * | `Slice[]` | | The parts of the whole, each with an `id`, a `label`, a `value` and an optional `color`. Slices under 2% are grouped as Other when there are two or more. |
351
+ | `slices` * | `Slice[]` | | The parts of the whole, each with an `id`, a `label`, a `value` and an optional `color`. Slices under 2% are grouped as Other when there are two or more, and past the eighth slice the rest are grouped too, so no two slices share a color. |
352
352
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
353
- | `empty` | `boolean` | | Shows the empty state (`emptyText`) in place of the data. By default it shows when every value is 0. |
353
+ | `empty` | `boolean` | | Shows the empty state (`emptyText`) in place of the ring and legend. By default it shows when every value is 0, since a ring of nothing has no shares. |
354
354
  | `emptyText` | `ReactNode` | | What the empty state says. Defaults to "No data for this period" in the provider's language. |
355
- | `error` | `ReactNode` | | The data failed to load: the chart keeps its height, says so quietly and offers Try again. Errors are toasts, so the value isn't shown; toast the message where the request fails. |
355
+ | `error` | `ReactNode` | | The data failed to load: the chart keeps its height, hides its legend and table toggle, and says so quietly, with Try again when there is `onRetry` and otherwise a hint to reload the page. Errors are toasts, so the value isn't shown; pass `true` and toast the message where the request fails. |
356
356
  | `formatValue` | `((v: number) => string)` | `(v) => formatNumber(v)` | Formats the total in the center and the values in the legend. Defaults to `formatNumber`. |
357
- | `loading` | `boolean` | | The data is loading: the chart keeps its height and shows a quiet loading bar. |
357
+ | `loading` | `boolean` | | The data is loading: the chart keeps its height and is marked busy; data already on screen dims and breathes, and with none yet the plot is a skeleton. |
358
358
  | `onRetry` | `(() => void)` | | Called when Try again is pressed after `error`; without it, the button doesn't show. |
359
359
  | `size` | `"md" \| "sm" \| "lg"` | `md` | The ring's diameter: `sm` 140px, `md` 160px (default) or `lg` 180px. |
360
- | `total` | `ReactNode` | | Replaces the total in the center, which is otherwise the sum of the slices written with `formatValue`. |
360
+ | `total` | `ReactNode` | | Replaces the total in the center, which is otherwise the sum of the slices written with `formatValue`. A long total steps down a size to fit the ring. |
361
361
  | `totalLabel` | `ReactNode` | | The word under the total. Defaults to "Total" in the provider's language. |
362
362
 
363
363
  ### Sankey
364
364
 
365
- A flow diagram, such as requests from keys to models to providers, with ribbons as wide as each flow. Hovering a node highlights its paths.
365
+ A flow diagram, such as requests from keys to models to providers, with ribbons as wide as each flow. Hovering a node, or reaching it with the arrow keys, highlights its paths. Each column keeps room for its labels; when narrow, the values go first, then long names end in an ellipsis.
366
366
 
367
367
  | Prop | Type | Default | Description |
368
368
  |---|---|---|---|
@@ -370,12 +370,12 @@ A flow diagram, such as requests from keys to models to providers, with ribbons
370
370
  | `links` * | `SankeyLinkIn[]` | | The flows, each with a `source` and a `target` node `id` and a `value`. |
371
371
  | `nodes` * | `SankeyNodeIn[]` | | The nodes, each with an `id` and a `label`. Columns follow from the links. |
372
372
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
373
- | `empty` | `boolean` | | Shows the empty state (`emptyText`) in place of the data. Pass it when the period has no data. |
373
+ | `empty` | `boolean` | | Shows the empty state (`emptyText`) in place of the data. By default it shows when no link carries a value. |
374
374
  | `emptyText` | `ReactNode` | | What the empty state says. Defaults to "No data for this period" in the provider's language. |
375
- | `error` | `ReactNode` | | The data failed to load: the chart keeps its height, says so quietly and offers Try again. Errors are toasts, so the value isn't shown; toast the message where the request fails. |
375
+ | `error` | `ReactNode` | | The data failed to load: the chart keeps its height, hides its legend and table toggle, and says so quietly, with Try again when there is `onRetry` and otherwise a hint to reload the page. Errors are toasts, so the value isn't shown; pass `true` and toast the message where the request fails. |
376
376
  | `formatValue` | `((v: number) => string)` | `(v) => formatNumber(v)` | Formats the values beside the nodes and in the data table. Defaults to `formatNumber`. |
377
377
  | `height` | `number` | `320` | The diagram's height in px (320 by default). |
378
- | `loading` | `boolean` | | The data is loading: the chart keeps its height and shows a quiet loading bar. |
378
+ | `loading` | `boolean` | | The data is loading: the chart keeps its height and is marked busy; data already on screen dims and breathes, and with none yet the plot is a skeleton. |
379
379
  | `onRetry` | `(() => void)` | | Called when Try again is pressed after `error`; without it, the button doesn't show. |
380
380
 
381
381
  ### ShareBar
@@ -387,7 +387,7 @@ One pill split into segments by share, with a legend under it. Use it for a comp
387
387
  | `aria-label` * | `string` | | The chart's accessible name ("Requests by model"). |
388
388
  | `slices` * | `Slice[]` | | The parts of the whole, each with an `id`, a `label`, a `value` and an optional `color`. |
389
389
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
390
- | `formatValue` | `((v: number) => string)` | `(v) => formatNumber(v)` | Formats a segment's value in its tooltip. Defaults to `formatNumber`. |
390
+ | `formatValue` | `((v: number) => string)` | `(v) => formatNumber(v)` | Formats each segment's value for screen readers, beside its share. Defaults to `formatNumber`. |
391
391
  | `legend` | `boolean` | `true` | Shows the legend with each share under the bar (on by default). |
392
392
 
393
393
  ### Sparkline
@@ -397,7 +397,7 @@ A small line chart of one series, inline beside a value, with its last point mar
397
397
  | Prop | Type | Default | Description |
398
398
  |---|---|---|---|
399
399
  | `aria-label` * | `string` | | The chart's accessible name ("Requests by model"). |
400
- | `values` * | `number[]` | | The values in order, oldest first. |
400
+ | `values` * | `number[]` | | The values in order, oldest first. One value is a dot at the newest end; none is a quiet flat line. |
401
401
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
402
402
  | `color` | `string` | `var(--k-viz-1)` | The line's color (`var(--k-viz-1)` by default). Pass `seriesColor(id)` to match the series elsewhere. |
403
403
  | `fluid` | `boolean` | | Fills the container's width at 32px high, without the last point's dot, as in a stat tile. Otherwise it is 80×24. |
@@ -409,7 +409,7 @@ The mark that keys a series: a short stroke for lines, a small rounded square fo
409
409
  | Prop | Type | Default | Description |
410
410
  |---|---|---|---|
411
411
  | `color` * | `string` | | The series color. |
412
- | `off` | `boolean` | | Draws the swatch as off, for a hidden series. |
412
+ | `off` | `boolean` | | Draws the swatch as an outline in the series color, for a hidden series. |
413
413
  | `shape` | `"square" \| "line"` | `square` | `square` for filled marks (default) or `line` for lines. |
414
414
 
415
415
  ### TimeseriesChart
@@ -421,17 +421,17 @@ A line or area chart of values over time, such as usage, with a crosshair and to
421
421
  | `aria-label` * | `string` | | The chart's accessible name ("Requests by model"). |
422
422
  | `series` * | `TimeSeries[]` | | The series, each with an `id`, a `label`, `points` of `t` (a time) and `v`, and an optional `color`. |
423
423
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
424
- | `empty` | `boolean` | | Shows the empty state (`emptyText`) in place of the data. By default it shows when every value is 0. |
424
+ | `empty` | `boolean` | | Shows the empty state (`emptyText`) in place of the data, over the baseline and the time axis. By default it shows when there are no points; zeros are data and draw a flat line on the baseline. |
425
425
  | `emptyText` | `ReactNode` | | What the empty state says. Defaults to "No data for this period" in the provider's language. |
426
- | `error` | `ReactNode` | | The data failed to load: the chart keeps its height, says so quietly and offers Try again. Errors are toasts, so the value isn't shown; toast the message where the request fails. |
426
+ | `error` | `ReactNode` | | The data failed to load: the chart keeps its height, hides its legend and table toggle, and says so quietly, with Try again when there is `onRetry` and otherwise a hint to reload the page. Errors are toasts, so the value isn't shown; pass `true` and toast the message where the request fails. |
427
427
  | `formatTick` | `((t: Date) => string)` | | Names the times under the axis ("3 Aug", "2026"). Defaults to calendar ticks in `timeZone`; pass it with `tickAt="points"` for buckets. |
428
428
  | `formatTime` | `((t: Date) => string)` | | Names a point's time in the tooltip, the table and for screen readers, where a point stands for more than its instant: "Week of 3 Aug", "Aug 2026". |
429
- | `formatValue` | `((v: number) => string)` | `(v) => formatNumber(v)` | Formats values on the axis and in the tooltip. |
429
+ | `formatValue` | `((v: number) => string)` | | Formats values in the tooltip, the table and on the axis. Without it, values are written in full and the axis in short form (1.2M), and the axis takes the room its widest label needs. |
430
430
  | `height` | `number` | `240` | The plot's height in px (240 by default). |
431
431
  | `hideLegend` | `boolean` | | Hide the legend (one series). |
432
432
  | `highlight` | `number` | | Highlight a point in time as the pointer does, with the crosshair and tooltip: a linked view, or the states pages. |
433
433
  | `kind` | `"stacked" \| "line" \| "area"` | `line` | `line` draws lines (default), `area` adds a light fill under each line, and `stacked` stacks the areas. |
434
- | `loading` | `boolean` | | The data is loading: the chart keeps its height and shows a quiet loading bar. |
434
+ | `loading` | `boolean` | | The data is loading: the chart keeps its height and is marked busy; data already on screen dims and breathes, and with none yet the plot is a skeleton. |
435
435
  | `onRetry` | `(() => void)` | | Called when Try again is pressed after `error`; without it, the button doesn't show. |
436
436
  | `partial` | `{ first?: boolean; last?: boolean; ongoing?: boolean \| undefined; } \| undefined` | | Marks the `first` or `last` point as covering only part of its span: the line to it is dashed and its tooltip says "partial". `ongoing` marks the last one as still counting, such as today, and says "so far". |
437
437
  | `shares` | `boolean` | `true` | Shows each series' share of the point's total in the tooltip (on by default). Turn it off when one series is part of another, such as errors within requests. |
@@ -462,7 +462,7 @@ A checkbox with its label and description; with a `parent`, it checks or uncheck
462
462
  | `disabled` | `boolean` | | Turns it off: it can't be used, and it looks dimmed. |
463
463
  | `id` | `string` | | The id of the control, so a label elsewhere can point to it. |
464
464
  | `indeterminate` | `boolean` | | Shows a dash: some, but not all, of a group is checked. |
465
- | `invalid` | `boolean` | | Shows it as invalid; pair it with a message that says what to fix. |
465
+ | `invalid` | `boolean` | | Shows it as invalid; inside a `Field` with `error`, it is invalid on its own and reads the message with it. |
466
466
  | `label` | `ReactNode` | | The label; the whole row becomes the target. |
467
467
  | `name` | `string` | | The field name the value is sent under in a form. |
468
468
  | `onCheckedChange` | `((checked: boolean) => void)` | | Called with the new state when it is checked or unchecked. |
@@ -487,7 +487,7 @@ The box alone: 18px, raised and ringed; ink when checked with a check that draws
487
487
  | `disabled` | `boolean` | | Turns it off: it can't be used, and it looks dimmed. |
488
488
  | `id` | `string` | | The id of the control, so a label elsewhere can point to it. |
489
489
  | `indeterminate` | `boolean` | | Shows a dash: some, but not all, of a group is checked. |
490
- | `invalid` | `boolean` | | Shows it as invalid; pair it with a message that says what to fix. |
490
+ | `invalid` | `boolean` | | Shows it as invalid; inside a `Field` with `error`, it is invalid on its own and reads the message with it. |
491
491
  | `label` | `ReactNode` | | The label; the whole row becomes the target. |
492
492
  | `name` | `string` | | The field name the value is sent under in a form. |
493
493
  | `onCheckedChange` | `((checked: boolean) => void)` | | Called with the new state when it is checked or unchecked. |
@@ -516,7 +516,7 @@ Checkboxes that share one value, a list of the checked values.
516
516
 
517
517
  `import { Code } from "@logicplanes/kaeso-ui/code";`
518
518
 
519
- - **shape** (code): `auto` (default) — Pill for a single word, radius 6 for anything longer (default); `pill` — Always a pill; `rounded` — Always radius 6
519
+ - **shape** (code): `auto` (default) — Radius 6, like every inline code in running text (default); `pill` — Always a pill; `rounded` — Always radius 6
520
520
  - **flow** (code): `box` (default) — One box: it moves to the next line whole and wraps inside itself (default); `text` — Breaks with the sentence around it, each line keeping its fill and corners; for long code in running text; `cell` — Breaks with the text around it and ends square at a break, so no padding hangs past a narrow table cell; for long code in a table
521
521
 
522
522
  ### Code
@@ -525,19 +525,20 @@ Inline code: Geist Mono 13 on fill-1.
525
525
 
526
526
  | Prop | Type | Default | Description |
527
527
  |---|---|---|---|
528
- | `flow` | `"cell" \| "text" \| "box"` | `box` | `text` for long code in running text, so it breaks with the sentence instead of jumping to its own line as one box; `cell` for the same in a table cell. |
529
- | `shape` | `"auto" \| "pill" \| "rounded"` | `auto` | A pill on one line, rounded corners when it wraps, or `auto` to choose by length. |
528
+ | `flow` | `"cell" \| "text" \| "box"` | `box` | `text` for long code in running text, so it breaks with the sentence instead of jumping to its own line as one box; `cell` for the same in a table cell. The default box wraps inside itself when it is wider than its line. |
529
+ | `shape` | `"auto" \| "pill" \| "rounded"` | `auto` | `auto` (default) and `rounded` keep radius 6, so code in a sentence never mixes shapes; pass `pill` for one word standing alone, such as a model name in a table cell. |
530
530
 
531
531
  ## code-block
532
532
 
533
- `import { CodeBlock, CodeHighlighted, JsonView } from "@logicplanes/kaeso-ui/code-block";`
533
+ `import { CodeBlock, CodeHighlighted, DiffView, JsonView } from "@logicplanes/kaeso-ui/code-block";`
534
534
 
535
535
  - **surface** (code_block): `well` (default) — A well: radius 14, fill, no ring (default); `plain` — No surface, inside another well
536
+ - **surface** (diff_view): `well` (default) — A well: radius 14, fill, no ring (default); `plain` — No surface, inside another well
536
537
  - **surface** (json_view): `well` (default) — On a well (default); `plain` — No surface
537
538
 
538
539
  ### CodeBlock
539
540
 
540
- Highlighted code on a well: Kaeso's monochrome theme, copy on hover, tabs, line numbers, collapse. Long lines scroll sideways inside 16px of padding at both ends, and the code fades out at an edge with more to scroll to.
541
+ Highlighted code on a well: Kaeso's monochrome theme, copy in the header with a title or tabs and on hover without, tabs, line numbers, collapse with a fade at the cut. Long lines scroll sideways inside 16px of padding at both ends, and the code fades out at an edge with more to scroll to.
541
542
 
542
543
  | Prop | Type | Default | Description |
543
544
  |---|---|---|---|
@@ -575,9 +576,26 @@ The same component as `CodeBlock`, under another name.
575
576
  | `title` | `ReactNode` | | A file name in the title bar. |
576
577
  | `wrap` | `boolean \| "phone"` | `false` | Long lines wrap instead of scrolling sideways: code in a narrow column (a model's response). `phone` wraps them only below 640px, with wrapped parts indented, and scrolls from there up. |
577
578
 
579
+ ### DiffView
580
+
581
+ Two versions of a text side by side in one column: removed lines on red, added lines on green, the changed words inside them marked, syntax highlighted, and long unchanged runs folded away.
582
+
583
+ | Prop | Type | Default | Description |
584
+ |---|---|---|---|
585
+ | `after` * | `string` | | The new version. |
586
+ | `before` * | `string` | | The old version. |
587
+ | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
588
+ | `context` | `number` | `3` | Unchanged lines kept around each change before the rest folds (3 by default). |
589
+ | `copy` | `boolean` | `true` | Hide the copy circle, which copies the diff with + and - markers. |
590
+ | `lang` | `CodeLang` | `text` | The language of both versions, for highlighting (`text` by default). |
591
+ | `lineNumbers` | `boolean` | | Shows the old and the new line numbers. |
592
+ | `surface` | `"well" \| "plain"` | `well` | On a filled well (`well`) or on the panel itself (`plain`). |
593
+ | `title` | `ReactNode` | | A name in the title bar, beside the count of added and removed lines. |
594
+ | `wrap` | `boolean` | `false` | Long lines wrap instead of scrolling sideways, keeping their indent: values in a narrow column such as a sheet. |
595
+
578
596
  ### JsonView
579
597
 
580
- A folding JSON tree: copy any path, highlight a search. For request and response bodies.
598
+ A folding JSON tree: copy any path, highlight a search. For request and response bodies. It is one tab stop: the arrow keys move between rows and open and close them, and ⌘C or Ctrl C copies the row's path.
581
599
 
582
600
  | Prop | Type | Default | Description |
583
601
  |---|---|---|---|
@@ -591,11 +609,11 @@ A folding JSON tree: copy any path, highlight a search. For request and response
591
609
 
592
610
  `import { Accordion, Collapsible } from "@logicplanes/kaeso-ui/collapsible";`
593
611
 
594
- - **state** (collapsible): `closed` (default) — Closed: the chevron points to the row (default); `open` — Open: the chevron turns down and the content shows
612
+ - **state** (collapsible): `closed` (default) — Closed: a pill row with the title 12px in and a chevron at its end pointing right (default); `open` — Open: the chevron turns down in 200ms and the content shows under the title
595
613
 
596
614
  ### Accordion
597
615
 
598
- Collapsible rows separated by hairlines.
616
+ Collapsible rows separated by hairlines, each the same pill row as Collapsible.
599
617
 
600
618
  | Prop | Type | Default | Description |
601
619
  |---|---|---|---|
@@ -606,7 +624,7 @@ Collapsible rows separated by hairlines.
606
624
 
607
625
  ### Collapsible
608
626
 
609
- A disclosure row: a chevron that rotates in 180ms, a measured height animation.
627
+ A disclosure row: a pill with the title 12px in and a chevron at its end that turns in 200ms, the content on the title's line, a measured height animation.
610
628
 
611
629
  | Prop | Type | Default | Description |
612
630
  |---|---|---|---|
@@ -665,13 +683,13 @@ A pill input with a filtered list: matched characters highlighted, async, chips
665
683
  | `defaultValue` | `string \| string[] \| null` | | The value on first render, when the component keeps its own value. |
666
684
  | `description` | `ReactNode` | | One sentence of help under the label. |
667
685
  | `disabled` | `boolean` | | Turns it off: it can't be used, and it looks dimmed. |
668
- | `emptyText` | `ReactNode` | | What the empty list says: "No models match". Defaults to "No results" in the provider's language. |
686
+ | `emptyText` | `ReactNode` | | What the empty list says: "No models match". Defaults to "No matches for" and the typed text, in the provider's language. |
669
687
  | `error` | `ReactNode` | | The error message, shown under the control in the danger color; it marks the control invalid and is read out with its description. |
670
688
  | `id` | `string` | | The id of the control, so a label elsewhere can point to it. |
671
689
  | `invalid` | `boolean` | | Shows it as invalid; pair it with a message that says what to fix. |
672
690
  | `label` | `ReactNode` | | The visible label. |
673
691
  | `layout` | `"horizontal" \| "vertical"` | | The label above the control (`vertical`) or beside it (`horizontal`). |
674
- | `loading` | `boolean` | | Shows a quiet progress line at the top of the list (async results). |
692
+ | `loading` | `boolean` | | Shows a quiet progress line at the top of the list (async results) once loading takes 300ms; with reduced motion, only the words. |
675
693
  | `multiple` | `boolean` | | Allows choosing more than one option; `value` is then a list. |
676
694
  | `name` | `string` | | The field name the value is sent under in a form. |
677
695
  | `onCreate` | `((label: string) => void)` | | Offers "Add “…”" when nothing matches exactly. |
@@ -708,18 +726,18 @@ A search field over a long list that stays fast with thousands of rows: fuzzy ma
708
726
  | Prop | Type | Default | Description |
709
727
  |---|---|---|---|
710
728
  | `aria-label` * | `string` | | The list's accessible name. |
711
- | `groups` * | `CommandListGroup[]` | | The rows, in groups; a group with a label gets a sticky caption with its mark and count, and a loading group keeps its caption while it has no rows yet. |
729
+ | `groups` * | `CommandListGroup[]` | | The rows, in groups; a group with a label gets a sticky caption with its mark and count, and a loading group keeps its caption, without a count, over a Loading… row while it has no rows yet. |
712
730
  | `autoFocus` | `boolean` | | Focuses the search field when it appears, as in a popover or a dialog step. |
713
731
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
714
732
  | `counts` | `boolean` | `true` | Shows each group's count beside its caption; false leaves them out, for a site whose house style has no result counters. |
715
733
  | `data-force` | `string` | | Forces an interaction state for state matrices: `hover`, `pressed`, `focus`, `open`. |
716
734
  | `defaultQuery` | `string` | | The search text on first render. |
717
- | `emptyText` | `ReactNode` | | What the list says when nothing matches: "No models match". |
735
+ | `emptyText` | `ReactNode` | | What the list says when nothing matches: "No models match". Defaults to "No results for “claude”", naming the query, in the provider's language. |
718
736
  | `escapeClears` | `boolean` | `true` | Escape first clears the search, and only an empty search lets Escape close what holds the list (true by default). |
719
737
  | `footer` | `ReactNode` | | A line under the list, such as key hints. |
720
738
  | `height` | `"fill" \| "popover" \| "inline"` | | How tall it is: bounded in a popover, a fixed raised frame in a dialog, or filling a phone sheet. Inside `PickerPopover` it follows the popover. |
721
739
  | `inputProps` | `{ [attribute: `data-${string}`]: string; }` | | Data attributes for the search field, such as a marker other code looks for. |
722
- | `loading` | `boolean` | | Shows a quiet progress line at the top while more rows load. |
740
+ | `loading` | `boolean` | | Shows a quiet progress line at the top while more rows load; with reduced motion it breathes instead of moving. |
723
741
  | `match` | `((item: CommandListItem, query: string) => number)` | `(item: CommandListItem, query: string) => commandMatch(query, [item.label, ...(item.keywords ?? [])])` | Scores a row against the search: above 0 keeps it, and higher scores come first. Fuzzy matching on the label and keywords by default. |
724
742
  | `multiple` | `boolean` | | Rows toggle with a checkbox instead of choosing one. |
725
743
  | `onEscape` | `(() => void)` | | Called on Escape when the search field is already empty. |
@@ -770,14 +788,14 @@ The pill that opens a picker and shows its value, in the same looks and sizes as
770
788
 
771
789
  ### CommandPalette
772
790
 
773
- ⌘K: search every page and action; nested pages; async groups with a quiet progress line.
791
+ ⌘K: search every page and action; nested pages with a chip that goes back; async groups with a quiet progress line. Escape closes; on a nested page it clears the search, then goes back a page. ⌘K does nothing while another dialog is open.
774
792
 
775
793
  | Prop | Type | Default | Description |
776
794
  |---|---|---|---|
777
795
  | `groups` * | `CommandGroup[]` | | The commands, in groups with a heading each. |
778
796
  | `counts` | `boolean` | | Shows each group's count beside its caption; false leaves them out, for a site whose house style has no result counters. |
779
797
  | `defaultQuery` | `string` | | Start with this query (documentation). |
780
- | `emptyText` | `ReactNode` | | Defaults to "No results" in the provider's language. |
798
+ | `emptyText` | `ReactNode` | | Defaults to "No results for “claude”" (naming the query) in the provider's language. |
781
799
  | `hotkey` | `boolean` | | Open with ⌘K / Ctrl+K anywhere (default true). |
782
800
  | `inline` | `boolean` | | Render without a portal, for documentation and state matrices. |
783
801
  | `keyHints` | `boolean` | | A footer with the keys (↑ ↓ to navigate, ↵ to open, esc to close). Off by default: key hints only where asked for. |
@@ -836,23 +854,24 @@ Inline mono text that copies itself on click. On hover and keyboard focus a copy
836
854
 
837
855
  `import { DataTable } from "@logicplanes/kaeso-ui/data-table";`
838
856
 
839
- - **density** (data_table): `compact` — 36px rows; `default` (default) — 40px rows (default); `comfortable` — 48px rows
857
+ - **density** (data_table): `compact` — 36px rows; 44px with a coarse pointer; `default` (default) — 40px rows (default); 44px with a coarse pointer; `comfortable` — 48px rows
840
858
 
841
859
  ### DataTable
842
860
 
843
- A table for many rows: sorting, selection, loading and empty states, more rows on demand, and virtual scrolling for long lists.
861
+ A table for many rows: sorting, selection, loading and empty states, more rows on demand, and virtual scrolling for long lists. One tab stop: the arrows move between rows and header buttons, Right reaches a row's controls, Shift with Left or Right resizes a column from its header, and a header's context menu widens, narrows or resets it.
844
862
 
845
863
  | Prop | Type | Default | Description |
846
864
  |---|---|---|---|
847
865
  | `aria-label` * | `string` | | The table's accessible name. |
848
866
  | `columns` * | `ColumnDef<T, any>[]` | | The columns, as TanStack Table column definitions. |
849
867
  | `data` * | `T[]` | | The rows. |
850
- | `activeRowId` | `string` | | The id of a row to show as active (open in a sheet). |
868
+ | `activeRowId` | `string` | | The id of the row whose detail is open, in a sheet beside the table: it keeps the selected fill and is marked aria-current. |
851
869
  | `canSelectRow` | `((row: T) => boolean)` | | Whether a row can be selected; a row that can't keeps a disabled checkbox, and select all skips it. |
852
870
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
871
+ | `data-force-row` | `string` | | Force a state on the first row for state matrices: hover, pressed, focus. |
853
872
  | `density` | `"default" \| "compact" \| "comfortable"` | | How much room each row gets. |
854
- | `empty` | `ReactNode` | | What to show when there are no rows, usually an `Empty`. |
855
- | `error` | `ReactNode` | | The rows failed to load: the table says so where its rows would be and offers Try again (`onRetry`). Errors are toasts, so the value isn't shown; toast the message where the request fails. |
873
+ | `empty` | `ReactNode` | | What to show when there are no rows: an `Empty` with the page's own sentence, such as "No requests yet" or, behind filters, "No requests match". Without it the table says "No rows". |
874
+ | `error` | `ReactNode` | | The rows failed to load: the table says so where its rows would be and offers Try again (`onRetry`), or, without it, says to reload the page. Errors are toasts, so the value isn't shown; toast the message where the request fails. |
856
875
  | `freshRowIds` | `ReadonlySet<string>` | | Rows that just arrived (a live list): each shows a fill that fades out over a second. |
857
876
  | `getRowId` | `((row: T) => string)` | | Returns a row's stable id, for selection and keys. |
858
877
  | `hasMore` | `boolean` | | Whether more rows can be loaded. |
@@ -867,7 +886,7 @@ A table for many rows: sorting, selection, loading and empty states, more rows o
867
886
  | `onSortingChange` | `((sorting: SortingState) => void)` | | Called with the new sort order. |
868
887
  | `ref` | `Ref<HTMLDivElement>` | | A ref to the outer element. |
869
888
  | `rowMenu` | `((row: T) => ReactNode)` | | Items for a row's context menu (right-click). |
870
- | `selectable` | `boolean` | | Adds a checkbox to every row. |
889
+ | `selectable` | `boolean` | | Adds a checkbox to every row, named after the row's first text column; Space, Shift with the arrows and ⌘A select from the keyboard. |
871
890
  | `selection` | `RowSelectionState` | | The selected rows, when you control them. |
872
891
  | `sorting` | `SortingState` | | The sort order, when you control it. |
873
892
  | `stickyFirstColumn` | `boolean` | | Keeps the first column in view while scrolling sideways. |
@@ -900,7 +919,7 @@ A pill showing the date; a popover with the calendar and a typed ISO field.
900
919
  | `layout` | `"horizontal" \| "vertical"` | | The label above the control (`vertical`) or beside it (`horizontal`). |
901
920
  | `onValueChange` | `((value: Date \| null) => void)` | | Called with the chosen day, or `null` when it is cleared. |
902
921
  | `optional` | `boolean` | | Adds “Optional” to the label, for forms where most fields are required. |
903
- | `placeholder` | `string` | | Shown without a date. Defaults to "Pick a date" ("Pick a range" for a range) in the provider's language. |
922
+ | `placeholder` | `string` | | Shown without a date. Defaults to "Choose a date" ("Choose a date range" for a range) in the provider's language. |
904
923
  | `required` | `boolean` | | Marks it as required in a form. |
905
924
  | `size` | `"md" \| "sm" \| "lg"` | | The height of the field. |
906
925
  | `value` | `Date \| null` | | The chosen day, when you control it. |
@@ -926,7 +945,7 @@ A pill showing the range ("Oct 1 – Oct 12") or its preset ("Last 30 days"); pr
926
945
  | `layout` | `"horizontal" \| "vertical"` | | The label above the control (`vertical`) or beside it (`horizontal`). |
927
946
  | `onValueChange` | `((value: DateRange \| null, details: { preset: string \| null; }) => void)` | | A preset's range, or the days chosen with Apply; `preset` is the preset's id ("Last 7 days"), `null` for chosen days. |
928
947
  | `optional` | `boolean` | | Adds “Optional” to the label, for forms where most fields are required. |
929
- | `placeholder` | `string` | | Shown without a date. Defaults to "Pick a date" ("Pick a range" for a range) in the provider's language. |
948
+ | `placeholder` | `string` | | Shown without a date. Defaults to "Choose a date" ("Choose a date range" for a range) in the provider's language. |
930
949
  | `preset` | `string \| null` | | The preset the value is, by its id (or label): the trigger shows its name ("Last 6 months", "All time") and the popover marks it. Set it from where the period lives (the address), with `null` for chosen days. Without it, the trigger names a preset picked here while the range is still that preset's. |
931
950
  | `presets` | `DateRangePreset[]` | | Defaults to the last 24 hours, 7 and 30 days, this month and last month, named in the provider's language. |
932
951
  | `required` | `boolean` | | Marks it as required in a form. |
@@ -961,34 +980,34 @@ Hours and minutes as two segments in one pill; arrows step, typing advances.
961
980
 
962
981
  `import { DeleteResource } from "@logicplanes/kaeso-ui/blocks/delete-resource";`
963
982
 
964
- - **confirm** (delete_resource): `typed` (default) — The person types the resource's name (default); `simple` — A confirm button only, for reversible archives
983
+ - **confirm** (delete_resource): `typed` (default) — The person types the resource's name, for one that holds a lot: a project, an organization (default); `simple` — A confirm button only, for a resource that holds little: a key, an alias
965
984
 
966
985
  ### DeleteResource
967
986
 
968
- Confirms deleting a resource: names the object and the consequence, asks for its name typed, and ends with a danger button.
987
+ Confirms deleting a resource for good: the title names it, the body says the consequence, the person types its name, and a danger button names the action. A reversible action needs no confirmation: act at once and offer Undo in a toast.
969
988
 
970
989
  | Prop | Type | Default | Description |
971
990
  |---|---|---|---|
972
991
  | `consequence` * | `ReactNode` | | What happens: "Applications using it will stop authenticating with the gateway." |
973
- | `kind` * | `string` | | "project", "key", "organization" |
974
- | `name` * | `string` | | The resource's name; typed to confirm. |
992
+ | `kind` * | `string` | | The kind of resource in the provider's language, as it reads after the verb on the button: "project", "key"; in German "Projekt". |
993
+ | `name` * | `string` | | The resource's name: the title names it, and the person types it to confirm. |
975
994
  | `onConfirm` * | `() => void \| Promise<void>` | | Called when the action is confirmed; return a promise to keep the dialog busy until it ends. |
976
995
  | `confirm` | `"typed" \| "simple"` | `typed` | Asks to type the resource's name (`typed`) or just to confirm (`simple`). |
977
996
  | `inline` | `boolean` | | Renders in place, without a trigger, for review pages and tests. |
978
997
  | `onOpenChange` | `((open: boolean) => void)` | | Called when it opens or closes. |
979
998
  | `open` | `boolean` | | Whether it is open, when you control it. |
980
999
  | `trigger` | `ReactElement<unknown, string \| JSXElementConstructor<any>>` | | The element that opens it. |
981
- | `verb` | `string` | | "Delete", "Archive". Defaults to "Delete" in the provider's language. |
1000
+ | `verb` | `string` | | The action in the provider's language, in the form it takes on the button and in the title: "Archive" ("Archive project", "Archive “Checkout”?"); in German the infinitive, "archivieren" ("Projekt archivieren"). Defaults to "Delete" in the provider's language. |
982
1001
 
983
1002
  ## dialog
984
1003
 
985
1004
  `import { AlertDialog, Dialog, DialogScope, LayerDialog, StepDialog } from "@logicplanes/kaeso-ui/dialog";`
986
1005
 
987
- - **tone** (alert_dialog): `danger` (default) — Destructive (default); `warning` — Risky but reversible; `info` — Neutral confirmation
1006
+ - **tone** (alert_dialog): `danger` (default) — Destructive: a danger confirm, with the focus on Cancel (default); `warning` — Risky but reversible: a primary confirm, with the focus on Cancel; `info` — A neutral confirmation: a primary confirm, with the focus on it
988
1007
  - **size** (dialog): `sm` — 440px: confirmations, short forms; `md` (default) — 560px: forms (default); `lg` — 720px: two columns, previews
989
1008
  - **anchor** (dialog): `center` (default) — Centered on the screen (default); `top` — A fixed top edge, for content that changes height, such as the steps of a StepDialog
990
1009
  - **size** (layer_dialog): `sm` — 440px: confirmations, short forms; `md` (default) — 560px: forms (default); `lg` — 720px: two columns, previews
991
- - **anchor** (layer_dialog): `center` (default) — Centered on the screen (default); `top` — A fixed top edge, for content that changes height, such as the steps of a StepDialog
1010
+ - **anchor** (layer_dialog): `center` — Centered on the screen (default); `top` (default) — A fixed top edge, for content that changes height, such as the steps of a StepDialog
992
1011
  - **size** (step_dialog): `sm` (default) — 440px: most tasks in a few steps (default); `md` — 560px: steps with longer forms; `lg` — 720px: steps with two columns or previews
993
1012
  - **tone** (step_dialog): `default` (default) — The last step's button is primary (default); `danger` — The last step's button is a danger button, for a task that ends in deletion
994
1013
 
@@ -1001,7 +1020,7 @@ Confirms an irreversible action: names it, explains the consequence, optionally
1001
1020
  | `confirmLabel` * | `string` | | The confirm label, the verb and object: "Delete key". |
1002
1021
  | `description` * | `ReactNode` | | The practical consequence. |
1003
1022
  | `onConfirm` * | `() => void \| Promise<unknown>` | | Called when the action is confirmed; return a promise to keep the dialog busy until it ends. It closes when the promise resolves and stays open for another try when it rejects, so toast the error there. |
1004
- | `title` * | `ReactNode` | | Names the action: "Delete this key?" |
1023
+ | `title` * | `ReactNode` | | Names the action and the object: "Delete “checkout-web”?" |
1005
1024
  | `cancelLabel` | `string` | | Defaults to "Cancel" in the provider's language. |
1006
1025
  | `confirmText` | `string` | | Typed confirmation: the person types this to enable the confirm. |
1007
1026
  | `defaultOpen` | `boolean` | | Whether it starts open, when the component keeps its own state. |
@@ -1009,7 +1028,7 @@ Confirms an irreversible action: names it, explains the consequence, optionally
1009
1028
  | `loading` | `boolean` | | Shows a spinner on the confirm while work runs (also automatic for a promise); until it ends, the dialog stays open. |
1010
1029
  | `onOpenChange` | `((open: boolean) => void)` | | Called when it opens or closes. |
1011
1030
  | `open` | `boolean` | | Whether it is open, when you control it. |
1012
- | `tone` | `"warning" \| "danger" \| "info"` | | How serious the confirmation is; `danger` for actions that can't be undone. |
1031
+ | `tone` | `"warning" \| "danger" \| "info"` | | How serious the confirmation is: `danger` for an action that can't be undone (a danger confirm, the focus on Cancel), `warning` for a risky one that can (a primary confirm, the focus still on Cancel), `info` for a neutral one (the focus on the confirm). |
1013
1032
  | `trigger` | `ReactElement<unknown, string \| JSXElementConstructor<any>>` | | The element that opens it. |
1014
1033
 
1015
1034
  ### Dialog
@@ -1018,8 +1037,8 @@ A modal dialog: 440 / 560 / 720, radius 20, title, description, body, actions. E
1018
1037
 
1019
1038
  | Prop | Type | Default | Description |
1020
1039
  |---|---|---|---|
1021
- | `title` * | `ReactNode` | | The dialog's heading, also its accessible name. |
1022
- | `anchor` | `"center" \| "top"` | | Where it sits: centered, or with a fixed top edge for content that changes height, so the title never moves. |
1040
+ | `title` * | `ReactNode` | | The dialog's heading, also its accessible name; a long one, or an id, wraps. |
1041
+ | `anchor` | `"center" \| "top"` | `top` | Where it sits: centered, or with a fixed top edge for content that changes height, so the title never moves. |
1023
1042
  | `busy` | `boolean` | | Keeps the dialog open while work it started is underway: Escape, a press outside, the close circle, Dialog.Close, Enter and ⌘Enter do nothing, so a request is never abandoned or sent twice. |
1024
1043
  | `children` | `ReactNode` | | The dialog's content and actions. |
1025
1044
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
@@ -1033,7 +1052,7 @@ A modal dialog: 440 / 560 / 720, radius 20, title, description, body, actions. E
1033
1052
  | `onOpenChange` | `((open: boolean) => void)` | | Called when it opens or closes. |
1034
1053
  | `onSubmit` | `(() => void)` | | Enter in a single-line field and ⌘/Ctrl+Enter anywhere call this (usually the primary action); Enter in a text area, a search field, a combobox or a picker, and the Enter that confirms an input method's text, keep their own meaning. |
1035
1054
  | `open` | `boolean` | | Whether it is open, when you control it. |
1036
- | `persistent` | `boolean` | | A press outside doesn't close it, for forms that would lose what was typed; Escape and the close circle still do. Every StepDialog is persistent. |
1055
+ | `persistent` | `boolean` | | A press outside doesn't close it or move the focus, for forms that would lose what was typed; Escape and the close circle still close it. Every StepDialog is persistent. |
1037
1056
  | `size` | `"md" \| "sm" \| "lg"` | | The dialog's width. |
1038
1057
  | `toolbar` | `ReactNode` | | Controls that stay under the title while the body scrolls, such as a search over the list below; a hairline shows once the body is scrolled. |
1039
1058
  | `trigger` | `ReactElement<unknown, string \| JSXElementConstructor<any>>` | | The trigger, a single element. |
@@ -1049,12 +1068,12 @@ Opens a dialog's flow fresh every time: its children mount anew when `open` turn
1049
1068
 
1050
1069
  ### LayerDialog
1051
1070
 
1052
- A stacked dialog: a second layer slides over the first (add model → review values); back returns. The layers below stay as they were. Moving to a layer puts the focus on its first field, or its primary action; Back returns it to the control that opened the layer, scrolled where it was. Enter in a single-line field and ⌘/Ctrl+Enter call onSubmit on every layer.
1071
+ A stacked dialog: a second layer slides over the first (add model → review values); Back returns, and Escape closes the dialog from any layer. The layers below stay as they were. The close circle sits in a bar above the title, with Back at its start from the second layer, so the title keeps its place on every layer. Moving to a layer puts the focus on its first field, or its primary action; Back returns it to the control that opened the layer, scrolled where it was. Enter in a single-line field and ⌘/Ctrl+Enter call onSubmit on every layer.
1053
1072
 
1054
1073
  | Prop | Type | Default | Description |
1055
1074
  |---|---|---|---|
1056
1075
  | `layers` * | `DialogLayer[]` | | The layers, each with its title, content and footer, and optionally a toolbar and a footer start; one shows at a time, and the ones below it stay mounted and hidden. |
1057
- | `anchor` | `"center" \| "top"` | | Where it sits: centered, or with a fixed top edge for layers of different heights. |
1076
+ | `anchor` | `"center" \| "top"` | `top` | Where it sits: with a fixed top edge (default), so the title stays put on layers of different heights, or centered. |
1058
1077
  | `busy` | `boolean` | | Keeps the dialog open while work it started is underway: Escape, a press outside, the close circle, Dialog.Close, Enter and ⌘Enter do nothing, so a request is never abandoned or sent twice. |
1059
1078
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
1060
1079
  | `defaultOpen` | `boolean` | | Whether it starts open, when the component keeps its own state. |
@@ -1076,7 +1095,7 @@ A form split into steps, one question at a time, like sign-in: the step's title
1076
1095
  | Prop | Type | Default | Description |
1077
1096
  |---|---|---|---|
1078
1097
  | `onSubmit` * | `() => void` | | Called when the last step is submitted. |
1079
- | `steps` * | `DialogStep[]` | | The steps, each with its title, content and whether it can be continued; `onContinue` checks a step before the next opens, such as asking a server, and `continueLabel` names that check: "Detect settings". |
1098
+ | `steps` * | `DialogStep[]` | | The steps, each with its title, content and whether it can be continued: with `blockedReason`, Continue waits, and Enter shows and announces the reason under the step; `onContinue` checks a step before the next opens, such as asking a server, and `continueLabel` names that check: "Detect settings". |
1080
1099
  | `submitLabel` * | `string` | | The last step's button: "Create key". |
1081
1100
  | `title` * | `ReactNode` | | What the whole dialog does: "Create key". |
1082
1101
  | `defaultStep` | `number` | `0` | Start on this step (state matrices). |
@@ -1116,16 +1135,16 @@ Display options: view, grouping and ordering, toggles, properties.
1116
1135
 
1117
1136
  ### Empty
1118
1137
 
1119
- An empty state: a title, one sentence, one or two actions. No icon, no illustration.
1138
+ An empty state: a title, one sentence, one action. No icon, no illustration. The `lg` title is a heading (h2) for a page that is empty; `md` and `compact` titles are text, so an empty table, list or section adds no heading to the page's outline.
1120
1139
 
1121
1140
  | Prop | Type | Default | Description |
1122
1141
  |---|---|---|---|
1123
1142
  | `title` * | `ReactNode` | | What is missing, in a few words. |
1124
- | `actions` | `ReactNode` | | One primary and at most one secondary action. |
1143
+ | `actions` | `ReactNode` | | The one action that makes something appear; put a link to read more in the description. |
1125
1144
  | `children` | `ReactNode` | | One sentence that says what to do, and an action. |
1126
1145
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
1127
1146
  | `description` | `ReactNode` | | One sentence: what is absent and the next step. |
1128
- | `size` | `"md" \| "lg" \| "compact"` | `lg` | How much room it takes: a whole page (`lg`), a section (`md`) or a row (`compact`). |
1147
+ | `size` | `"md" \| "lg" \| "compact"` | `lg` | How much room it takes: a whole page (`lg`, with a heading), a section (`md`) or a row (`compact`). |
1129
1148
 
1130
1149
  ## field
1131
1150
 
@@ -1140,7 +1159,7 @@ The aria wiring a control needs, whether it sits in a <Field> or wraps itself in
1140
1159
  | Prop | Type | Default | Description |
1141
1160
  |---|---|---|---|
1142
1161
  | `description` | `ReactNode` | | One sentence of help under the label. |
1143
- | `error` | `ReactNode` | | The error message, shown under the control in the danger color: it marks the field invalid and is read out with the description. |
1162
+ | `error` | `ReactNode` | | The error message, shown under the control in the danger color: it marks the field invalid and is read out with the description. After a failed submit, move focus to the first invalid field so its error is heard. |
1144
1163
  | `id` | `string` | | The id of the control inside, so the label points to it. |
1145
1164
  | `invalid` | `boolean` | | Marks the field invalid without a message. |
1146
1165
  | `label` | `ReactNode` | | The field's label. |
@@ -1148,12 +1167,12 @@ The aria wiring a control needs, whether it sits in a <Field> or wraps itself in
1148
1167
 
1149
1168
  ### Fieldset
1150
1169
 
1151
- A group of fields under one legend.
1170
+ A group of fields under one legend, which names the group for screen readers.
1152
1171
 
1153
1172
  | Prop | Type | Default | Description |
1154
1173
  |---|---|---|---|
1155
- | `legend` * | `ReactNode` | | The heading of the group of fields. |
1156
- | `description` | `ReactNode` | | One sentence of help under the heading. |
1174
+ | `legend` * | `ReactNode` | | The heading of the group of fields, read out as the group's name. |
1175
+ | `description` | `ReactNode` | | One sentence of help under the heading; it also describes the group. |
1157
1176
 
1158
1177
  ## figure
1159
1178
 
@@ -1168,7 +1187,7 @@ A diagram or image set apart from the text: centred on a well, with a caption, s
1168
1187
  | Prop | Type | Default | Description |
1169
1188
  |---|---|---|---|
1170
1189
  | `children` * | `ReactNode` | | What the figure shows, usually a ThemeImage. |
1171
- | `label` * | `string` | | The name of the figure's scrolling region, read by screen readers. |
1190
+ | `label` * | `string` | | The name of the figure's scrolling region, read by screen readers; give each figure on a page its own. |
1172
1191
  | `caption` | `ReactNode` | | A few words under the figure that say what it shows, such as a diagram's title. |
1173
1192
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
1174
1193
  | `focus` | `number` | `0.5` | Where a figure wider than its column starts, as a share of its width: 0.5, the middle, by default. |
@@ -1213,7 +1232,7 @@ A filter as one pill: "Status is 2xx ×", each part opening a menu.
1213
1232
 
1214
1233
  ### FilterRow
1215
1234
 
1216
- The row between a page's header and its list or table: pill tabs at the start, filters at the end. It grows with its content instead of keeping a toolbar's 48px, and on a narrow screen the filters wrap under the tabs, at the start. The tabs keep their own arrow keys; Left and Right move across the filters only, which form their own toolbar.
1235
+ The row between a page's header and its list or table: pill tabs at the start, filters at the end. It grows with its content instead of keeping a toolbar's 48px, and on a narrow screen the filters wrap under the tabs, at the start. The tabs keep their own arrow keys; Left and Right move from filter to filter, which form their own toolbar.
1217
1236
 
1218
1237
  | Prop | Type | Default | Description |
1219
1238
  |---|---|---|---|
@@ -1226,17 +1245,17 @@ The row between a page's header and its list or table: pill tabs at the start, f
1226
1245
 
1227
1246
  `import { Flow } from "@logicplanes/kaeso-ui/flow";`
1228
1247
 
1229
- - **node** (flow): `pill` (default) — A raised pill (default); `box` — A rounded-14 box with a description line
1248
+ - **node** (flow): `pill` (default) — A pill with a hairline (default); `box` — A rounded-14 box with a description line
1230
1249
 
1231
1250
  ### Flow
1232
1251
 
1233
- A node-and-connector diagram: the route "app → Kaeso → provider / model".
1252
+ A node-and-connector diagram: the route "app → Kaeso → provider / model". A diagram wider than its column scrolls sideways with a fade at the edge and takes focus.
1234
1253
 
1235
1254
  | Prop | Type | Default | Description |
1236
1255
  |---|---|---|---|
1237
1256
  | `columns` * | `FlowNode[][]` | | Columns of nodes, left to right. |
1238
1257
  | `edges` * | `[string, string][]` | | Connections as [from, to] node ids. |
1239
- | `animated` | `boolean` | `false` | Dots that travel along the connectors. Off by default; never on loaded pages that need calm. |
1258
+ | `animated` | `boolean` | `false` | When the route changes, a dot runs once along each connector, to show where requests now go. Never on first render and never with reduced motion. |
1240
1259
  | `aria-label` | `string` | | The accessible name of the diagram: what it shows, such as "Route of checkout requests". Defaults to "Flow diagram"; screen readers hear each node and each connection after it. |
1241
1260
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
1242
1261
  | `node` | `"pill" \| "box"` | `pill` | The shape of each step: a pill or a box. |
@@ -1304,8 +1323,8 @@ A circle with an icon, a required name, and a tooltip that says it.
1304
1323
 
1305
1324
  - **size** (input): `sm` — 32px: toolbars and compact forms; `md` (default) — 36px: the default; `lg` — 40px; `xl` — 48px: sign-in and setup forms
1306
1325
  - **size** (input_group): `sm` — 32px: toolbars and compact forms; `md` (default) — 36px: the default; `lg` — 40px; `xl` — 48px: sign-in and setup forms
1307
- - **align** (number_input): `end` (default) — Right-aligned tabular digits (default); `start` — Left-aligned
1308
- - **size** (otp_input): `md` (default) — 48px cells (default); `sm` — 40px cells
1326
+ - **align** (number_input): `end` (default) — End-aligned tabular digits (default); `start` — Start-aligned
1327
+ - **size** (otp_input): `md` (default) — 48px cells (default); they shrink, square, when the row is narrower; `sm` — 40px cells
1309
1328
  - **size** (search_input): `sm` (default) — 32px: toolbars (default); `md` — 36px: a search at the top of a page or dialog; `lg` — 40px; `xl` — 48px
1310
1329
  - **kind** (sensitive_input): `secret` (default) — Provider keys and tokens: never autocompleted (default); `password` — Passwords: browser password managers allowed, Caps Lock hint
1311
1330
  - **size** (tag_input): `md` (default) — 36px at one row; grows as tags wrap (default)
@@ -1348,7 +1367,7 @@ Joins an input with buttons or text before or after it into one pill.
1348
1367
 
1349
1368
  ### NumberInput
1350
1369
 
1351
- Numbers that stay exact: right-aligned tabular digits, a unit, stepper circles on hover, thousands separators on blur, and a decimal string value.
1370
+ Numbers that stay exact: end-aligned tabular digits, a unit, quiet stepper circles, thousands separators on blur, and a decimal string value.
1352
1371
 
1353
1372
  | Prop | Type | Default | Description |
1354
1373
  |---|---|---|---|
@@ -1358,7 +1377,7 @@ Numbers that stay exact: right-aligned tabular digits, a unit, stepper circles o
1358
1377
  | `defaultValue` | `string` | | The number on first render, as text. |
1359
1378
  | `description` | `ReactNode` | | One sentence of help under the label. |
1360
1379
  | `error` | `ReactNode` | | The error message, shown under the control in the danger color; it marks the control invalid and is read out with its description. |
1361
- | `hideStepper` | `boolean` | | Hide the stepper circles. |
1380
+ | `hideStepper` | `boolean` | | Hide the stepper circles, where a value is typed rather than nudged, such as an id or a year. |
1362
1381
  | `integer` | `boolean` | | Whole numbers only, such as a count of days: a numeric keypad on phones and no thousands separators in the field. |
1363
1382
  | `invalid` | `boolean` | | Shows it as invalid; pair it with a message that says what to fix. |
1364
1383
  | `label` | `ReactNode` | | The visible label. |
@@ -1502,13 +1521,14 @@ A model's capabilities as small icons, each named in a tooltip and read as one l
1502
1521
 
1503
1522
  ### ClientButton
1504
1523
 
1505
- An agent client's mark, such as Claude, Cursor or GitHub Copilot, on a raised tile, as a button that opens how to connect it.
1524
+ An agent client's mark, such as Claude, Cursor or GitHub Copilot, in a raised circle beside the other header buttons, as a button that opens how to connect it.
1506
1525
 
1507
1526
  | Prop | Type | Default | Description |
1508
1527
  |---|---|---|---|
1509
1528
  | `aria-label` * | `string` | | The client's name; also the tooltip. |
1510
1529
  | `client` * | `"cursor" \| "claude" \| "github-copilot"` | | Which client's mark it shows. |
1511
1530
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
1531
+ | `data-force` | `string` | | Forces an interaction state for state matrices: `hover`, `pressed`, `focus`, `open`. |
1512
1532
  | `onClick` | `(() => void)` | | Opens how to connect the client. |
1513
1533
 
1514
1534
  ### ConversationView
@@ -1525,7 +1545,7 @@ A model conversation from a request log: role captions, prose, tool calls and re
1525
1545
 
1526
1546
  ### EffectiveAccess
1527
1547
 
1528
- What someone can do, at a glance: a row per group with the granted rights in words ("Every right", "None", or their names) and how many of the group's rights that is, under the roles it comes from. The detail, with a source per right, is RightsMatrix in read-only mode.
1548
+ What someone can do, at a glance: a row per group with the granted rights in words ("Every right", "None", or their names) and how many of the group's rights that is, under the roles it comes from; groups with nothing granted share one "No rights" row. A role chip with more to say has a dotted underline and says it in a tooltip. The detail, with a source per right, is RightsMatrix in read-only mode.
1529
1549
 
1530
1550
  | Prop | Type | Default | Description |
1531
1551
  |---|---|---|---|
@@ -1548,19 +1568,19 @@ The gateway's base URL and a key placeholder to copy, with snippets per SDK.
1548
1568
 
1549
1569
  ### GrantSummary
1550
1570
 
1551
- What an agent or a key may do, one short line each after a check mark, on a group surface.
1571
+ What an agent or a key may do, one short line each after a check mark, on a group surface with 20px inside, like a settings group.
1552
1572
 
1553
1573
  | Prop | Type | Default | Description |
1554
1574
  |---|---|---|---|
1555
1575
  | `aria-label` * | `string` | | The list's accessible name ("What it can do"). |
1556
1576
  | `items` * | `readonly ReactNode[]` | | The lines, short and without a final period. |
1557
- | `action` | `ReactNode` | | A small button after the note, such as Customize. |
1577
+ | `action` | `ReactNode` | | A small button after the note (or alone, at the end), such as Customize. |
1558
1578
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
1559
- | `footer` | `ReactNode` | | A quiet note under the lines, such as how long it lasts. |
1579
+ | `footer` | `ReactNode` | | A note under the lines in secondary text, such as how long it lasts. |
1560
1580
 
1561
1581
  ### KeyDisplay
1562
1582
 
1563
- A redacted key: mono 13 with its state dot, copy of the redacted form, and its access.
1583
+ A redacted key: mono 13, a word badge for any state but active, a copy of the redacted form, and its access in an outline badge.
1564
1584
 
1565
1585
  | Prop | Type | Default | Description |
1566
1586
  |---|---|---|---|
@@ -1573,13 +1593,13 @@ A redacted key: mono 13 with its state dot, copy of the redacted form, and its a
1573
1593
 
1574
1594
  ### LimitMeter
1575
1595
 
1576
- A limit: its kind, scope and window, hard or soft, the meter with alert ticks, and when it resets.
1596
+ A limit: its kind, scope and window, hard or soft, the meter with alert ticks, and when it resets. Over the limit it says so, and what happens to requests.
1577
1597
 
1578
1598
  | Prop | Type | Default | Description |
1579
1599
  |---|---|---|---|
1580
1600
  | `kind` * | `LimitKind` | | What is limited: requests, tokens or spend, and over which period. |
1581
1601
  | `limit` * | `number` | | The limit. |
1582
- | `scope` * | `ReactNode` | | "Project", "Key ci-runner", "Member Ada". |
1602
+ | `scope` * | `ReactNode` | | "Project", "Key ci-runner", "Member Ada". A text scope also names the meter for screen readers, and shows whole on hover when it doesn't fit. |
1583
1603
  | `used` * | `number` | | How much is used. |
1584
1604
  | `valueLabel` * | `ReactNode` | | Formatted values: "$32.10 of $50.00". |
1585
1605
  | `window` * | `ReactNode` | | "Per minute", "Per month". |
@@ -1668,7 +1688,7 @@ A bar of time to first byte against the total: 240px (default), 160px in a cell,
1668
1688
 
1669
1689
  ### RightsMatrix
1670
1690
 
1671
- Rights by group, for a role, a member or a key. Edit mode: a checkbox per right and per group (mixed when some are granted), requirements kept (granting "edit" grants "view"; withdrawing "view" withdraws "edit"), each right's needs said under it, and arrow keys moving between checkboxes. Read-only mode: a mark per right and the roles that grant it. Rows keep their size whatever their state. Fits a sheet and a phone.
1691
+ Rights by group, for a role, a member or a key. Edit mode: a checkbox per right and per group (checked only when every right in it is granted, mixed when some are), requirements kept (granting "edit" grants "view"; withdrawing "view" withdraws "edit"), each right's needs said under it, and a right that can't change saying why under it. The matrix is one tab stop: the arrow keys move between checkboxes, and the right arrow reaches a right's sensitive mark. A group's name toggles the group, as a right's row toggles the right. Read-only mode: a mark per right and the roles that grant it. Rows keep their size whatever their state. Fits a sheet and a phone.
1672
1692
 
1673
1693
  | Prop | Type | Default | Description |
1674
1694
  |---|---|---|---|
@@ -1683,7 +1703,7 @@ Rights by group, for a role, a member or a key. Edit mode: a checkbox per right
1683
1703
 
1684
1704
  ### RolePicker
1685
1705
 
1686
- Choosing a role: built-in roles first, then custom ones under their own caption, each with its one-sentence description. A role the person can't give stays in the list, disabled, with the reason under it and in its tooltip, so nobody wonders where it went.
1706
+ Choosing a role: built-in roles first, then custom ones under their own caption, each with its one-sentence description. A role the person can't give stays in the list, disabled, with the reason under it, so nobody wonders where it went.
1687
1707
 
1688
1708
  | Prop | Type | Default | Description |
1689
1709
  |---|---|---|---|
@@ -1701,11 +1721,11 @@ Choosing a role: built-in roles first, then custom ones under their own caption,
1701
1721
 
1702
1722
  ### SecretReveal
1703
1723
 
1704
- The one-time secret: calm, centered, certain. The secret on a well (selected on click), a large "Copy key" that becomes "Copied" without changing size, a plain warning, and snippets that use it.
1724
+ The one-time secret: calm, centered, certain. The secret on a well (selected on click), a plain warning, a large "Copy key" that becomes "Key copied" without changing size, and a `.env` tab with the gateway's URL and the key beside SDK snippets that read the key from the environment.
1705
1725
 
1706
1726
  | Prop | Type | Default | Description |
1707
1727
  |---|---|---|---|
1708
- | `baseUrl` * | `string` | | The gateway's address, for the code snippet that uses the key. |
1728
+ | `baseUrl` * | `string` | | The gateway's address, for the `.env` tab and the code snippets. |
1709
1729
  | `secret` * | `string` | | The full secret, shown once. |
1710
1730
  | `apiKey` | `string` | `$KAESO_API_KEY` | What stands in for the key: the real key right after creation, a placeholder elsewhere. |
1711
1731
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
@@ -1726,7 +1746,7 @@ An HTTP status: the code in mono, in its class color (with its phrase in a toolt
1726
1746
 
1727
1747
  ### UsageBreakdown
1728
1748
 
1729
- A stacked bar of token kinds with the numbers under it, in the fixed series mapping.
1749
+ A stacked bar of token kinds with the numbers under it, in the fixed series mapping; cache read is a soft blue edged in input's blue. Each rounded count shows the exact one on hover and focus.
1730
1750
 
1731
1751
  | Prop | Type | Default | Description |
1732
1752
  |---|---|---|---|
@@ -1766,7 +1786,7 @@ A shortcut: `⌘ K`, or a sequence like `G then L`.
1766
1786
 
1767
1787
  ### KeyValue
1768
1788
 
1769
- Label and value pairs (13 secondary label, 14 value), copyable values. Side by side for sheets; label above value in columns (`grid`) where a sheet is wide enough for two or more to a row. A text value that doesn't fit ends in an ellipsis and shows whole in a tooltip.
1789
+ Label and value pairs (13 secondary label, 14 value), copyable values. Side by side for sheets; label above value in columns (`grid`) where a sheet is wide enough for two or more to a row. A value or grid label that doesn't fit ends in an ellipsis, takes focus and shows whole in a tooltip. Side by side, the label column grows to its longest label up to 240px, and longer labels wrap. Ids and keys (`mono`) are 13px, like ids everywhere in the library.
1770
1790
 
1771
1791
  | Prop | Type | Default | Description |
1772
1792
  |---|---|---|---|
@@ -1783,7 +1803,7 @@ Label and value pairs (13 secondary label, 14 value), copyable values. Side by s
1783
1803
 
1784
1804
  ### Label
1785
1805
 
1786
- The label of a form control.
1806
+ The label of a form control. Pass `data-disabled` beside a disabled control and it dims with it.
1787
1807
 
1788
1808
  | Prop | Type | Default | Description |
1789
1809
  |---|---|---|---|
@@ -1797,7 +1817,7 @@ The label of a form control.
1797
1817
 
1798
1818
  - **align** (layout): `start` — Align to the start; `center` — Center on the cross axis; `end` — Align to the end; `baseline` — Align text baselines; `stretch` (default) — Stretch
1799
1819
  - **justify** (layout): `start` (default) — Pack to the start; `center` — Center; `end` — Pack to the end; `between` — Space between
1800
- - **columns** (layout): `1` — One column; `2` (default) — Two columns from 768px; `3` — Three columns from 768px; `4` — Two, then four from 1024px; `6` — Three, then six from 1024px
1820
+ - **columns** (layout): `1` — One column; `2` (default) — Two columns from 768px; `3` — Three columns from 768px; `4` — Two, then four from 1024px; `6` — Two, three from 768px, six from 1024px
1801
1821
 
1802
1822
  ### Grid
1803
1823
 
@@ -1808,7 +1828,7 @@ A responsive grid.
1808
1828
  | `align` | `"start" \| "end" \| "center" \| "baseline" \| "stretch"` | `center` | How items line up within their cells. |
1809
1829
  | `as` | `ElementType` | | The element or component to render as, such as `section` or `ul`. |
1810
1830
  | `columns` | `2 \| 3 \| 4 \| 1 \| 6` | `2` | The number of columns. |
1811
- | `gap` | `0 \| 2 \| 24 \| 20 \| 32 \| 40 \| 4 \| 6 \| 8 \| 12 \| 16 \| 48 \| 64` | `16` | The space between items, in pixels on the spacing scale. |
1831
+ | `gap` | `0 \| 2 \| 24 \| 8 \| 12 \| 16 \| 20 \| 32 \| 40 \| 4 \| 6 \| 48 \| 64` | `16` | The space between items, in pixels on the spacing scale. |
1812
1832
 
1813
1833
  ### Inline
1814
1834
 
@@ -1818,7 +1838,7 @@ A horizontal row that wraps.
1818
1838
  |---|---|---|---|
1819
1839
  | `align` | `"start" \| "end" \| "center" \| "baseline" \| "stretch"` | `center` | How items line up across the row. |
1820
1840
  | `as` | `ElementType` | | The element or component to render as, such as `section` or `ul`. |
1821
- | `gap` | `0 \| 2 \| 24 \| 20 \| 32 \| 40 \| 4 \| 6 \| 8 \| 12 \| 16 \| 48 \| 64` | `16` | The space between items, in pixels on the spacing scale. |
1841
+ | `gap` | `0 \| 2 \| 24 \| 8 \| 12 \| 16 \| 20 \| 32 \| 40 \| 4 \| 6 \| 48 \| 64` | `16` | The space between items, in pixels on the spacing scale. |
1822
1842
  | `justify` | `"start" \| "end" \| "center" \| "between"` | | How items are spread along the main axis. |
1823
1843
  | `wrap` | `boolean` | `true` | Lets items wrap onto the next line. |
1824
1844
 
@@ -1830,14 +1850,14 @@ A vertical stack.
1830
1850
  |---|---|---|---|
1831
1851
  | `align` | `"start" \| "end" \| "center" \| "baseline" \| "stretch"` | `center` | How items line up across the column. |
1832
1852
  | `as` | `ElementType` | | The element or component to render as, such as `section` or `ul`. |
1833
- | `gap` | `0 \| 2 \| 24 \| 20 \| 32 \| 40 \| 4 \| 6 \| 8 \| 12 \| 16 \| 48 \| 64` | `16` | The space between items, in pixels on the spacing scale. |
1853
+ | `gap` | `0 \| 2 \| 24 \| 8 \| 12 \| 16 \| 20 \| 32 \| 40 \| 4 \| 6 \| 48 \| 64` | `16` | The space between items, in pixels on the spacing scale. |
1834
1854
  | `justify` | `"start" \| "end" \| "center" \| "between"` | | How items are spread along the main axis. |
1835
1855
 
1836
1856
  ## link
1837
1857
 
1838
1858
  `import { Link } from "@logicplanes/kaeso-ui/link";`
1839
1859
 
1840
- - **variant** (link): `inline` (default) — Inside prose: text color with a quiet underline that turns solid on hover; `quiet` — Navigation-style links in footers and metadata; no underline until hover; `standalone` — A link on its own line (“Team overview ›”); `heading` — A heading's link to itself: the heading's own look, with a # beside it on hover and keyboard focus; `card` — A page to read next: a filled well with the page's name and one sentence about it
1860
+ - **variant** (link): `inline` (default) — Inside prose: text color with a grey underline that turns to the text color on hover; `quiet` — Navigation-style links in footers and metadata; no underline until hover; `standalone` — A link on its own line (“Team overview ›”); `heading` — A heading's link to itself: the heading's own look, with a # beside it on hover and keyboard focus; `card` — A page to read next: a filled well with the page's name and one sentence about it
1841
1861
 
1842
1862
  ### Link
1843
1863
 
@@ -1854,11 +1874,11 @@ A link. Router links come from `LinkProvider`.
1854
1874
 
1855
1875
  `import { GroupHeader, List, ListRow, SelectionAction, SelectionBar } from "@logicplanes/kaeso-ui/list";`
1856
1876
 
1857
- - **density** (list): `default` (default) — 44px rows (default); `compact` — 36px rows
1877
+ - **density** (list): `default` (default) — 44px rows (default); `compact` — 36px rows; 44px with a coarse pointer
1858
1878
 
1859
1879
  ### GroupHeader
1860
1880
 
1861
- A quiet caption row above its group: title, count and a disclosure chevron, set in from the edges like the rows. No band: space separates the groups, and the + circle appears with hover or focus.
1881
+ A quiet caption row above its group: title, count and a disclosure chevron, set in from the edges like the rows. On the panel there is no band: 16px of space separates the groups. In a card the header is a `fill-1` band with a hairline, the card's way of separating groups. The + circle appears with hover or focus.
1862
1882
 
1863
1883
  | Prop | Type | Default | Description |
1864
1884
  |---|---|---|---|
@@ -1867,9 +1887,9 @@ A quiet caption row above its group: title, count and a disclosure chevron, set
1867
1887
  | `addLabel` | `string` | | The + circle's name. Defaults to "Add" in the provider's language. |
1868
1888
  | `collapsed` | `boolean` | | Whether the group is collapsed. |
1869
1889
  | `count` | `number` | | How many items the group has. |
1870
- | `first` | `boolean` | | The list's first row (no hairline above it in a card). |
1890
+ | `first` | `boolean` | | The list's first row: no space above it on the panel, no hairline above it in a card. |
1871
1891
  | `glyph` | `ReactNode` | | A mark before the name, such as a status dot. |
1872
- | `indent` | `boolean` | | In a selectable list, line the title up with the row titles after the checkbox column. |
1892
+ | `indent` | `boolean` | | In a selectable list, line the title up with the row titles after the checkbox column; the hover fill still starts on the gutter. |
1873
1893
  | `index` | `number` | | The header's position in the list, for keyboard navigation. |
1874
1894
  | `onAdd` | `(() => void)` | | Shows an Add button and is called when it is pressed. |
1875
1895
  | `onFocus` | `(() => void)` | | Called when the header's toggle or its add button gets focus. |
@@ -1877,25 +1897,25 @@ A quiet caption row above its group: title, count and a disclosure chevron, set
1877
1897
 
1878
1898
  ### List
1879
1899
 
1880
- The console list: 44px rows on the panel, no lines, metadata on the right, keyboard-first. An ARIA grid of one-cell rows with one tab stop: arrows move between rows, Space selects, Enter opens, and the right arrow reaches a row's actions.
1900
+ The console list: 44px rows on the panel (48px in a card, 56px with a second line), no lines, metadata on the right, keyboard-first. An ARIA grid of one-cell rows with one tab stop: arrows move between rows, Space selects, Enter opens, the right arrow reaches a row's actions and Escape comes back. A row's text can be selected and copied; a click that selects text doesn't open the row.
1881
1901
 
1882
1902
  | Prop | Type | Default | Description |
1883
1903
  |---|---|---|---|
1884
1904
  | `aria-label` * | `string` | | The list's accessible name. |
1885
1905
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
1886
- | `data-force-row` | `string` | | Force a state on the first row for state matrices: hover, focus, selected. |
1906
+ | `data-force-row` | `string` | | Force a state on the first row for state matrices: hover, pressed, focus. |
1887
1907
  | `density` | `"default" \| "compact"` | `default` | How much room each row gets. |
1888
1908
  | `empty` | `ReactNode` | | Shown when there are no rows and the list isn't loading: usually an `Empty` (`size="md"` in a settings column, where it sits inside the list's card; `size="compact"` on an edge-to-edge page). |
1889
1909
  | `groups` | `ListGroup[]` | | …rows under group headers. |
1890
1910
  | `idWidth` | `48 \| 64 \| 80 \| 96 \| 120` | | A fixed width for the id column when ids differ in length, so titles align. By default the id takes its own width. |
1891
1911
  | `items` | `ListItemData[]` | | Rows without groups, or… |
1892
- | `loading` | `boolean` | | Loading rows shaped like items, while the rows aren't known yet. |
1912
+ | `loading` | `boolean` | | Loading rows shaped like items, under a group header's shape when the list has groups, while the rows aren't known yet. |
1893
1913
  | `onOpen` | `((item: ListItemData) => void)` | | Called when a row is opened with a click or Enter. Enter with ⌘ or Ctrl is left to the surrounding form. |
1894
1914
  | `onSelectedChange` | `((selected: Set<string>) => void)` | | Called with the selected rows; rows then get checkboxes. |
1895
1915
  | `selectable` | `boolean` | | Selection: checkboxes appear on hover, and on every row once something is selected. |
1896
1916
  | `selected` | `Set<string>` | | The ids of the selected rows. |
1897
1917
  | `selectionActions` | `ReactNode` | | Actions in the floating selection bar. |
1898
- | `selectionBar` | `boolean` | `true` | The floating selection bar; off where the host shows the count itself, as in a dialog. |
1918
+ | `selectionBar` | `boolean` | `true` | The floating selection bar; off where the host shows the count itself, as in a dialog. Rows reached with the arrow keys scroll clear of it. |
1899
1919
  | `virtualizeAbove` | `number` | `100` | Virtualize above this many rows (100). |
1900
1920
  | `wrapSubtitle` | `boolean` | `false` | Lets a subtitle under its title wrap instead of ending with an ellipsis, for descriptions people read in full. |
1901
1921
 
@@ -1913,7 +1933,7 @@ One row: checkbox, glyph, id, title, subtitle, metadata, date, avatar, hover act
1913
1933
  | `idWidth` | `48 \| 64 \| 80 \| 96 \| 120` | | The width of the id column in pixels, so ids line up. |
1914
1934
  | `index` | `number` | | The row's position, for keyboard navigation. |
1915
1935
  | `lastChild` | `boolean` | | Marks the last child of a parent, for the connecting line. |
1916
- | `narrow` | `boolean` | `false` | The list is narrow (a phone): the title, the subtitle and the metadata with the date are lines of their own. |
1936
+ | `narrow` | `boolean` | `false` | The list is narrow (a phone): the title and the subtitle are lines of their own, and the metadata, the date, the avatar and the actions share one line under them, so titles keep the row's width. |
1917
1937
  | `onFocus` | `(() => void)` | | Called when the row gets focus. |
1918
1938
  | `onOpen` | `(() => void)` | | Called when the row is opened. |
1919
1939
  | `onSelect` | `(() => void)` | | Called when the row is selected or unselected. |
@@ -1953,15 +1973,15 @@ The floating capsule with the selection count and its actions: the toast's mater
1953
1973
 
1954
1974
  ### Loader
1955
1975
 
1956
- A status region with the spinner and a label: "Saving provider…", or a page or region that is loading. Its place is kept while it waits out `delay`, so nothing moves when it shows.
1976
+ A status region with the spinner and a label: "Saving provider…", or a page or region that is loading. Its place is kept while it waits out `delay`, so nothing moves when it shows; the status region is there, empty, from the start, and its words arrive when the spinner shows, so screen readers announce them.
1957
1977
 
1958
1978
  | Prop | Type | Default | Description |
1959
1979
  |---|---|---|---|
1960
- | `delay` | `number \| boolean` | | Waits before the spinner and its label show, so quick work shows nothing: `true` for the library's 300ms (`useDelayedLoading`), or milliseconds. None by default. |
1980
+ | `delay` | `number \| boolean` | | Waits before the spinner and its label show, so quick work shows nothing: the library's 300ms by default (`useDelayedLoading`), a number of milliseconds, or `false` to show at once. |
1961
1981
  | `hideLabel` | `boolean` | | Keeps `label` for assistive technology only, where the page around it already says what is happening. |
1962
1982
  | `label` | `string` | | Shown beside the spinner ("Saving provider…"); without one, "Loading" is announced in the provider's language. |
1963
1983
  | `loading` | `boolean` | `true` | Whether the work is underway; true by default. With `delay` and `minDuration`, it times the spinner. |
1964
- | `minDuration` | `number` | | Once shown, they stay at least this many milliseconds: 400 with a delay, 0 without. |
1984
+ | `minDuration` | `number` | | Once shown, they stay at least this many milliseconds: 400 by default, 0 with `delay={false}`. |
1965
1985
  | `size` | `"md" \| "xs" \| "sm" \| "lg" \| "xl"` | `sm` | The loader's size on the type scale. |
1966
1986
  | `tone` | `"secondary" \| "tertiary" \| "current"` | | The spinner's and the label's color: `secondary` by default. |
1967
1987
 
@@ -2000,7 +2020,7 @@ Kaeso's spinner: three routes on a ring, the lead in full color and the two behi
2000
2020
 
2001
2021
  ### Markdown
2002
2022
 
2003
- Markdown, safely: headings, paragraphs, lists, tasks, code fences (CodeBlock), inline code, emphasis, links, quotes, rules and tables. Raw HTML stays text, links open only for http, https and mailto in a new tab, images are links. Long texts show their start until "Show all".
2023
+ Markdown, safely: headings, paragraphs, lists, tasks, code fences (CodeBlock), inline code, emphasis, links, quotes, rules and tables. Raw HTML stays text, links open only for http, https and mailto in a new tab, images are links. Long texts show their start until "Show all". A table wider than its column scrolls sideways with a fade and takes focus.
2004
2024
 
2005
2025
  | Prop | Type | Default | Description |
2006
2026
  |---|---|---|---|
@@ -2028,12 +2048,12 @@ The same menu, opened by a right click, a long press or the context-menu key on
2028
2048
 
2029
2049
  | Prop | Type | Default | Description |
2030
2050
  |---|---|---|---|
2031
- | `children` * | `ReactNode` | | The area that opens the menu on a right click or long press. |
2051
+ | `children` * | `ReactNode` | | The area that opens the menu on a right click or long press. When it holds nothing focusable, it becomes a focus stop, so Shift F10 and the context-menu key reach it; the focus returns to it when the menu closes. |
2032
2052
  | `onOpenChange` | `((open: boolean) => void)` | | Called when it opens or closes. |
2033
2053
 
2034
2054
  ### Menu
2035
2055
 
2036
- A dropdown menu: 16px radius, 34px rows, typeahead, Home/End, loops.
2056
+ A dropdown menu: 16px radius, 34px rows that grow when a label wraps, typeahead, Home/End, loops. An item's shortcut and hint describe it rather than name it. Checkbox and radio items show a check when chosen; the group's label says whether it takes one or several.
2037
2057
 
2038
2058
  | Prop | Type | Default | Description |
2039
2059
  |---|---|---|---|
@@ -2057,18 +2077,18 @@ A row of menus, as in a desktop app's title bar.
2057
2077
 
2058
2078
  `import { Meter, Progress } from "@logicplanes/kaeso-ui/meter";`
2059
2079
 
2060
- - **tone** (meter): `auto` (default) — Series 1 until the first alert threshold, warning after, danger at 100% (default); `neutral` — A plain share
2080
+ - **tone** (meter): `auto` (default) — Series 1 until the first alert threshold, amber (series 2) after, danger at 100%; the value and the caption take the warning or danger color too (default); `neutral` — A plain share
2061
2081
  - **kind** (progress): `determinate` (default) — A pill bar with a known amount; `indeterminate` — A 2px line at the top of a container
2062
2082
 
2063
2083
  ### Meter
2064
2084
 
2065
- A limit or quota: label and value, a 6px pill track, threshold ticks, a caption.
2085
+ A limit or quota: label and value, a 6px pill track, threshold ticks cut out of the bar, a caption. Past the first threshold the bar turns amber and the value and caption turn the warning color, at the limit red, and screen readers hear "near the limit" or "over the limit" after the value; in light the bar's end keeps 3:1 against the track.
2066
2086
 
2067
2087
  | Prop | Type | Default | Description |
2068
2088
  |---|---|---|---|
2069
2089
  | `value` * | `number` | | 0–1 (or more when over the limit). |
2070
2090
  | `aria-label` | `string` | | The accessible name, for when there is no visible label. |
2071
- | `caption` | `ReactNode` | | "Resets in 12 days" |
2091
+ | `caption` | `ReactNode` | | "Resets in 12 days"; near or over the limit, say what happens, such as "Over the limit: requests are refused". |
2072
2092
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
2073
2093
  | `label` | `ReactNode` | | The label above the bar. |
2074
2094
  | `leading` | `ReactNode` | | Leading content in the label row (an icon). |
@@ -2079,7 +2099,7 @@ A limit or quota: label and value, a 6px pill track, threshold ticks, a caption.
2079
2099
 
2080
2100
  ### Progress
2081
2101
 
2082
- Progress for work over a second: a determinate pill, or an indeterminate 2px line.
2102
+ Progress for work over a second: a determinate pill, or an indeterminate 2px line. With reduced motion the indeterminate line spans the width and pulses instead of sliding, so it never reads as a third done.
2083
2103
 
2084
2104
  | Prop | Type | Default | Description |
2085
2105
  |---|---|---|---|
@@ -2091,7 +2111,7 @@ Progress for work over a second: a determinate pill, or an indeterminate 2px lin
2091
2111
 
2092
2112
  `import { PageHeader } from "@logicplanes/kaeso-ui/page-header";`
2093
2113
 
2094
- - **size** (page_header): `md` (default) — 52px, no bottom line (default); on a phone the tabs take a second row
2114
+ - **size** (page_header): `md` (default) — 52px, no bottom line (default); on a phone the title and actions keep the first row and the tabs take a second
2095
2115
 
2096
2116
  ### PageHeader
2097
2117
 
@@ -2166,7 +2186,7 @@ Big numbers, period controls, a chart on the panel, a breakdown, an optional rig
2166
2186
 
2167
2187
  `import { Pagination } from "@logicplanes/kaeso-ui/pagination";`
2168
2188
 
2169
- - **variant** (pagination): `load-more` (default) — A “Load more” pill while more rows exist, nothing once all are shown (cursor APIs, default); `cursor` — Previous and next circles, without a count; `pages` — Page numbers, for lists with a known number of pages
2189
+ - **variant** (pagination): `load-more` (default) — A “Load more” pill while more rows exist; once all are shown, nothing, or “All rows shown” where the button had focus (cursor APIs, default); `cursor` — Previous and next circles, without a count; `pages` — Page numbers in seven fixed slots, so Next stays under the pointer, for lists with a known number of pages
2170
2190
 
2171
2191
  ### Pagination
2172
2192
 
@@ -2175,14 +2195,14 @@ Moves through long lists by pages, by cursor, or with a Load more button.
2175
2195
  | Prop | Type | Default | Description |
2176
2196
  |---|---|---|---|
2177
2197
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
2178
- | `hasMore` | `boolean` | | Whether there is a next page. |
2198
+ | `hasMore` | `boolean` | | Whether there is a next page; with Load more, turning it off after the last load shows “All rows shown” where focus was. |
2179
2199
  | `hasPrevious` | `boolean` | | Whether there is a previous page. |
2180
2200
  | `loading` | `boolean` | | Shows that a page is loading. |
2181
2201
  | `onLoadMore` | `(() => void)` | | Called by the Load more button. |
2182
2202
  | `onNext` | `(() => void)` | | Called to go to the next page. |
2183
2203
  | `onPageChange` | `((page: number) => void)` | | Called with the chosen page number. |
2184
2204
  | `onPrevious` | `(() => void)` | | Called to go to the previous page. |
2185
- | `page` | `number` | `1` | pages: |
2205
+ | `page` | `number` | `1` | The current page, for numbered pages; previous and next stay in place and only announce themselves unavailable at the ends. |
2186
2206
  | `pageCount` | `number` | `1` | The number of pages, for numbered pages. |
2187
2207
  | `variant` | `"cursor" \| "load-more" \| "pages"` | `load-more` | Numbered pages, previous and next by cursor, or a Load more button. |
2188
2208
 
@@ -2201,7 +2221,7 @@ Moves through long lists by pages, by cursor, or with a Load more button.
2201
2221
 
2202
2222
  ### CompareGrid
2203
2223
 
2204
- Columns side by side to compare models: equal widths, a header, a body that scrolls on its own and a footer each.
2224
+ Columns side by side to compare models: equal widths of at least 320px, a header, a body that scrolls on its own and a footer each. When the columns don't fit, Previous column and Next column reach the hidden ones. Removing a column is instant, so offer Undo in a toast.
2205
2225
 
2206
2226
  | Prop | Type | Default | Description |
2207
2227
  |---|---|---|---|
@@ -2213,15 +2233,15 @@ Columns side by side to compare models: equal widths, a header, a body that scro
2213
2233
  | `divider` | `"none" \| "hairline"` | `hairline` | A hairline between columns, or none. |
2214
2234
  | `max` | `number` | `4` | Columns at most (4 by default): the add circle is disabled there, with the reason in its tooltip. |
2215
2235
  | `onActiveChange` | `((index: number) => void)` | | Called with the index of the column in focus. |
2216
- | `onAdd` | `(() => void)` | | Adds a column: a circle at the end of the last column's header (and in the phone's switcher). |
2236
+ | `onAdd` | `(() => void)` | | Adds a column: a circle in a narrow rail after the columns (on a phone, in the switcher, or in the header of a single column). Focus moves to the new column's header. |
2217
2237
 
2218
2238
  ### Composer
2219
2239
 
2220
- The prompt box: a text box that grows with what is written up to `maxRows`, then scrolls; Send, which becomes Stop while a response streams. Enter sends and Shift Enter adds a line (`submitOn`); ⌘ Enter or Ctrl Enter also sends. On a touch screen Enter adds a line and the button sends.
2240
+ The prompt box: a text box that grows with what is written up to `maxRows`, then scrolls, its edge fading where more lines wait; Send, which becomes Stop while a response streams. Enter sends and Shift Enter adds a line (`submitOn`); ⌘ Enter or Ctrl Enter also sends. On a touch screen Enter adds a line and the button sends. A click anywhere in the box, the button row included, puts the cursor in the text.
2221
2241
 
2222
2242
  | Prop | Type | Default | Description |
2223
2243
  |---|---|---|---|
2224
- | `actions` | `ReactNode` | | Controls at the start of the button row: parameters, clear. |
2244
+ | `actions` | `ReactNode` | | Controls at the start of the button row: parameters, clear. Ghost and secondary buttons there take tones made for the composer's surface. |
2225
2245
  | `aria-label` | `string` | | The text box's accessible name ("Prompt" by default). |
2226
2246
  | `autoFocus` | `boolean` | | Focuses the composer when it appears. |
2227
2247
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
@@ -2237,9 +2257,9 @@ The prompt box: a text box that grows with what is written up to `maxRows`, then
2237
2257
  | `onValueChange` | `((value: string) => void)` | | Called with the message as it is typed. |
2238
2258
  | `placeholder` | `string` | | Text shown while there is no value. |
2239
2259
  | `size` | `"md" \| "sm"` | `md` | The composer's height. |
2240
- | `stopLabel` | `string` | | The stop button's accessible name, shown while a reply streams. |
2241
- | `streaming` | `boolean` | `false` | A response is arriving: Send becomes Stop. The text box stays editable for the next prompt. |
2242
- | `submitLabel` | `string` | | The send button's accessible name. |
2260
+ | `stopLabel` | `string` | | The Stop button's label, shown while a response streams ("Stop" by default). |
2261
+ | `streaming` | `boolean` | `false` | A response is arriving: Send becomes Stop. The text box stays editable for the next prompt; Enter waits, and the text box's description says to stop the response to send. |
2262
+ | `submitLabel` | `string` | | The Send button's label ("Send" by default). |
2243
2263
  | `submitOn` | `"enter" \| "mod-enter"` | `enter` | The key that sends from the text box. `"enter"` (default): Enter sends and Shift Enter adds a line; on a touch screen Enter adds a line and the Send button sends. `"mod-enter"`: Enter adds a line and only ⌘ Enter (Ctrl Enter) sends. ⌘ Enter and Ctrl Enter send with either. |
2244
2264
  | `value` | `string` | | The message being written, when you control it. |
2245
2265
 
@@ -2278,7 +2298,7 @@ A model from a catalogue of any size: a pill showing the chosen model that opens
2278
2298
 
2279
2299
  ### ParameterPanel
2280
2300
 
2281
- A request's parameters: system instructions, temperature, top P, most output tokens, and, for a model that reasons, reasoning effort and summary. Unset values are the model's defaults; Reset returns to them (instructions stay).
2301
+ A request's parameters: system instructions, temperature, top P, maximum output tokens, and, for a model that reasons, reasoning effort and summary. Unset values are the model's defaults; Reset returns to them (instructions stay).
2282
2302
 
2283
2303
  | Prop | Type | Default | Description |
2284
2304
  |---|---|---|---|
@@ -2289,13 +2309,13 @@ A request's parameters: system instructions, temperature, top P, most output tok
2289
2309
  | `disabled` | `boolean` | `false` | Turns off every parameter. |
2290
2310
  | `instructions` | `boolean` | `true` | Shows the system instructions field (true by default). |
2291
2311
  | `layout` | `"popover" \| "panel"` | `popover` | Compact inside a popover, or roomier in a side panel. |
2292
- | `maxOutputTokensLimit` | `number` | | The model's most output tokens: the field's maximum. |
2312
+ | `maxOutputTokensLimit` | `number` | | The model's maximum output tokens: the field's maximum, named in a hint under it. |
2293
2313
  | `reasoning` | `boolean \| ReasoningEffort[]` | `false` | The reasoning efforts the model takes, or false (the default) when it doesn't reason: no effort and no summary. |
2294
2314
  | `sampling` | `boolean` | `true` | Shows temperature and top P; models that reason often take neither (true by default). |
2295
2315
 
2296
2316
  ### ParameterPopover
2297
2317
 
2298
- ParameterPanel in a 320px popover from a sliders circle (or any trigger).
2318
+ ParameterPanel in a 320px popover from a sliders circle (or any trigger), with a Close button beside its title. Focus stays inside until it closes.
2299
2319
 
2300
2320
  | Prop | Type | Default | Description |
2301
2321
  |---|---|---|---|
@@ -2306,7 +2326,7 @@ ParameterPanel in a 320px popover from a sliders circle (or any trigger).
2306
2326
  | `defaults` | `Pick<PlaygroundParameters, "temperature" \| "topP">` | | What unset shows (temperature 1 and top P 1 unless given): the model's defaults. |
2307
2327
  | `disabled` | `boolean` | `false` | Turns off the button that opens the parameters. |
2308
2328
  | `instructions` | `boolean` | `true` | Shows the system instructions field (true by default). |
2309
- | `maxOutputTokensLimit` | `number` | | The model's most output tokens: the field's maximum. |
2329
+ | `maxOutputTokensLimit` | `number` | | The model's maximum output tokens: the field's maximum, named in a hint under it. |
2310
2330
  | `onOpenChange` | `((open: boolean) => void)` | | Called when it opens or closes. |
2311
2331
  | `open` | `boolean` | | Whether it is open, when you control it. |
2312
2332
  | `reasoning` | `boolean \| ReasoningEffort[]` | `false` | The reasoning efforts the model takes, or false (the default) when it doesn't reason: no effort and no summary. |
@@ -2317,24 +2337,26 @@ ParameterPanel in a 320px popover from a sliders circle (or any trigger).
2317
2337
 
2318
2338
  ### PromptSuggestions
2319
2339
 
2320
- Example prompts before a thread starts: up to three lines of plain secondary text that take a quiet fill on hover. No outlines, no icons; leave them out once a prompt is sent.
2340
+ Example prompts before a thread starts: up to three pill rows of secondary text that take a quiet fill on hover. No outlines, no icons; a prompt too long for its row shows in full in a tooltip. Leave them out once a prompt is sent.
2321
2341
 
2322
2342
  | Prop | Type | Default | Description |
2323
2343
  |---|---|---|---|
2324
- | `onSelect` * | `(prompt: string) => void` | | Puts the prompt in the composer (or sends it). |
2344
+ | `onSelect` * | `(prompt: string) => void` | | Puts the prompt in the composer (or sends it). The list usually goes away then, so move focus to the composer. |
2325
2345
  | `suggestions` * | `string[]` | | Up to three short prompts; more are left out. |
2326
2346
  | `align` | `"start" \| "center"` | `start` | Aligns the suggestions at the start or in the center. |
2327
2347
  | `aria-label` | `string` | | The list's accessible name. Defaults to "Example prompts" in the provider's language. |
2328
2348
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
2349
+ | `data-force` | `string` | | Forces an interaction state for state matrices: `hover`, `pressed`, `focus`, `open`. |
2329
2350
 
2330
2351
  ### Reasoning
2331
2352
 
2332
- A model's reasoning behind a quiet disclosure, closed by default: “Thought for 4.2 s” when it is done, “Thinking” with the latest line beside it while it streams. Opened, the reasoning reads in small secondary text beside a line. The Playground and the request log show reasoning with it.
2353
+ A model's reasoning behind a quiet disclosure, closed by default: a chevron, then “Thought for 4.2 s” when it is done, or “Thinking” with the latest line beside it while it streams. Opened, the reasoning reads in small secondary text under the title, beside a line under the chevron. The Playground and the request log (ConversationView) show reasoning with it.
2333
2354
 
2334
2355
  | Prop | Type | Default | Description |
2335
2356
  |---|---|---|---|
2336
2357
  | `children` | `ReactNode` | | What the open disclosure shows in place of `text`, such as why the reasoning can't be shown. |
2337
2358
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
2359
+ | `data-force` | `string` | | Forces an interaction state for state matrices: `hover`, `pressed`, `focus`, `open`. |
2338
2360
  | `defaultOpen` | `boolean` | | Whether it starts open. |
2339
2361
  | `duration` | `number` | | How long the model reasoned, in milliseconds: “Thought for 4.2 s”. |
2340
2362
  | `hint` | `ReactNode` | | A short note beside the title, such as “Redacted by the provider”; while `live`, the latest line of the reasoning shows there instead. |
@@ -2346,25 +2368,25 @@ A model's reasoning behind a quiet disclosure, closed by default: “Thought for
2346
2368
 
2347
2369
  ### ResponseMetrics
2348
2370
 
2349
- A response's numbers on one line: time to first token, total time, tokens ("412 in · 168 out", and reasoning), cost to the millionth of a dollar, as request logs show it. Tabular figures, labels in tertiary text. While `live`, values not known yet show "—" in the room they will take; before any response the line is empty, its height kept.
2371
+ A response's numbers on one line: time to first token, total time, tokens ("412 in · 168 out", and reasoning), cost with the decimals it was given, as request logs show it. Tabular figures, labels in tertiary text. Every value keeps the room a typical value takes, so nothing moves when values arrive; while `live`, values not known yet show "—"; before any response the line is empty, its height kept.
2350
2372
 
2351
2373
  | Prop | Type | Default | Description |
2352
2374
  |---|---|---|---|
2353
2375
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
2354
- | `cost` | `string \| null` | | USD as a decimal string: "0.004213" reads "$0.004213", and zero reads "$0". |
2376
+ | `cost` | `string \| null` | | USD as a decimal string, shown with its own decimals (two at least, six at most): "0.004213" reads "$0.004213", "1.2311" reads "$1.2311", zero reads "$0" and less than a millionth reads "< $0.000001". |
2355
2377
  | `duration` | `number \| null` | | Milliseconds from sending to the last token. |
2356
2378
  | `inputTokens` | `number \| null` | | The tokens sent, once known. |
2357
2379
  | `live` | `boolean` | `false` | A response is arriving: values not known yet show a quiet "—" in the room they will take. |
2358
2380
  | `outputTokens` | `number \| null` | | The tokens received, once known. |
2359
2381
  | `reasoning` | `boolean` | | The model reasons: while `live`, the reasoning item waits with a placeholder. |
2360
- | `reasoningTokens` | `number \| null` | | Of the output tokens, those spent reasoning. Shown when given, or when `reasoning` is set. |
2382
+ | `reasoningTokens` | `number \| null` | | Of the output tokens, those spent reasoning. Shown when given, or when `reasoning` is set ("—" when the provider didn't report them). |
2361
2383
  | `size` | `"md" \| "sm"` | `sm` | The text size. |
2362
- | `startedAt` | `number` | | When the request was sent (Date.now()): while live, Total counts up quietly until `duration` arrives. |
2384
+ | `startedAt` | `number` | | When the request was sent (Date.now()): while live, Total counts up quietly, in tenths of a second and in whole seconds past ten, until `duration` arrives. |
2363
2385
  | `timeToFirstToken` | `number \| null` | | Milliseconds from sending to the first token. |
2364
2386
 
2365
2387
  ### ResponseView
2366
2388
 
2367
- A model's response as it arrives: Markdown text for reading (15/22), the reasoning summary in a "Thinking" disclosure (closed by default, live while it streams), and calm states for a stop, a cut-off reply or a failure, which shows its error in place.
2389
+ A model's response as it arrives: a quiet caret where the text will start until the first token, then Markdown text for reading (15/22) with the caret at its end while it streams; the reasoning summary in a "Thinking" disclosure (closed by default, live while it streams); and calm states for a stop, a cut-off reply or a failure, which shows its error in place. Text sits 12px in, code and tables on the edge; screen readers hear when a response finishes or stops.
2368
2390
 
2369
2391
  | Prop | Type | Default | Description |
2370
2392
  |---|---|---|---|
@@ -2372,10 +2394,10 @@ A model's response as it arrives: Markdown text for reading (15/22), the reasoni
2372
2394
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
2373
2395
  | `defaultReasoningOpen` | `boolean` | | Whether the reasoning starts expanded. |
2374
2396
  | `error` | `string` | | Why the reply failed, shown under "No response" with status "error": the gateway's message in the reader's language; `code` spans render as code. |
2375
- | `footer` | `ReactNode` | | Under the response: its metrics, actions. |
2397
+ | `footer` | `ReactNode` | | Under the response, on its text line: its metrics, actions. |
2376
2398
  | `incompleteReason` | `string` | | Why the model cut the reply off, with status "incomplete": `max_output_tokens` reads "Stopped at the output limit", `content_filter` names the filter. |
2377
2399
  | `onReasoningOpenChange` | `((open: boolean) => void)` | | Called when the reasoning is expanded or collapsed. |
2378
- | `onRetry` | `(() => void)` | | Sends the turn again; shown with an error, a stop or a cut-off reply. |
2400
+ | `onRetry` | `(() => void)` | | Sends the turn again: a Retry button after a stop, a cut-off reply or an error. |
2379
2401
  | `reasoning` | `string` | | The reasoning summary so far, as Markdown. A "Thinking" disclosure shows it, closed by default. |
2380
2402
  | `reasoningDuration` | `number` | | How long the model reasoned, in milliseconds: "Thought for 4.2 s". |
2381
2403
  | `reasoningOpen` | `boolean` | | Whether the reasoning is expanded, when you control it. |
@@ -2393,7 +2415,7 @@ A conversation's turns, 32px apart: spacing, not lines or boxes, separates them.
2393
2415
 
2394
2416
  ### UserMessage
2395
2417
 
2396
- A person's turn: their prompt as quiet text that opens the turn, no bubble. A long prompt shows its first lines until "Show all".
2418
+ A person's turn: their prompt as quiet text that opens the turn, no bubble. A long prompt shows its first lines until "Show all", a disclosure button under them.
2397
2419
 
2398
2420
  | Prop | Type | Default | Description |
2399
2421
  |---|---|---|---|
@@ -2421,7 +2443,7 @@ A preview that opens while the pointer rests on its trigger or the trigger has f
2421
2443
 
2422
2444
  ### Popover
2423
2445
 
2424
- A floating panel next to its trigger: radius 16, raised; collision-aware.
2446
+ A floating panel next to its trigger: radius 16, raised; collision-aware and never wider than the screen. Its content takes a title, or an aria-label, which names it.
2425
2447
 
2426
2448
  | Prop | Type | Default | Description |
2427
2449
  |---|---|---|---|
@@ -2565,7 +2587,7 @@ A release's artwork: flat geometric art in one of eight styles and Kaeso's palet
2565
2587
 
2566
2588
  ### ResourceList
2567
2589
 
2568
- A console list of resources: search, group headers, row actions and a selection bar.
2590
+ A console list of resources: search, group headers, row actions and a selection bar. A search announces how many rows it leaves, and its no-match state offers Clear search.
2569
2591
 
2570
2592
  | Prop | Type | Default | Description |
2571
2593
  |---|---|---|---|
@@ -2574,7 +2596,7 @@ A console list of resources: search, group headers, row actions and a selection
2574
2596
  | `bulkActions` | `{ label: string; icon?: IconSvgElement; onClick: (ids: string[]) => void; }[]` | `[]` | Actions for selected rows: [{label, icon, onClick(ids)}]. |
2575
2597
  | `emptyAction` | `ReactNode` | | The action shown when there are no items. |
2576
2598
  | `emptyDescription` | `string` | | The sentence shown when there are no items. |
2577
- | `emptyTitle` | `string` | | Defaults to "Nothing here yet" in the provider's language. |
2599
+ | `emptyTitle` | `string` | | What will appear, such as "No keys yet". Pass it: the default names the collection by its `aria-label` ("No keys yet", in the provider's language), which only reads well for a plural noun. |
2578
2600
  | `onOpen` | `((item: ListItemData) => void)` | | Called when an item is opened. |
2579
2601
  | `toolbar` | `ReactNode` | | The filters and display options above the list. |
2580
2602
 
@@ -2582,11 +2604,11 @@ A console list of resources: search, group headers, row actions and a selection
2582
2604
 
2583
2605
  `import { ScrollArea } from "@logicplanes/kaeso-ui/scroll-area";`
2584
2606
 
2585
- - **orientation** (scroll_area): `vertical` (default) — Scrolls up and down; the content fades at an edge with more to scroll to (default); `horizontal` — Scrolls sideways; `both` — Both directions
2607
+ - **orientation** (scroll_area): `vertical` (default) — Scrolls up and down; the content fades at an edge with more to scroll to (default); `horizontal` — Scrolls sideways; `both` — Both directions; the content fades at every edge with more to scroll to
2586
2608
 
2587
2609
  ### ScrollArea
2588
2610
 
2589
- A scroll container with thin scrollbars in the strong line color that show on hover (5.1), its content fading at an edge with more to scroll to.
2611
+ A scroll container with thin scrollbars that show on hover and darken while held, its content fading at every edge with more to scroll to; its focus ring sits above the fade.
2590
2612
 
2591
2613
  | Prop | Type | Default | Description |
2592
2614
  |---|---|---|---|
@@ -2694,7 +2716,7 @@ A pill that opens a list on the menu surface: check on the selected item, groups
2694
2716
  | `onValueChange` | `((value: string) => void) \| ((value: string[]) => void)` | | Called with the chosen value, or the list of values with `multiple`. |
2695
2717
  | `open` | `boolean` | | Whether the list is open, when you control it. |
2696
2718
  | `optional` | `boolean` | | Adds “Optional” to the label, for forms where most fields are required. |
2697
- | `placeholder` | `ReactNode` | | Defaults to "Select" in the provider's language. |
2719
+ | `placeholder` | `ReactNode` | | Defaults to "Not set" in the provider's language. |
2698
2720
  | `required` | `boolean` | | Marks it as required in a form. |
2699
2721
  | `size` | `"md" \| "sm" \| "lg" \| "xl"` | | The height of the field. |
2700
2722
  | `value` | `string \| string[] \| null` | | The chosen value, or a list of values with `multiple`, when you control it. |
@@ -2776,17 +2798,17 @@ A panel that slides in from the edge of the screen, for details and longer forms
2776
2798
  | Prop | Type | Default | Description |
2777
2799
  |---|---|---|---|
2778
2800
  | `children` * | `ReactNode` | | The sheet's content. |
2779
- | `title` * | `ReactNode` | | The sheet's heading, also its accessible name. |
2801
+ | `title` * | `ReactNode` | | The sheet's heading, also its accessible name; a long one wraps. |
2780
2802
  | `actions` | `ReactNode` | | Header actions before the close circle. |
2781
2803
  | `defaultOpen` | `boolean` | | Whether it starts open, when the component keeps its own state. |
2782
2804
  | `footer` | `ReactNode` | | Content at the bottom, usually actions. |
2783
2805
  | `inline` | `boolean` | | Render without a portal, for documentation and state matrices. |
2784
- | `modal` | `boolean` | | Keep the page behind interactive (non-modal). |
2806
+ | `modal` | `boolean` | | `false` keeps the page behind interactive, for an inspector: a press on the page leaves the sheet open, so the next row can fill it; Escape and the close circle close it. |
2785
2807
  | `onOpenChange` | `((open: boolean) => void)` | | Called when it opens or closes. |
2786
2808
  | `open` | `boolean` | | Whether it is open, when you control it. |
2787
2809
  | `side` | `"bottom" \| "left" \| "right"` | | The edge it slides in from. |
2788
- | `size` | `"md" \| "sm" \| "lg"` | | The sheet's width, or its height from the bottom. |
2789
- | `subtitle` | `ReactNode` | | A mono subtitle for ids: `req_01J…`. |
2810
+ | `size` | `"md" \| "sm" \| "lg"` | | The sheet's width from the side; a sheet from the bottom takes its content's height and ignores it. |
2811
+ | `subtitle` | `ReactNode` | | A mono subtitle for ids, shown whole: `req_01J…`. |
2790
2812
  | `trigger` | `ReactElement<unknown, string \| JSXElementConstructor<any>>` | | The element that opens it. |
2791
2813
 
2792
2814
  ## sidebar
@@ -2827,7 +2849,7 @@ Provided by NavSheet: how the sidebar's own toggle closes the sheet it floats in
2827
2849
 
2828
2850
  ### Skeleton
2829
2851
 
2830
- A placeholder in the shape of the content that is loading.
2852
+ A placeholder in the shape of the content that is loading. It is hidden from screen readers, so the region it stands in for sets `aria-busy` while it loads (List, DataTable and StatTile do). In forced colours it keeps an outline.
2831
2853
 
2832
2854
  | Prop | Type | Default | Description |
2833
2855
  |---|---|---|---|
@@ -2845,7 +2867,7 @@ Lines of text: the last one shorter.
2845
2867
 
2846
2868
  `import { Slider } from "@logicplanes/kaeso-ui/slider";`
2847
2869
 
2848
- - **size** (slider): `md` (default) — A 4px track in a 20px hit area (default)
2870
+ - **size** (slider): `md` (default) — A 4px track in a 32px hit area (default)
2849
2871
 
2850
2872
  ### Slider
2851
2873
 
@@ -2898,7 +2920,7 @@ A big number followed by its word, no box, as on a usage page.
2898
2920
 
2899
2921
  ### StatGrid
2900
2922
 
2901
- `StatTile`s in one raised group, divided by hairlines: two to a row, then as many as there are tiles (up to four) from 1024px. The last tile of a short row widens to fill it (the third of three spans both columns below 1024px), so the group never shows an empty cell. Where a number doesn't fit its tile (a phone, a long amount), every tile's number steps down a size, and the tiles take a row each when even the smallest doesn't fit: a value is never cut short.
2923
+ `StatTile`s in one raised group, divided by hairlines: two to a row, then as many as there are tiles (up to four) from 1024px. The last tile of a short row widens to fill it (the third of three spans both columns below 1024px), so the group never shows an empty cell. Where a number doesn't fit its tile (a phone, a long amount), every tile's number steps down a size, and the tiles take a row each when even the smallest doesn't fit. At the same width, live numbers only step the size down, never back up, so a digit that comes and goes doesn't make the tiles jump; a value that still can't fit ends in an ellipsis and shows in full in a tooltip.
2902
2924
 
2903
2925
  | Prop | Type | Default | Description |
2904
2926
  |---|---|---|---|
@@ -2914,7 +2936,7 @@ One metric of a dashboard row: its label, the number, the change against the pre
2914
2936
  |---|---|---|---|
2915
2937
  | `label` * | `ReactNode` | | What the number is: "Requests", "Cost". |
2916
2938
  | `value` * | `ReactNode` | | The number, already formatted. |
2917
- | `change` | `{ value: number; better?: "up" \| "down"; }` | | The change against the previous period, as a fraction (0.12 is +12%). `better` says which direction is good: errors are better down. |
2939
+ | `change` | `{ value: number; better?: "up" \| "down"; }` | | The change against the previous period, as a fraction (0.12 is +12%). `better` says which direction is good: errors are better down. The badge is green or red and says "better" or "worse" to screen readers. |
2918
2940
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
2919
2941
  | `detail` | `ReactNode` | | A quiet line under the number: "vs. the previous 30 days", "0.4% of requests". |
2920
2942
  | `loading` | `boolean` | | While the numbers load: the value, the change and the trend show their shape at the tile's final height. |
@@ -2936,7 +2958,7 @@ The same component under its plain name.
2936
2958
  | `children` | `ReactNode` | | The word that carries the meaning. |
2937
2959
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
2938
2960
  | `icon` | `IconSvgElement` | | A mark before the word in the same color, e.g. `icons.success` for “Up to date”. |
2939
- | `size` | `"md" \| "sm"` | `md` | The text size. |
2961
+ | `size` | `"md" \| "sm"` | `md` | The text size: 14px, or 13px (`sm`) with a 14px icon. |
2940
2962
  | `tone` | `"neutral" \| "success" \| "warning" \| "danger" \| "info"` | `neutral` | The status it marks. |
2941
2963
 
2942
2964
  ### StatusDot
@@ -2948,8 +2970,8 @@ A status word: "Active", "Expiring", "Down".
2948
2970
  | `children` | `ReactNode` | | The word that carries the meaning. |
2949
2971
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
2950
2972
  | `icon` | `IconSvgElement` | | A mark before the word in the same color, e.g. `icons.success` for “Up to date”. |
2951
- | `size` | `"md" \| "sm"` | `md` | The dot's size. |
2952
- | `tone` | `"neutral" \| "success" \| "warning" \| "danger" \| "info"` | `neutral` | The status the dot marks; keep it next to words that say the same. |
2973
+ | `size` | `"md" \| "sm"` | `md` | The text size: 14px, or 13px (`sm`) with a 14px icon. |
2974
+ | `tone` | `"neutral" \| "success" \| "warning" \| "danger" \| "info"` | `neutral` | The status the word marks; keep it next to words that say the same. |
2953
2975
 
2954
2976
  ## surface
2955
2977
 
@@ -3001,10 +3023,10 @@ A pill track and a round thumb that travels in 180ms.
3001
3023
  | `defaultChecked` | `boolean` | | Whether it starts checked, when the component keeps its own state. |
3002
3024
  | `description` | `ReactNode` | | One sentence of help under the label. |
3003
3025
  | `disabled` | `boolean` | | Turns it off: it can't be used, and it looks dimmed. |
3004
- | `disabledReason` | `string` | | Why it is disabled, shown as a tooltip; it stays focusable so people can read it. |
3026
+ | `disabledReason` | `string` | | Why it is disabled: shown under the label when there is one, and as a tooltip; it stays focusable so people can read it. |
3005
3027
  | `id` | `string` | | The id of the control, so a label elsewhere can point to it. |
3006
3028
  | `label` | `ReactNode` | | The switch's label. |
3007
- | `loading` | `boolean` | | Shows that the change is being saved and ignores clicks until it is. |
3029
+ | `loading` | `boolean` | | Shows that the change is being saved: it ignores clicks at once, and a spinner shows in the track once saving takes 300ms. |
3008
3030
  | `name` | `string` | | The field name the value is sent under in a form. |
3009
3031
  | `onCheckedChange` | `((checked: boolean) => void)` | | Called with the new state when it is checked or unchecked. |
3010
3032
  | `readOnly` | `boolean` | | Shows the value without letting people change it. |
@@ -3019,7 +3041,7 @@ A pill track and a round thumb that travels in 180ms.
3019
3041
 
3020
3042
  ### Table
3021
3043
 
3022
- A plain table for small amounts of data; use `DataTable` for sorting, selection and many rows.
3044
+ A plain table for small amounts of data; use `DataTable` for sorting, selection and many rows. It has no row boxes, so its text sits on the gutter, not 12px in; its rows are 40px like DataTable's and grow when a cell wraps. Wider than its room, it scrolls sideways inside its own box under an edge fade, and the box takes focus as a group named "Table, scrolls sideways". Keep ids and model names on one line with `className="whitespace-nowrap"` on their cells.
3023
3045
 
3024
3046
  | Prop | Type | Default | Description |
3025
3047
  |---|---|---|---|
@@ -3029,8 +3051,8 @@ A plain table for small amounts of data; use `DataTable` for sorting, selection
3029
3051
 
3030
3052
  `import { PillTabs, Tabs } from "@logicplanes/kaeso-ui/tabs";`
3031
3053
 
3032
- - **variant** (pill_tabs): `underline` — Underline tabs for detail pages: 40px, a 2px ink indicator that slides; `pill` (default) — Header tabs: separate 32px pills, the active one filled
3033
- - **variant** (tabs): `underline` (default) — Underline tabs for detail pages: 40px, a 2px ink indicator that slides; `pill` — Header tabs: separate 32px pills, the active one filled
3054
+ - **variant** (pill_tabs): `underline` — Underline tabs for detail pages: 40px, labels 12px in like every box, a 2px ink indicator under the label that slides; `pill` (default) — Header tabs: separate 32px pills, the active one filled; the first pill's edge on the gutter
3055
+ - **variant** (tabs): `underline` (default) — Underline tabs for detail pages: 40px, labels 12px in like every box, a 2px ink indicator under the label that slides; `pill` — Header tabs: separate 32px pills, the active one filled; the first pill's edge on the gutter
3034
3056
 
3035
3057
  ### PillTabs
3036
3058
 
@@ -3074,10 +3096,10 @@ Another name for Tag.
3074
3096
  | `children` * | `ReactNode` | | The pill's text. |
3075
3097
  | `data-force` | `string` | | Forces an interaction state for state matrices: `hover`, `pressed`, `focus`, `open`. |
3076
3098
  | `icon` | `IconSvgElement` | | An icon before the text. |
3077
- | `invalid` | `boolean` | | Marks a value that isn't accepted. |
3078
- | `onClick` | `((e: MouseEvent<HTMLElement, MouseEvent>) => void)` | | Renders a button with a hover fill. |
3099
+ | `invalid` | `boolean` | | Marks a value that isn't accepted: a red ring, red text and an error icon named "Not accepted", so it doesn't rest on color. |
3100
+ | `onClick` | `((e: MouseEvent<HTMLElement, MouseEvent>) => void)` | | Renders a button with the control's hover, press and focus: raised tags take the secondary button's material, outline tags the ghost's. |
3079
3101
  | `onRemove` | `((e: MouseEvent<HTMLButtonElement, MouseEvent>) => void)` | | Shows a remove circle; called with the click. |
3080
- | `pressed` | `boolean` | | For toggle pills (DisplayOptions). |
3102
+ | `pressed` | `boolean` | | For toggle pills (DisplayOptions): sets aria-pressed, and `true` draws the selected soft fill whatever the variant, so a toggle needs no variant swap. |
3081
3103
  | `removeLabel` | `string` | | The remove circle's accessible name. Defaults to "Remove" and the label in the provider's language. |
3082
3104
  | `size` | `"md" \| "sm"` | `md` | The pill's height. |
3083
3105
  | `variant` | `"outline" \| "soft" \| "raised"` | `raised` | Raised on the panel, soft fill, or outlined. |
@@ -3091,10 +3113,10 @@ A metadata pill: 28px, 13/500, an optional icon, an optional remove circle. A la
3091
3113
  | `children` * | `ReactNode` | | The tag's text. |
3092
3114
  | `data-force` | `string` | | Forces an interaction state for state matrices: `hover`, `pressed`, `focus`, `open`. |
3093
3115
  | `icon` | `IconSvgElement` | | An icon before the text. |
3094
- | `invalid` | `boolean` | | Marks a value that isn't accepted. |
3095
- | `onClick` | `((e: MouseEvent<HTMLElement, MouseEvent>) => void)` | | Renders a button with a hover fill. |
3116
+ | `invalid` | `boolean` | | Marks a value that isn't accepted: a red ring, red text and an error icon named "Not accepted", so it doesn't rest on color. |
3117
+ | `onClick` | `((e: MouseEvent<HTMLElement, MouseEvent>) => void)` | | Renders a button with the control's hover, press and focus: raised tags take the secondary button's material, outline tags the ghost's. |
3096
3118
  | `onRemove` | `((e: MouseEvent<HTMLButtonElement, MouseEvent>) => void)` | | Shows a remove circle; called with the click. |
3097
- | `pressed` | `boolean` | | For toggle pills (DisplayOptions). |
3119
+ | `pressed` | `boolean` | | For toggle pills (DisplayOptions): sets aria-pressed, and `true` draws the selected soft fill whatever the variant, so a toggle needs no variant swap. |
3098
3120
  | `removeLabel` | `string` | | The remove circle's accessible name. Defaults to "Remove" and the label in the provider's language. |
3099
3121
  | `size` | `"md" \| "sm"` | `md` | The tag's height. |
3100
3122
  | `variant` | `"outline" \| "soft" \| "raised"` | `raised` | Raised on the panel, soft fill, or outlined. |
@@ -3118,7 +3140,7 @@ Text in the type scale.
3118
3140
  | `mono` | `boolean` | | Geist Mono, for keys, ids, model ids and code. |
3119
3141
  | `tabular` | `boolean` | | Tabular numerals. On by default for `metric`. |
3120
3142
  | `tone` | `"success" \| "warning" \| "danger" \| "info" \| "inherit" \| "secondary" \| "default" \| "tertiary"` | `default` | The text color role; status tones go next to words that say the same. |
3121
- | `truncate` | `boolean` | | One line with an ellipsis; the full text appears in a tooltip when it is cut. |
3143
+ | `truncate` | `boolean` | | One line with an ellipsis; when it is cut, plain text becomes a focus stop whose tooltip shows all of it. |
3122
3144
  | `variant` | `"title" \| "display" \| "caption" \| "title-sm" \| "title-lg" \| "body" \| "small" \| "micro" \| "body-lg" \| "metric"` | `body` | The type style, from `micro` to `display`. |
3123
3145
  | `weight` | `"medium" \| "regular" \| "semibold"` | | The weight, when it differs from the type style's. |
3124
3146
 
@@ -3139,7 +3161,7 @@ An image drawn twice, once for each theme: it follows the site's theme setting,
3139
3161
  | `light` * | `string` | | The image's address for the light theme and for print. |
3140
3162
  | `aria-describedby` | `string` | | The id of a longer description, such as a diagram's text alternative. |
3141
3163
  | `className` | `string` | | Classes for the layout of the outer element: margin, width and placement, never its look. |
3142
- | `height` | `number` | | The image's own height in pixels, so the page keeps its place before it loads. |
3164
+ | `height` | `number` | | The image's own height in pixels. Pass it with `width` so the page keeps the image's place before it loads; without both, the content below moves when it arrives. |
3143
3165
  | `width` | `number` | | The image's own width in pixels; the image shrinks to its container, never grows past this. |
3144
3166
 
3145
3167
  ## theme-menu
@@ -3204,7 +3226,7 @@ A square image someone sent, such as a photo in a conversation: cropped to fill,
3204
3226
 
3205
3227
  ### Timeline
3206
3228
 
3207
- Events down a 1px line (the audit log): each event marks the line with a short 3px bar in its tone, no dots; titles, and times on the right.
3229
+ Events down a 1px line (the audit log): each event marks the line with a short 3px bar in its tone, no dots; titles, and times on the right. A toned event's title starts with its tone in words for screen readers ("Critical: Key revoked"), and a time with `datetime` shows the exact date and time in a tooltip.
3208
3230
 
3209
3231
  | Prop | Type | Default | Description |
3210
3232
  |---|---|---|---|
@@ -3224,7 +3246,7 @@ Events down a 1px line (the audit log): each event marks the line with a short 3
3224
3246
  | Prop | Type | Default | Description |
3225
3247
  |---|---|---|---|
3226
3248
  | `limit` | `number` | `3` | How many toasts show at once. |
3227
- | `timeout` | `number` | `5000` | How long a toast stays, in milliseconds. |
3249
+ | `timeout` | `number` | `5000` | How long a toast stays, in milliseconds; errors and toasts with an action stay until dismissed, unless `toast()` gets a timeout of its own. |
3228
3250
 
3229
3251
  ### ToastCapsule
3230
3252
 
@@ -3234,29 +3256,29 @@ The capsule alone, for documentation and state matrices.
3234
3256
  |---|---|---|---|
3235
3257
  | `title` * | `ReactNode` | | The message. |
3236
3258
  | `action` | `string` | | The label of the toast's action button. |
3237
- | `closable` | `boolean` | | Shows a close button. |
3259
+ | `closable` | `boolean` | | Shows the close button at its end, as a toast that stays until dismissed has. |
3238
3260
  | `data-force` | `string` | | Forces an interaction state for state matrices: `hover`, `pressed`, `focus`, `open`. |
3239
3261
  | `description` | `ReactNode` | | One more sentence, when the message needs it. |
3240
3262
  | `tone` | `"neutral" \| "success" \| "warning" \| "info" \| "loading" \| "error"` | `neutral` | The kind of message; `loading` shows a spinner. |
3241
3263
 
3242
3264
  ### Toaster
3243
3265
 
3244
- Mount once near the root. Three visible at most; 5s, paused on hover and focus; swipe or Escape to dismiss. With a client router that replaces <body> on navigation (Astro's ClientRouter), mount it in a persisted element inside a `PortalContainer`, so the toasts are not swapped away with the page.
3266
+ Mount once near the root. Three visible at most; 5s, paused on hover and focus; an error, or a toast with an action such as Undo, stays until it is dismissed; the close button, a swipe or Escape dismisses, and F6 moves the focus to the toasts. With a client router that replaces <body> on navigation (Astro's ClientRouter), mount it in a persisted element inside a `PortalContainer`, so the toasts are not swapped away with the page.
3245
3267
 
3246
3268
  | Prop | Type | Default | Description |
3247
3269
  |---|---|---|---|
3248
3270
  | `limit` | `number` | `3` | How many toasts show at once. |
3249
- | `timeout` | `number` | `5000` | How long a toast stays, in milliseconds. |
3271
+ | `timeout` | `number` | `5000` | How long a toast stays, in milliseconds; errors and toasts with an action stay until dismissed, unless `toast()` gets a timeout of its own. |
3250
3272
 
3251
3273
  ## toc
3252
3274
 
3253
3275
  `import { TableOfContents } from "@logicplanes/kaeso-ui/toc";`
3254
3276
 
3255
- - **state** (table_of_contents): `default` (default) — A heading; `active` — The heading in view, with a 2px ink bar
3277
+ - **state** (table_of_contents): `default` (default) — A heading; `active` — The heading in view, with a 2px ink bar on the rail (a solid line in forced colours)
3256
3278
 
3257
3279
  ### TableOfContents
3258
3280
 
3259
- "On this page": the heading in view in text color with a 2px ink bar.
3281
+ "On this page": the heading in view in text color with a 2px ink bar on the rail.
3260
3282
 
3261
3283
  | Prop | Type | Default | Description |
3262
3284
  |---|---|---|---|
@@ -3269,11 +3291,11 @@ Mount once near the root. Three visible at most; 5s, paused on hover and focus;
3269
3291
 
3270
3292
  `import { Toolbar } from "@logicplanes/kaeso-ui/toolbar";`
3271
3293
 
3272
- - **size** (toolbar): `md` (default) — 48px, 24px side padding, under the page header (default); `inset` — 48px without side padding, inside padded content
3294
+ - **size** (toolbar): `md` (default) — 48px, 24px side padding, under the page header (default); one tab stop, arrows move between controls; `inset` — 48px without side padding, inside padded content
3273
3295
 
3274
3296
  ### Toolbar
3275
3297
 
3276
- A row of controls above a list or a chart.
3298
+ A row of controls above a list or a chart: one tab stop, with the arrow keys moving between its controls.
3277
3299
 
3278
3300
  | Prop | Type | Default | Description |
3279
3301
  |---|---|---|---|
@@ -3289,7 +3311,7 @@ A row of controls above a list or a chart.
3289
3311
 
3290
3312
  ### Tooltip
3291
3313
 
3292
- A short label for a control, shown on hover and focus. Never on disabled elements without a reason.
3314
+ A short label for a control, shown on hover and focus. When it says more than the control's name, it is also the control's accessible description. Never on disabled elements without a reason.
3293
3315
 
3294
3316
  | Prop | Type | Default | Description |
3295
3317
  |---|---|---|---|
@@ -3300,14 +3322,14 @@ A short label for a control, shown on hover and focus. Never on disabled element
3300
3322
  | `disabled` | `boolean` | | Never shows the tooltip. |
3301
3323
  | `onOpenChange` | `((open: boolean) => void)` | | Called when it opens or closes. |
3302
3324
  | `open` | `boolean` | | Whether it is open, when you control it. |
3303
- | `shape` | `"pill" \| "multiline"` | `pill` | A pill for a short label, or a box for several lines. |
3325
+ | `shape` | `"pill" \| "multiline"` | `pill` | A pill for a short label, or a box for several lines; a pill too long for the screen wraps into the box. |
3304
3326
  | `shortcut` | `string[] \| string[][]` | | A shortcut shown after the text: `["mod", "k"]` or `[["g"], ["m"]]`. |
3305
3327
  | `side` | `"top" \| "bottom" \| "left" \| "right"` | | The side it opens on. |
3306
3328
  | `sideOffset` | `number` | | Distance from the trigger in px. |
3307
3329
 
3308
3330
  ### TooltipProvider
3309
3331
 
3310
- Tooltips open after 500ms, and instantly when moving between tooltipped siblings.
3332
+ Tooltips open once the pointer has rested on a control for 500ms, and instantly when moving between tooltipped siblings.
3311
3333
 
3312
3334
  | Prop | Type | Default | Description |
3313
3335
  |---|---|---|---|