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
@@ -1,33 +1,38 @@
1
- import { css as b, nothing as c, html as p } from "lit";
2
- import { queryAll as v, property as n, state as m } from "lit/decorators.js";
1
+ import { css as v, nothing as c, html as h } from "lit";
2
+ import { queryAll as f, property as s, state as m } from "lit/decorators.js";
3
3
  import { classMap as u } from "lit/directives/class-map.js";
4
- import { K as f, d as g } from "../../../chunks/kt-element-T0VbIBNp.js";
5
- import { e as x } from "../../../chunks/events-r51msXNf.js";
6
- import { a as y, s as k, b as w } from "../../../chunks/form-control-B74_EHtG.js";
7
- import { s as $ } from "../../../chunks/index-TWJzttLX.js";
4
+ import { K as b, d as g } from "../../../chunks/kt-element-DvWtPQ1Y.js";
5
+ import { I as y } from "../../../chunks/indicator-B_Rs8F92.js";
6
+ import { e as k } from "../../../chunks/events-r51msXNf.js";
7
+ import { a as x, s as w, b as $ } from "../../../chunks/form-control-B74_EHtG.js";
8
+ import { s as I } from "../../../chunks/index-1ZFgagWW.js";
8
9
  import "../../core/kt-icon/kt-icon.js";
9
- var I = Object.defineProperty, s = (h, t, i, o) => {
10
- for (var e = void 0, r = h.length - 1, l; r >= 0; r--)
11
- (l = h[r]) && (e = l(t, i, e) || e);
12
- return e && I(t, i, e), e;
10
+ var S = Object.defineProperty, n = (p, t, i, o) => {
11
+ for (var e = void 0, r = p.length - 1, l; r >= 0; r--)
12
+ (l = p[r]) && (e = l(t, i, e) || e);
13
+ return e && S(t, i, e), e;
13
14
  };
14
- const S = { small: 16, medium: 20, large: 24 };
15
- class a extends f {
15
+ const C = { small: 16, medium: 20, large: 24 };
16
+ class a extends b {
16
17
  constructor() {
17
- super(...arguments), this.internals = null, this.defaultValue = null, this.options = [], this.value = null, this.size = "medium", this.orientation = "horizontal", this.disabled = !1, this.formDisabled = !1, this.label = "", this.name = "", this.required = !1;
18
+ super(), this.internals = null, this.defaultValue = null, this.options = [], this.value = null, this.size = "medium", this.orientation = "horizontal", this.disabled = !1, this.formDisabled = !1, this.label = "", this.name = "", this.required = !1, new y(this, {
19
+ container: () => this.renderRoot.querySelector(".track"),
20
+ selected: () => this.renderRoot.querySelector(".option.selected")
21
+ });
18
22
  }
19
23
  static {
20
24
  this.formAssociated = !0;
21
25
  }
22
26
  static {
23
27
  this.styles = [
24
- f.styles,
25
- b`
28
+ b.styles,
29
+ v`
26
30
  :host {
27
31
  display: inline-block;
28
32
  }
29
33
 
30
34
  .track {
35
+ position: relative;
31
36
  display: inline-flex;
32
37
  box-sizing: border-box;
33
38
  gap: 4px;
@@ -86,13 +91,44 @@ class a extends f {
86
91
  background-color: var(--surface-card);
87
92
  }
88
93
 
89
- .option.selected {
94
+ /* Its surface is the thumb below, not its own background. */
95
+ .option.selected,
96
+ .option.selected:hover:not(:disabled) {
90
97
  color: var(--text-body);
98
+ background-color: transparent;
99
+ }
100
+
101
+ /* One surface that slides from segment to segment, placed by
102
+ IndicatorController before the first paint. The segments sit above
103
+ it. */
104
+ .thumb {
105
+ position: absolute;
106
+ top: 0;
107
+ left: 0;
108
+ display: none;
109
+ width: var(--kt-indicator-width);
110
+ height: var(--kt-indicator-height);
91
111
  background-color: var(--surface-raised);
112
+ border-radius: calc(var(--border-radius) - 4px);
113
+ translate: var(--kt-indicator-x) var(--kt-indicator-y);
114
+ pointer-events: none;
92
115
  }
93
- .option.selected:hover:not(:disabled) {
116
+ .track[data-indicator] .thumb {
117
+ display: block;
118
+ }
119
+ .option {
120
+ position: relative;
121
+ }
122
+ .track:has(.option.selected:hover:not(:disabled)) .thumb {
94
123
  background-color: var(--surface-hover);
95
124
  }
125
+ .track[data-indicator='ready'] .thumb {
126
+ transition:
127
+ translate var(--duration-normal) var(--easing-standard),
128
+ width var(--duration-normal) var(--easing-standard),
129
+ height var(--duration-normal) var(--easing-standard),
130
+ background-color var(--duration-normal) var(--easing-standard);
131
+ }
96
132
 
97
133
  .option:disabled {
98
134
  color: var(--text-disabled);
@@ -140,13 +176,13 @@ class a extends f {
140
176
  return this.disabled || this.formDisabled;
141
177
  }
142
178
  connectedCallback() {
143
- super.connectedCallback(), this.internals ??= y(this), this.defaultValue = this.value;
179
+ super.connectedCallback(), this.internals ??= x(this), this.defaultValue = this.value;
144
180
  }
145
181
  willUpdate(t) {
146
182
  if (t.has("value") || t.has("required") || this.stringsChanged(t)) {
147
- k(this.internals, this.value === null ? null : String(this.value));
183
+ w(this.internals, this.value === null ? null : String(this.value));
148
184
  const i = this.required && this.value === null;
149
- w(this.internals, { valueMissing: i }, i ? $().selectOption : "");
185
+ $(this.internals, { valueMissing: i }, i ? I().selectOption : "");
150
186
  }
151
187
  }
152
188
  formResetCallback() {
@@ -166,7 +202,7 @@ class a extends f {
166
202
  return this.options.findIndex((t) => t.value === this.value);
167
203
  }
168
204
  choose(t) {
169
- this.inactive || t.disabled || this.value === t.value || (this.value = t.value, x(this, "kt-change", { value: t.value, option: t }));
205
+ this.inactive || t.disabled || this.value === t.value || (this.value = t.value, k(this, "kt-change", { value: t.value, option: t }));
170
206
  }
171
207
  /**
172
208
  * Radio-group semantics: the arrows move *and* select, wrapping at the ends
@@ -198,7 +234,7 @@ class a extends f {
198
234
  }
199
235
  render() {
200
236
  const t = this.selectedIndex, i = t >= 0 ? t : this.options.findIndex((o) => !o.disabled);
201
- return p`<div
237
+ return h`<div
202
238
  part="base"
203
239
  class=${u({
204
240
  track: !0,
@@ -211,9 +247,10 @@ class a extends f {
211
247
  aria-disabled=${this.inactive ? "true" : c}
212
248
  @keydown=${this.onKeyDown}
213
249
  >
250
+ <span class="thumb" aria-hidden="true"></span>
214
251
  ${this.options.map((o, e) => {
215
252
  const r = o.value === this.value, l = o.label ?? "", d = !!o.icon && l === "";
216
- return p`<button
253
+ return h`<button
217
254
  part="option"
218
255
  type="button"
219
256
  role="radio"
@@ -229,42 +266,42 @@ class a extends f {
229
266
  ?disabled=${this.inactive || o.disabled}
230
267
  @click=${() => this.choose(o)}
231
268
  >
232
- ${o.icon ? p`<kt-icon name=${o.icon} size=${S[this.size]}></kt-icon>` : c}
233
- ${d ? c : p`<span class="text">${l}</span>`}
269
+ ${o.icon ? h`<kt-icon name=${o.icon} size=${C[this.size]}></kt-icon>` : c}
270
+ ${d ? c : h`<span class="text">${l}</span>`}
234
271
  </button>`;
235
272
  })}
236
273
  </div>`;
237
274
  }
238
275
  }
239
- s([
240
- v(".option")
276
+ n([
277
+ f(".option")
241
278
  ], a.prototype, "segments");
242
- s([
243
- n({ attribute: !1 })
279
+ n([
280
+ s({ attribute: !1 })
244
281
  ], a.prototype, "options");
245
- s([
246
- n({ type: String })
282
+ n([
283
+ s({ type: String })
247
284
  ], a.prototype, "value");
248
- s([
249
- n({ type: String, reflect: !0 })
285
+ n([
286
+ s({ type: String, reflect: !0 })
250
287
  ], a.prototype, "size");
251
- s([
252
- n({ type: String, reflect: !0 })
288
+ n([
289
+ s({ type: String, reflect: !0 })
253
290
  ], a.prototype, "orientation");
254
- s([
255
- n({ type: Boolean, reflect: !0 })
291
+ n([
292
+ s({ type: Boolean, reflect: !0 })
256
293
  ], a.prototype, "disabled");
257
- s([
294
+ n([
258
295
  m()
259
296
  ], a.prototype, "formDisabled");
260
- s([
261
- n({ type: String })
297
+ n([
298
+ s({ type: String })
262
299
  ], a.prototype, "label");
263
- s([
264
- n({ type: String })
300
+ n([
301
+ s({ type: String })
265
302
  ], a.prototype, "name");
266
- s([
267
- n({ type: Boolean, reflect: !0 })
303
+ n([
304
+ s({ type: Boolean, reflect: !0 })
268
305
  ], a.prototype, "required");
269
306
  g("kt-segmented-control", a);
270
307
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"kt-segmented-control.js","sources":["../../../../src/components/navigation/kt-segmented-control/kt-segmented-control.ts"],"sourcesContent":["import { css, html, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { property, queryAll, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport {\n attachFormInternals,\n setFormValue,\n setValidity,\n type UsableInternals,\n} from '#internal/form-control';\nimport { strings } from '#internal/strings';\nimport '../../core/kt-icon/kt-icon.js';\n\nexport type KtSegmentedSize = 'small' | 'medium' | 'large';\n\nexport interface KtSegmentedOption {\n readonly value: string | number;\n readonly label?: string;\n readonly icon?: string;\n readonly disabled?: boolean;\n}\n\nconst ICON_SIZE: Record<KtSegmentedSize, number> = { small: 16, medium: 20, large: 24 };\n\n/**\n * A small set of mutually exclusive choices, shown as one inset track with the\n * selected segment raised out of it.\n *\n * Use it for two to five options that all fit on screen — a view switch, a date\n * range. Past that, `<kt-select>`.\n *\n * Implemented as a radio group: one tab stop for the whole control, arrows to\n * move between segments. That is what a keyboard user expects here, and it\n * keeps a five-option control from adding five tab stops to the page.\n *\n * @element kt-segmented-control\n *\n * @csspart base - The track.\n * @csspart option - A segment.\n *\n * @fires kt-change - A segment was chosen. `detail: { value, option }`.\n *\n * @example\n * ```js\n * control.options = [\n * { value: 'day', label: 'Day' },\n * { value: 'week', label: 'Week' },\n * { value: 'month', label: 'Month' },\n * ];\n * control.value = 'week';\n * ```\n */\nexport class KtSegmentedControl extends KtElement {\n static readonly formAssociated = true;\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: inline-block;\n }\n\n .track {\n display: inline-flex;\n box-sizing: border-box;\n gap: 4px;\n padding: 4px;\n background-color: var(--color-dark-14);\n border-radius: var(--border-radius);\n }\n\n .track.small {\n gap: 3px;\n padding: 3px;\n }\n .track.large {\n gap: 5px;\n padding: 5px;\n }\n\n .track.vertical {\n flex-direction: column;\n width: fit-content;\n }\n\n :host(:disabled) .track {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .option {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n gap: var(--gap-button);\n height: var(--button-height-small);\n padding: 0 12px;\n color: var(--text-muted);\n font: var(--font-normal-regular);\n /* Segments share the width equally from a basis of zero, so in a\n container that shrinks to fit they would split a label over two\n lines of a fixed-height button. */\n white-space: nowrap;\n background-color: transparent;\n border: none;\n border-radius: calc(var(--border-radius) - 4px);\n cursor: pointer;\n transition:\n background-color var(--duration-normal) var(--easing-standard),\n color var(--duration-normal) var(--easing-standard);\n }\n\n .option:hover:not(:disabled) {\n background-color: var(--color-dark-18);\n }\n .option:active:not(:disabled) {\n background-color: var(--surface-card);\n }\n\n .option.selected {\n color: var(--text-body);\n background-color: var(--surface-raised);\n }\n .option.selected:hover:not(:disabled) {\n background-color: var(--surface-hover);\n }\n\n .option:disabled {\n color: var(--text-disabled);\n background-color: transparent;\n pointer-events: none;\n }\n\n .option:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: -2px;\n }\n\n .option.small {\n height: 24px;\n gap: 6px;\n padding: 0 8px;\n font: var(--font-normal-small);\n }\n .option.large {\n height: var(--button-height);\n padding: 0 16px;\n font: var(--font-normal-medium);\n }\n\n .option.icon-only {\n width: var(--button-height-small);\n padding: 0;\n }\n .option.icon-only.small {\n width: 24px;\n }\n .option.icon-only.large {\n width: var(--button-height);\n }\n\n .text {\n flex: 1;\n text-align: center;\n }\n `,\n ];\n\n @queryAll('.option')\n private segments!: NodeListOf<HTMLButtonElement>;\n\n private internals: UsableInternals | null = null;\n private defaultValue: string | number | null = null;\n\n @property({ attribute: false })\n options: readonly KtSegmentedOption[] = [];\n\n @property({ type: String })\n value: string | number | null = null;\n\n @property({ type: String, reflect: true })\n size: KtSegmentedSize = 'medium';\n\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Disabled by an enclosing `<fieldset>`, which leaves `disabled` alone. */\n @state()\n private formDisabled = false;\n\n /** Whether the control is off, by its own `disabled` or by its form. */\n private get inactive(): boolean {\n return this.disabled || this.formDisabled;\n }\n\n /** Accessible name for the group. */\n @property({ type: String })\n label = '';\n\n @property({ type: String })\n name = '';\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.internals ??= attachFormInternals(this);\n this.defaultValue = this.value;\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has('value') || changed.has('required') || this.stringsChanged(changed)) {\n setFormValue(this.internals, this.value === null ? null : String(this.value));\n\n const missing = this.required && this.value === null;\n setValidity(this.internals, { valueMissing: missing }, missing ? strings().selectOption : '');\n }\n }\n\n formResetCallback(): void {\n this.value = this.defaultValue;\n }\n\n /**\n * Called by the platform when the control's disabled state changes — its\n * own `disabled`, or an ancestor `<fieldset disabled>` it cannot see.\n */\n formDisabledCallback(disabled: boolean): void {\n this.formDisabled = disabled;\n }\n\n formStateRestoreCallback(state: string): void {\n // The form stores a string; hand back the option's own value, which may be\n // a number.\n this.value = this.options.find((option) => String(option.value) === state)?.value ?? state;\n }\n\n private get selectedIndex(): number {\n return this.options.findIndex((option) => option.value === this.value);\n }\n\n private choose(option: KtSegmentedOption): void {\n if (this.inactive || option.disabled || this.value === option.value) return;\n this.value = option.value;\n emit(this, 'kt-change', { value: option.value, option });\n }\n\n /**\n * Radio-group semantics: the arrows move *and* select, wrapping at the ends\n * and skipping disabled segments.\n */\n private onKeyDown(event: KeyboardEvent): void {\n const forward = this.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight';\n const back = this.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft';\n\n let target: number | undefined;\n if (event.key === forward) target = this.step(1);\n else if (event.key === back) target = this.step(-1);\n else if (event.key === 'Home') target = this.options.findIndex((o) => !o.disabled);\n else if (event.key === 'End')\n target = this.options.length - 1 - [...this.options].reverse().findIndex((o) => !o.disabled);\n else return;\n\n event.preventDefault();\n if (target === undefined || target < 0) return;\n\n const option = this.options[target];\n if (!option) return;\n\n const index = target;\n this.choose(option);\n void this.updateComplete.then(() => this.segments[index]?.focus());\n }\n\n private step(direction: 1 | -1): number | undefined {\n const count = this.options.length;\n if (count === 0) return undefined;\n\n const from = this.selectedIndex < 0 ? (direction === 1 ? -1 : 0) : this.selectedIndex;\n for (let offset = 1; offset <= count; offset += 1) {\n const index = (((from + direction * offset) % count) + count) % count;\n if (!this.options[index]?.disabled) return index;\n }\n return undefined;\n }\n\n override render(): TemplateResult {\n const selectedIndex = this.selectedIndex;\n // One tab stop for the whole group: the selected segment holds it, or the\n // first selectable one when nothing is chosen yet.\n const tabStop = selectedIndex >= 0 ? selectedIndex : this.options.findIndex((o) => !o.disabled);\n\n return html`<div\n part=\"base\"\n class=${classMap({\n track: true,\n [this.size]: true,\n vertical: this.orientation === 'vertical',\n })}\n role=\"radiogroup\"\n aria-label=${this.label || nothing}\n aria-orientation=${this.orientation}\n aria-disabled=${this.inactive ? 'true' : nothing}\n @keydown=${this.onKeyDown}\n >\n ${this.options.map((option, index) => {\n const selected = option.value === this.value;\n const text = option.label ?? '';\n const iconOnly = Boolean(option.icon) && text === '';\n\n return html`<button\n part=\"option\"\n type=\"button\"\n role=\"radio\"\n class=${classMap({\n option: true,\n [this.size]: true,\n selected,\n 'icon-only': iconOnly,\n })}\n aria-checked=${selected ? 'true' : 'false'}\n aria-label=${iconOnly ? (option.icon ?? '') : nothing}\n tabindex=${index === tabStop ? 0 : -1}\n ?disabled=${this.inactive || option.disabled}\n @click=${() => this.choose(option)}\n >\n ${\n option.icon\n ? html`<kt-icon name=${option.icon} size=${ICON_SIZE[this.size]}></kt-icon>`\n : nothing\n }\n ${iconOnly ? nothing : html`<span class=\"text\">${text}</span>`}\n </button>`;\n })}\n </div>`;\n }\n}\n\ndefineElement('kt-segmented-control', KtSegmentedControl);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-segmented-control': KtSegmentedControl;\n }\n}\n"],"names":["ICON_SIZE","KtSegmentedControl","KtElement","css","attachFormInternals","changed","setFormValue","missing","setValidity","strings","disabled","state","option","emit","event","forward","back","target","o","index","direction","count","from","offset","selectedIndex","tabStop","html","classMap","nothing","selected","text","iconOnly","__decorateClass","queryAll","property","defineElement"],"mappings":"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"}
1
+ {"version":3,"file":"kt-segmented-control.js","sources":["../../../../src/components/navigation/kt-segmented-control/kt-segmented-control.ts"],"sourcesContent":["import { css, html, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { property, queryAll, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { IndicatorController } from '#internal/indicator';\nimport { emit } from '#internal/events';\nimport {\n attachFormInternals,\n setFormValue,\n setValidity,\n type UsableInternals,\n} from '#internal/form-control';\nimport { strings } from '#internal/strings';\nimport '../../core/kt-icon/kt-icon.js';\n\nexport type KtSegmentedSize = 'small' | 'medium' | 'large';\n\nexport interface KtSegmentedOption {\n readonly value: string | number;\n readonly label?: string;\n readonly icon?: string;\n readonly disabled?: boolean;\n}\n\nconst ICON_SIZE: Record<KtSegmentedSize, number> = { small: 16, medium: 20, large: 24 };\n\n/**\n * A small set of mutually exclusive choices, shown as one inset track with the\n * selected segment raised out of it.\n *\n * Use it for two to five options that all fit on screen — a view switch, a date\n * range. Past that, `<kt-select>`.\n *\n * Implemented as a radio group: one tab stop for the whole control, arrows to\n * move between segments. That is what a keyboard user expects here, and it\n * keeps a five-option control from adding five tab stops to the page.\n *\n * @element kt-segmented-control\n *\n * @csspart base - The track.\n * @csspart option - A segment.\n *\n * @fires kt-change - A segment was chosen. `detail: { value, option }`.\n *\n * @example\n * ```js\n * control.options = [\n * { value: 'day', label: 'Day' },\n * { value: 'week', label: 'Week' },\n * { value: 'month', label: 'Month' },\n * ];\n * control.value = 'week';\n * ```\n */\nexport class KtSegmentedControl extends KtElement {\n static readonly formAssociated = true;\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: inline-block;\n }\n\n .track {\n position: relative;\n display: inline-flex;\n box-sizing: border-box;\n gap: 4px;\n padding: 4px;\n background-color: var(--color-dark-14);\n border-radius: var(--border-radius);\n }\n\n .track.small {\n gap: 3px;\n padding: 3px;\n }\n .track.large {\n gap: 5px;\n padding: 5px;\n }\n\n .track.vertical {\n flex-direction: column;\n width: fit-content;\n }\n\n :host(:disabled) .track {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .option {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n gap: var(--gap-button);\n height: var(--button-height-small);\n padding: 0 12px;\n color: var(--text-muted);\n font: var(--font-normal-regular);\n /* Segments share the width equally from a basis of zero, so in a\n container that shrinks to fit they would split a label over two\n lines of a fixed-height button. */\n white-space: nowrap;\n background-color: transparent;\n border: none;\n border-radius: calc(var(--border-radius) - 4px);\n cursor: pointer;\n transition:\n background-color var(--duration-normal) var(--easing-standard),\n color var(--duration-normal) var(--easing-standard);\n }\n\n .option:hover:not(:disabled) {\n background-color: var(--color-dark-18);\n }\n .option:active:not(:disabled) {\n background-color: var(--surface-card);\n }\n\n /* Its surface is the thumb below, not its own background. */\n .option.selected,\n .option.selected:hover:not(:disabled) {\n color: var(--text-body);\n background-color: transparent;\n }\n\n /* One surface that slides from segment to segment, placed by\n IndicatorController before the first paint. The segments sit above\n it. */\n .thumb {\n position: absolute;\n top: 0;\n left: 0;\n display: none;\n width: var(--kt-indicator-width);\n height: var(--kt-indicator-height);\n background-color: var(--surface-raised);\n border-radius: calc(var(--border-radius) - 4px);\n translate: var(--kt-indicator-x) var(--kt-indicator-y);\n pointer-events: none;\n }\n .track[data-indicator] .thumb {\n display: block;\n }\n .option {\n position: relative;\n }\n .track:has(.option.selected:hover:not(:disabled)) .thumb {\n background-color: var(--surface-hover);\n }\n .track[data-indicator='ready'] .thumb {\n transition:\n translate var(--duration-normal) var(--easing-standard),\n width var(--duration-normal) var(--easing-standard),\n height var(--duration-normal) var(--easing-standard),\n background-color var(--duration-normal) var(--easing-standard);\n }\n\n .option:disabled {\n color: var(--text-disabled);\n background-color: transparent;\n pointer-events: none;\n }\n\n .option:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: -2px;\n }\n\n .option.small {\n height: 24px;\n gap: 6px;\n padding: 0 8px;\n font: var(--font-normal-small);\n }\n .option.large {\n height: var(--button-height);\n padding: 0 16px;\n font: var(--font-normal-medium);\n }\n\n .option.icon-only {\n width: var(--button-height-small);\n padding: 0;\n }\n .option.icon-only.small {\n width: 24px;\n }\n .option.icon-only.large {\n width: var(--button-height);\n }\n\n .text {\n flex: 1;\n text-align: center;\n }\n `,\n ];\n\n @queryAll('.option')\n private segments!: NodeListOf<HTMLButtonElement>;\n\n constructor() {\n super();\n new IndicatorController(this, {\n container: () => this.renderRoot.querySelector<HTMLElement>('.track'),\n selected: () => this.renderRoot.querySelector<HTMLElement>('.option.selected'),\n });\n }\n\n private internals: UsableInternals | null = null;\n private defaultValue: string | number | null = null;\n\n @property({ attribute: false })\n options: readonly KtSegmentedOption[] = [];\n\n @property({ type: String })\n value: string | number | null = null;\n\n @property({ type: String, reflect: true })\n size: KtSegmentedSize = 'medium';\n\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Disabled by an enclosing `<fieldset>`, which leaves `disabled` alone. */\n @state()\n private formDisabled = false;\n\n /** Whether the control is off, by its own `disabled` or by its form. */\n private get inactive(): boolean {\n return this.disabled || this.formDisabled;\n }\n\n /** Accessible name for the group. */\n @property({ type: String })\n label = '';\n\n @property({ type: String })\n name = '';\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.internals ??= attachFormInternals(this);\n this.defaultValue = this.value;\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has('value') || changed.has('required') || this.stringsChanged(changed)) {\n setFormValue(this.internals, this.value === null ? null : String(this.value));\n\n const missing = this.required && this.value === null;\n setValidity(this.internals, { valueMissing: missing }, missing ? strings().selectOption : '');\n }\n }\n\n formResetCallback(): void {\n this.value = this.defaultValue;\n }\n\n /**\n * Called by the platform when the control's disabled state changes — its\n * own `disabled`, or an ancestor `<fieldset disabled>` it cannot see.\n */\n formDisabledCallback(disabled: boolean): void {\n this.formDisabled = disabled;\n }\n\n formStateRestoreCallback(state: string): void {\n // The form stores a string; hand back the option's own value, which may be\n // a number.\n this.value = this.options.find((option) => String(option.value) === state)?.value ?? state;\n }\n\n private get selectedIndex(): number {\n return this.options.findIndex((option) => option.value === this.value);\n }\n\n private choose(option: KtSegmentedOption): void {\n if (this.inactive || option.disabled || this.value === option.value) return;\n this.value = option.value;\n emit(this, 'kt-change', { value: option.value, option });\n }\n\n /**\n * Radio-group semantics: the arrows move *and* select, wrapping at the ends\n * and skipping disabled segments.\n */\n private onKeyDown(event: KeyboardEvent): void {\n const forward = this.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight';\n const back = this.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft';\n\n let target: number | undefined;\n if (event.key === forward) target = this.step(1);\n else if (event.key === back) target = this.step(-1);\n else if (event.key === 'Home') target = this.options.findIndex((o) => !o.disabled);\n else if (event.key === 'End')\n target = this.options.length - 1 - [...this.options].reverse().findIndex((o) => !o.disabled);\n else return;\n\n event.preventDefault();\n if (target === undefined || target < 0) return;\n\n const option = this.options[target];\n if (!option) return;\n\n const index = target;\n this.choose(option);\n void this.updateComplete.then(() => this.segments[index]?.focus());\n }\n\n private step(direction: 1 | -1): number | undefined {\n const count = this.options.length;\n if (count === 0) return undefined;\n\n const from = this.selectedIndex < 0 ? (direction === 1 ? -1 : 0) : this.selectedIndex;\n for (let offset = 1; offset <= count; offset += 1) {\n const index = (((from + direction * offset) % count) + count) % count;\n if (!this.options[index]?.disabled) return index;\n }\n return undefined;\n }\n\n override render(): TemplateResult {\n const selectedIndex = this.selectedIndex;\n // One tab stop for the whole group: the selected segment holds it, or the\n // first selectable one when nothing is chosen yet.\n const tabStop = selectedIndex >= 0 ? selectedIndex : this.options.findIndex((o) => !o.disabled);\n\n return html`<div\n part=\"base\"\n class=${classMap({\n track: true,\n [this.size]: true,\n vertical: this.orientation === 'vertical',\n })}\n role=\"radiogroup\"\n aria-label=${this.label || nothing}\n aria-orientation=${this.orientation}\n aria-disabled=${this.inactive ? 'true' : nothing}\n @keydown=${this.onKeyDown}\n >\n <span class=\"thumb\" aria-hidden=\"true\"></span>\n ${this.options.map((option, index) => {\n const selected = option.value === this.value;\n const text = option.label ?? '';\n const iconOnly = Boolean(option.icon) && text === '';\n\n return html`<button\n part=\"option\"\n type=\"button\"\n role=\"radio\"\n class=${classMap({\n option: true,\n [this.size]: true,\n selected,\n 'icon-only': iconOnly,\n })}\n aria-checked=${selected ? 'true' : 'false'}\n aria-label=${iconOnly ? (option.icon ?? '') : nothing}\n tabindex=${index === tabStop ? 0 : -1}\n ?disabled=${this.inactive || option.disabled}\n @click=${() => this.choose(option)}\n >\n ${\n option.icon\n ? html`<kt-icon name=${option.icon} size=${ICON_SIZE[this.size]}></kt-icon>`\n : nothing\n }\n ${iconOnly ? nothing : html`<span class=\"text\">${text}</span>`}\n </button>`;\n })}\n </div>`;\n }\n}\n\ndefineElement('kt-segmented-control', KtSegmentedControl);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-segmented-control': KtSegmentedControl;\n }\n}\n"],"names":["ICON_SIZE","KtSegmentedControl","KtElement","IndicatorController","css","attachFormInternals","changed","setFormValue","missing","setValidity","strings","disabled","state","option","emit","event","forward","back","target","o","index","direction","count","from","offset","selectedIndex","tabStop","html","classMap","nothing","selected","text","iconOnly","__decorateClass","queryAll","property","defineElement"],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import { type PropertyValues, type TemplateResult } from 'lit';
2
+ import { KtElement } from '#internal/kt-element';
3
+ import '../../core/kt-icon/kt-icon.js';
4
+ export interface KtStep {
5
+ readonly id: string;
6
+ readonly label: string;
7
+ /** A line under the label. */
8
+ readonly description?: string;
9
+ /** Something on this step needs fixing — a field it holds failed. */
10
+ readonly error?: boolean;
11
+ }
12
+ export type KtStepsOrientation = 'horizontal' | 'vertical';
13
+ /**
14
+ * The steps of a flow — sign-up, checkout, onboarding — and where the reader
15
+ * is in it.
16
+ *
17
+ * Steps before `current` are complete, `current` is current, the rest are to
18
+ * come — all of them, while `current` names no step; a step with `error` shows as needing attention wherever it is. With
19
+ * `navigable`, a completed step is a button that goes back to it; going
20
+ * forward is the flow's job, not the stepper's.
21
+ *
22
+ * An ordered list: the number is the step's place, `aria-current="step"`
23
+ * marks the current one, and each state is said in words, not only shown.
24
+ *
25
+ * @element kt-steps
26
+ *
27
+ * @csspart list - The `<ol>`.
28
+ * @csspart step - A step.
29
+ * @csspart marker - A step's number, tick or alert.
30
+ * @csspart connector - The line from a step to the next.
31
+ *
32
+ * @fires kt-change - A completed step was picked, with `navigable`. `detail: { id }`.
33
+ *
34
+ * @example
35
+ * ```html
36
+ * <kt-steps label="Sign-up" current="billing"></kt-steps>
37
+ * <script>
38
+ * steps.steps = [
39
+ * { id: 'account', label: 'Account' },
40
+ * { id: 'billing', label: 'Billing', description: 'Card or invoice' },
41
+ * { id: 'team', label: 'Team' },
42
+ * ];
43
+ * </script>
44
+ * ```
45
+ */
46
+ export declare class KtSteps extends KtElement {
47
+ static styles: import("lit").CSSResultGroup[];
48
+ /** The steps, in order. Set as a property. */
49
+ steps: readonly KtStep[];
50
+ /** The id of the step the reader is on. */
51
+ current: string;
52
+ /** Accessible name of the list: what the flow is. */
53
+ label: string;
54
+ orientation: KtStepsOrientation;
55
+ /** Completed steps become buttons that go back to them. */
56
+ navigable: boolean;
57
+ /** Steps completed by the last change of `current`, whose tick comes in. */
58
+ private entering;
59
+ willUpdate(changed: PropertyValues<this>): void;
60
+ private stateOf;
61
+ private goTo;
62
+ render(): TemplateResult;
63
+ }
64
+ declare global {
65
+ interface HTMLElementTagNameMap {
66
+ 'kt-steps': KtSteps;
67
+ }
68
+ }
@@ -0,0 +1,286 @@
1
+ import { css as g, nothing as p, html as i } from "lit";
2
+ import { property as l } from "lit/decorators.js";
3
+ import { K as m, d as b } from "../../../chunks/kt-element-DvWtPQ1Y.js";
4
+ import { e as k } from "../../../chunks/events-r51msXNf.js";
5
+ import { s as v } from "../../../chunks/index-1ZFgagWW.js";
6
+ import "../../core/kt-icon/kt-icon.js";
7
+ var x = Object.defineProperty, c = (d, r, a, o) => {
8
+ for (var t = void 0, e = d.length - 1, s; e >= 0; e--)
9
+ (s = d[e]) && (t = s(r, a, t) || t);
10
+ return t && x(r, a, t), t;
11
+ };
12
+ class n extends m {
13
+ constructor() {
14
+ super(...arguments), this.steps = [], this.current = "", this.label = "", this.orientation = "horizontal", this.navigable = !1, this.entering = /* @__PURE__ */ new Set();
15
+ }
16
+ static {
17
+ this.styles = [
18
+ m.styles,
19
+ g`
20
+ :host {
21
+ display: block;
22
+ --kt-steps-marker: calc(28px * var(--density-scale, 1));
23
+ }
24
+
25
+ ol {
26
+ display: flex;
27
+ margin: 0;
28
+ padding: 0;
29
+ list-style: none;
30
+ }
31
+ :host([orientation='vertical']) ol {
32
+ flex-direction: column;
33
+ }
34
+
35
+ /* Across, the steps share the width evenly: a column each, the marker
36
+ on top and the text centred under it. */
37
+ li {
38
+ position: relative;
39
+ flex: 1 1 0;
40
+ min-width: 0;
41
+ }
42
+ .step {
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: 8px;
46
+ align-items: center;
47
+ text-align: center;
48
+ }
49
+ :host([orientation='vertical']) li {
50
+ flex: none;
51
+ padding-bottom: 24px;
52
+ }
53
+ :host([orientation='vertical']) li:last-child {
54
+ padding-bottom: 0;
55
+ }
56
+ :host([orientation='vertical']) .step {
57
+ flex-direction: row;
58
+ gap: 12px;
59
+ align-items: flex-start;
60
+ text-align: start;
61
+ }
62
+
63
+ /* The line to the next step, from marker to marker through their
64
+ middle, clear of each: 8px across, 6px down. */
65
+ .connector {
66
+ position: absolute;
67
+ top: calc(var(--kt-steps-marker) / 2 - 1px);
68
+ left: calc(50% + var(--kt-steps-marker) / 2 + 8px);
69
+ width: calc(100% - var(--kt-steps-marker) - 16px);
70
+ height: 2px;
71
+ background: var(--border-field);
72
+ border-radius: var(--radius-full);
73
+ }
74
+ /* The fill runs from this step to the next as it is completed, and
75
+ back as it is undone. */
76
+ .fill {
77
+ display: block;
78
+ width: 100%;
79
+ height: 100%;
80
+ background: var(--color-primary-base);
81
+ border-radius: inherit;
82
+ transform: scaleX(0);
83
+ transform-origin: left;
84
+ transition: transform var(--duration-slow) var(--easing-standard);
85
+ }
86
+ li[data-state='complete'] .fill {
87
+ transform: none;
88
+ }
89
+ :host([orientation='vertical']) .fill {
90
+ transform: scaleY(0);
91
+ transform-origin: top;
92
+ }
93
+ :host([orientation='vertical']) li[data-state='complete'] .fill {
94
+ transform: none;
95
+ }
96
+ :host([orientation='vertical']) .connector {
97
+ top: calc(var(--kt-steps-marker) + 6px);
98
+ left: calc(var(--kt-steps-marker) / 2 - 1px);
99
+ width: 2px;
100
+ height: calc(100% - var(--kt-steps-marker) - 12px);
101
+ }
102
+
103
+ /* A filled circle: the tick when done, the number otherwise. */
104
+ .marker {
105
+ display: grid;
106
+ flex: none;
107
+ place-items: center;
108
+ width: var(--kt-steps-marker);
109
+ height: var(--kt-steps-marker);
110
+ color: var(--text-body);
111
+ font: var(--font-normal-small);
112
+ font-weight: 600;
113
+ /* A field's border colour: a grey that reads on a card and a page,
114
+ in both themes. */
115
+ background: var(--border-field);
116
+ border-radius: 50%;
117
+ transition:
118
+ background-color var(--duration-fast) var(--easing-standard),
119
+ color var(--duration-fast) var(--easing-standard);
120
+ }
121
+ li[data-state='complete'] .marker,
122
+ li[data-state='current'] .marker {
123
+ color: var(--color-white);
124
+ background: var(--color-primary-base);
125
+ }
126
+ li[data-state='error'] .marker {
127
+ color: var(--color-white);
128
+ background: var(--color-danger-base);
129
+ }
130
+ /* Trimmed to the digits' height, so the grid centres the ink, not a
131
+ line box padded by the font's ascent and descent. */
132
+ .number {
133
+ display: block;
134
+ line-height: 1;
135
+ font-variant-numeric: tabular-nums;
136
+ text-box: trim-both cap alphabetic;
137
+ }
138
+ /* Lucide's tick sits high in its square; this puts its ink on the
139
+ marker's middle. */
140
+ .marker kt-icon[name='check'] {
141
+ translate: 0 0.5px;
142
+ }
143
+ /* A step just completed: its tick comes in as the line reaches the
144
+ next step. Never on the first render — a page opens still. */
145
+ .marker kt-icon.enter {
146
+ animation: kt-steps-tick var(--duration-normal) var(--easing-standard) backwards;
147
+ }
148
+ @keyframes kt-steps-tick {
149
+ from {
150
+ opacity: 0;
151
+ scale: 0.4;
152
+ }
153
+ }
154
+
155
+ .text {
156
+ display: grid;
157
+ gap: 2px;
158
+ min-width: 0;
159
+ padding: 0 4px;
160
+ }
161
+ :host([orientation='vertical']) .text {
162
+ gap: 0;
163
+ padding: 0;
164
+ }
165
+ .label {
166
+ color: var(--text-muted);
167
+ font: var(--font-normal-medium);
168
+ }
169
+ /* Down, as tall as the marker, so the label sits on its middle. */
170
+ :host([orientation='vertical']) .label {
171
+ display: flex;
172
+ align-items: center;
173
+ min-height: var(--kt-steps-marker);
174
+ }
175
+ li[data-state='current'] .label,
176
+ li[data-state='complete'] .label {
177
+ color: var(--text-body);
178
+ }
179
+ li[data-state='error'] .label {
180
+ color: var(--color-danger-text);
181
+ }
182
+ .description {
183
+ color: var(--text-muted);
184
+ font: var(--font-normal-small);
185
+ }
186
+
187
+ button.step {
188
+ width: 100%;
189
+ margin: 0;
190
+ padding: 0;
191
+ color: inherit;
192
+ font: inherit;
193
+ background: none;
194
+ border: none;
195
+ border-radius: var(--radius-input);
196
+ cursor: pointer;
197
+ }
198
+ button.step:hover .label {
199
+ color: var(--color-primary-text);
200
+ }
201
+ button.step:hover .marker {
202
+ background: var(--color-primary-hover);
203
+ }
204
+ button.step:focus-visible {
205
+ outline: var(--outline-width) solid var(--color-primary-base);
206
+ outline-offset: 4px;
207
+ }
208
+
209
+ .visually-hidden {
210
+ position: absolute;
211
+ width: 1px;
212
+ height: 1px;
213
+ overflow: hidden;
214
+ clip-path: inset(50%);
215
+ white-space: nowrap;
216
+ }
217
+ `
218
+ ];
219
+ }
220
+ willUpdate(r) {
221
+ if (!r.has("current") || !this.hasUpdated) return;
222
+ const a = (e) => this.steps.findIndex((s) => s.id === e), o = a(r.get("current")), t = a(this.current);
223
+ this.entering = /* @__PURE__ */ new Set();
224
+ for (let e = Math.max(o, 0); e < t; e += 1) this.entering.add(e);
225
+ }
226
+ stateOf(r, a, o) {
227
+ return r.error ? "error" : a < o ? "complete" : a === o ? "current" : "upcoming";
228
+ }
229
+ goTo(r) {
230
+ this.current = r.id, k(this, "kt-change", { id: r.id });
231
+ }
232
+ render() {
233
+ const r = v(), a = this.steps.findIndex((t) => t.id === this.current), o = {
234
+ complete: r.stepComplete,
235
+ current: r.stepCurrent,
236
+ upcoming: r.stepUpcoming,
237
+ error: r.stepError
238
+ };
239
+ return i`<ol part="list" aria-label=${this.label || p}>
240
+ ${this.steps.map((t, e) => {
241
+ const s = this.stateOf(t, e, a), u = s === "complete" ? i`<kt-icon
242
+ class=${this.entering.has(e) ? "enter" : ""}
243
+ name="check"
244
+ size="14"
245
+ ></kt-icon>` : s === "error" ? i`<kt-icon name="circle-alert" size="14"></kt-icon>` : i`<span class="number">${e + 1}</span>`, h = i`<span part="marker" class="marker" aria-hidden="true">${u}</span>
246
+ <span class="text">
247
+ <span class="label">${t.label}</span>
248
+ ${t.description ? i`<span class="description">${t.description}</span>` : p}
249
+ <span class="visually-hidden">${o[s]}</span>
250
+ </span>`, f = this.navigable && e < a;
251
+ return i`<li
252
+ part="step"
253
+ data-state=${s}
254
+ aria-current=${e === a ? "step" : p}
255
+ >
256
+ ${f ? i`<button class="step" type="button" @click=${() => this.goTo(t)}>
257
+ ${h}
258
+ </button>` : i`<span class="step">${h}</span>`}
259
+ ${e < this.steps.length - 1 ? i`<span part="connector" class="connector" aria-hidden="true"
260
+ ><span class="fill"></span
261
+ ></span>` : p}
262
+ </li>`;
263
+ })}
264
+ </ol>`;
265
+ }
266
+ }
267
+ c([
268
+ l({ attribute: !1 })
269
+ ], n.prototype, "steps");
270
+ c([
271
+ l({ type: String, reflect: !0 })
272
+ ], n.prototype, "current");
273
+ c([
274
+ l({ type: String })
275
+ ], n.prototype, "label");
276
+ c([
277
+ l({ type: String, reflect: !0 })
278
+ ], n.prototype, "orientation");
279
+ c([
280
+ l({ type: Boolean, reflect: !0 })
281
+ ], n.prototype, "navigable");
282
+ b("kt-steps", n);
283
+ export {
284
+ n as KtSteps
285
+ };
286
+ //# sourceMappingURL=kt-steps.js.map