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.
- package/README.md +26 -14
- package/dist/AGENTS.md +157 -0
- package/dist/cdn/kanto.min.js +4743 -932
- package/dist/chunks/block-Cci-Kff_.js +69 -0
- package/dist/chunks/block-Cci-Kff_.js.map +1 -0
- package/dist/chunks/defaults-yhaR6U65.js +70 -0
- package/dist/chunks/{defaults-Cpeg13O5.js.map → defaults-yhaR6U65.js.map} +1 -1
- package/dist/chunks/heading-DsnZsfg-.js +21 -0
- package/dist/chunks/heading-DsnZsfg-.js.map +1 -0
- package/dist/chunks/{index-TWJzttLX.js → index-1ZFgagWW.js} +37 -12
- package/dist/chunks/index-1ZFgagWW.js.map +1 -0
- package/dist/chunks/indicator-B_Rs8F92.js +49 -0
- package/dist/chunks/indicator-B_Rs8F92.js.map +1 -0
- package/dist/chunks/{kt-calendar-CtwOby1R.js → kt-calendar-SK8eapuy.js} +3 -3
- package/dist/chunks/{kt-calendar-CtwOby1R.js.map → kt-calendar-SK8eapuy.js.map} +1 -1
- package/dist/chunks/kt-color-picker-BoezCAmx.js +365 -0
- package/dist/chunks/kt-color-picker-BoezCAmx.js.map +1 -0
- package/dist/chunks/{kt-element-T0VbIBNp.js → kt-element-DvWtPQ1Y.js} +2 -2
- package/dist/chunks/{kt-element-T0VbIBNp.js.map → kt-element-DvWtPQ1Y.js.map} +1 -1
- package/dist/chunks/motion-ChVUUO7O.js +28 -0
- package/dist/chunks/motion-ChVUUO7O.js.map +1 -0
- package/dist/chunks/numbers-QyecMiSJ.js +9 -0
- package/dist/chunks/numbers-QyecMiSJ.js.map +1 -0
- package/dist/chunks/{segmented-field-BBXR4XFL.js → segmented-field-T_Zo6lc1.js} +2 -2
- package/dist/chunks/{segmented-field-BBXR4XFL.js.map → segmented-field-T_Zo6lc1.js.map} +1 -1
- package/dist/chunks/{typed-date-CPAUNHzr.js → typed-date-CaU0kXoY.js} +2 -2
- package/dist/chunks/{typed-date-CPAUNHzr.js.map → typed-date-CaU0kXoY.js.map} +1 -1
- package/dist/components/blocks/kt-auth-form/kt-auth-form.d.ts +143 -0
- package/dist/components/blocks/kt-auth-form/kt-auth-form.js +368 -0
- package/dist/components/blocks/kt-auth-form/kt-auth-form.js.map +1 -0
- package/dist/components/blocks/kt-blog-post/kt-blog-post.d.ts +75 -0
- package/dist/components/blocks/kt-blog-post/kt-blog-post.js +285 -0
- package/dist/components/blocks/kt-blog-post/kt-blog-post.js.map +1 -0
- package/dist/components/blocks/kt-cta/kt-cta.d.ts +51 -0
- package/dist/components/blocks/kt-cta/kt-cta.js +126 -0
- package/dist/components/blocks/kt-cta/kt-cta.js.map +1 -0
- package/dist/components/blocks/kt-empty-page/kt-empty-page.d.ts +75 -0
- package/dist/components/blocks/kt-empty-page/kt-empty-page.js +245 -0
- package/dist/components/blocks/kt-empty-page/kt-empty-page.js.map +1 -0
- package/dist/components/blocks/kt-error-page/kt-error-page.d.ts +65 -0
- package/dist/components/blocks/kt-error-page/kt-error-page.js +177 -0
- package/dist/components/blocks/kt-error-page/kt-error-page.js.map +1 -0
- package/dist/components/blocks/kt-faq/kt-faq.d.ts +61 -0
- package/dist/components/blocks/kt-faq/kt-faq.js +129 -0
- package/dist/components/blocks/kt-faq/kt-faq.js.map +1 -0
- package/dist/components/blocks/kt-feature-grid/kt-feature-grid.d.ts +59 -0
- package/dist/components/blocks/kt-feature-grid/kt-feature-grid.js +166 -0
- package/dist/components/blocks/kt-feature-grid/kt-feature-grid.js.map +1 -0
- package/dist/components/blocks/kt-hero/kt-hero.d.ts +51 -0
- package/dist/components/blocks/kt-hero/kt-hero.js +138 -0
- package/dist/components/blocks/kt-hero/kt-hero.js.map +1 -0
- package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.d.ts +46 -0
- package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.js +100 -0
- package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.js.map +1 -0
- package/dist/components/blocks/kt-newsletter/kt-newsletter.d.ts +85 -0
- package/dist/components/blocks/kt-newsletter/kt-newsletter.js +247 -0
- package/dist/components/blocks/kt-newsletter/kt-newsletter.js.map +1 -0
- package/dist/components/blocks/kt-post-grid/kt-post-grid.d.ts +73 -0
- package/dist/components/blocks/kt-post-grid/kt-post-grid.js +249 -0
- package/dist/components/blocks/kt-post-grid/kt-post-grid.js.map +1 -0
- package/dist/components/blocks/kt-pricing-table/kt-pricing-table.d.ts +102 -0
- package/dist/components/blocks/kt-pricing-table/kt-pricing-table.js +307 -0
- package/dist/components/blocks/kt-pricing-table/kt-pricing-table.js.map +1 -0
- package/dist/components/blocks/kt-settings-section/kt-settings-section.d.ts +52 -0
- package/dist/components/blocks/kt-settings-section/kt-settings-section.js +158 -0
- package/dist/components/blocks/kt-settings-section/kt-settings-section.js.map +1 -0
- package/dist/components/blocks/kt-testimonials/kt-testimonials.d.ts +56 -0
- package/dist/components/blocks/kt-testimonials/kt-testimonials.js +161 -0
- package/dist/components/blocks/kt-testimonials/kt-testimonials.js.map +1 -0
- package/dist/components/core/kt-avatar/kt-avatar.js +2 -2
- package/dist/components/core/kt-avatar-group/kt-avatar-group.d.ts +42 -0
- package/dist/components/core/kt-avatar-group/kt-avatar-group.js +97 -0
- package/dist/components/core/kt-avatar-group/kt-avatar-group.js.map +1 -0
- package/dist/components/core/kt-badge/kt-badge.js +2 -2
- package/dist/components/core/kt-button/flights.d.ts +27 -0
- package/dist/components/core/kt-button/kt-button.d.ts +52 -1
- package/dist/components/core/kt-button/kt-button.js +353 -77
- package/dist/components/core/kt-button/kt-button.js.map +1 -1
- package/dist/components/core/kt-button/morph.d.ts +27 -0
- package/dist/components/core/kt-card/kt-card.js +1 -1
- package/dist/components/core/kt-code/kt-code.d.ts +2 -1
- package/dist/components/core/kt-code/kt-code.js +52 -37
- package/dist/components/core/kt-code/kt-code.js.map +1 -1
- package/dist/components/core/kt-copy-button/kt-copy-button.d.ts +47 -0
- package/dist/components/core/kt-copy-button/kt-copy-button.js +74 -0
- package/dist/components/core/kt-copy-button/kt-copy-button.js.map +1 -0
- package/dist/components/core/kt-icon/kt-icon.js +2 -2
- package/dist/components/core/kt-kbd/kt-kbd.js +1 -1
- package/dist/components/core/kt-split-button/kt-split-button.js +2 -2
- package/dist/components/data/kt-chart/kt-chart.js +2 -2
- package/dist/components/data/kt-chat-message/kt-chat-message.d.ts +60 -0
- package/dist/components/data/kt-chat-message/kt-chat-message.js +204 -0
- package/dist/components/data/kt-chat-message/kt-chat-message.js.map +1 -0
- package/dist/components/data/kt-description-list/kt-description-list.d.ts +56 -0
- package/dist/components/data/kt-description-list/kt-description-list.js +120 -0
- package/dist/components/data/kt-description-list/kt-description-list.js.map +1 -0
- package/dist/components/data/kt-meter/kt-meter.js +8 -6
- package/dist/components/data/kt-meter/kt-meter.js.map +1 -1
- package/dist/components/data/kt-pagination/kt-pagination.js +2 -2
- package/dist/components/data/kt-stat/kt-stat.d.ts +3 -1
- package/dist/components/data/kt-stat/kt-stat.js +31 -16
- package/dist/components/data/kt-stat/kt-stat.js.map +1 -1
- package/dist/components/data/kt-table/kt-table.js +2 -2
- package/dist/components/data/kt-timeline/kt-timeline.js +2 -2
- package/dist/components/data/kt-timeline/kt-timeline.js.map +1 -1
- package/dist/components/data/kt-tree/kt-tree.d.ts +69 -0
- package/dist/components/data/kt-tree/kt-tree.js +208 -0
- package/dist/components/data/kt-tree/kt-tree.js.map +1 -0
- package/dist/components/feedback/kt-alert/kt-alert.js +2 -2
- package/dist/components/feedback/kt-empty-state/kt-empty-state.js +1 -1
- package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +1 -1
- package/dist/components/feedback/kt-skeleton/kt-skeleton.js +1 -1
- package/dist/components/feedback/kt-toast/kt-toast.js +2 -2
- package/dist/components/feedback/kt-toast-container/kt-toast-container.d.ts +8 -1
- package/dist/components/feedback/kt-toast-container/kt-toast-container.js +65 -26
- package/dist/components/feedback/kt-toast-container/kt-toast-container.js.map +1 -1
- package/dist/components/feedback/kt-tooltip/kt-tooltip.js +1 -1
- package/dist/components/forms/kt-calendar/kt-calendar.js +3 -3
- package/dist/components/forms/kt-checkbox/kt-checkbox.d.ts +2 -0
- package/dist/components/forms/kt-checkbox/kt-checkbox.js +19 -8
- package/dist/components/forms/kt-checkbox/kt-checkbox.js.map +1 -1
- package/dist/components/forms/kt-color-picker/kt-color-picker.d.ts +66 -0
- package/dist/components/forms/kt-color-picker/kt-color-picker.js +14 -0
- package/dist/components/forms/kt-color-picker/kt-color-picker.js.map +1 -0
- package/dist/components/forms/kt-date-input/kt-date-input.js +5 -5
- package/dist/components/forms/kt-date-picker/kt-date-picker.js +4 -4
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +2 -2
- package/dist/components/forms/kt-form/kt-form.js +2 -2
- package/dist/components/forms/kt-input/kt-input.js +2 -2
- package/dist/components/forms/kt-input-menu/kt-input-menu.js +2 -2
- package/dist/components/forms/kt-label-input/kt-label-input.js +1 -1
- package/dist/components/forms/kt-multi-select/kt-multi-select.js +2 -2
- package/dist/components/forms/kt-number-input/kt-number-input.d.ts +92 -0
- package/dist/components/forms/kt-number-input/kt-number-input.js +366 -0
- package/dist/components/forms/kt-number-input/kt-number-input.js.map +1 -0
- package/dist/components/forms/kt-otp-input/kt-otp-input.d.ts +74 -0
- package/dist/components/forms/kt-otp-input/kt-otp-input.js +232 -0
- package/dist/components/forms/kt-otp-input/kt-otp-input.js.map +1 -0
- package/dist/components/forms/kt-prompt-input/kt-prompt-input.d.ts +74 -0
- package/dist/components/forms/kt-prompt-input/kt-prompt-input.js +213 -0
- package/dist/components/forms/kt-prompt-input/kt-prompt-input.js.map +1 -0
- package/dist/components/forms/kt-radio-group/kt-radio-group.js +2 -2
- package/dist/components/forms/kt-select/kt-select.js +2 -2
- package/dist/components/forms/kt-slider/kt-slider.d.ts +69 -0
- package/dist/components/forms/kt-slider/kt-slider.js +252 -0
- package/dist/components/forms/kt-slider/kt-slider.js.map +1 -0
- package/dist/components/forms/kt-textarea/kt-textarea.js +2 -2
- package/dist/components/forms/kt-time-input/kt-time-input.js +3 -3
- package/dist/components/forms/kt-toggle/kt-toggle.js +1 -1
- package/dist/components/navigation/kt-app-shell/kt-app-shell.d.ts +85 -0
- package/dist/components/navigation/kt-app-shell/kt-app-shell.js +220 -0
- package/dist/components/navigation/kt-app-shell/kt-app-shell.js.map +1 -0
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +2 -2
- package/dist/components/navigation/kt-footer/kt-footer.d.ts +82 -0
- package/dist/components/navigation/kt-footer/kt-footer.js +220 -0
- package/dist/components/navigation/kt-footer/kt-footer.js.map +1 -0
- package/dist/components/navigation/kt-header/kt-header.js +2 -2
- package/dist/components/navigation/kt-page-header/kt-page-header.js +2 -2
- package/dist/components/navigation/kt-page-header/kt-page-header.js.map +1 -1
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.d.ts +1 -0
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +81 -44
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js.map +1 -1
- package/dist/components/navigation/kt-steps/kt-steps.d.ts +68 -0
- package/dist/components/navigation/kt-steps/kt-steps.js +286 -0
- package/dist/components/navigation/kt-steps/kt-steps.js.map +1 -0
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +3 -3
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js.map +1 -1
- package/dist/components/navigation/kt-tabs/kt-tabs.d.ts +1 -0
- package/dist/components/navigation/kt-tabs/kt-tabs.js +92 -64
- package/dist/components/navigation/kt-tabs/kt-tabs.js.map +1 -1
- package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +1 -1
- package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +2 -2
- package/dist/components/navigation/kt-user-menu/kt-user-menu.d.ts +86 -0
- package/dist/components/navigation/kt-user-menu/kt-user-menu.js +298 -0
- package/dist/components/navigation/kt-user-menu/kt-user-menu.js.map +1 -0
- package/dist/components/overlays/kt-accordion/kt-accordion.d.ts +47 -0
- package/dist/components/overlays/kt-accordion/kt-accordion.js +80 -0
- package/dist/components/overlays/kt-accordion/kt-accordion.js.map +1 -0
- package/dist/components/overlays/kt-collapsible/kt-collapsible.d.ts +17 -1
- package/dist/components/overlays/kt-collapsible/kt-collapsible.js +87 -32
- package/dist/components/overlays/kt-collapsible/kt-collapsible.js.map +1 -1
- package/dist/components/overlays/kt-command-palette/kt-command-palette.d.ts +87 -0
- package/dist/components/overlays/kt-command-palette/kt-command-palette.js +370 -0
- package/dist/components/overlays/kt-command-palette/kt-command-palette.js.map +1 -0
- package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +2 -2
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js +2 -2
- package/dist/components/overlays/kt-modal/kt-modal.js +2 -2
- package/dist/components/overlays/kt-side-panel/kt-side-panel.js +2 -2
- package/dist/components/overlays/kt-tour/kt-tour.d.ts +77 -0
- package/dist/components/overlays/kt-tour/kt-tour.js +200 -0
- package/dist/components/overlays/kt-tour/kt-tour.js.map +1 -0
- package/dist/custom-elements.json +16427 -8061
- package/dist/docs/kt-accordion.md +49 -0
- package/dist/docs/kt-app-shell.md +89 -0
- package/dist/docs/kt-auth-form.md +111 -0
- package/dist/docs/kt-avatar-group.md +49 -0
- package/dist/docs/kt-blog-post.md +77 -0
- package/dist/docs/kt-button.md +21 -0
- package/dist/docs/kt-chat-message.md +68 -0
- package/dist/docs/kt-color-picker.md +67 -0
- package/dist/docs/kt-command-palette.md +99 -0
- package/dist/docs/kt-copy-button.md +50 -0
- package/dist/docs/kt-cta.md +45 -0
- package/dist/docs/kt-description-list.md +58 -0
- package/dist/docs/kt-empty-page.md +92 -0
- package/dist/docs/kt-error-page.md +64 -0
- package/dist/docs/kt-faq.md +54 -0
- package/dist/docs/kt-feature-grid.md +53 -0
- package/dist/docs/kt-footer.md +115 -0
- package/dist/docs/kt-hero.md +53 -0
- package/dist/docs/kt-logo-cloud.md +41 -0
- package/dist/docs/kt-newsletter.md +69 -0
- package/dist/docs/kt-number-input.md +77 -0
- package/dist/docs/kt-otp-input.md +68 -0
- package/dist/docs/kt-post-grid.md +66 -0
- package/dist/docs/kt-pricing-table.md +101 -0
- package/dist/docs/kt-prompt-input.md +86 -0
- package/dist/docs/kt-settings-section.md +65 -0
- package/dist/docs/kt-slider.md +76 -0
- package/dist/docs/kt-steps.md +79 -0
- package/dist/docs/kt-testimonials.md +52 -0
- package/dist/docs/kt-tour.md +75 -0
- package/dist/docs/kt-tree.md +83 -0
- package/dist/docs/kt-user-menu.md +77 -0
- package/dist/icons/defaults.d.ts +2 -0
- package/dist/icons/index.js +1 -1
- package/dist/index.d.ts +56 -0
- package/dist/index.js +225 -284
- package/dist/index.js.map +1 -1
- package/dist/internal/block.d.ts +23 -0
- package/dist/internal/command-search.d.ts +27 -0
- package/dist/internal/heading.d.ts +8 -0
- package/dist/internal/indicator.d.ts +34 -0
- package/dist/internal/motion.d.ts +25 -0
- package/dist/internal/numbers.d.ts +2 -0
- package/dist/internal/strings.d.ts +36 -0
- package/dist/react/index.d.ts +165 -0
- package/dist/react/index.js +420 -171
- package/dist/react/index.js.map +1 -1
- package/dist/react/jsx.d.ts +128 -1
- package/dist/strings/index.js +1 -1
- package/dist/tokens/base.css +35 -2
- package/dist/vscode.css-custom-data.json +165 -19
- package/dist/vscode.html-custom-data.json +1023 -149
- package/dist/vue/index.d.ts +62 -0
- package/dist/vue/index.js +39 -8
- package/dist/vue/index.js.map +1 -1
- package/dist/web-types.json +3238 -836
- package/package.json +128 -3
- package/dist/chunks/defaults-Cpeg13O5.js +0 -68
- package/dist/chunks/index-TWJzttLX.js.map +0 -1
|
@@ -1,33 +1,38 @@
|
|
|
1
|
-
import { css as
|
|
2
|
-
import { queryAll as
|
|
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
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { s as $ } from "../../../chunks/
|
|
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
|
|
10
|
-
for (var e = void 0, r =
|
|
11
|
-
(l =
|
|
12
|
-
return 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
|
|
15
|
-
class a extends
|
|
15
|
+
const C = { small: 16, medium: 20, large: 24 };
|
|
16
|
+
class a extends b {
|
|
16
17
|
constructor() {
|
|
17
|
-
super(
|
|
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
|
-
|
|
25
|
-
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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 ??=
|
|
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
|
-
|
|
183
|
+
w(this.internals, this.value === null ? null : String(this.value));
|
|
148
184
|
const i = this.required && this.value === null;
|
|
149
|
-
|
|
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,
|
|
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
|
|
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
|
|
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 ?
|
|
233
|
-
${d ? c :
|
|
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
|
-
|
|
240
|
-
|
|
276
|
+
n([
|
|
277
|
+
f(".option")
|
|
241
278
|
], a.prototype, "segments");
|
|
242
|
-
|
|
243
|
-
|
|
279
|
+
n([
|
|
280
|
+
s({ attribute: !1 })
|
|
244
281
|
], a.prototype, "options");
|
|
245
|
-
|
|
246
|
-
|
|
282
|
+
n([
|
|
283
|
+
s({ type: String })
|
|
247
284
|
], a.prototype, "value");
|
|
248
|
-
|
|
249
|
-
|
|
285
|
+
n([
|
|
286
|
+
s({ type: String, reflect: !0 })
|
|
250
287
|
], a.prototype, "size");
|
|
251
|
-
|
|
252
|
-
|
|
288
|
+
n([
|
|
289
|
+
s({ type: String, reflect: !0 })
|
|
253
290
|
], a.prototype, "orientation");
|
|
254
|
-
|
|
255
|
-
|
|
291
|
+
n([
|
|
292
|
+
s({ type: Boolean, reflect: !0 })
|
|
256
293
|
], a.prototype, "disabled");
|
|
257
|
-
|
|
294
|
+
n([
|
|
258
295
|
m()
|
|
259
296
|
], a.prototype, "formDisabled");
|
|
260
|
-
|
|
261
|
-
|
|
297
|
+
n([
|
|
298
|
+
s({ type: String })
|
|
262
299
|
], a.prototype, "label");
|
|
263
|
-
|
|
264
|
-
|
|
300
|
+
n([
|
|
301
|
+
s({ type: String })
|
|
265
302
|
], a.prototype, "name");
|
|
266
|
-
|
|
267
|
-
|
|
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
|