@logicplanes/kaeso-ui 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/AGENTS.md +1 -0
  2. package/LICENSE +1 -1
  3. package/ai/component-guides.md +269 -7
  4. package/ai/component-registry.json +600 -800
  5. package/ai/component-registry.md +200 -141
  6. package/ai/icons.md +2 -2
  7. package/ai/tokens.md +1 -1
  8. package/dist/blocks/delete-resource.js +1 -1
  9. package/dist/blocks/pages.js +3 -3
  10. package/dist/blocks/resource-list.js +2 -2
  11. package/dist/chunks/app-frame-BXh-06HL.js +214 -0
  12. package/dist/chunks/app-frame-BXh-06HL.js.map +1 -0
  13. package/dist/chunks/{banner-BiziJuBZ.js → banner-DxGBPQ7p.js} +2 -2
  14. package/dist/chunks/{banner-BiziJuBZ.js.map → banner-DxGBPQ7p.js.map} +1 -1
  15. package/dist/chunks/{button-BHKAE6ui.js → button-DQvoOxVQ.js} +2 -2
  16. package/dist/chunks/{button-BHKAE6ui.js.map → button-DQvoOxVQ.js.map} +1 -1
  17. package/dist/chunks/{calendar-B5SSTE56.js → calendar-CN3YJi2k.js} +3 -3
  18. package/dist/chunks/{calendar-B5SSTE56.js.map → calendar-CN3YJi2k.js.map} +1 -1
  19. package/dist/chunks/code-BADhvsgC.js +33 -0
  20. package/dist/chunks/code-BADhvsgC.js.map +1 -0
  21. package/dist/chunks/{code-block-BbK6E4Eo.js → code-block-DxtladFW.js} +41 -37
  22. package/dist/chunks/code-block-DxtladFW.js.map +1 -0
  23. package/dist/chunks/{combobox-D8pQk22r.js → combobox-D30Wt11R.js} +4 -4
  24. package/dist/chunks/{combobox-D8pQk22r.js.map → combobox-D30Wt11R.js.map} +1 -1
  25. package/dist/chunks/{copy-button-mAzHjYXq.js → copy-button-DXxn-YYZ.js} +4 -4
  26. package/dist/chunks/{copy-button-mAzHjYXq.js.map → copy-button-DXxn-YYZ.js.map} +1 -1
  27. package/dist/chunks/{core-Bgefcs3z.js → core-K960A4OT.js} +119 -120
  28. package/dist/chunks/core-K960A4OT.js.map +1 -0
  29. package/dist/chunks/{date-popup-Er1oQwtU.js → date-popup-B-6xhb-1.js} +3 -3
  30. package/dist/chunks/{date-popup-Er1oQwtU.js.map → date-popup-B-6xhb-1.js.map} +1 -1
  31. package/dist/chunks/{de-BCg1eRVd.js → de-CTAo4KL7.js} +10 -10
  32. package/dist/chunks/de-CTAo4KL7.js.map +1 -0
  33. package/dist/chunks/dialog-LNKgPEsV.js +319 -0
  34. package/dist/chunks/dialog-LNKgPEsV.js.map +1 -0
  35. package/dist/chunks/{icon-Bha63LaN.js → icon-CBzvyEqC.js} +30 -29
  36. package/dist/chunks/icon-CBzvyEqC.js.map +1 -0
  37. package/dist/chunks/{icon-button-Bw67oKtx.js → icon-button-_x1RUphC.js} +3 -3
  38. package/dist/chunks/{icon-button-Bw67oKtx.js.map → icon-button-_x1RUphC.js.map} +1 -1
  39. package/dist/chunks/{identity-DQinp-Ep.js → identity-BtZC_d_Q.js} +3 -3
  40. package/dist/chunks/{identity-DQinp-Ep.js.map → identity-BtZC_d_Q.js.map} +1 -1
  41. package/dist/chunks/{input-Biakz6GB.js → input-CNTfI6YE.js} +2 -2
  42. package/dist/chunks/{input-Biakz6GB.js.map → input-CNTfI6YE.js.map} +1 -1
  43. package/dist/chunks/{input-group-DQqEPFj_.js → input-group-CYA1MEoZ.js} +2 -2
  44. package/dist/chunks/{input-group-DQqEPFj_.js.map → input-group-CYA1MEoZ.js.map} +1 -1
  45. package/dist/chunks/{iso-field-CznqNVrH.js → iso-field-1qmg7TP8.js} +2 -2
  46. package/dist/chunks/{iso-field-CznqNVrH.js.map → iso-field-1qmg7TP8.js.map} +1 -1
  47. package/dist/chunks/linear-scale-BWKeRqDX.js +37 -0
  48. package/dist/chunks/linear-scale-BWKeRqDX.js.map +1 -0
  49. package/dist/chunks/{link-tTapNTpM.js → link-vz9aV8WX.js} +9 -2
  50. package/dist/chunks/link-vz9aV8WX.js.map +1 -0
  51. package/dist/chunks/{list-CN8pO8lv.js → list-CzaiyNja.js} +119 -111
  52. package/dist/chunks/list-CzaiyNja.js.map +1 -0
  53. package/dist/chunks/{markdown-C-iJsYnd.js → markdown-5NyaHHfN.js} +6 -6
  54. package/dist/chunks/{markdown-C-iJsYnd.js.map → markdown-5NyaHHfN.js.map} +1 -1
  55. package/dist/chunks/{menu-OURWt_hD.js → menu-DyVPwgfF.js} +2 -2
  56. package/dist/chunks/{menu-OURWt_hD.js.map → menu-DyVPwgfF.js.map} +1 -1
  57. package/dist/chunks/nav-sheet-BIErlV74.js +58 -0
  58. package/dist/chunks/nav-sheet-BIErlV74.js.map +1 -0
  59. package/dist/chunks/{logo-VmXYhIJL.js → nav-wordmark-DLkItdvo.js} +12 -93
  60. package/dist/chunks/nav-wordmark-DLkItdvo.js.map +1 -0
  61. package/dist/chunks/observe-resize-DhxhmoyB.js +25 -0
  62. package/dist/chunks/observe-resize-DhxhmoyB.js.map +1 -0
  63. package/dist/chunks/{page-header-BIRswR73.js → page-header-CEPZzhRp.js} +2 -2
  64. package/dist/chunks/{page-header-BIRswR73.js.map → page-header-CEPZzhRp.js.map} +1 -1
  65. package/dist/chunks/{pagination-DYdLm18-.js → pagination-CCMxQ5pH.js} +3 -3
  66. package/dist/chunks/{pagination-DYdLm18-.js.map → pagination-CCMxQ5pH.js.map} +1 -1
  67. package/dist/chunks/{range-popup-AbRzgHtY.js → range-popup-DGOnGGag.js} +4 -4
  68. package/dist/chunks/{range-popup-AbRzgHtY.js.map → range-popup-DGOnGGag.js.map} +1 -1
  69. package/dist/chunks/resize-motion-CMaidkwe.js +101 -0
  70. package/dist/chunks/resize-motion-CMaidkwe.js.map +1 -0
  71. package/dist/chunks/{rights-CXo7zEf6.js → rights-BbiJ0AJB.js} +4 -4
  72. package/dist/chunks/{rights-CXo7zEf6.js.map → rights-BbiJ0AJB.js.map} +1 -1
  73. package/dist/chunks/{section-XStLtXKa.js → section-DzOLLN1p.js} +3 -3
  74. package/dist/chunks/section-DzOLLN1p.js.map +1 -0
  75. package/dist/chunks/{segmented-CDTx2n29.js → segmented-MrinfDL8.js} +36 -35
  76. package/dist/chunks/segmented-MrinfDL8.js.map +1 -0
  77. package/dist/chunks/select-Bc4kRiSG.js +227 -0
  78. package/dist/chunks/select-Bc4kRiSG.js.map +1 -0
  79. package/dist/chunks/{sidebar-C4fL_KMm.js → sidebar-5IA18LuP.js} +180 -183
  80. package/dist/chunks/sidebar-5IA18LuP.js.map +1 -0
  81. package/dist/chunks/{sidebar-menu-sd9vCpDy.js → sidebar-menu-DRWRxcJ3.js} +2 -2
  82. package/dist/chunks/{sidebar-menu-sd9vCpDy.js.map → sidebar-menu-DRWRxcJ3.js.map} +1 -1
  83. package/dist/chunks/{switch-CztLhA8F.js → switch-XMY_CQE-.js} +2 -2
  84. package/dist/chunks/{switch-CztLhA8F.js.map → switch-XMY_CQE-.js.map} +1 -1
  85. package/dist/chunks/{tag-BsmQ1xPj.js → tag-Dg89uYpV.js} +3 -3
  86. package/dist/chunks/{tag-BsmQ1xPj.js.map → tag-Dg89uYpV.js.map} +1 -1
  87. package/dist/chunks/{text-BPglS3vq.js → text--5MKh2G4.js} +3 -3
  88. package/dist/chunks/{text-BPglS3vq.js.map → text--5MKh2G4.js.map} +1 -1
  89. package/dist/chunks/{textarea-Bvk7N2bh.js → textarea-Cj8iR82R.js} +3 -3
  90. package/dist/chunks/{textarea-Bvk7N2bh.js.map → textarea-Cj8iR82R.js.map} +1 -1
  91. package/dist/chunks/theme-provider-DJhORMlc.js +72 -0
  92. package/dist/chunks/theme-provider-DJhORMlc.js.map +1 -0
  93. package/dist/chunks/tooltip-DEbCCsru.js +151 -0
  94. package/dist/chunks/tooltip-DEbCCsru.js.map +1 -0
  95. package/dist/chunks/{tooltip-root-DWhtAtFb.js → tooltip-root-DRd4ciUv.js} +2 -2
  96. package/dist/chunks/{tooltip-root-DWhtAtFb.js.map → tooltip-root-DRd4ciUv.js.map} +1 -1
  97. package/dist/chunks/use-layout-width-CbSDbRb0.js +28 -0
  98. package/dist/chunks/use-layout-width-CbSDbRb0.js.map +1 -0
  99. package/dist/chunks/use-scroll-margin-DfdTc_5D.js +26 -0
  100. package/dist/chunks/use-scroll-margin-DfdTc_5D.js.map +1 -0
  101. package/dist/chunks/use-truncated-CW0hByYt.js +24 -0
  102. package/dist/chunks/use-truncated-CW0hByYt.js.map +1 -0
  103. package/dist/chunks/{virtual-rows-BgMdVelU.js → virtual-rows-BZe49bKi.js} +2 -2
  104. package/dist/chunks/{virtual-rows-BgMdVelU.js.map → virtual-rows-BZe49bKi.js.map} +1 -1
  105. package/dist/chunks/{zh-CN-cPjO1OOo.js → zh-CN-C7GmVswt.js} +15 -15
  106. package/dist/chunks/zh-CN-C7GmVswt.js.map +1 -0
  107. package/dist/components/app-frame.js +3 -1
  108. package/dist/components/banner.js +1 -1
  109. package/dist/components/button-group.js +2 -2
  110. package/dist/components/button.js +1 -1
  111. package/dist/components/calendar.js +1 -1
  112. package/dist/components/charts/bar.js +78 -77
  113. package/dist/components/charts/bar.js.map +1 -1
  114. package/dist/components/charts/donut.js +2 -2
  115. package/dist/components/charts/gauge.js +1 -1
  116. package/dist/components/charts/sankey.js +1 -1
  117. package/dist/components/charts/timeseries.js +75 -75
  118. package/dist/components/charts/timeseries.js.map +1 -1
  119. package/dist/components/charts.js +1 -1
  120. package/dist/components/code-block.js +1 -1
  121. package/dist/components/code.js +1 -1
  122. package/dist/components/combobox.js +1 -1
  123. package/dist/components/command-palette.js +105 -97
  124. package/dist/components/command-palette.js.map +1 -1
  125. package/dist/components/copy-button.js +1 -1
  126. package/dist/components/data-table.js +94 -95
  127. package/dist/components/data-table.js.map +1 -1
  128. package/dist/components/date-picker.js +3 -3
  129. package/dist/components/date-picker.js.map +1 -1
  130. package/dist/components/dialog.js +141 -153
  131. package/dist/components/dialog.js.map +1 -1
  132. package/dist/components/display-options.js +5 -5
  133. package/dist/components/filter-chip.js +1 -1
  134. package/dist/components/flow.js +37 -36
  135. package/dist/components/flow.js.map +1 -1
  136. package/dist/components/icon-button.js +1 -1
  137. package/dist/components/icon.js +1 -1
  138. package/dist/components/input.js +5 -5
  139. package/dist/components/kaeso/conversation.js +2 -2
  140. package/dist/components/kaeso/identity.js +1 -1
  141. package/dist/components/kaeso/moments.js +3 -3
  142. package/dist/components/kaeso/rights.js +1 -1
  143. package/dist/components/kaeso/usage.js +1 -1
  144. package/dist/components/kaeso.js +4 -4
  145. package/dist/components/key-value.js +3 -3
  146. package/dist/components/link.js +1 -1
  147. package/dist/components/list.js +1 -1
  148. package/dist/components/logo.js +101 -1
  149. package/dist/components/logo.js.map +1 -0
  150. package/dist/components/markdown.js +1 -1
  151. package/dist/components/menu.js +1 -1
  152. package/dist/components/page-header.js +1 -1
  153. package/dist/components/pagination.js +1 -1
  154. package/dist/components/playground.js +8 -8
  155. package/dist/components/scroll-area.js +30 -23
  156. package/dist/components/scroll-area.js.map +1 -1
  157. package/dist/components/section.js +1 -1
  158. package/dist/components/segmented.js +1 -1
  159. package/dist/components/select.js +1 -1
  160. package/dist/components/sheet.js +46 -41
  161. package/dist/components/sheet.js.map +1 -1
  162. package/dist/components/sidebar.js +1 -1
  163. package/dist/components/stat.js +75 -76
  164. package/dist/components/stat.js.map +1 -1
  165. package/dist/components/switch.js +1 -1
  166. package/dist/components/tag.js +1 -1
  167. package/dist/components/text.js +1 -1
  168. package/dist/components/theme-image.js +38 -0
  169. package/dist/components/theme-image.js.map +1 -0
  170. package/dist/components/theme-menu.js +3 -3
  171. package/dist/components/theme-select.js +58 -0
  172. package/dist/components/theme-select.js.map +1 -0
  173. package/dist/components/toast.js +91 -92
  174. package/dist/components/toast.js.map +1 -1
  175. package/dist/components/tooltip.js +1 -1
  176. package/dist/i18n-provider.js +1 -1
  177. package/dist/index.js +76 -74
  178. package/dist/kaeso.css +39 -16
  179. package/dist/styles.css +1 -1
  180. package/dist/theme.js +1 -1
  181. package/dist/types/components/app-frame/app-frame.d.ts +2 -10
  182. package/dist/types/components/app-frame/docs.d.ts +1 -0
  183. package/dist/types/components/app-frame/index.d.ts +1 -0
  184. package/dist/types/components/app-frame/nav-sheet.d.ts +11 -0
  185. package/dist/types/components/charts/linear-scale.d.ts +17 -0
  186. package/dist/types/components/code/code.d.ts +16 -0
  187. package/dist/types/components/code/docs.d.ts +1 -0
  188. package/dist/types/components/code-block/code-block.d.ts +2 -0
  189. package/dist/types/components/code-block/docs.d.ts +4 -0
  190. package/dist/types/components/command-palette/command-palette.d.ts +1 -0
  191. package/dist/types/components/command-palette/docs.d.ts +1 -0
  192. package/dist/types/components/dialog/dialog.d.ts +5 -2
  193. package/dist/types/components/dialog/docs.d.ts +10 -0
  194. package/dist/types/components/dialog/index.d.ts +1 -0
  195. package/dist/types/components/dialog/scope.d.ts +9 -0
  196. package/dist/types/components/dialog/step-dialog.d.ts +9 -1
  197. package/dist/types/components/link/link.d.ts +8 -0
  198. package/dist/types/components/logo/nav-wordmark.d.ts +6 -0
  199. package/dist/types/components/scroll-area/scroll-area.d.ts +3 -3
  200. package/dist/types/components/theme-image/docs.d.ts +13 -0
  201. package/dist/types/components/theme-image/index.d.ts +1 -0
  202. package/dist/types/components/theme-image/theme-image.d.ts +23 -0
  203. package/dist/types/components/theme-select/docs.d.ts +10 -0
  204. package/dist/types/components/theme-select/index.d.ts +1 -0
  205. package/dist/types/components/theme-select/theme-select.d.ts +34 -0
  206. package/dist/types/icons/groups.d.ts +1 -1
  207. package/dist/types/icons/vocabulary.d.ts +5 -0
  208. package/dist/types/index.d.ts +2 -0
  209. package/dist/types/theme/theme-provider.d.ts +1 -1
  210. package/dist/types/utils/dialog-scope.d.ts +7 -0
  211. package/dist/types/utils/lazy-module.d.ts +7 -2
  212. package/dist/types/utils/observe-resize.d.ts +1 -0
  213. package/dist/types/utils/resize-motion.d.ts +2 -0
  214. package/foundations/motion.md +1 -0
  215. package/package.json +2 -2
  216. package/dist/chunks/app-frame-BBIMch8X.js +0 -224
  217. package/dist/chunks/app-frame-BBIMch8X.js.map +0 -1
  218. package/dist/chunks/code-DDyOlIFO.js +0 -23
  219. package/dist/chunks/code-DDyOlIFO.js.map +0 -1
  220. package/dist/chunks/code-block-BbK6E4Eo.js.map +0 -1
  221. package/dist/chunks/core-Bgefcs3z.js.map +0 -1
  222. package/dist/chunks/de-BCg1eRVd.js.map +0 -1
  223. package/dist/chunks/dialog-CVqSVk3T.js +0 -283
  224. package/dist/chunks/dialog-CVqSVk3T.js.map +0 -1
  225. package/dist/chunks/icon-Bha63LaN.js.map +0 -1
  226. package/dist/chunks/link-tTapNTpM.js.map +0 -1
  227. package/dist/chunks/list-CN8pO8lv.js.map +0 -1
  228. package/dist/chunks/logo-VmXYhIJL.js.map +0 -1
  229. package/dist/chunks/restore-focus-Cap1Q-R3.js +0 -19
  230. package/dist/chunks/restore-focus-Cap1Q-R3.js.map +0 -1
  231. package/dist/chunks/section-XStLtXKa.js.map +0 -1
  232. package/dist/chunks/segmented-CDTx2n29.js.map +0 -1
  233. package/dist/chunks/select-Ca3HGsN1.js +0 -223
  234. package/dist/chunks/select-Ca3HGsN1.js.map +0 -1
  235. package/dist/chunks/sidebar-C4fL_KMm.js.map +0 -1
  236. package/dist/chunks/theme-provider-mgUaQK7L.js +0 -69
  237. package/dist/chunks/theme-provider-mgUaQK7L.js.map +0 -1
  238. package/dist/chunks/tooltip-CDu00nzg.js +0 -124
  239. package/dist/chunks/tooltip-CDu00nzg.js.map +0 -1
  240. package/dist/chunks/use-layout-width-DZaLOQMT.js +0 -27
  241. package/dist/chunks/use-layout-width-DZaLOQMT.js.map +0 -1
  242. package/dist/chunks/use-scroll-margin-DWcfIXac.js +0 -25
  243. package/dist/chunks/use-scroll-margin-DWcfIXac.js.map +0 -1
  244. package/dist/chunks/use-truncated-DmQoePvG.js +0 -25
  245. package/dist/chunks/use-truncated-DmQoePvG.js.map +0 -1
  246. package/dist/chunks/zh-CN-cPjO1OOo.js.map +0 -1
package/AGENTS.md CHANGED
@@ -97,6 +97,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
97
97
  | One of many options | `Select`; searchable: `Combobox` |
98
98
  | A confirmation of an irreversible action | `AlertDialog`; deletion: the `DeleteResource` block |
99
99
  | A task in several steps | `StepDialog` |
100
+ | A dialog that opens fresh every time | `DialogScope` around the component that keeps its state |
100
101
  | Feedback after an action | `toast()`, with Undo for reversible actions |
101
102
  | A secret shown once | `SecretReveal` |
102
103
  | Numbers at a glance | `MetricRow` with `Stat`; over time: `TimeseriesChart` |
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Devin Oldenburg
3
+ Copyright (c) 2026 Devin Oldenburg (Logicplanes)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
1
  # @logicplanes/kaeso-ui component guides
2
2
 
3
- Version 0.1.0. Generated from the showcase's demo modules (apps/showcase/src/demos); do not edit. For each component: what it is for, its import, keyboard, accessibility, do and don't, and every example's code. Props and variants: `component-registry.md`.
3
+ Version 0.2.1. Generated from the showcase's demo modules (apps/showcase/src/demos); do not edit. For each component: what it is for, its import, keyboard, accessibility, do and don't, and every example's code. Props and variants: `component-registry.md`.
4
4
 
5
5
  ## AlertDialog
6
6
 
@@ -1202,7 +1202,7 @@ A modal dialog: 440, 560 or 720 wide, radius 20; title, description, body, actio
1202
1202
  - The title names the dialog; the description is its accessible description.
1203
1203
  - The footer line appears only while content scrolls under it.
1204
1204
  - In steps, Continue and Back move focus to the new step's first field, or by the same rule to its primary or safe action when it has none, and the step's number and question are announced.
1205
- - In steps, the dialog takes each step's height and keeps its top; with reduced motion the step and the height change at once.
1205
+ - The dialog stays centered while its content changes: it grows or shrinks to the new height from the size it has, and the body scrolls between the header and the footer when the content is taller than the screen. With reduced motion the size and the step change at once.
1206
1206
 
1207
1207
  ### Examples
1208
1208
 
@@ -1261,7 +1261,7 @@ function Steps() {
1261
1261
  const [name, setName] = useState("");
1262
1262
  return (
1263
1263
  <>
1264
- <Button variant="primary" onClick={() => setOpen(true)}>
1264
+ <Button variant="primary" onClick={() => (setName(""), setOpen(true))}>
1265
1265
  Create key
1266
1266
  </Button>
1267
1267
  <StepDialog
@@ -1302,7 +1302,7 @@ function StepHeights() {
1302
1302
  const [level, setLevel] = useState("project");
1303
1303
  return (
1304
1304
  <>
1305
- <Button variant="primary" onClick={() => setOpen(true)}>
1305
+ <Button variant="primary" onClick={() => (setLevel("project"), setOpen(true))}>
1306
1306
  Add limit
1307
1307
  </Button>
1308
1308
  <StepDialog
@@ -1322,6 +1322,125 @@ function StepHeights() {
1322
1322
  }
1323
1323
  ```
1324
1324
 
1325
+ #### The key, shown once after the last step
1326
+
1327
+ ```tsx
1328
+ function WithResult() {
1329
+ const [open, setOpen] = useState(false);
1330
+ const [name, setName] = useState("");
1331
+ const [created, setCreated] = useState(false);
1332
+ const close = () => setOpen(false);
1333
+ const start = () => {
1334
+ setName("");
1335
+ setCreated(false);
1336
+ setOpen(true);
1337
+ };
1338
+ return (
1339
+ <>
1340
+ <Button variant="primary" onClick={start}>
1341
+ Create key
1342
+ </Button>
1343
+ <StepDialog
1344
+ open={open}
1345
+ onOpenChange={(o) => !o && close()}
1346
+ title="Create key"
1347
+ submitLabel="Create key"
1348
+ onSubmit={() => setCreated(true)}
1349
+ steps={[
1350
+ {
1351
+ id: "name",
1352
+ title: "What is it for?",
1353
+ description: "Shown in request logs and alerts.",
1354
+ blockedReason: name.trim() ? undefined : "Enter a name",
1355
+ content: <Input aria-label="Name" placeholder="checkout-web" value={name} onChange={(e) => setName(e.target.value)} autoFocus />,
1356
+ },
1357
+ {
1358
+ id: "expiry",
1359
+ title: "When does it expire?",
1360
+ content: <Select aria-label="Expires" options={expiry} defaultValue="90" fullWidth />,
1361
+ },
1362
+ ]}
1363
+ result={
1364
+ created
1365
+ ? {
1366
+ title: "Key created",
1367
+ description: "Copy the key now: it's shown once, and Kaeso keeps only a hash of it.",
1368
+ size: "lg",
1369
+ content: <SecretReveal secret={SECRET} name={name.trim()} baseUrl="https://gateway.northwind.example" model="gpt-5-mini" />,
1370
+ footer: <Button onClick={close}>Done</Button>,
1371
+ }
1372
+ : undefined
1373
+ }
1374
+ />
1375
+ </>
1376
+ );
1377
+ }
1378
+ ```
1379
+
1380
+ #### Content that grows and shrinks
1381
+
1382
+ ```tsx
1383
+ function Changing() {
1384
+ const [open, setOpen] = useState(false);
1385
+ const [email, setEmail] = useState("");
1386
+ const [tried, setTried] = useState(false);
1387
+ const [toProjects, setToProjects] = useState(false);
1388
+ const invalid = tried && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email);
1389
+ const send = () => {
1390
+ setTried(true);
1391
+ if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) return;
1392
+ setOpen(false);
1393
+ toast.success(`Invitation sent to ${email}`);
1394
+ };
1395
+ return (
1396
+ <Dialog
1397
+ open={open}
1398
+ onOpenChange={(o) => {
1399
+ if (o) {
1400
+ setEmail("");
1401
+ setTried(false);
1402
+ setToProjects(false);
1403
+ }
1404
+ setOpen(o);
1405
+ }}
1406
+ trigger={<Button variant="primary">Invite member</Button>}
1407
+ title="Invite member"
1408
+ description="The link works for 21 days."
1409
+ onSubmit={send}
1410
+ footer={
1411
+ <>
1412
+ <Dialog.Close>
1413
+ <Button>Cancel</Button>
1414
+ </Dialog.Close>
1415
+ <Button variant="primary" onClick={send}>
1416
+ Send invitation
1417
+ </Button>
1418
+ </>
1419
+ }
1420
+ >
1421
+ <div className="flex flex-col gap-20">
1422
+ <Input
1423
+ label="Email address"
1424
+ placeholder="ana@northwind.example"
1425
+ value={email}
1426
+ onChange={(e) => setEmail(e.target.value)}
1427
+ error={invalid ? "Enter a full address, like ana@northwind.example" : undefined}
1428
+ autoFocus
1429
+ />
1430
+ <Checkbox label="Add them to projects now" checked={toProjects} onCheckedChange={setToProjects} />
1431
+ {toProjects && (
1432
+ <CheckboxGroup aria-label="Projects" defaultValue={projects.slice(0, 1).map((p) => p.id)} className="flex flex-col">
1433
+ {projects.map((p) => (
1434
+ <Checkbox key={p.id} value={p.id} label={p.name} />
1435
+ ))}
1436
+ </CheckboxGroup>
1437
+ )}
1438
+ </div>
1439
+ </Dialog>
1440
+ );
1441
+ }
1442
+ ```
1443
+
1325
1444
  #### Sizes
1326
1445
 
1327
1446
  ```tsx
@@ -1343,6 +1462,39 @@ function StepHeights() {
1343
1462
  </div>
1344
1463
  ```
1345
1464
 
1465
+ ## DialogScope
1466
+
1467
+ Opens a dialog's flow fresh every time: the first step, empty fields, no earlier result or secret. The content stays as it was while the dialog closes.
1468
+
1469
+ `import { DialogScope } from "@logicplanes/kaeso-ui";`
1470
+
1471
+ ### Accessibility
1472
+
1473
+ - Each open starts on the first step with the focus on its first field, as a new dialog does.
1474
+ - A secret shown once leaves the page and the component's state when the dialog has closed.
1475
+
1476
+ ### Examples
1477
+
1478
+ #### Create a key, then another
1479
+
1480
+ The key is shown once; closing the dialog forgets it, so the next key starts on the first step.
1481
+
1482
+ ```tsx
1483
+ function CreateKey() {
1484
+ const [open, setOpen] = useState(false);
1485
+ return (
1486
+ <>
1487
+ <Button variant="primary" onClick={() => setOpen(true)}>
1488
+ Create key
1489
+ </Button>
1490
+ <DialogScope open={open}>
1491
+ <CreateKeyFlow open={open} onClose={() => setOpen(false)} />
1492
+ </DialogScope>
1493
+ </>
1494
+ );
1495
+ }
1496
+ ```
1497
+
1346
1498
  ## DisplayOptions
1347
1499
 
1348
1500
  View, grouping and ordering, toggles, and the properties to show, behind one circle at the end of a toolbar.
@@ -2151,11 +2303,13 @@ function Wizard() {
2151
2303
  const [model, setModel] = useState("");
2152
2304
  const [custom, setCustom] = useState("");
2153
2305
  const m = models.find((x) => x.model === model);
2154
- const close = () => {
2155
- setOpen(false);
2306
+ const start = () => {
2156
2307
  setView("pick");
2308
+ setModel("");
2157
2309
  setCustom("");
2310
+ setOpen(true);
2158
2311
  };
2312
+ const close = () => setOpen(false);
2159
2313
  const add = (id: string) => {
2160
2314
  close();
2161
2315
  toast.success(`Added ${id}`);
@@ -2219,7 +2373,7 @@ function Wizard() {
2219
2373
  };
2220
2374
  return (
2221
2375
  <>
2222
- <Button variant="primary" onClick={() => setOpen(true)}>
2376
+ <Button variant="primary" onClick={start}>
2223
2377
  Add model
2224
2378
  </Button>
2225
2379
  <LayerDialog
@@ -2282,6 +2436,35 @@ Links look like links: text color with a quiet underline that turns solid on hov
2282
2436
  </div>
2283
2437
  ```
2284
2438
 
2439
+ #### Heading
2440
+
2441
+ ```tsx
2442
+ <h2 id="create-a-key" className="text-title font-semibold text-fg">
2443
+ <Link href="#create-a-key" variant="heading">
2444
+ Create a key
2445
+ </Link>
2446
+ </h2>
2447
+ ```
2448
+
2449
+ #### Next pages
2450
+
2451
+ ```tsx
2452
+ <ul className="grid max-w-640 gap-12 sm:grid-cols-2">
2453
+ <li className="flex">
2454
+ <Link href="#" variant="card" className="w-full">
2455
+ <span className="text-body font-medium">Calling models</span>
2456
+ <span className="text-small text-fg-secondary">Call models from your app with the OpenAI and Anthropic SDKs.</span>
2457
+ </Link>
2458
+ </li>
2459
+ <li className="flex">
2460
+ <Link href="#" variant="card" className="w-full">
2461
+ <span className="text-body font-medium">API keys</span>
2462
+ <span className="text-small text-fg-secondary">Limit a key to the models and rates an app needs.</span>
2463
+ </Link>
2464
+ </li>
2465
+ </ul>
2466
+ ```
2467
+
2285
2468
  ## List
2286
2469
 
2287
2470
  44px rows on the panel, no lines, metadata on the right, group headers, keyboard first.
@@ -4484,6 +4667,85 @@ Multi-line text at radius 14: grows to eight lines, then scrolls.
4484
4667
  </div>
4485
4668
  ```
4486
4669
 
4670
+ ## ThemeImage
4671
+
4672
+ An image drawn twice, once for each theme, such as a diagram: it follows the theme setting, not only the system's, and prints the light one.
4673
+
4674
+ `import { ThemeImage } from "@logicplanes/kaeso-ui";`
4675
+
4676
+ ### Accessibility
4677
+
4678
+ - Both images carry the same text alternative; only the one for the current theme is shown, so a screen reader reads it once.
4679
+ - Pass aria-describedby with the id of a longer description when the image is a diagram.
4680
+
4681
+ ### Examples
4682
+
4683
+ #### A diagram in both themes
4684
+
4685
+ ```tsx
4686
+ <ThemeImage light="/demos/route.light.svg" dark="/demos/route.dark.svg" alt="Route of a request: app, Kaeso, provider" width={364} height={49} />
4687
+ ```
4688
+
4689
+ ## ThemeSelect
4690
+
4691
+ A select for system, light or dark, stored as `kaeso:theme`, with its label in the provider's language.
4692
+
4693
+ `import { ThemeSelect } from "@logicplanes/kaeso-ui";`
4694
+
4695
+ ### Keyboard
4696
+
4697
+ | Key | Action |
4698
+ |---|---|
4699
+ | Enter Space | Opens |
4700
+ | Up Down | Moves |
4701
+ | Type | Jumps to an option |
4702
+ | Escape | Closes and returns focus |
4703
+
4704
+ ### Accessibility
4705
+
4706
+ - Named Theme in the provider's language, and shows the choice in words, so it needs no aria-label and no icon.
4707
+ - Reads and sets the choice of the nearest ThemeProvider; every provider on the page follows it.
4708
+
4709
+ ### Examples
4710
+
4711
+ #### Basic
4712
+
4713
+ ```tsx
4714
+ <ThemeProvider>
4715
+ <ThemeSelect />
4716
+ </ThemeProvider>
4717
+ ```
4718
+
4719
+ #### In a sidebar's footer, beside the language
4720
+
4721
+ ```tsx
4722
+ <ThemeProvider>
4723
+ <div className="grid w-240 grid-cols-2 gap-4">
4724
+ <Select
4725
+ aria-label="Language"
4726
+ size="sm"
4727
+ appearance="ghost"
4728
+ fullWidth
4729
+ defaultValue="en"
4730
+ options={[
4731
+ { value: "en", label: "English" },
4732
+ { value: "de", label: "Deutsch" },
4733
+ { value: "zh-CN", label: "简体中文" },
4734
+ ]}
4735
+ />
4736
+ <ThemeSelect fullWidth />
4737
+ </div>
4738
+ </ThemeProvider>
4739
+ ```
4740
+
4741
+ #### Raised
4742
+
4743
+ ```tsx
4744
+ <ThemeProvider>
4745
+ <ThemeSelect appearance="default" size="md" />
4746
+ </ThemeProvider>
4747
+ ```
4748
+
4487
4749
  ## Timeline
4488
4750
 
4489
4751
  Events down a 1px line: the audit log.