kanto-ds 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/README.md +26 -14
  2. package/dist/AGENTS.md +157 -0
  3. package/dist/cdn/kanto.min.js +4743 -932
  4. package/dist/chunks/block-Cci-Kff_.js +69 -0
  5. package/dist/chunks/block-Cci-Kff_.js.map +1 -0
  6. package/dist/chunks/defaults-yhaR6U65.js +70 -0
  7. package/dist/chunks/{defaults-Cpeg13O5.js.map → defaults-yhaR6U65.js.map} +1 -1
  8. package/dist/chunks/heading-DsnZsfg-.js +21 -0
  9. package/dist/chunks/heading-DsnZsfg-.js.map +1 -0
  10. package/dist/chunks/{index-TWJzttLX.js → index-1ZFgagWW.js} +37 -12
  11. package/dist/chunks/index-1ZFgagWW.js.map +1 -0
  12. package/dist/chunks/indicator-B_Rs8F92.js +49 -0
  13. package/dist/chunks/indicator-B_Rs8F92.js.map +1 -0
  14. package/dist/chunks/{kt-calendar-CtwOby1R.js → kt-calendar-SK8eapuy.js} +3 -3
  15. package/dist/chunks/{kt-calendar-CtwOby1R.js.map → kt-calendar-SK8eapuy.js.map} +1 -1
  16. package/dist/chunks/kt-color-picker-BoezCAmx.js +365 -0
  17. package/dist/chunks/kt-color-picker-BoezCAmx.js.map +1 -0
  18. package/dist/chunks/{kt-element-T0VbIBNp.js → kt-element-DvWtPQ1Y.js} +2 -2
  19. package/dist/chunks/{kt-element-T0VbIBNp.js.map → kt-element-DvWtPQ1Y.js.map} +1 -1
  20. package/dist/chunks/motion-ChVUUO7O.js +28 -0
  21. package/dist/chunks/motion-ChVUUO7O.js.map +1 -0
  22. package/dist/chunks/numbers-QyecMiSJ.js +9 -0
  23. package/dist/chunks/numbers-QyecMiSJ.js.map +1 -0
  24. package/dist/chunks/{segmented-field-BBXR4XFL.js → segmented-field-T_Zo6lc1.js} +2 -2
  25. package/dist/chunks/{segmented-field-BBXR4XFL.js.map → segmented-field-T_Zo6lc1.js.map} +1 -1
  26. package/dist/chunks/{typed-date-CPAUNHzr.js → typed-date-CaU0kXoY.js} +2 -2
  27. package/dist/chunks/{typed-date-CPAUNHzr.js.map → typed-date-CaU0kXoY.js.map} +1 -1
  28. package/dist/components/blocks/kt-auth-form/kt-auth-form.d.ts +143 -0
  29. package/dist/components/blocks/kt-auth-form/kt-auth-form.js +368 -0
  30. package/dist/components/blocks/kt-auth-form/kt-auth-form.js.map +1 -0
  31. package/dist/components/blocks/kt-blog-post/kt-blog-post.d.ts +75 -0
  32. package/dist/components/blocks/kt-blog-post/kt-blog-post.js +285 -0
  33. package/dist/components/blocks/kt-blog-post/kt-blog-post.js.map +1 -0
  34. package/dist/components/blocks/kt-cta/kt-cta.d.ts +51 -0
  35. package/dist/components/blocks/kt-cta/kt-cta.js +126 -0
  36. package/dist/components/blocks/kt-cta/kt-cta.js.map +1 -0
  37. package/dist/components/blocks/kt-empty-page/kt-empty-page.d.ts +75 -0
  38. package/dist/components/blocks/kt-empty-page/kt-empty-page.js +245 -0
  39. package/dist/components/blocks/kt-empty-page/kt-empty-page.js.map +1 -0
  40. package/dist/components/blocks/kt-error-page/kt-error-page.d.ts +65 -0
  41. package/dist/components/blocks/kt-error-page/kt-error-page.js +177 -0
  42. package/dist/components/blocks/kt-error-page/kt-error-page.js.map +1 -0
  43. package/dist/components/blocks/kt-faq/kt-faq.d.ts +61 -0
  44. package/dist/components/blocks/kt-faq/kt-faq.js +129 -0
  45. package/dist/components/blocks/kt-faq/kt-faq.js.map +1 -0
  46. package/dist/components/blocks/kt-feature-grid/kt-feature-grid.d.ts +59 -0
  47. package/dist/components/blocks/kt-feature-grid/kt-feature-grid.js +166 -0
  48. package/dist/components/blocks/kt-feature-grid/kt-feature-grid.js.map +1 -0
  49. package/dist/components/blocks/kt-hero/kt-hero.d.ts +51 -0
  50. package/dist/components/blocks/kt-hero/kt-hero.js +138 -0
  51. package/dist/components/blocks/kt-hero/kt-hero.js.map +1 -0
  52. package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.d.ts +46 -0
  53. package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.js +100 -0
  54. package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.js.map +1 -0
  55. package/dist/components/blocks/kt-newsletter/kt-newsletter.d.ts +85 -0
  56. package/dist/components/blocks/kt-newsletter/kt-newsletter.js +247 -0
  57. package/dist/components/blocks/kt-newsletter/kt-newsletter.js.map +1 -0
  58. package/dist/components/blocks/kt-post-grid/kt-post-grid.d.ts +73 -0
  59. package/dist/components/blocks/kt-post-grid/kt-post-grid.js +249 -0
  60. package/dist/components/blocks/kt-post-grid/kt-post-grid.js.map +1 -0
  61. package/dist/components/blocks/kt-pricing-table/kt-pricing-table.d.ts +102 -0
  62. package/dist/components/blocks/kt-pricing-table/kt-pricing-table.js +307 -0
  63. package/dist/components/blocks/kt-pricing-table/kt-pricing-table.js.map +1 -0
  64. package/dist/components/blocks/kt-settings-section/kt-settings-section.d.ts +52 -0
  65. package/dist/components/blocks/kt-settings-section/kt-settings-section.js +158 -0
  66. package/dist/components/blocks/kt-settings-section/kt-settings-section.js.map +1 -0
  67. package/dist/components/blocks/kt-testimonials/kt-testimonials.d.ts +56 -0
  68. package/dist/components/blocks/kt-testimonials/kt-testimonials.js +161 -0
  69. package/dist/components/blocks/kt-testimonials/kt-testimonials.js.map +1 -0
  70. package/dist/components/core/kt-avatar/kt-avatar.js +2 -2
  71. package/dist/components/core/kt-avatar-group/kt-avatar-group.d.ts +42 -0
  72. package/dist/components/core/kt-avatar-group/kt-avatar-group.js +97 -0
  73. package/dist/components/core/kt-avatar-group/kt-avatar-group.js.map +1 -0
  74. package/dist/components/core/kt-badge/kt-badge.js +2 -2
  75. package/dist/components/core/kt-button/flights.d.ts +27 -0
  76. package/dist/components/core/kt-button/kt-button.d.ts +52 -1
  77. package/dist/components/core/kt-button/kt-button.js +353 -77
  78. package/dist/components/core/kt-button/kt-button.js.map +1 -1
  79. package/dist/components/core/kt-button/morph.d.ts +27 -0
  80. package/dist/components/core/kt-card/kt-card.js +1 -1
  81. package/dist/components/core/kt-code/kt-code.d.ts +2 -1
  82. package/dist/components/core/kt-code/kt-code.js +52 -37
  83. package/dist/components/core/kt-code/kt-code.js.map +1 -1
  84. package/dist/components/core/kt-copy-button/kt-copy-button.d.ts +47 -0
  85. package/dist/components/core/kt-copy-button/kt-copy-button.js +74 -0
  86. package/dist/components/core/kt-copy-button/kt-copy-button.js.map +1 -0
  87. package/dist/components/core/kt-icon/kt-icon.js +2 -2
  88. package/dist/components/core/kt-kbd/kt-kbd.js +1 -1
  89. package/dist/components/core/kt-split-button/kt-split-button.js +2 -2
  90. package/dist/components/data/kt-chart/kt-chart.js +2 -2
  91. package/dist/components/data/kt-chat-message/kt-chat-message.d.ts +60 -0
  92. package/dist/components/data/kt-chat-message/kt-chat-message.js +204 -0
  93. package/dist/components/data/kt-chat-message/kt-chat-message.js.map +1 -0
  94. package/dist/components/data/kt-description-list/kt-description-list.d.ts +56 -0
  95. package/dist/components/data/kt-description-list/kt-description-list.js +120 -0
  96. package/dist/components/data/kt-description-list/kt-description-list.js.map +1 -0
  97. package/dist/components/data/kt-meter/kt-meter.js +8 -6
  98. package/dist/components/data/kt-meter/kt-meter.js.map +1 -1
  99. package/dist/components/data/kt-pagination/kt-pagination.js +2 -2
  100. package/dist/components/data/kt-stat/kt-stat.d.ts +3 -1
  101. package/dist/components/data/kt-stat/kt-stat.js +31 -16
  102. package/dist/components/data/kt-stat/kt-stat.js.map +1 -1
  103. package/dist/components/data/kt-table/kt-table.js +2 -2
  104. package/dist/components/data/kt-timeline/kt-timeline.js +2 -2
  105. package/dist/components/data/kt-timeline/kt-timeline.js.map +1 -1
  106. package/dist/components/data/kt-tree/kt-tree.d.ts +69 -0
  107. package/dist/components/data/kt-tree/kt-tree.js +208 -0
  108. package/dist/components/data/kt-tree/kt-tree.js.map +1 -0
  109. package/dist/components/feedback/kt-alert/kt-alert.js +2 -2
  110. package/dist/components/feedback/kt-empty-state/kt-empty-state.js +1 -1
  111. package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +1 -1
  112. package/dist/components/feedback/kt-skeleton/kt-skeleton.js +1 -1
  113. package/dist/components/feedback/kt-toast/kt-toast.js +2 -2
  114. package/dist/components/feedback/kt-toast-container/kt-toast-container.d.ts +8 -1
  115. package/dist/components/feedback/kt-toast-container/kt-toast-container.js +65 -26
  116. package/dist/components/feedback/kt-toast-container/kt-toast-container.js.map +1 -1
  117. package/dist/components/feedback/kt-tooltip/kt-tooltip.js +1 -1
  118. package/dist/components/forms/kt-calendar/kt-calendar.js +3 -3
  119. package/dist/components/forms/kt-checkbox/kt-checkbox.d.ts +2 -0
  120. package/dist/components/forms/kt-checkbox/kt-checkbox.js +19 -8
  121. package/dist/components/forms/kt-checkbox/kt-checkbox.js.map +1 -1
  122. package/dist/components/forms/kt-color-picker/kt-color-picker.d.ts +66 -0
  123. package/dist/components/forms/kt-color-picker/kt-color-picker.js +14 -0
  124. package/dist/components/forms/kt-color-picker/kt-color-picker.js.map +1 -0
  125. package/dist/components/forms/kt-date-input/kt-date-input.js +5 -5
  126. package/dist/components/forms/kt-date-picker/kt-date-picker.js +4 -4
  127. package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +2 -2
  128. package/dist/components/forms/kt-form/kt-form.js +2 -2
  129. package/dist/components/forms/kt-input/kt-input.js +2 -2
  130. package/dist/components/forms/kt-input-menu/kt-input-menu.js +2 -2
  131. package/dist/components/forms/kt-label-input/kt-label-input.js +1 -1
  132. package/dist/components/forms/kt-multi-select/kt-multi-select.js +2 -2
  133. package/dist/components/forms/kt-number-input/kt-number-input.d.ts +92 -0
  134. package/dist/components/forms/kt-number-input/kt-number-input.js +366 -0
  135. package/dist/components/forms/kt-number-input/kt-number-input.js.map +1 -0
  136. package/dist/components/forms/kt-otp-input/kt-otp-input.d.ts +74 -0
  137. package/dist/components/forms/kt-otp-input/kt-otp-input.js +232 -0
  138. package/dist/components/forms/kt-otp-input/kt-otp-input.js.map +1 -0
  139. package/dist/components/forms/kt-prompt-input/kt-prompt-input.d.ts +74 -0
  140. package/dist/components/forms/kt-prompt-input/kt-prompt-input.js +213 -0
  141. package/dist/components/forms/kt-prompt-input/kt-prompt-input.js.map +1 -0
  142. package/dist/components/forms/kt-radio-group/kt-radio-group.js +2 -2
  143. package/dist/components/forms/kt-select/kt-select.js +2 -2
  144. package/dist/components/forms/kt-slider/kt-slider.d.ts +69 -0
  145. package/dist/components/forms/kt-slider/kt-slider.js +252 -0
  146. package/dist/components/forms/kt-slider/kt-slider.js.map +1 -0
  147. package/dist/components/forms/kt-textarea/kt-textarea.js +2 -2
  148. package/dist/components/forms/kt-time-input/kt-time-input.js +3 -3
  149. package/dist/components/forms/kt-toggle/kt-toggle.js +1 -1
  150. package/dist/components/navigation/kt-app-shell/kt-app-shell.d.ts +85 -0
  151. package/dist/components/navigation/kt-app-shell/kt-app-shell.js +220 -0
  152. package/dist/components/navigation/kt-app-shell/kt-app-shell.js.map +1 -0
  153. package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +2 -2
  154. package/dist/components/navigation/kt-footer/kt-footer.d.ts +82 -0
  155. package/dist/components/navigation/kt-footer/kt-footer.js +220 -0
  156. package/dist/components/navigation/kt-footer/kt-footer.js.map +1 -0
  157. package/dist/components/navigation/kt-header/kt-header.js +2 -2
  158. package/dist/components/navigation/kt-page-header/kt-page-header.js +2 -2
  159. package/dist/components/navigation/kt-page-header/kt-page-header.js.map +1 -1
  160. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.d.ts +1 -0
  161. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +81 -44
  162. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js.map +1 -1
  163. package/dist/components/navigation/kt-steps/kt-steps.d.ts +68 -0
  164. package/dist/components/navigation/kt-steps/kt-steps.js +286 -0
  165. package/dist/components/navigation/kt-steps/kt-steps.js.map +1 -0
  166. package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +3 -3
  167. package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js.map +1 -1
  168. package/dist/components/navigation/kt-tabs/kt-tabs.d.ts +1 -0
  169. package/dist/components/navigation/kt-tabs/kt-tabs.js +92 -64
  170. package/dist/components/navigation/kt-tabs/kt-tabs.js.map +1 -1
  171. package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +1 -1
  172. package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +2 -2
  173. package/dist/components/navigation/kt-user-menu/kt-user-menu.d.ts +86 -0
  174. package/dist/components/navigation/kt-user-menu/kt-user-menu.js +298 -0
  175. package/dist/components/navigation/kt-user-menu/kt-user-menu.js.map +1 -0
  176. package/dist/components/overlays/kt-accordion/kt-accordion.d.ts +47 -0
  177. package/dist/components/overlays/kt-accordion/kt-accordion.js +80 -0
  178. package/dist/components/overlays/kt-accordion/kt-accordion.js.map +1 -0
  179. package/dist/components/overlays/kt-collapsible/kt-collapsible.d.ts +17 -1
  180. package/dist/components/overlays/kt-collapsible/kt-collapsible.js +87 -32
  181. package/dist/components/overlays/kt-collapsible/kt-collapsible.js.map +1 -1
  182. package/dist/components/overlays/kt-command-palette/kt-command-palette.d.ts +87 -0
  183. package/dist/components/overlays/kt-command-palette/kt-command-palette.js +370 -0
  184. package/dist/components/overlays/kt-command-palette/kt-command-palette.js.map +1 -0
  185. package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +2 -2
  186. package/dist/components/overlays/kt-dropdown/kt-dropdown.js +2 -2
  187. package/dist/components/overlays/kt-modal/kt-modal.js +2 -2
  188. package/dist/components/overlays/kt-side-panel/kt-side-panel.js +2 -2
  189. package/dist/components/overlays/kt-tour/kt-tour.d.ts +77 -0
  190. package/dist/components/overlays/kt-tour/kt-tour.js +200 -0
  191. package/dist/components/overlays/kt-tour/kt-tour.js.map +1 -0
  192. package/dist/custom-elements.json +16427 -8061
  193. package/dist/docs/kt-accordion.md +49 -0
  194. package/dist/docs/kt-app-shell.md +89 -0
  195. package/dist/docs/kt-auth-form.md +111 -0
  196. package/dist/docs/kt-avatar-group.md +49 -0
  197. package/dist/docs/kt-blog-post.md +77 -0
  198. package/dist/docs/kt-button.md +21 -0
  199. package/dist/docs/kt-chat-message.md +68 -0
  200. package/dist/docs/kt-color-picker.md +67 -0
  201. package/dist/docs/kt-command-palette.md +99 -0
  202. package/dist/docs/kt-copy-button.md +50 -0
  203. package/dist/docs/kt-cta.md +45 -0
  204. package/dist/docs/kt-description-list.md +58 -0
  205. package/dist/docs/kt-empty-page.md +92 -0
  206. package/dist/docs/kt-error-page.md +64 -0
  207. package/dist/docs/kt-faq.md +54 -0
  208. package/dist/docs/kt-feature-grid.md +53 -0
  209. package/dist/docs/kt-footer.md +115 -0
  210. package/dist/docs/kt-hero.md +53 -0
  211. package/dist/docs/kt-logo-cloud.md +41 -0
  212. package/dist/docs/kt-newsletter.md +69 -0
  213. package/dist/docs/kt-number-input.md +77 -0
  214. package/dist/docs/kt-otp-input.md +68 -0
  215. package/dist/docs/kt-post-grid.md +66 -0
  216. package/dist/docs/kt-pricing-table.md +101 -0
  217. package/dist/docs/kt-prompt-input.md +86 -0
  218. package/dist/docs/kt-settings-section.md +65 -0
  219. package/dist/docs/kt-slider.md +76 -0
  220. package/dist/docs/kt-steps.md +79 -0
  221. package/dist/docs/kt-testimonials.md +52 -0
  222. package/dist/docs/kt-tour.md +75 -0
  223. package/dist/docs/kt-tree.md +83 -0
  224. package/dist/docs/kt-user-menu.md +77 -0
  225. package/dist/icons/defaults.d.ts +2 -0
  226. package/dist/icons/index.js +1 -1
  227. package/dist/index.d.ts +56 -0
  228. package/dist/index.js +225 -284
  229. package/dist/index.js.map +1 -1
  230. package/dist/internal/block.d.ts +23 -0
  231. package/dist/internal/command-search.d.ts +27 -0
  232. package/dist/internal/heading.d.ts +8 -0
  233. package/dist/internal/indicator.d.ts +34 -0
  234. package/dist/internal/motion.d.ts +25 -0
  235. package/dist/internal/numbers.d.ts +2 -0
  236. package/dist/internal/strings.d.ts +36 -0
  237. package/dist/react/index.d.ts +165 -0
  238. package/dist/react/index.js +420 -171
  239. package/dist/react/index.js.map +1 -1
  240. package/dist/react/jsx.d.ts +128 -1
  241. package/dist/strings/index.js +1 -1
  242. package/dist/tokens/base.css +35 -2
  243. package/dist/vscode.css-custom-data.json +165 -19
  244. package/dist/vscode.html-custom-data.json +1023 -149
  245. package/dist/vue/index.d.ts +62 -0
  246. package/dist/vue/index.js +39 -8
  247. package/dist/vue/index.js.map +1 -1
  248. package/dist/web-types.json +3238 -836
  249. package/package.json +128 -3
  250. package/dist/chunks/defaults-Cpeg13O5.js +0 -68
  251. package/dist/chunks/index-TWJzttLX.js.map +0 -1
@@ -0,0 +1,69 @@
1
+ # `<kt-newsletter>`
2
+
3
+ A way to hear from you again: a heading, a line, an email field and the
4
+ button that subscribes it.
5
+
6
+ ```html
7
+ <kt-newsletter id="letter" heading="Notes, monthly" lead="What we shipped, and what we learned.">
8
+ <span slot="note">One email a month. Unsubscribe in one click.</span>
9
+ </kt-newsletter>
10
+ <script>
11
+ letter.addEventListener('kt-subscribe', (e) => e.detail.wait(api.subscribe(e.detail.email)));
12
+ </script>
13
+ ```
14
+
15
+ ## Subscribing
16
+
17
+ The button, or Enter in the field, checks the address first: one that is not
18
+ an address says so on the field, and nothing is sent. Then `kt-subscribe`
19
+ carries the `email` and `wait(promise)`:
20
+
21
+ - hand `wait` the request, and the button shows it running;
22
+ - when it resolves, the field gives way to a thanks, announced to screen
23
+ readers, and `subscribed` is set;
24
+ - when it rejects, its message — or a plain one — shows on the field.
25
+
26
+ Without a `wait`, it thanks at once. `subscribe()` does what the button does.
27
+
28
+ ## Variants and layout
29
+
30
+ `panel`, the default, sets it on a tinted panel; `plain` on the page.
31
+ `stacked` puts the field under the words; `inline` beside them, once the block
32
+ is 760px wide. On a narrow screen the button goes under the field.
33
+
34
+ ## Words
35
+
36
+ ```js
37
+ letter.texts = {
38
+ email: 'Adresse e-mail',
39
+ placeholder: 'vous@exemple.fr',
40
+ subscribe: "S'abonner",
41
+ invalid: 'Saisissez une adresse e-mail, comme nom@exemple.fr.',
42
+ failed: "Ça n'est pas passé. Réessayez dans un instant.",
43
+ done: 'C’est fait. Confirmez depuis votre boîte de réception.',
44
+ };
45
+ ```
46
+
47
+ ## Accessibility
48
+
49
+ A section named by its heading, an `<h2>` by default (`heading-level`). The
50
+ field is named — Email address — and asks for an email, so phones show the
51
+ right keyboard and browsers offer the reader's own. An error is said on the
52
+ field; the thanks sits in a status region, read out when it appears.
53
+
54
+ ## API
55
+
56
+ | Property | Attribute | Type | Default |
57
+ | -------------- | --------------- | ---------------------------- | ----------- |
58
+ | `heading` | `heading` | `string` | `''` |
59
+ | `lead` | `lead` | `string` | `''` |
60
+ | `variant` | `variant` | `'panel' \| 'plain'` | `'panel'` |
61
+ | `layout` | `layout` | `'stacked' \| 'inline'` | `'stacked'` |
62
+ | `subscribed` | `subscribed` | `boolean` | `false` |
63
+ | `align` | `align` | `'center' \| 'start'` | `'center'` |
64
+ | `headingLevel` | `heading-level` | `number` | `2` |
65
+ | `texts` | — | `Partial<KtNewsletterTexts>` | `{}` |
66
+
67
+ | Event | Detail |
68
+ | -------------- | -------------------------- |
69
+ | `kt-subscribe` | `{ email, wait(promise) }` |
@@ -0,0 +1,77 @@
1
+ # `<kt-number-input>`
2
+
3
+ A number field with − and + beside it: a quantity, a seat count, an amount.
4
+
5
+ ```html
6
+ <kt-number-input label="Seats" min="1" max="50" value="5"></kt-number-input>
7
+ ```
8
+
9
+ ```js
10
+ amount.formatOptions = { style: 'currency', currency: 'EUR' };
11
+ ```
12
+
13
+ ## Typing and stepping
14
+
15
+ Type a number the way your language writes one — `1 234,5` in French,
16
+ `1,234.5` in English — or step it:
17
+
18
+ | Key | Does |
19
+ | -------------- | -------------------- |
20
+ | `↑` / `↓` | one step up or down |
21
+ | `Page Up/Down` | ten steps |
22
+ | `Home`/`End` | to `min` or `max` |
23
+ | `Enter` | reads what was typed |
24
+
25
+ The − and + buttons step too, and grey out at the bounds. They stay out of the
26
+ tab order: the arrows already do their work from the field.
27
+
28
+ What is typed is read when the field is left, or on Enter, and kept within
29
+ `min` and `max` and on `step`. Text that is no number puts back the value the
30
+ field had; an emptied field holds `null`.
31
+
32
+ ## Reading at rest
33
+
34
+ While the field has the focus it shows the plain number, easy to edit. At rest
35
+ it reads the way the locale writes it, through `formatOptions` — any
36
+ `Intl.NumberFormat` option: a currency, a percentage, a unit, a number of
37
+ decimals. A screen reader hears that text as the value.
38
+
39
+ ## In a form
40
+
41
+ A form control: it submits the number under `name`, and nothing while empty.
42
+ `required` blocks submission while it is empty, `error` shows a message, and
43
+ `form.reset()` puts back the first value.
44
+
45
+ ## API
46
+
47
+ | Property | Attribute | Type | Default |
48
+ | --------------- | ------------- | -------------------------------- | ------------------ |
49
+ | `value` | `value` | `number \| null` | `null` |
50
+ | `min` | `min` | `number` | none |
51
+ | `max` | `max` | `number` | none |
52
+ | `step` | `step` | `number` | `1` |
53
+ | `formatOptions` | — | `Intl.NumberFormatOptions` | `{}` |
54
+ | `locale` | `locale` | `string` | page, then browser |
55
+ | `name` | `name` | `string` | `''` |
56
+ | `label` | `label` | `string` | `''` |
57
+ | `placeholder` | `placeholder` | `string` | `''` |
58
+ | `size` | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
59
+ | `disabled` | `disabled` | `boolean` | `false` |
60
+ | `required` | `required` | `boolean` | `false` |
61
+ | `error` | `error` | `string` | `''` |
62
+
63
+ | Event | Detail |
64
+ | ----------- | --------------------------- |
65
+ | `kt-change` | `{ value: number \| null }` |
66
+
67
+ | Part | Description |
68
+ | ---------- | -------------- |
69
+ | `field` | The field |
70
+ | `input` | The text field |
71
+ | `decrease` | The − button |
72
+ | `increase` | The + button |
73
+
74
+ ## Accessibility
75
+
76
+ The field is a `spinbutton` with its bounds, its value and the text it shows;
77
+ `error` is announced with it.
@@ -0,0 +1,68 @@
1
+ # `<kt-otp-input>`
2
+
3
+ A one-time code — the six digits of a sign-in, a verification, a second factor —
4
+ one box per character.
5
+
6
+ ```html
7
+ <form>
8
+ <kt-otp-input label="Verification code" name="code" required></kt-otp-input>
9
+ </form>
10
+
11
+ <script>
12
+ document.querySelector('kt-otp-input').addEventListener('kt-complete', (event) => {
13
+ verify(event.detail.value);
14
+ });
15
+ </script>
16
+ ```
17
+
18
+ ## Typing
19
+
20
+ Typing moves to the next box. Backspace clears a box, and from an empty one
21
+ steps back and clears the one before. The arrows, Home and End move between
22
+ boxes. A pasted code — with spaces or dashes, as codes are often written — is
23
+ cleaned and spread over the boxes from the one it was pasted into.
24
+
25
+ The first box asks the browser for `autocomplete="one-time-code"`, so a code
26
+ that arrived by text message fills itself in on a phone. `kt-change` fires as
27
+ the code changes, `kt-complete` once it is whole.
28
+
29
+ `length` sets how many characters the code has (6 by default). `type="numeric"`,
30
+ the default, takes digits and opens the number pad; `type="alphanumeric"` takes
31
+ letters and digits, shown in capitals.
32
+
33
+ ## Forms
34
+
35
+ A form control: submitted under `name`, `required` until the code is whole
36
+ ("Enter the whole code."), reset to its first `value` with the form, disabled
37
+ with a disabled fieldset. `error` shows a message under the boxes, announced
38
+ with each of them.
39
+
40
+ ## Accessibility
41
+
42
+ A group named by `label`, each box named by its place — "Character 2 of 6" — so
43
+ a screen reader says where the person is in the code. Translate both strings
44
+ through `setStrings` as `otpCharacter` and `otpRequired`.
45
+
46
+ ## API
47
+
48
+ | Property | Attribute | Type | Default |
49
+ | ---------- | ---------- | ----------------------------- | ----------- |
50
+ | `value` | `value` | `string` | `''` |
51
+ | `length` | `length` | `number` | `6` |
52
+ | `type` | `type` | `'numeric' \| 'alphanumeric'` | `'numeric'` |
53
+ | `label` | `label` | `string` | `''` |
54
+ | `name` | `name` | `string` | `''` |
55
+ | `required` | `required` | `boolean` | `false` |
56
+ | `disabled` | `disabled` | `boolean` | `false` |
57
+ | `error` | `error` | `string` | `''` |
58
+
59
+ | Event | Detail |
60
+ | ------------- | ------------------- |
61
+ | `kt-change` | `{ value: string }` |
62
+ | `kt-complete` | `{ value: string }` |
63
+
64
+ | Part | Description |
65
+ | ------- | ----------------- |
66
+ | `group` | The boxes |
67
+ | `box` | One box |
68
+ | `error` | The error message |
@@ -0,0 +1,66 @@
1
+ # `<kt-post-grid>`
2
+
3
+ The latest posts, each a card that leads to it: a cover, a title, a line, and
4
+ who wrote it when.
5
+
6
+ ```html
7
+ <kt-post-grid id="latest" heading="From the blog">
8
+ <a slot="more" href="/blog">Every post</a>
9
+ </kt-post-grid>
10
+ <script>
11
+ latest.posts = [
12
+ {
13
+ title: 'Closing the month in a day',
14
+ href: '/blog/close',
15
+ excerpt: 'What changed when the bank feed matched itself.',
16
+ date: '2026-09-14',
17
+ image: '/covers/close.jpg',
18
+ author: { name: 'Ada Park', avatar: '/ada.jpg' },
19
+ tags: ['Finance'],
20
+ },
21
+ ];
22
+ </script>
23
+ ```
24
+
25
+ ## Posts
26
+
27
+ | Field | What it is |
28
+ | ---------- | ----------------------------------------------------------- |
29
+ | `title` | The post's title, a link to it — the whole card answers it. |
30
+ | `href` | Where the post is. |
31
+ | `excerpt` | Optional: a line on what it says. |
32
+ | `date` | Optional: when it was published, `2026-09-14`. |
33
+ | `image` | Optional: a cover, cropped to 16:9. |
34
+ | `imageAlt` | Optional: the cover's text alternative; empty by default. |
35
+ | `author` | Optional: `{ name, avatar }`. |
36
+ | `tags` | Optional: a few words over the title. |
37
+
38
+ Dates are written for people — Sep 14, 2026 — in `locale`, the page's
39
+ language when it is empty, and kept for machines in a `<time datetime>`.
40
+
41
+ ## Layout
42
+
43
+ `grid`, the default, sets the posts in `columns` — 3 or 2 — where there is
44
+ room: two at most under 760px, one under 520px. `list` puts one under
45
+ another, the cover beside the words once the block is 640px wide. The
46
+ `more` slot sits under the posts: a link to every one.
47
+
48
+ ## Accessibility
49
+
50
+ A section named by its heading, an `<h2>` by default (`heading-level`). The
51
+ posts are a list of `<article>`s; each title is a link one level under the
52
+ heading. A cover is decoration unless given `imageAlt` — the title already
53
+ says what the post is.
54
+
55
+ ## API
56
+
57
+ | Property | Attribute | Type | Default |
58
+ | -------------- | --------------- | --------------------- | ---------- |
59
+ | `heading` | `heading` | `string` | `''` |
60
+ | `lead` | `lead` | `string` | `''` |
61
+ | `posts` | — | `KtPost[]` | `[]` |
62
+ | `columns` | `columns` | `2 \| 3` | `3` |
63
+ | `layout` | `layout` | `'grid' \| 'list'` | `'grid'` |
64
+ | `locale` | `locale` | `string` | `''` |
65
+ | `align` | `align` | `'center' \| 'start'` | `'center'` |
66
+ | `headingLevel` | `heading-level` | `number` | `2` |
@@ -0,0 +1,101 @@
1
+ # `<kt-pricing-table>`
2
+
3
+ The plans, side by side: what each costs, what it includes, and the way in —
4
+ with a switch between monthly and yearly prices when the plans have both.
5
+
6
+ ```html
7
+ <kt-pricing-table id="pricing" heading="Pricing" currency="EUR" yearly-note="Two months free">
8
+ <a slot="note" href="/compare">Compare every feature</a>
9
+ </kt-pricing-table>
10
+ <script>
11
+ pricing.plans = [
12
+ {
13
+ id: 'starter',
14
+ name: 'Starter',
15
+ price: { monthly: 0, yearly: 0 },
16
+ features: ['10 invoices a month'],
17
+ },
18
+ {
19
+ id: 'team',
20
+ name: 'Team',
21
+ description: 'For a team that bills.',
22
+ price: { monthly: 29, yearly: 290 },
23
+ features: ['Unlimited invoices', 'Bank reconciliation'],
24
+ featured: true,
25
+ action: 'Start a trial',
26
+ },
27
+ {
28
+ id: 'scale',
29
+ name: 'Scale',
30
+ price: 'Custom',
31
+ features: ['SSO'],
32
+ href: '/sales',
33
+ action: 'Talk to sales',
34
+ },
35
+ ];
36
+ pricing.addEventListener('kt-plan', (e) => checkout(e.detail.id, e.detail.billing));
37
+ </script>
38
+ ```
39
+
40
+ ## Plans
41
+
42
+ | Field | What it is |
43
+ | ------------- | ---------------------------------------------------------------------------------- |
44
+ | `id` | What `kt-plan` carries. |
45
+ | `name` | The plan's name, a heading. |
46
+ | `description` | Optional: who it is for. |
47
+ | `price` | A number, formatted in `currency`; a string, as written; or `{ monthly, yearly }`. |
48
+ | `features` | What it includes, a line each, ticked. |
49
+ | `action` | The button's words. Get started by default. |
50
+ | `href` | Makes the button a link; without it, the button fires `kt-plan`. |
51
+ | `featured` | The plan to pick: outlined and badged. |
52
+
53
+ ## Billing
54
+
55
+ When a plan has a price per period, a switch shows over the plans, monthly
56
+ first. `billing` sets the period shown; changing it fires `kt-billing`. A
57
+ yearly price is the year's — `290` reads $290/year. `yearly-note` sits beside
58
+ the switch: what paying yearly saves.
59
+
60
+ Prices follow `locale`, the page's language when it is empty.
61
+
62
+ ## Words
63
+
64
+ Every word is in `texts`, English until given others:
65
+
66
+ ```js
67
+ pricing.texts = {
68
+ monthly: 'Mensuel',
69
+ yearly: 'Annuel',
70
+ perMonth: '/mois',
71
+ perYear: '/an',
72
+ featured: 'Le plus choisi',
73
+ action: 'Commencer',
74
+ };
75
+ ```
76
+
77
+ ## Accessibility
78
+
79
+ A section named by its heading, an `<h2>` by default (`heading-level`); the
80
+ plans are a list, each name one level under. The switch is a radio group,
81
+ one tab stop, moved with the arrows.
82
+
83
+ ## API
84
+
85
+ | Property | Attribute | Type | Default |
86
+ | -------------- | --------------- | ------------------------------ | ----------- |
87
+ | `heading` | `heading` | `string` | `''` |
88
+ | `lead` | `lead` | `string` | `''` |
89
+ | `plans` | — | `KtPlan[]` | `[]` |
90
+ | `billing` | `billing` | `'monthly' \| 'yearly'` | `'monthly'` |
91
+ | `currency` | `currency` | `string` | `'USD'` |
92
+ | `locale` | `locale` | `string` | `''` |
93
+ | `yearlyNote` | `yearly-note` | `string` | `''` |
94
+ | `align` | `align` | `'center' \| 'start'` | `'center'` |
95
+ | `headingLevel` | `heading-level` | `number` | `2` |
96
+ | `texts` | — | `Partial<KtPricingTableTexts>` | `{}` |
97
+
98
+ | Event | Detail |
99
+ | ------------ | ----------------- |
100
+ | `kt-billing` | `{ billing }` |
101
+ | `kt-plan` | `{ id, billing }` |
@@ -0,0 +1,86 @@
1
+ # `<kt-prompt-input>`
2
+
3
+ The field a person writes to an assistant in: it grows with what is written,
4
+ sends on Enter, and shows the sending on its own send button.
5
+
6
+ ```html
7
+ <kt-prompt-input placeholder="Ask Northwind anything"></kt-prompt-input>
8
+
9
+ <script>
10
+ const prompt = document.querySelector('kt-prompt-input');
11
+ prompt.addEventListener('kt-submit', (event) => {
12
+ event.detail.wait(api.ask(event.detail.value));
13
+ });
14
+ </script>
15
+ ```
16
+
17
+ ## Sending
18
+
19
+ Enter sends; Shift+Enter starts a new line. With `submit-on="mod-enter"`,
20
+ Enter starts a new line and Cmd or Ctrl+Enter sends — for long messages,
21
+ where a stray Enter should not send half a thought. An input method composing
22
+ a character keeps Enter for itself.
23
+
24
+ `kt-submit` carries the text and `wait(promise)`. Hand it the request:
25
+
26
+ - the send button runs it — its plane turns into the spinner, then flies off;
27
+ - the field holds the text, read-only, until the request settles;
28
+ - on success the field empties; on failure the text stays, to send again.
29
+
30
+ Without `wait`, the field empties as soon as it sends. `submit()` sends from
31
+ script, as Enter would. Nothing is sent while the text is blank — the send
32
+ button says so by being disabled — nor while `disabled`.
33
+
34
+ ## Growing
35
+
36
+ The field starts one line tall and grows with each line, up to `max-rows`
37
+ (8 by default); past that it scrolls.
38
+
39
+ ## Slots
40
+
41
+ | Slot | Where |
42
+ | ------------- | ----------------------------------------------------------------------------- |
43
+ | `attachments` | Above the text: files or context added to the message. Collapses while empty. |
44
+ | `actions` | Beside the send button: attach, a model picker, a mode. |
45
+
46
+ ```html
47
+ <kt-prompt-input>
48
+ <kt-badge slot="attachments" icon="file" removable>q3-report.pdf</kt-badge>
49
+ <kt-button
50
+ slot="actions"
51
+ size="small"
52
+ variant="secondary-no-bg"
53
+ icon="paperclip"
54
+ label="Attach a file"
55
+ ></kt-button>
56
+ </kt-prompt-input>
57
+ ```
58
+
59
+ ## Accessibility
60
+
61
+ A `<textarea>` named by `label` — "Message" by default — and a send button
62
+ named "Send", both translated through `setStrings`. The button is a real
63
+ button, reached by Tab after the field. While a message is sending, the field
64
+ is read-only rather than disabled, so the focus stays where the person left it.
65
+
66
+ ## API
67
+
68
+ | Property | Attribute | Type | Default |
69
+ | ------------- | ------------- | ------------------------ | --------- |
70
+ | `value` | `value` | `string` | `''` |
71
+ | `placeholder` | `placeholder` | `string` | `''` |
72
+ | `label` | `label` | `string` | `''` |
73
+ | `disabled` | `disabled` | `boolean` | `false` |
74
+ | `maxRows` | `max-rows` | `number` | `8` |
75
+ | `submitOn` | `submit-on` | `'enter' \| 'mod-enter'` | `'enter'` |
76
+
77
+ | Event | Detail |
78
+ | ----------- | ---------------------------------- |
79
+ | `kt-input` | `{ value: string }` |
80
+ | `kt-submit` | `{ value: string, wait(promise) }` |
81
+
82
+ | Part | Description |
83
+ | ---------- | ----------------------- |
84
+ | `base` | The field |
85
+ | `textarea` | The native `<textarea>` |
86
+ | `send` | The send button |
@@ -0,0 +1,65 @@
1
+ # `<kt-settings-section>`
2
+
3
+ One part of a settings page: what it is about, the fields that change it, and
4
+ the button that saves them.
5
+
6
+ ```html
7
+ <kt-settings-section heading="Profile" description="How others see you in the workspace.">
8
+ <kt-label-input label="Name"><kt-input value="Ada Park"></kt-input></kt-label-input>
9
+ <kt-label-input label="Email"
10
+ ><kt-input type="email" value="ada@northwind.com"></kt-input
11
+ ></kt-label-input>
12
+ <span slot="note">Saved 2 minutes ago</span>
13
+ <kt-button slot="actions">Save</kt-button>
14
+ </kt-settings-section>
15
+
16
+ <kt-settings-section
17
+ danger
18
+ heading="Delete workspace"
19
+ description="Everything in it goes, for good."
20
+ >
21
+ <kt-button slot="actions" variant="delete">Delete workspace</kt-button>
22
+ </kt-settings-section>
23
+ ```
24
+
25
+ A settings page is several of these, one under another.
26
+
27
+ ## Layout
28
+
29
+ `split`, the default, sets the heading and its description beside the fields
30
+ once the section is 760px wide — a third for the words, two thirds for the
31
+ card — and over them below. `stacked` always puts them over the fields.
32
+
33
+ ## Slots
34
+
35
+ | Slot | What goes in it |
36
+ | --------- | ---------------------------------------------------- |
37
+ | (default) | The fields, spaced as a form. |
38
+ | `actions` | In the card's footer, at the end: Save, Cancel. |
39
+ | `note` | In the footer, at the start: when it was last saved. |
40
+
41
+ The footer shows only when it has actions or a note; a card with only actions
42
+ — a danger zone — is just its footer.
43
+
44
+ ## Danger
45
+
46
+ `danger` turns the heading and the card's border red: the section that
47
+ deletes the workspace or the account. Pair it with a `delete` button and a
48
+ `kt-confirm-dialog`.
49
+
50
+ ## Accessibility
51
+
52
+ A section named by its heading — an `<h2>` by default, `heading-level`
53
+ changes it — and described by its description. The section does not make a
54
+ form: wrap the page's sections in a `<form>` or a `<kt-form>`, or each one,
55
+ to save them together or apart.
56
+
57
+ ## API
58
+
59
+ | Property | Attribute | Type | Default |
60
+ | -------------- | --------------- | ---------------------- | --------- |
61
+ | `heading` | `heading` | `string` | `''` |
62
+ | `description` | `description` | `string` | `''` |
63
+ | `layout` | `layout` | `'split' \| 'stacked'` | `'split'` |
64
+ | `danger` | `danger` | `boolean` | `false` |
65
+ | `headingLevel` | `heading-level` | `number` | `2` |
@@ -0,0 +1,76 @@
1
+ # `<kt-slider>`
2
+
3
+ A value picked by sliding along a range: a volume, a threshold, or with `range`, a price between two ends.
4
+
5
+ ```html
6
+ <kt-slider label="Volume" value="40" show-value></kt-slider>
7
+ <kt-slider label="Price" range min="0" max="500" step="10" value="50/300" show-value></kt-slider>
8
+ ```
9
+
10
+ ## Native underneath
11
+
12
+ Each thumb is a native `<input type="range">`, laid over a track Kanto draws.
13
+ The keyboard comes from the platform — arrows and Page Up/Down step, Home and
14
+ End go to the bounds — and so does what a screen reader announces. A `range`
15
+ lays two inputs over one track; each thumb catches its own pointer.
16
+
17
+ ## The value
18
+
19
+ The value is text, as a form field's is: `"40"`, or with `range`, `"20/80"` —
20
+ low, then high. It is kept within `min` and `max` and on `step`: `value="42"`
21
+ with `step="5"` reads `40`. Without a value, a slider starts at `min`, and a
22
+ range at its two bounds. The two thumbs of a range never cross: the low end
23
+ stops at the high one.
24
+
25
+ `kt-input` fires while sliding, `kt-change` once the thumb is let go — the one
26
+ to save on.
27
+
28
+ ## Showing the value
29
+
30
+ `show-value` puts the label and the current value above the slider. `format`
31
+ says how a number reads, there and to a screen reader:
32
+
33
+ ```js
34
+ slider.format = (n) => `$${n.toLocaleString('en-US')}`;
35
+ ```
36
+
37
+ ## In a form
38
+
39
+ A form control: it submits its value under `name` — `"20/80"` for a range —
40
+ and `form.reset()` puts back the first value. A disabled fieldset disables it.
41
+
42
+ ## API
43
+
44
+ | Property | Attribute | Type | Default |
45
+ | ----------- | ------------ | ----------------------- | ----------- |
46
+ | `value` | `value` | `string` | `min` |
47
+ | `min` | `min` | `number` | `0` |
48
+ | `max` | `max` | `number` | `100` |
49
+ | `step` | `step` | `number` | `1` |
50
+ | `range` | `range` | `boolean` | `false` |
51
+ | `label` | `label` | `string` | `''` |
52
+ | `name` | `name` | `string` | `''` |
53
+ | `showValue` | `show-value` | `boolean` | `false` |
54
+ | `format` | — | `(n: number) => string` | `String(n)` |
55
+ | `disabled` | `disabled` | `boolean` | `false` |
56
+
57
+ | Event | Detail |
58
+ | ----------- | ------------------- |
59
+ | `kt-input` | `{ value: string }` |
60
+ | `kt-change` | `{ value: string }` |
61
+
62
+ | Part | Description |
63
+ | ------- | ---------------------------------- |
64
+ | `track` | The rail |
65
+ | `fill` | The selected stretch of it |
66
+ | `value` | The shown value, with `show-value` |
67
+
68
+ | Property | Description | Default |
69
+ | ------------------- | -------------------- | ------- |
70
+ | `--kt-slider-thumb` | The thumb's diameter | `18px` |
71
+ | `--kt-slider-track` | The rail's thickness | `6px` |
72
+
73
+ ## Accessibility
74
+
75
+ Each thumb is a native slider named by `label` — "Price, minimum" and "Price,
76
+ maximum" for a range — announcing its value through `format`.