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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kt-steps.js","sources":["../../../../src/components/navigation/kt-steps/kt-steps.ts"],"sourcesContent":["import { css, html, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport { strings } from '#internal/strings';\nimport '../../core/kt-icon/kt-icon.js';\n\nexport interface KtStep {\n readonly id: string;\n readonly label: string;\n /** A line under the label. */\n readonly description?: string;\n /** Something on this step needs fixing — a field it holds failed. */\n readonly error?: boolean;\n}\n\nexport type KtStepsOrientation = 'horizontal' | 'vertical';\n\ntype StepState = 'complete' | 'current' | 'upcoming' | 'error';\n\n/**\n * The steps of a flow — sign-up, checkout, onboarding — and where the reader\n * is in it.\n *\n * Steps before `current` are complete, `current` is current, the rest are to\n * come — all of them, while `current` names no step; a step with `error` shows as needing attention wherever it is. With\n * `navigable`, a completed step is a button that goes back to it; going\n * forward is the flow's job, not the stepper's.\n *\n * An ordered list: the number is the step's place, `aria-current=\"step\"`\n * marks the current one, and each state is said in words, not only shown.\n *\n * @element kt-steps\n *\n * @csspart list - The `<ol>`.\n * @csspart step - A step.\n * @csspart marker - A step's number, tick or alert.\n * @csspart connector - The line from a step to the next.\n *\n * @fires kt-change - A completed step was picked, with `navigable`. `detail: { id }`.\n *\n * @example\n * ```html\n * <kt-steps label=\"Sign-up\" current=\"billing\"></kt-steps>\n * <script>\n * steps.steps = [\n * { id: 'account', label: 'Account' },\n * { id: 'billing', label: 'Billing', description: 'Card or invoice' },\n * { id: 'team', label: 'Team' },\n * ];\n * </script>\n * ```\n */\nexport class KtSteps extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n --kt-steps-marker: calc(28px * var(--density-scale, 1));\n }\n\n ol {\n display: flex;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n :host([orientation='vertical']) ol {\n flex-direction: column;\n }\n\n /* Across, the steps share the width evenly: a column each, the marker\n on top and the text centred under it. */\n li {\n position: relative;\n flex: 1 1 0;\n min-width: 0;\n }\n .step {\n display: flex;\n flex-direction: column;\n gap: 8px;\n align-items: center;\n text-align: center;\n }\n :host([orientation='vertical']) li {\n flex: none;\n padding-bottom: 24px;\n }\n :host([orientation='vertical']) li:last-child {\n padding-bottom: 0;\n }\n :host([orientation='vertical']) .step {\n flex-direction: row;\n gap: 12px;\n align-items: flex-start;\n text-align: start;\n }\n\n /* The line to the next step, from marker to marker through their\n middle, clear of each: 8px across, 6px down. */\n .connector {\n position: absolute;\n top: calc(var(--kt-steps-marker) / 2 - 1px);\n left: calc(50% + var(--kt-steps-marker) / 2 + 8px);\n width: calc(100% - var(--kt-steps-marker) - 16px);\n height: 2px;\n background: var(--border-field);\n border-radius: var(--radius-full);\n }\n /* The fill runs from this step to the next as it is completed, and\n back as it is undone. */\n .fill {\n display: block;\n width: 100%;\n height: 100%;\n background: var(--color-primary-base);\n border-radius: inherit;\n transform: scaleX(0);\n transform-origin: left;\n transition: transform var(--duration-slow) var(--easing-standard);\n }\n li[data-state='complete'] .fill {\n transform: none;\n }\n :host([orientation='vertical']) .fill {\n transform: scaleY(0);\n transform-origin: top;\n }\n :host([orientation='vertical']) li[data-state='complete'] .fill {\n transform: none;\n }\n :host([orientation='vertical']) .connector {\n top: calc(var(--kt-steps-marker) + 6px);\n left: calc(var(--kt-steps-marker) / 2 - 1px);\n width: 2px;\n height: calc(100% - var(--kt-steps-marker) - 12px);\n }\n\n /* A filled circle: the tick when done, the number otherwise. */\n .marker {\n display: grid;\n flex: none;\n place-items: center;\n width: var(--kt-steps-marker);\n height: var(--kt-steps-marker);\n color: var(--text-body);\n font: var(--font-normal-small);\n font-weight: 600;\n /* A field's border colour: a grey that reads on a card and a page,\n in both themes. */\n background: var(--border-field);\n border-radius: 50%;\n transition:\n background-color var(--duration-fast) var(--easing-standard),\n color var(--duration-fast) var(--easing-standard);\n }\n li[data-state='complete'] .marker,\n li[data-state='current'] .marker {\n color: var(--color-white);\n background: var(--color-primary-base);\n }\n li[data-state='error'] .marker {\n color: var(--color-white);\n background: var(--color-danger-base);\n }\n /* Trimmed to the digits' height, so the grid centres the ink, not a\n line box padded by the font's ascent and descent. */\n .number {\n display: block;\n line-height: 1;\n font-variant-numeric: tabular-nums;\n text-box: trim-both cap alphabetic;\n }\n /* Lucide's tick sits high in its square; this puts its ink on the\n marker's middle. */\n .marker kt-icon[name='check'] {\n translate: 0 0.5px;\n }\n /* A step just completed: its tick comes in as the line reaches the\n next step. Never on the first render — a page opens still. */\n .marker kt-icon.enter {\n animation: kt-steps-tick var(--duration-normal) var(--easing-standard) backwards;\n }\n @keyframes kt-steps-tick {\n from {\n opacity: 0;\n scale: 0.4;\n }\n }\n\n .text {\n display: grid;\n gap: 2px;\n min-width: 0;\n padding: 0 4px;\n }\n :host([orientation='vertical']) .text {\n gap: 0;\n padding: 0;\n }\n .label {\n color: var(--text-muted);\n font: var(--font-normal-medium);\n }\n /* Down, as tall as the marker, so the label sits on its middle. */\n :host([orientation='vertical']) .label {\n display: flex;\n align-items: center;\n min-height: var(--kt-steps-marker);\n }\n li[data-state='current'] .label,\n li[data-state='complete'] .label {\n color: var(--text-body);\n }\n li[data-state='error'] .label {\n color: var(--color-danger-text);\n }\n .description {\n color: var(--text-muted);\n font: var(--font-normal-small);\n }\n\n button.step {\n width: 100%;\n margin: 0;\n padding: 0;\n color: inherit;\n font: inherit;\n background: none;\n border: none;\n border-radius: var(--radius-input);\n cursor: pointer;\n }\n button.step:hover .label {\n color: var(--color-primary-text);\n }\n button.step:hover .marker {\n background: var(--color-primary-hover);\n }\n button.step:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 4px;\n }\n\n .visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n }\n `,\n ];\n\n /** The steps, in order. Set as a property. */\n @property({ attribute: false })\n steps: readonly KtStep[] = [];\n\n /** The id of the step the reader is on. */\n @property({ type: String, reflect: true })\n current = '';\n\n /** Accessible name of the list: what the flow is. */\n @property({ type: String })\n label = '';\n\n @property({ type: String, reflect: true })\n orientation: KtStepsOrientation = 'horizontal';\n\n /** Completed steps become buttons that go back to them. */\n @property({ type: Boolean, reflect: true })\n navigable = false;\n\n /** Steps completed by the last change of `current`, whose tick comes in. */\n private entering = new Set<number>();\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (!changed.has('current') || !this.hasUpdated) return;\n const index = (id: string | undefined) => this.steps.findIndex((step) => step.id === id);\n const before = index(changed.get('current'));\n const now = index(this.current);\n this.entering = new Set();\n for (let step = Math.max(before, 0); step < now; step += 1) this.entering.add(step);\n }\n\n private stateOf(step: KtStep, index: number, currentIndex: number): StepState {\n if (step.error) return 'error';\n if (index < currentIndex) return 'complete';\n return index === currentIndex ? 'current' : 'upcoming';\n }\n\n private goTo(step: KtStep): void {\n this.current = step.id;\n emit(this, 'kt-change', { id: step.id });\n }\n\n override render(): TemplateResult {\n const s = strings();\n const currentIndex = this.steps.findIndex((step) => step.id === this.current);\n const said: Record<StepState, string> = {\n complete: s.stepComplete,\n current: s.stepCurrent,\n upcoming: s.stepUpcoming,\n error: s.stepError,\n };\n\n return html`<ol part=\"list\" aria-label=${this.label || nothing}>\n ${this.steps.map((step, index) => {\n const state = this.stateOf(step, index, currentIndex);\n const marker =\n state === 'complete'\n ? html`<kt-icon\n class=${this.entering.has(index) ? 'enter' : ''}\n name=\"check\"\n size=\"14\"\n ></kt-icon>`\n : state === 'error'\n ? html`<kt-icon name=\"circle-alert\" size=\"14\"></kt-icon>`\n : html`<span class=\"number\">${index + 1}</span>`;\n const body = html`<span part=\"marker\" class=\"marker\" aria-hidden=\"true\">${marker}</span>\n <span class=\"text\">\n <span class=\"label\">${step.label}</span>\n ${step.description ? html`<span class=\"description\">${step.description}</span>` : nothing}\n <span class=\"visually-hidden\">${said[state]}</span>\n </span>`;\n const back = this.navigable && index < currentIndex;\n\n return html`<li\n part=\"step\"\n data-state=${state}\n aria-current=${index === currentIndex ? 'step' : nothing}\n >\n ${\n back\n ? html`<button class=\"step\" type=\"button\" @click=${() => this.goTo(step)}>\n ${body}\n </button>`\n : html`<span class=\"step\">${body}</span>`\n }\n ${\n index < this.steps.length - 1\n ? html`<span part=\"connector\" class=\"connector\" aria-hidden=\"true\"\n ><span class=\"fill\"></span\n ></span>`\n : nothing\n }\n </li>`;\n })}\n </ol>`;\n }\n}\n\ndefineElement('kt-steps', KtSteps);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-steps': KtSteps;\n }\n}\n"],"names":["KtSteps","KtElement","css","changed","index","id","step","before","now","currentIndex","emit","s","strings","said","html","nothing","state","marker","body","back","__decorateClass","property","defineElement"],"mappings":"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"}
|
|
@@ -2,9 +2,9 @@ import { css as y, html as a, nothing as n } from "lit";
|
|
|
2
2
|
import { property as c, state as x } from "lit/decorators.js";
|
|
3
3
|
import { classMap as f } from "lit/directives/class-map.js";
|
|
4
4
|
import { styleMap as $ } from "lit/directives/style-map.js";
|
|
5
|
-
import { K as b, d as k } from "../../../chunks/kt-element-
|
|
5
|
+
import { K as b, d as k } from "../../../chunks/kt-element-DvWtPQ1Y.js";
|
|
6
6
|
import { e as g } from "../../../chunks/events-r51msXNf.js";
|
|
7
|
-
import { s as w } from "../../../chunks/index-
|
|
7
|
+
import { s as w } from "../../../chunks/index-1ZFgagWW.js";
|
|
8
8
|
import "../../core/kt-icon/kt-icon.js";
|
|
9
9
|
import "../../core/kt-badge/kt-badge.js";
|
|
10
10
|
var A = Object.defineProperty, d = (p, e, t, o) => {
|
|
@@ -137,7 +137,7 @@ class s extends b {
|
|
|
137
137
|
.chevron {
|
|
138
138
|
flex: none;
|
|
139
139
|
color: var(--text-muted);
|
|
140
|
-
transition: transform var(--duration-fast) var(--
|
|
140
|
+
transition: transform var(--duration-fast) var(--easing-standard);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
.chevron.open {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-sub-menu-navigation.js","sources":["../../../../src/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport { strings } from '#internal/strings';\nimport '../../core/kt-icon/kt-icon.js';\nimport '../../core/kt-badge/kt-badge.js';\n\nexport interface KtNavItem {\n readonly label: string;\n readonly href?: string;\n /** Lucide icon name. Conventionally only the top level carries one. */\n readonly icon?: string;\n /** A count or a short status, right-aligned. */\n readonly badge?: string;\n readonly active?: boolean;\n readonly disabled?: boolean;\n /** Nested items. Any depth: a branch is drawn exactly like the level above. */\n readonly children?: readonly KtNavItem[];\n /** Open on first render. A branch holding the active item opens regardless. */\n readonly open?: boolean;\n}\n\nexport interface KtNavSection {\n readonly title?: string;\n readonly items: readonly KtNavItem[];\n}\n\n/**\n * The sidebar navigation: uppercase overline section titles over lists of\n * links, to any depth.\n *\n * The recursion is the point. Every product grows a third level eventually —\n * Settings holds Members holds Roles — and the usual answer is to hand-roll\n * that one branch beside the component, which is how two navigation styles end\n * up on one screen. Here a branch renders exactly like the level above it,\n * indented by depth, and a branch containing the current page opens itself.\n *\n * @element kt-sub-menu-navigation\n *\n * @csspart nav - The `<nav>`.\n * @csspart section - A section.\n * @csspart title - A section title.\n * @csspart item - A navigation link or branch button, at any depth.\n *\n * @fires kt-navigate - A link was activated. `detail: { item }`. Cancel it to\n * keep the browser from following the href, for client-side routing.\n * @fires kt-toggle - A branch opened or closed. `detail: { item, open }`.\n *\n * @example\n * ```js\n * nav.sections = [\n * {\n * title: 'Workspace',\n * items: [\n * { label: 'Home', href: '#/home', icon: 'house' },\n * { label: 'Inbox', href: '#/inbox', icon: 'inbox', badge: '4' },\n * {\n * label: 'Settings',\n * icon: 'settings',\n * children: [\n * { label: 'General', href: '#/settings/general' },\n * { label: 'Members', href: '#/settings/members',\n * children: [{ label: 'Roles', href: '#/settings/members/roles' }] },\n * ],\n * },\n * ],\n * },\n * ];\n * nav.activeHref = '#/settings/members/roles';\n * ```\n */\nexport class KtSubMenuNavigation extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n }\n\n nav {\n display: flex;\n flex-direction: column;\n gap: var(--gap-sub-menu);\n padding: var(--padding-card);\n background-color: var(--surface-card);\n border-radius: var(--radius-sub-menu);\n }\n\n /* A full-height sidebar owns its own background; the card chrome would\n be a panel inside a panel. */\n :host([flush]) nav {\n gap: 20px;\n padding: 0;\n background: none;\n border-radius: 0;\n }\n\n .title {\n margin: 0;\n padding: 0 var(--nav-inset, 0) 6px;\n color: var(--text-muted);\n font: var(--font-title-overline);\n letter-spacing: var(--letter-spacing-overline);\n text-transform: uppercase;\n }\n\n ul {\n display: flex;\n flex-direction: column;\n gap: var(--gap-element);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n /* width: 100% matters on the branch rows: a <button> sizes to its content\n even as a flex container, so a branch's hover and active fill stopped\n at the end of its label while a link's ran the full row. */\n .item {\n position: relative;\n display: flex;\n box-sizing: border-box;\n align-items: center;\n width: 100%;\n gap: 10px;\n padding: var(--padding-sub-menu-item);\n padding-left: calc(var(--nav-pad-left, 16px) + var(--depth, 0) * 20px);\n color: var(--text-muted);\n font: var(--font-normal-regular);\n text-align: left;\n text-decoration: none;\n background: none;\n border: none;\n border-radius: var(--radius-input);\n cursor: pointer;\n }\n\n .item:hover {\n color: var(--text-body);\n background-color: var(--surface-hover);\n text-decoration: none;\n }\n\n .item:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: -2px;\n }\n\n .item[aria-disabled='true'] {\n color: var(--text-disabled);\n pointer-events: none;\n }\n\n .active {\n color: var(--color-primary-text);\n background-color: var(--color-primary-soft);\n }\n\n .active:hover {\n color: var(--color-primary-text);\n background-color: var(--color-primary-soft);\n }\n\n /* The accent bar marks the current page without relying on the tint\n alone, which is the part that survives a forced-colors mode. */\n .active::before {\n position: absolute;\n top: 50%;\n left: 0;\n width: 3px;\n height: 18px;\n background: var(--color-primary-base);\n border-radius: 0 var(--radius-full) var(--radius-full) 0;\n transform: translateY(-50%);\n content: '';\n }\n\n /* A branch is highlighted, not marked current: the page is below it. */\n .within {\n color: var(--text-body);\n }\n\n .label {\n flex: 1;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .chevron {\n flex: none;\n color: var(--text-muted);\n transition: transform var(--duration-fast) var(--ease-standard);\n }\n\n .chevron.open {\n transform: rotate(90deg);\n }\n\n kt-icon {\n flex: none;\n }\n\n /* Collapsed: icons only. Hidden rather than clipped — a label sliced in\n half at 48px reads as a bug, not as a narrow sidebar. */\n :host([collapsed]) .title,\n :host([collapsed]) .label,\n :host([collapsed]) .chevron,\n :host([collapsed]) kt-badge,\n :host([collapsed]) .children {\n display: none;\n }\n\n :host([collapsed]) .item {\n justify-content: center;\n padding-right: 0;\n padding-left: 0;\n }\n `,\n ];\n\n @property({ attribute: false })\n sections: readonly KtNavSection[] = [];\n\n /** The href of the current page. Marks the matching link active. */\n @property({ type: String, attribute: 'active-href' })\n activeHref = '';\n\n @property({ type: String })\n label: string | undefined = undefined;\n\n /** Drops the card background, for a sidebar that owns its own surface. */\n @property({ type: Boolean, reflect: true })\n flush = false;\n\n /** Icons only. Labels, badges and branches are hidden rather than clipped. */\n @property({ type: Boolean, reflect: true })\n collapsed = false;\n\n /** Branch paths the reader has opened or closed, overriding the default. */\n @state()\n private overrides: Record<string, boolean> = {};\n\n private isActive(item: KtNavItem): boolean {\n return item.active === true || (this.activeHref !== '' && item.href === this.activeHref);\n }\n\n /** True when this item, or anything under it, is the current page. */\n private holdsActive(item: KtNavItem): boolean {\n if (this.isActive(item)) return true;\n return (item.children ?? []).some((child) => this.holdsActive(child));\n }\n\n private isOpen(item: KtNavItem, path: string): boolean {\n // A branch holding the current page opens regardless of what was clicked:\n // navigating to a page that is not visible is worse than losing a fold.\n if (this.holdsActive(item)) return true;\n return this.overrides[path] ?? item.open === true;\n }\n\n private onSelect(event: MouseEvent, item: KtNavItem): void {\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.button !== 0) return;\n\n const proceed = emit(this, 'kt-navigate', { item });\n if (proceed.defaultPrevented) event.preventDefault();\n }\n\n private onToggle(item: KtNavItem, path: string): void {\n const open = !this.isOpen(item, path);\n this.overrides = { ...this.overrides, [path]: open };\n emit(this, 'kt-toggle', { item, open });\n }\n\n /** Opens every branch down to `activeHref`. Called on the section list. */\n private renderItems(items: readonly KtNavItem[], depth: number, prefix: string): TemplateResult {\n return html`<ul>\n ${items.map((item, index) => this.renderItem(item, depth, `${prefix}.${index}`))}\n </ul>`;\n }\n\n private renderItem(item: KtNavItem, depth: number, path: string): TemplateResult {\n const branch = (item.children ?? []).length > 0;\n const active = this.isActive(item);\n const open = branch && this.isOpen(item, path);\n const classes = classMap({\n item: true,\n active,\n within: branch && !active && this.holdsActive(item),\n });\n const inset = styleMap({ '--depth': String(depth) });\n\n const body = html`\n ${item.icon ? html`<kt-icon name=${item.icon} size=\"16\"></kt-icon>` : nothing}\n <span class=\"label\">${item.label}</span>\n ${item.badge ? html`<kt-badge variant=\"count\">${item.badge}</kt-badge>` : nothing}\n ${\n branch\n ? html`<kt-icon\n class=${classMap({ chevron: true, open })}\n name=\"chevron-right\"\n size=\"14\"\n ></kt-icon>`\n : nothing\n }\n `;\n\n return html`<li>\n ${\n branch\n ? html`<button\n part=\"item\"\n type=\"button\"\n class=${classes}\n style=${inset}\n aria-expanded=${open ? 'true' : 'false'}\n aria-disabled=${item.disabled ? 'true' : nothing}\n @click=${() => this.onToggle(item, path)}\n >\n ${body}\n </button>`\n : html`<a\n part=\"item\"\n class=${classes}\n style=${inset}\n href=${item.href ?? '#'}\n aria-current=${active ? 'page' : nothing}\n aria-disabled=${item.disabled ? 'true' : nothing}\n @click=${(event: MouseEvent) => this.onSelect(event, item)}\n >\n ${body}\n </a>`\n }\n ${\n branch && open\n ? html`<div class=\"children\">${this.renderItems(item.children!, depth + 1, path)}</div>`\n : nothing\n }\n </li>`;\n }\n\n override render(): TemplateResult {\n return html`<nav part=\"nav\" aria-label=${this.label ?? strings().secondaryNavigation}>\n ${this.sections.map(\n (section, index) =>\n html`<div part=\"section\">\n ${section.title ? html`<h6 part=\"title\" class=\"title\">${section.title}</h6>` : nothing}\n ${this.renderItems(section.items, 0, String(index))}\n </div>`,\n )}\n </nav>`;\n }\n}\n\ndefineElement('kt-sub-menu-navigation', KtSubMenuNavigation);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-sub-menu-navigation': KtSubMenuNavigation;\n }\n}\n"],"names":["KtSubMenuNavigation","KtElement","css","item","child","path","event","emit","open","items","depth","prefix","html","index","branch","active","classes","classMap","inset","styleMap","body","nothing","strings","section","__decorateClass","property","state","defineElement"],"mappings":";;;;;;;;;;;;;;AA0EO,MAAMA,UAA4BC,EAAU;AAAA,EAA5C,cAAA;AAAA,UAAA,GAAA,SAAA,GAuJL,KAAA,WAAoC,CAAA,GAIpC,KAAA,aAAa,IAGb,KAAA,QAA4B,QAI5B,KAAA,QAAQ,IAIR,KAAA,YAAY,IAIZ,KAAQ,YAAqC,CAAA;AAAA,EAAC;AAAA,EAzK9C,OAAA;AAAA,SAAgB,SAAS;AAAA,MACvBA,EAAU;AAAA,MACVC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA;AAAA,EAiJF;AAAA,EAwBQ,SAASC,GAA0B;AACzC,WAAOA,EAAK,WAAW,MAAS,KAAK,eAAe,MAAMA,EAAK,SAAS,KAAK;AAAA,EAC/E;AAAA;AAAA,EAGQ,YAAYA,GAA0B;AAC5C,WAAI,KAAK,SAASA,CAAI,IAAU,MACxBA,EAAK,YAAY,IAAI,KAAK,CAACC,MAAU,KAAK,YAAYA,CAAK,CAAC;AAAA,EACtE;AAAA,EAEQ,OAAOD,GAAiBE,GAAuB;AAGrD,WAAI,KAAK,YAAYF,CAAI,IAAU,KAC5B,KAAK,UAAUE,CAAI,KAAKF,EAAK,SAAS;AAAA,EAC/C;AAAA,EAEQ,SAASG,GAAmBH,GAAuB;AACzD,QAAIG,EAAM,WAAWA,EAAM,WAAWA,EAAM,YAAYA,EAAM,WAAW,EAAG;AAG5E,IADgBC,EAAK,MAAM,eAAe,EAAE,MAAAJ,GAAM,EACtC,oBAAkBG,EAAM,eAAA;AAAA,EACtC;AAAA,EAEQ,SAASH,GAAiBE,GAAoB;AACpD,UAAMG,IAAO,CAAC,KAAK,OAAOL,GAAME,CAAI;AACpC,SAAK,YAAY,EAAE,GAAG,KAAK,WAAW,CAACA,CAAI,GAAGG,EAAA,GAC9CD,EAAK,MAAM,aAAa,EAAE,MAAAJ,GAAM,MAAAK,GAAM;AAAA,EACxC;AAAA;AAAA,EAGQ,YAAYC,GAA6BC,GAAeC,GAAgC;AAC9F,WAAOC;AAAA,QACHH,EAAM,IAAI,CAACN,GAAMU,MAAU,KAAK,WAAWV,GAAMO,GAAO,GAAGC,CAAM,IAAIE,CAAK,EAAE,CAAC,CAAC;AAAA;AAAA,EAEpF;AAAA,EAEQ,WAAWV,GAAiBO,GAAeL,GAA8B;AAC/E,UAAMS,KAAUX,EAAK,YAAY,CAAA,GAAI,SAAS,GACxCY,IAAS,KAAK,SAASZ,CAAI,GAC3BK,IAAOM,KAAU,KAAK,OAAOX,GAAME,CAAI,GACvCW,IAAUC,EAAS;AAAA,MACvB,MAAM;AAAA,MACN,QAAAF;AAAA,MACA,QAAQD,KAAU,CAACC,KAAU,KAAK,YAAYZ,CAAI;AAAA,IAAA,CACnD,GACKe,IAAQC,EAAS,EAAE,WAAW,OAAOT,CAAK,GAAG,GAE7CU,IAAOR;AAAA,QACTT,EAAK,OAAOS,kBAAqBT,EAAK,IAAI,0BAA0BkB,CAAO;AAAA,4BACvDlB,EAAK,KAAK;AAAA,QAC9BA,EAAK,QAAQS,8BAAiCT,EAAK,KAAK,gBAAgBkB,CAAO;AAAA,QAE/EP,IACIF;AAAA,sBACUK,EAAS,EAAE,SAAS,IAAM,MAAAT,EAAA,CAAM,CAAC;AAAA;AAAA;AAAA,2BAI3Ca,CACN;AAAA;AAGF,WAAOT;AAAA,QAEHE,IACIF;AAAA;AAAA;AAAA,sBAGUI,CAAO;AAAA,sBACPE,CAAK;AAAA,8BACGV,IAAO,SAAS,OAAO;AAAA,8BACvBL,EAAK,WAAW,SAASkB,CAAO;AAAA,uBACvC,MAAM,KAAK,SAASlB,GAAME,CAAI,CAAC;AAAA;AAAA,gBAEtCe,CAAI;AAAA,yBAERR;AAAA;AAAA,sBAEUI,CAAO;AAAA,sBACPE,CAAK;AAAA,qBACNf,EAAK,QAAQ,GAAG;AAAA,6BACRY,IAAS,SAASM,CAAO;AAAA,8BACxBlB,EAAK,WAAW,SAASkB,CAAO;AAAA,uBACvC,CAACf,MAAsB,KAAK,SAASA,GAAOH,CAAI,CAAC;AAAA;AAAA,gBAExDiB,CAAI;AAAA,iBAEd;AAAA,QAEEN,KAAUN,IACNI,0BAA6B,KAAK,YAAYT,EAAK,UAAWO,IAAQ,GAAGL,CAAI,CAAC,WAC9EgB,CACN;AAAA;AAAA,EAEJ;AAAA,EAES,SAAyB;AAChC,WAAOT,+BAAkC,KAAK,SAASU,EAAA,EAAU,mBAAmB;AAAA,QAChF,KAAK,SAAS;AAAA,MACd,CAACC,GAASV,MACRD;AAAA,cACIW,EAAQ,QAAQX,mCAAsCW,EAAQ,KAAK,UAAUF,CAAO;AAAA,cACpF,KAAK,YAAYE,EAAQ,OAAO,GAAG,OAAOV,CAAK,CAAC,CAAC;AAAA;AAAA,IAAA,CAExD;AAAA;AAAA,EAEL;AACF;AAjIEW,EAAA;AAAA,EADCC,EAAS,EAAE,WAAW,GAAA,CAAO;AAAA,GAtJnBzB,EAuJX,WAAA,UAAA;AAIAwB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,WAAW,eAAe;AAAA,GA1JzCzB,EA2JX,WAAA,YAAA;AAGAwB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA7JfzB,EA8JX,WAAA,OAAA;AAIAwB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAjK/BzB,EAkKX,WAAA,OAAA;AAIAwB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GArK/BzB,EAsKX,WAAA,WAAA;AAIQwB,EAAA;AAAA,EADPE,EAAA;AAAM,GAzKI1B,EA0KH,WAAA,WAAA;AAgHV2B,EAAc,0BAA0B3B,CAAmB;"}
|
|
1
|
+
{"version":3,"file":"kt-sub-menu-navigation.js","sources":["../../../../src/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport { strings } from '#internal/strings';\nimport '../../core/kt-icon/kt-icon.js';\nimport '../../core/kt-badge/kt-badge.js';\n\nexport interface KtNavItem {\n readonly label: string;\n readonly href?: string;\n /** Lucide icon name. Conventionally only the top level carries one. */\n readonly icon?: string;\n /** A count or a short status, right-aligned. */\n readonly badge?: string;\n readonly active?: boolean;\n readonly disabled?: boolean;\n /** Nested items. Any depth: a branch is drawn exactly like the level above. */\n readonly children?: readonly KtNavItem[];\n /** Open on first render. A branch holding the active item opens regardless. */\n readonly open?: boolean;\n}\n\nexport interface KtNavSection {\n readonly title?: string;\n readonly items: readonly KtNavItem[];\n}\n\n/**\n * The sidebar navigation: uppercase overline section titles over lists of\n * links, to any depth.\n *\n * The recursion is the point. Every product grows a third level eventually —\n * Settings holds Members holds Roles — and the usual answer is to hand-roll\n * that one branch beside the component, which is how two navigation styles end\n * up on one screen. Here a branch renders exactly like the level above it,\n * indented by depth, and a branch containing the current page opens itself.\n *\n * @element kt-sub-menu-navigation\n *\n * @csspart nav - The `<nav>`.\n * @csspart section - A section.\n * @csspart title - A section title.\n * @csspart item - A navigation link or branch button, at any depth.\n *\n * @fires kt-navigate - A link was activated. `detail: { item }`. Cancel it to\n * keep the browser from following the href, for client-side routing.\n * @fires kt-toggle - A branch opened or closed. `detail: { item, open }`.\n *\n * @example\n * ```js\n * nav.sections = [\n * {\n * title: 'Workspace',\n * items: [\n * { label: 'Home', href: '#/home', icon: 'house' },\n * { label: 'Inbox', href: '#/inbox', icon: 'inbox', badge: '4' },\n * {\n * label: 'Settings',\n * icon: 'settings',\n * children: [\n * { label: 'General', href: '#/settings/general' },\n * { label: 'Members', href: '#/settings/members',\n * children: [{ label: 'Roles', href: '#/settings/members/roles' }] },\n * ],\n * },\n * ],\n * },\n * ];\n * nav.activeHref = '#/settings/members/roles';\n * ```\n */\nexport class KtSubMenuNavigation extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n }\n\n nav {\n display: flex;\n flex-direction: column;\n gap: var(--gap-sub-menu);\n padding: var(--padding-card);\n background-color: var(--surface-card);\n border-radius: var(--radius-sub-menu);\n }\n\n /* A full-height sidebar owns its own background; the card chrome would\n be a panel inside a panel. */\n :host([flush]) nav {\n gap: 20px;\n padding: 0;\n background: none;\n border-radius: 0;\n }\n\n .title {\n margin: 0;\n padding: 0 var(--nav-inset, 0) 6px;\n color: var(--text-muted);\n font: var(--font-title-overline);\n letter-spacing: var(--letter-spacing-overline);\n text-transform: uppercase;\n }\n\n ul {\n display: flex;\n flex-direction: column;\n gap: var(--gap-element);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n /* width: 100% matters on the branch rows: a <button> sizes to its content\n even as a flex container, so a branch's hover and active fill stopped\n at the end of its label while a link's ran the full row. */\n .item {\n position: relative;\n display: flex;\n box-sizing: border-box;\n align-items: center;\n width: 100%;\n gap: 10px;\n padding: var(--padding-sub-menu-item);\n padding-left: calc(var(--nav-pad-left, 16px) + var(--depth, 0) * 20px);\n color: var(--text-muted);\n font: var(--font-normal-regular);\n text-align: left;\n text-decoration: none;\n background: none;\n border: none;\n border-radius: var(--radius-input);\n cursor: pointer;\n }\n\n .item:hover {\n color: var(--text-body);\n background-color: var(--surface-hover);\n text-decoration: none;\n }\n\n .item:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: -2px;\n }\n\n .item[aria-disabled='true'] {\n color: var(--text-disabled);\n pointer-events: none;\n }\n\n .active {\n color: var(--color-primary-text);\n background-color: var(--color-primary-soft);\n }\n\n .active:hover {\n color: var(--color-primary-text);\n background-color: var(--color-primary-soft);\n }\n\n /* The accent bar marks the current page without relying on the tint\n alone, which is the part that survives a forced-colors mode. */\n .active::before {\n position: absolute;\n top: 50%;\n left: 0;\n width: 3px;\n height: 18px;\n background: var(--color-primary-base);\n border-radius: 0 var(--radius-full) var(--radius-full) 0;\n transform: translateY(-50%);\n content: '';\n }\n\n /* A branch is highlighted, not marked current: the page is below it. */\n .within {\n color: var(--text-body);\n }\n\n .label {\n flex: 1;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .chevron {\n flex: none;\n color: var(--text-muted);\n transition: transform var(--duration-fast) var(--easing-standard);\n }\n\n .chevron.open {\n transform: rotate(90deg);\n }\n\n kt-icon {\n flex: none;\n }\n\n /* Collapsed: icons only. Hidden rather than clipped — a label sliced in\n half at 48px reads as a bug, not as a narrow sidebar. */\n :host([collapsed]) .title,\n :host([collapsed]) .label,\n :host([collapsed]) .chevron,\n :host([collapsed]) kt-badge,\n :host([collapsed]) .children {\n display: none;\n }\n\n :host([collapsed]) .item {\n justify-content: center;\n padding-right: 0;\n padding-left: 0;\n }\n `,\n ];\n\n @property({ attribute: false })\n sections: readonly KtNavSection[] = [];\n\n /** The href of the current page. Marks the matching link active. */\n @property({ type: String, attribute: 'active-href' })\n activeHref = '';\n\n @property({ type: String })\n label: string | undefined = undefined;\n\n /** Drops the card background, for a sidebar that owns its own surface. */\n @property({ type: Boolean, reflect: true })\n flush = false;\n\n /** Icons only. Labels, badges and branches are hidden rather than clipped. */\n @property({ type: Boolean, reflect: true })\n collapsed = false;\n\n /** Branch paths the reader has opened or closed, overriding the default. */\n @state()\n private overrides: Record<string, boolean> = {};\n\n private isActive(item: KtNavItem): boolean {\n return item.active === true || (this.activeHref !== '' && item.href === this.activeHref);\n }\n\n /** True when this item, or anything under it, is the current page. */\n private holdsActive(item: KtNavItem): boolean {\n if (this.isActive(item)) return true;\n return (item.children ?? []).some((child) => this.holdsActive(child));\n }\n\n private isOpen(item: KtNavItem, path: string): boolean {\n // A branch holding the current page opens regardless of what was clicked:\n // navigating to a page that is not visible is worse than losing a fold.\n if (this.holdsActive(item)) return true;\n return this.overrides[path] ?? item.open === true;\n }\n\n private onSelect(event: MouseEvent, item: KtNavItem): void {\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.button !== 0) return;\n\n const proceed = emit(this, 'kt-navigate', { item });\n if (proceed.defaultPrevented) event.preventDefault();\n }\n\n private onToggle(item: KtNavItem, path: string): void {\n const open = !this.isOpen(item, path);\n this.overrides = { ...this.overrides, [path]: open };\n emit(this, 'kt-toggle', { item, open });\n }\n\n /** Opens every branch down to `activeHref`. Called on the section list. */\n private renderItems(items: readonly KtNavItem[], depth: number, prefix: string): TemplateResult {\n return html`<ul>\n ${items.map((item, index) => this.renderItem(item, depth, `${prefix}.${index}`))}\n </ul>`;\n }\n\n private renderItem(item: KtNavItem, depth: number, path: string): TemplateResult {\n const branch = (item.children ?? []).length > 0;\n const active = this.isActive(item);\n const open = branch && this.isOpen(item, path);\n const classes = classMap({\n item: true,\n active,\n within: branch && !active && this.holdsActive(item),\n });\n const inset = styleMap({ '--depth': String(depth) });\n\n const body = html`\n ${item.icon ? html`<kt-icon name=${item.icon} size=\"16\"></kt-icon>` : nothing}\n <span class=\"label\">${item.label}</span>\n ${item.badge ? html`<kt-badge variant=\"count\">${item.badge}</kt-badge>` : nothing}\n ${\n branch\n ? html`<kt-icon\n class=${classMap({ chevron: true, open })}\n name=\"chevron-right\"\n size=\"14\"\n ></kt-icon>`\n : nothing\n }\n `;\n\n return html`<li>\n ${\n branch\n ? html`<button\n part=\"item\"\n type=\"button\"\n class=${classes}\n style=${inset}\n aria-expanded=${open ? 'true' : 'false'}\n aria-disabled=${item.disabled ? 'true' : nothing}\n @click=${() => this.onToggle(item, path)}\n >\n ${body}\n </button>`\n : html`<a\n part=\"item\"\n class=${classes}\n style=${inset}\n href=${item.href ?? '#'}\n aria-current=${active ? 'page' : nothing}\n aria-disabled=${item.disabled ? 'true' : nothing}\n @click=${(event: MouseEvent) => this.onSelect(event, item)}\n >\n ${body}\n </a>`\n }\n ${\n branch && open\n ? html`<div class=\"children\">${this.renderItems(item.children!, depth + 1, path)}</div>`\n : nothing\n }\n </li>`;\n }\n\n override render(): TemplateResult {\n return html`<nav part=\"nav\" aria-label=${this.label ?? strings().secondaryNavigation}>\n ${this.sections.map(\n (section, index) =>\n html`<div part=\"section\">\n ${section.title ? html`<h6 part=\"title\" class=\"title\">${section.title}</h6>` : nothing}\n ${this.renderItems(section.items, 0, String(index))}\n </div>`,\n )}\n </nav>`;\n }\n}\n\ndefineElement('kt-sub-menu-navigation', KtSubMenuNavigation);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-sub-menu-navigation': KtSubMenuNavigation;\n }\n}\n"],"names":["KtSubMenuNavigation","KtElement","css","item","child","path","event","emit","open","items","depth","prefix","html","index","branch","active","classes","classMap","inset","styleMap","body","nothing","strings","section","__decorateClass","property","state","defineElement"],"mappings":"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"}
|
|
@@ -41,6 +41,7 @@ export interface KtTab {
|
|
|
41
41
|
export declare class KtTabs extends KtElement {
|
|
42
42
|
static styles: import("lit").CSSResultGroup[];
|
|
43
43
|
private tabElements;
|
|
44
|
+
constructor();
|
|
44
45
|
/** The tabs to show. A property: this is data. */
|
|
45
46
|
tabs: readonly KtTab[];
|
|
46
47
|
/** The selected tab's value. */
|
|
@@ -1,28 +1,33 @@
|
|
|
1
|
-
import { css as
|
|
2
|
-
import { queryAll as
|
|
3
|
-
import { classMap as
|
|
4
|
-
import { K as
|
|
1
|
+
import { css as h, html as n, nothing as c } from "lit";
|
|
2
|
+
import { queryAll as u, property as l } from "lit/decorators.js";
|
|
3
|
+
import { classMap as v } from "lit/directives/class-map.js";
|
|
4
|
+
import { K as b, d as f } from "../../../chunks/kt-element-DvWtPQ1Y.js";
|
|
5
|
+
import { I as y } from "../../../chunks/indicator-B_Rs8F92.js";
|
|
5
6
|
import { e as m } from "../../../chunks/events-r51msXNf.js";
|
|
6
7
|
import "../../core/kt-icon/kt-icon.js";
|
|
7
8
|
import "../../feedback/kt-skeleton/kt-skeleton.js";
|
|
8
|
-
var x = Object.defineProperty,
|
|
9
|
-
for (var
|
|
10
|
-
(
|
|
11
|
-
return
|
|
9
|
+
var x = Object.defineProperty, s = (d, t, e, a) => {
|
|
10
|
+
for (var r = void 0, i = d.length - 1, p; i >= 0; i--)
|
|
11
|
+
(p = d[i]) && (r = p(t, e, r) || r);
|
|
12
|
+
return r && x(t, e, r), r;
|
|
12
13
|
};
|
|
13
|
-
class o extends
|
|
14
|
+
class o extends b {
|
|
14
15
|
constructor() {
|
|
15
|
-
super(
|
|
16
|
+
super(), this.tabs = [], this.value = null, this.disabled = !1, this.loading = !1, this.label = "", new y(this, {
|
|
17
|
+
container: () => this.renderRoot.querySelector(".tablist"),
|
|
18
|
+
selected: () => this.renderRoot.querySelector(".tab.selected")
|
|
19
|
+
});
|
|
16
20
|
}
|
|
17
21
|
static {
|
|
18
22
|
this.styles = [
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
b.styles,
|
|
24
|
+
h`
|
|
21
25
|
:host {
|
|
22
26
|
display: block;
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
.tablist {
|
|
30
|
+
position: relative;
|
|
26
31
|
display: flex;
|
|
27
32
|
gap: var(--gap-drag-drop);
|
|
28
33
|
border-bottom: var(--border-width) solid var(--border-subtle);
|
|
@@ -63,9 +68,31 @@ class o extends c {
|
|
|
63
68
|
color: var(--text-body);
|
|
64
69
|
}
|
|
65
70
|
|
|
71
|
+
/* Underlined by the indicator below, not by its own border. */
|
|
66
72
|
.tab.selected {
|
|
67
73
|
color: var(--text-body);
|
|
68
|
-
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* One underline that slides from tab to tab, placed by
|
|
77
|
+
IndicatorController before the first paint. */
|
|
78
|
+
.indicator {
|
|
79
|
+
position: absolute;
|
|
80
|
+
top: calc(var(--kt-indicator-y) + var(--kt-indicator-height) - 2px);
|
|
81
|
+
left: 0;
|
|
82
|
+
display: none;
|
|
83
|
+
width: var(--kt-indicator-width);
|
|
84
|
+
height: 2px;
|
|
85
|
+
background: var(--color-primary-base);
|
|
86
|
+
translate: var(--kt-indicator-x) 0;
|
|
87
|
+
pointer-events: none;
|
|
88
|
+
}
|
|
89
|
+
.tablist[data-indicator] .indicator {
|
|
90
|
+
display: block;
|
|
91
|
+
}
|
|
92
|
+
.tablist[data-indicator='ready'] .indicator {
|
|
93
|
+
transition:
|
|
94
|
+
translate var(--duration-normal) var(--easing-standard),
|
|
95
|
+
width var(--duration-normal) var(--easing-standard);
|
|
69
96
|
}
|
|
70
97
|
|
|
71
98
|
.tab:disabled {
|
|
@@ -88,87 +115,88 @@ class o extends c {
|
|
|
88
115
|
];
|
|
89
116
|
}
|
|
90
117
|
get selectedIndex() {
|
|
91
|
-
return this.tabs.findIndex((
|
|
118
|
+
return this.tabs.findIndex((t) => t.value === this.value);
|
|
92
119
|
}
|
|
93
|
-
select(
|
|
94
|
-
|
|
120
|
+
select(t) {
|
|
121
|
+
t.disabled || this.value === t.value || (this.value = t.value, m(this, "kt-change", { value: t.value, tab: t }));
|
|
95
122
|
}
|
|
96
123
|
/** Moves to the next selectable tab in `direction`, wrapping at both ends. */
|
|
97
|
-
step(
|
|
98
|
-
const
|
|
99
|
-
if (
|
|
100
|
-
const
|
|
101
|
-
for (let
|
|
102
|
-
const
|
|
103
|
-
if (!this.tabs[
|
|
124
|
+
step(t) {
|
|
125
|
+
const e = this.tabs.length;
|
|
126
|
+
if (e === 0) return;
|
|
127
|
+
const a = this.selectedIndex < 0 ? t === 1 ? -1 : 0 : this.selectedIndex;
|
|
128
|
+
for (let r = 1; r <= e; r += 1) {
|
|
129
|
+
const i = ((a + t * r) % e + e) % e;
|
|
130
|
+
if (!this.tabs[i]?.disabled) return i;
|
|
104
131
|
}
|
|
105
132
|
}
|
|
106
|
-
onKeyDown(
|
|
107
|
-
let
|
|
108
|
-
if (
|
|
109
|
-
else if (
|
|
110
|
-
else if (
|
|
111
|
-
else if (
|
|
112
|
-
|
|
133
|
+
onKeyDown(t) {
|
|
134
|
+
let e;
|
|
135
|
+
if (t.key === "ArrowRight") e = this.step(1);
|
|
136
|
+
else if (t.key === "ArrowLeft") e = this.step(-1);
|
|
137
|
+
else if (t.key === "Home") e = this.tabs.findIndex((i) => !i.disabled);
|
|
138
|
+
else if (t.key === "End")
|
|
139
|
+
e = this.tabs.length - 1 - [...this.tabs].reverse().findIndex((i) => !i.disabled);
|
|
113
140
|
else return;
|
|
114
|
-
if (
|
|
115
|
-
const
|
|
116
|
-
if (!
|
|
117
|
-
const
|
|
118
|
-
this.select(
|
|
141
|
+
if (t.preventDefault(), e === void 0 || e < 0) return;
|
|
142
|
+
const a = this.tabs[e];
|
|
143
|
+
if (!a) return;
|
|
144
|
+
const r = e;
|
|
145
|
+
this.select(a), this.updateComplete.then(() => this.tabElements[r]?.focus());
|
|
119
146
|
}
|
|
120
147
|
render() {
|
|
121
148
|
if (this.loading)
|
|
122
|
-
return
|
|
123
|
-
${[0, 1, 2].map(() =>
|
|
149
|
+
return n`<div class="loading" aria-hidden="true">
|
|
150
|
+
${[0, 1, 2].map(() => n`<kt-skeleton variant="rect" width="64px" height="22px"></kt-skeleton>`)}
|
|
124
151
|
</div>`;
|
|
125
|
-
const
|
|
126
|
-
return
|
|
152
|
+
const t = this.selectedIndex, e = t >= 0 ? t : this.tabs.findIndex((a) => !a.disabled);
|
|
153
|
+
return n`<div
|
|
127
154
|
part="base"
|
|
128
155
|
class="tablist"
|
|
129
156
|
role="tablist"
|
|
130
|
-
aria-label=${this.label ||
|
|
157
|
+
aria-label=${this.label || c}
|
|
131
158
|
@keydown=${this.onKeyDown}
|
|
132
159
|
>
|
|
133
|
-
${this.tabs.map((
|
|
134
|
-
const
|
|
135
|
-
return
|
|
160
|
+
${this.tabs.map((a, r) => {
|
|
161
|
+
const i = a.value === this.value;
|
|
162
|
+
return n`<button
|
|
136
163
|
part="tab"
|
|
137
164
|
type="button"
|
|
138
165
|
role="tab"
|
|
139
|
-
class=${
|
|
140
|
-
aria-selected=${
|
|
141
|
-
aria-controls=${
|
|
142
|
-
tabindex=${
|
|
143
|
-
?disabled=${this.disabled ||
|
|
144
|
-
@click=${() => this.select(
|
|
166
|
+
class=${v({ tab: !0, selected: i })}
|
|
167
|
+
aria-selected=${i ? "true" : "false"}
|
|
168
|
+
aria-controls=${a.panel ?? c}
|
|
169
|
+
tabindex=${r === e ? 0 : -1}
|
|
170
|
+
?disabled=${this.disabled || a.disabled}
|
|
171
|
+
@click=${() => this.select(a)}
|
|
145
172
|
>
|
|
146
|
-
${
|
|
147
|
-
${
|
|
173
|
+
${a.icon ? n`<kt-icon name=${a.icon} size="16"></kt-icon>` : c}
|
|
174
|
+
${a.label ?? String(a.value)}
|
|
148
175
|
</button>`;
|
|
149
176
|
})}
|
|
177
|
+
<span class="indicator" aria-hidden="true"></span>
|
|
150
178
|
</div>`;
|
|
151
179
|
}
|
|
152
180
|
}
|
|
153
|
-
|
|
154
|
-
|
|
181
|
+
s([
|
|
182
|
+
u(".tab")
|
|
155
183
|
], o.prototype, "tabElements");
|
|
156
|
-
|
|
157
|
-
|
|
184
|
+
s([
|
|
185
|
+
l({ attribute: !1 })
|
|
158
186
|
], o.prototype, "tabs");
|
|
159
|
-
|
|
160
|
-
|
|
187
|
+
s([
|
|
188
|
+
l({ type: String })
|
|
161
189
|
], o.prototype, "value");
|
|
162
|
-
|
|
163
|
-
|
|
190
|
+
s([
|
|
191
|
+
l({ type: Boolean, reflect: !0 })
|
|
164
192
|
], o.prototype, "disabled");
|
|
165
|
-
|
|
166
|
-
|
|
193
|
+
s([
|
|
194
|
+
l({ type: Boolean, reflect: !0 })
|
|
167
195
|
], o.prototype, "loading");
|
|
168
|
-
|
|
169
|
-
|
|
196
|
+
s([
|
|
197
|
+
l({ type: String })
|
|
170
198
|
], o.prototype, "label");
|
|
171
|
-
|
|
199
|
+
f("kt-tabs", o);
|
|
172
200
|
export {
|
|
173
201
|
o as KtTabs
|
|
174
202
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-tabs.js","sources":["../../../../src/components/navigation/kt-tabs/kt-tabs.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property, queryAll } 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 '../../core/kt-icon/kt-icon.js';\nimport '../../feedback/kt-skeleton/kt-skeleton.js';\n\nexport interface KtTab {\n readonly value: string | number;\n readonly label?: string;\n /** Lucide icon name, kebab-case. */\n readonly icon?: string;\n readonly disabled?: boolean;\n /** id of the element this tab controls, for `aria-controls`. */\n readonly panel?: string;\n}\n\n/**\n * An underlined tab bar.\n *\n * Against `<kt-segmented-control>`: a segmented control picks a *value* — a\n * date range, a unit — and sits inside a form or a toolbar. Tabs switch which\n * *region of the page* you are looking at, and read as part of the page\n * structure rather than as a control on it. The shapes say so: an inset track\n * with a raised pill, versus a rule with one segment underlined.\n *\n * Like the segmented control, this only manages selection. Swapping the panel\n * is the consumer's business.\n *\n * @element kt-tabs\n *\n * @csspart base - The tablist.\n * @csspart tab - One tab.\n *\n * @fires kt-change - A tab was selected. `detail: { value, tab }`.\n *\n * @example\n * ```js\n * tabs.tabs = [\n * { value: 'usage', label: 'Usage' },\n * { value: 'api', label: 'API', icon: 'code' },\n * ];\n * ```\n */\nexport class KtTabs extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n }\n\n .tablist {\n display: flex;\n gap: var(--gap-drag-drop);\n border-bottom: var(--border-width) solid var(--border-subtle);\n overflow-x: auto;\n scrollbar-width: none;\n }\n\n .tablist::-webkit-scrollbar {\n display: none;\n }\n\n :host([disabled]) .tablist {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .tab {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n /* The -1px pulls the active underline over the container's rule so the\n two read as one line rather than two stacked ones. */\n margin-bottom: calc(var(--border-width) * -1);\n padding: 10px 2px;\n color: var(--text-muted);\n font: var(--font-normal-medium);\n white-space: nowrap;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n transition:\n color var(--duration-instant),\n border-color var(--duration-instant);\n }\n\n .tab:hover:not(:disabled) {\n color: var(--text-body);\n }\n\n .tab.selected {\n color: var(--text-body);\n border-bottom-color: var(--color-primary-base);\n }\n\n .tab:disabled {\n color: var(--text-disabled);\n cursor: not-allowed;\n }\n\n .tab:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n border-radius: calc(4px * var(--radius-scale, 1));\n }\n\n .loading {\n display: flex;\n gap: var(--gap-drag-drop);\n padding: 10px 0;\n }\n `,\n ];\n\n @queryAll('.tab')\n private tabElements!: NodeListOf<HTMLButtonElement>;\n\n /** The tabs to show. A property: this is data. */\n @property({ attribute: false })\n tabs: readonly KtTab[] = [];\n\n /** The selected tab's value. */\n @property({ type: String })\n value: string | number | null = null;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Renders placeholder tabs instead of the real ones. */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /** Accessible name for the tablist. */\n @property({ type: String })\n label = '';\n\n private get selectedIndex(): number {\n return this.tabs.findIndex((tab) => tab.value === this.value);\n }\n\n private select(tab: KtTab): void {\n if (tab.disabled || this.value === tab.value) return;\n this.value = tab.value;\n emit(this, 'kt-change', { value: tab.value, tab });\n }\n\n /** Moves to the next selectable tab in `direction`, wrapping at both ends. */\n private step(direction: 1 | -1): number | undefined {\n const count = this.tabs.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.tabs[index]?.disabled) return index;\n }\n return undefined;\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n let target: number | undefined;\n\n if (event.key === 'ArrowRight') target = this.step(1);\n else if (event.key === 'ArrowLeft') target = this.step(-1);\n else if (event.key === 'Home') target = this.tabs.findIndex((tab) => !tab.disabled);\n else if (event.key === 'End')\n target = this.tabs.length - 1 - [...this.tabs].reverse().findIndex((tab) => !tab.disabled);\n else return;\n\n event.preventDefault();\n if (target === undefined || target < 0) return;\n\n const tab = this.tabs[target];\n if (!tab) return;\n\n const index = target;\n this.select(tab);\n void this.updateComplete.then(() => this.tabElements[index]?.focus());\n }\n\n override render(): TemplateResult {\n if (this.loading) {\n return html`<div class=\"loading\" aria-hidden=\"true\">\n ${[0, 1, 2].map(() => html`<kt-skeleton variant=\"rect\" width=\"64px\" height=\"22px\"></kt-skeleton>`)}\n </div>`;\n }\n\n const selectedIndex = this.selectedIndex;\n // One tab stop for the whole bar, as a tablist should have.\n const tabStop = selectedIndex >= 0 ? selectedIndex : this.tabs.findIndex((t) => !t.disabled);\n\n return html`<div\n part=\"base\"\n class=\"tablist\"\n role=\"tablist\"\n aria-label=${this.label || nothing}\n @keydown=${this.onKeyDown}\n >\n ${this.tabs.map((tab, index) => {\n const selected = tab.value === this.value;\n\n return html`<button\n part=\"tab\"\n type=\"button\"\n role=\"tab\"\n class=${classMap({ tab: true, selected })}\n aria-selected=${selected ? 'true' : 'false'}\n aria-controls=${tab.panel ?? nothing}\n tabindex=${index === tabStop ? 0 : -1}\n ?disabled=${this.disabled || tab.disabled}\n @click=${() => this.select(tab)}\n >\n ${tab.icon ? html`<kt-icon name=${tab.icon} size=\"16\"></kt-icon>` : nothing}\n ${tab.label ?? String(tab.value)}\n </button>`;\n })}\n </div>`;\n }\n}\n\ndefineElement('kt-tabs', KtTabs);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-tabs': KtTabs;\n }\n}\n"],"names":["KtTabs","KtElement","css","tab","emit","direction","count","from","offset","index","event","target","html","selectedIndex","tabStop","t","nothing","selected","classMap","__decorateClass","queryAll","property","defineElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"kt-tabs.js","sources":["../../../../src/components/navigation/kt-tabs/kt-tabs.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property, queryAll } 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 '../../core/kt-icon/kt-icon.js';\nimport '../../feedback/kt-skeleton/kt-skeleton.js';\n\nexport interface KtTab {\n readonly value: string | number;\n readonly label?: string;\n /** Lucide icon name, kebab-case. */\n readonly icon?: string;\n readonly disabled?: boolean;\n /** id of the element this tab controls, for `aria-controls`. */\n readonly panel?: string;\n}\n\n/**\n * An underlined tab bar.\n *\n * Against `<kt-segmented-control>`: a segmented control picks a *value* — a\n * date range, a unit — and sits inside a form or a toolbar. Tabs switch which\n * *region of the page* you are looking at, and read as part of the page\n * structure rather than as a control on it. The shapes say so: an inset track\n * with a raised pill, versus a rule with one segment underlined.\n *\n * Like the segmented control, this only manages selection. Swapping the panel\n * is the consumer's business.\n *\n * @element kt-tabs\n *\n * @csspart base - The tablist.\n * @csspart tab - One tab.\n *\n * @fires kt-change - A tab was selected. `detail: { value, tab }`.\n *\n * @example\n * ```js\n * tabs.tabs = [\n * { value: 'usage', label: 'Usage' },\n * { value: 'api', label: 'API', icon: 'code' },\n * ];\n * ```\n */\nexport class KtTabs extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n }\n\n .tablist {\n position: relative;\n display: flex;\n gap: var(--gap-drag-drop);\n border-bottom: var(--border-width) solid var(--border-subtle);\n overflow-x: auto;\n scrollbar-width: none;\n }\n\n .tablist::-webkit-scrollbar {\n display: none;\n }\n\n :host([disabled]) .tablist {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .tab {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n /* The -1px pulls the active underline over the container's rule so the\n two read as one line rather than two stacked ones. */\n margin-bottom: calc(var(--border-width) * -1);\n padding: 10px 2px;\n color: var(--text-muted);\n font: var(--font-normal-medium);\n white-space: nowrap;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n transition:\n color var(--duration-instant),\n border-color var(--duration-instant);\n }\n\n .tab:hover:not(:disabled) {\n color: var(--text-body);\n }\n\n /* Underlined by the indicator below, not by its own border. */\n .tab.selected {\n color: var(--text-body);\n }\n\n /* One underline that slides from tab to tab, placed by\n IndicatorController before the first paint. */\n .indicator {\n position: absolute;\n top: calc(var(--kt-indicator-y) + var(--kt-indicator-height) - 2px);\n left: 0;\n display: none;\n width: var(--kt-indicator-width);\n height: 2px;\n background: var(--color-primary-base);\n translate: var(--kt-indicator-x) 0;\n pointer-events: none;\n }\n .tablist[data-indicator] .indicator {\n display: block;\n }\n .tablist[data-indicator='ready'] .indicator {\n transition:\n translate var(--duration-normal) var(--easing-standard),\n width var(--duration-normal) var(--easing-standard);\n }\n\n .tab:disabled {\n color: var(--text-disabled);\n cursor: not-allowed;\n }\n\n .tab:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n border-radius: calc(4px * var(--radius-scale, 1));\n }\n\n .loading {\n display: flex;\n gap: var(--gap-drag-drop);\n padding: 10px 0;\n }\n `,\n ];\n\n @queryAll('.tab')\n private tabElements!: NodeListOf<HTMLButtonElement>;\n\n constructor() {\n super();\n new IndicatorController(this, {\n container: () => this.renderRoot.querySelector<HTMLElement>('.tablist'),\n selected: () => this.renderRoot.querySelector<HTMLElement>('.tab.selected'),\n });\n }\n\n /** The tabs to show. A property: this is data. */\n @property({ attribute: false })\n tabs: readonly KtTab[] = [];\n\n /** The selected tab's value. */\n @property({ type: String })\n value: string | number | null = null;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Renders placeholder tabs instead of the real ones. */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /** Accessible name for the tablist. */\n @property({ type: String })\n label = '';\n\n private get selectedIndex(): number {\n return this.tabs.findIndex((tab) => tab.value === this.value);\n }\n\n private select(tab: KtTab): void {\n if (tab.disabled || this.value === tab.value) return;\n this.value = tab.value;\n emit(this, 'kt-change', { value: tab.value, tab });\n }\n\n /** Moves to the next selectable tab in `direction`, wrapping at both ends. */\n private step(direction: 1 | -1): number | undefined {\n const count = this.tabs.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.tabs[index]?.disabled) return index;\n }\n return undefined;\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n let target: number | undefined;\n\n if (event.key === 'ArrowRight') target = this.step(1);\n else if (event.key === 'ArrowLeft') target = this.step(-1);\n else if (event.key === 'Home') target = this.tabs.findIndex((tab) => !tab.disabled);\n else if (event.key === 'End')\n target = this.tabs.length - 1 - [...this.tabs].reverse().findIndex((tab) => !tab.disabled);\n else return;\n\n event.preventDefault();\n if (target === undefined || target < 0) return;\n\n const tab = this.tabs[target];\n if (!tab) return;\n\n const index = target;\n this.select(tab);\n void this.updateComplete.then(() => this.tabElements[index]?.focus());\n }\n\n override render(): TemplateResult {\n if (this.loading) {\n return html`<div class=\"loading\" aria-hidden=\"true\">\n ${[0, 1, 2].map(() => html`<kt-skeleton variant=\"rect\" width=\"64px\" height=\"22px\"></kt-skeleton>`)}\n </div>`;\n }\n\n const selectedIndex = this.selectedIndex;\n // One tab stop for the whole bar, as a tablist should have.\n const tabStop = selectedIndex >= 0 ? selectedIndex : this.tabs.findIndex((t) => !t.disabled);\n\n return html`<div\n part=\"base\"\n class=\"tablist\"\n role=\"tablist\"\n aria-label=${this.label || nothing}\n @keydown=${this.onKeyDown}\n >\n ${this.tabs.map((tab, index) => {\n const selected = tab.value === this.value;\n\n return html`<button\n part=\"tab\"\n type=\"button\"\n role=\"tab\"\n class=${classMap({ tab: true, selected })}\n aria-selected=${selected ? 'true' : 'false'}\n aria-controls=${tab.panel ?? nothing}\n tabindex=${index === tabStop ? 0 : -1}\n ?disabled=${this.disabled || tab.disabled}\n @click=${() => this.select(tab)}\n >\n ${tab.icon ? html`<kt-icon name=${tab.icon} size=\"16\"></kt-icon>` : nothing}\n ${tab.label ?? String(tab.value)}\n </button>`;\n })}\n <span class=\"indicator\" aria-hidden=\"true\"></span>\n </div>`;\n }\n}\n\ndefineElement('kt-tabs', KtTabs);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-tabs': KtTabs;\n }\n}\n"],"names":["KtTabs","KtElement","IndicatorController","css","tab","emit","direction","count","from","offset","index","event","target","html","selectedIndex","tabStop","t","nothing","selected","classMap","__decorateClass","queryAll","property","defineElement"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { css as p, html as c, nothing as n } from "lit";
|
|
2
2
|
import { property as o } from "lit/decorators.js";
|
|
3
3
|
import { classMap as b } from "lit/directives/class-map.js";
|
|
4
|
-
import { K as u, d as g } from "../../../chunks/kt-element-
|
|
4
|
+
import { K as u, d as g } from "../../../chunks/kt-element-DvWtPQ1Y.js";
|
|
5
5
|
import { e as v } from "../../../chunks/events-r51msXNf.js";
|
|
6
6
|
import "../../core/kt-icon/kt-icon.js";
|
|
7
7
|
var m = Object.defineProperty, r = (l, e, i, s) => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { css as c, html as h } from "lit";
|
|
2
2
|
import { queryAssignedElements as g, property as l } from "lit/decorators.js";
|
|
3
|
-
import { K as d, d as b } from "../../../chunks/kt-element-
|
|
3
|
+
import { K as d, d as b } from "../../../chunks/kt-element-DvWtPQ1Y.js";
|
|
4
4
|
import { e as p } from "../../../chunks/events-r51msXNf.js";
|
|
5
|
-
import { s as v } from "../../../chunks/index-
|
|
5
|
+
import { s as v } from "../../../chunks/index-1ZFgagWW.js";
|
|
6
6
|
import { KtToggleButton as f } from "../kt-toggle-button/kt-toggle-button.js";
|
|
7
7
|
var m = Object.defineProperty, s = (n, t, e, r) => {
|
|
8
8
|
for (var o = void 0, a = n.length - 1, u; a >= 0; a--)
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
|
+
import { KtElement } from '#internal/kt-element';
|
|
3
|
+
import '../../core/kt-avatar/kt-avatar.js';
|
|
4
|
+
import '../../core/kt-icon/kt-icon.js';
|
|
5
|
+
export interface KtUserMenuItem {
|
|
6
|
+
readonly id: string;
|
|
7
|
+
readonly label: string;
|
|
8
|
+
/** A Lucide icon name, before the label. */
|
|
9
|
+
readonly icon?: string;
|
|
10
|
+
/** A rule above it, setting it apart from the items before. */
|
|
11
|
+
readonly separator?: boolean;
|
|
12
|
+
/** Drawn in the danger colour: sign out, delete the account. */
|
|
13
|
+
readonly danger?: boolean;
|
|
14
|
+
readonly disabled?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The account menu at the end of an application's header: the person's
|
|
18
|
+
* avatar, and under it who is signed in and what they can do — their profile,
|
|
19
|
+
* their settings, switching workspace, signing out.
|
|
20
|
+
*
|
|
21
|
+
* A menu button, as the WAI-ARIA pattern describes: Enter, Space or the down
|
|
22
|
+
* arrow open it on the first item, the up arrow on the last; the arrows, Home
|
|
23
|
+
* and End move between items; Escape closes it and gives the focus back; Tab
|
|
24
|
+
* or a click outside close it too. The panel is drawn in the top layer, so no
|
|
25
|
+
* overflow clips it.
|
|
26
|
+
*
|
|
27
|
+
* @element kt-user-menu
|
|
28
|
+
*
|
|
29
|
+
* @slot - Under the items: a workspace switcher, a theme toggle, a plan badge.
|
|
30
|
+
*
|
|
31
|
+
* @csspart trigger - The button.
|
|
32
|
+
* @csspart panel - The menu's panel.
|
|
33
|
+
* @csspart item - One item.
|
|
34
|
+
*
|
|
35
|
+
* @fires kt-select - An item was chosen. `detail: { id, item }`.
|
|
36
|
+
* @fires kt-open - The menu opened.
|
|
37
|
+
* @fires kt-close - The menu closed.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```html
|
|
41
|
+
* <kt-user-menu name="Dana Whitfield" email="dana@northwind.io"></kt-user-menu>
|
|
42
|
+
* <script>
|
|
43
|
+
* menu.items = [
|
|
44
|
+
* { id: 'profile', label: 'Profile', icon: 'user' },
|
|
45
|
+
* { id: 'signout', label: 'Sign out', separator: true, danger: true },
|
|
46
|
+
* ];
|
|
47
|
+
* </script>
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare class KtUserMenu extends KtElement {
|
|
51
|
+
static styles: import("lit").CSSResultGroup[];
|
|
52
|
+
/** The person signed in: names the button, draws the avatar's initials. */
|
|
53
|
+
name: string;
|
|
54
|
+
/** Under the name in the panel. */
|
|
55
|
+
email: string;
|
|
56
|
+
/** A picture for the avatar. */
|
|
57
|
+
avatar: string;
|
|
58
|
+
/** The menu's items. Set as a property: `menu.items = [...]`. */
|
|
59
|
+
items: readonly KtUserMenuItem[];
|
|
60
|
+
/** Shows the name beside the avatar on the button. */
|
|
61
|
+
showName: boolean;
|
|
62
|
+
/** Whether the menu is open. */
|
|
63
|
+
open: boolean;
|
|
64
|
+
private trigger;
|
|
65
|
+
private readonly menuId;
|
|
66
|
+
private readonly floating;
|
|
67
|
+
disconnectedCallback(): void;
|
|
68
|
+
private listen;
|
|
69
|
+
private onDocumentPointerDown;
|
|
70
|
+
private get menuItems();
|
|
71
|
+
/** Opens the menu, focusing its first item, or its last with `from: 'end'`. */
|
|
72
|
+
show(from?: 'start' | 'end'): void;
|
|
73
|
+
/** Closes the menu; the focus goes back to the button unless told otherwise. */
|
|
74
|
+
hide(refocus?: boolean): void;
|
|
75
|
+
updated(changed: PropertyValues): void;
|
|
76
|
+
private choose;
|
|
77
|
+
private onTriggerKeyDown;
|
|
78
|
+
private onMenuKeyDown;
|
|
79
|
+
private renderItem;
|
|
80
|
+
render(): TemplateResult;
|
|
81
|
+
}
|
|
82
|
+
declare global {
|
|
83
|
+
interface HTMLElementTagNameMap {
|
|
84
|
+
'kt-user-menu': KtUserMenu;
|
|
85
|
+
}
|
|
86
|
+
}
|