kanto-ds 1.2.0 → 1.3.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 +21 -3
- package/dist/chunks/index-fzPIgxe2.js +74 -0
- package/dist/chunks/index-fzPIgxe2.js.map +1 -0
- package/dist/chunks/kt-element-mdd5cXZX.js +52 -0
- package/dist/chunks/kt-element-mdd5cXZX.js.map +1 -0
- package/dist/components/core/kt-avatar/kt-avatar.js +8 -7
- package/dist/components/core/kt-avatar/kt-avatar.js.map +1 -1
- package/dist/components/core/kt-badge/kt-badge.js +7 -6
- package/dist/components/core/kt-badge/kt-badge.js.map +1 -1
- package/dist/components/core/kt-button/kt-button.js +1 -1
- package/dist/components/core/kt-card/kt-card.js +1 -1
- package/dist/components/core/kt-code/kt-code.js +31 -30
- package/dist/components/core/kt-code/kt-code.js.map +1 -1
- package/dist/components/core/kt-icon/kt-icon.js +1 -1
- package/dist/components/core/kt-kbd/kt-kbd.js +1 -1
- package/dist/components/core/kt-split-button/kt-split-button.d.ts +2 -2
- package/dist/components/core/kt-split-button/kt-split-button.js +27 -26
- package/dist/components/core/kt-split-button/kt-split-button.js.map +1 -1
- package/dist/components/data/kt-chart/kt-chart.d.ts +2 -2
- package/dist/components/data/kt-chart/kt-chart.js +205 -204
- package/dist/components/data/kt-chart/kt-chart.js.map +1 -1
- package/dist/components/data/kt-meter/kt-meter.js +1 -1
- package/dist/components/data/kt-pagination/kt-pagination.d.ts +1 -1
- package/dist/components/data/kt-pagination/kt-pagination.js +29 -28
- package/dist/components/data/kt-pagination/kt-pagination.js.map +1 -1
- package/dist/components/data/kt-stat/kt-stat.js +1 -1
- package/dist/components/data/kt-table/kt-table.d.ts +2 -2
- package/dist/components/data/kt-table/kt-table.js +30 -29
- package/dist/components/data/kt-table/kt-table.js.map +1 -1
- package/dist/components/data/kt-timeline/kt-timeline.js +1 -1
- package/dist/components/feedback/kt-alert/kt-alert.js +17 -16
- package/dist/components/feedback/kt-alert/kt-alert.js.map +1 -1
- 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 +25 -19
- package/dist/components/feedback/kt-toast/kt-toast.js.map +1 -1
- package/dist/components/feedback/kt-toast-container/kt-toast-container.js +1 -1
- package/dist/components/feedback/kt-tooltip/kt-tooltip.js +1 -1
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.d.ts +2 -2
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +60 -57
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js.map +1 -1
- package/dist/components/forms/kt-form/kt-form.js +1 -1
- package/dist/components/forms/kt-input/kt-input.js +56 -55
- package/dist/components/forms/kt-input/kt-input.js.map +1 -1
- package/dist/components/forms/kt-input-menu/kt-input-menu.d.ts +1 -1
- package/dist/components/forms/kt-input-menu/kt-input-menu.js +57 -56
- package/dist/components/forms/kt-input-menu/kt-input-menu.js.map +1 -1
- package/dist/components/forms/kt-label-input/kt-label-input.js +1 -1
- package/dist/components/forms/kt-select/kt-select.d.ts +2 -2
- package/dist/components/forms/kt-select/kt-select.js +62 -61
- package/dist/components/forms/kt-select/kt-select.js.map +1 -1
- package/dist/components/forms/kt-textarea/kt-textarea.js +9 -8
- package/dist/components/forms/kt-textarea/kt-textarea.js.map +1 -1
- package/dist/components/forms/kt-toggle/kt-toggle.js +1 -1
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.d.ts +1 -1
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +6 -5
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js.map +1 -1
- package/dist/components/navigation/kt-header/kt-header.js +11 -10
- package/dist/components/navigation/kt-header/kt-header.js.map +1 -1
- package/dist/components/navigation/kt-page-header/kt-page-header.js +1 -1
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +44 -43
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js.map +1 -1
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.d.ts +1 -1
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +6 -5
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js.map +1 -1
- package/dist/components/navigation/kt-tabs/kt-tabs.js +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 +1 -1
- package/dist/components/overlays/kt-collapsible/kt-collapsible.js +1 -1
- package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.d.ts +3 -3
- package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +30 -27
- package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js.map +1 -1
- package/dist/components/overlays/kt-dropdown/kt-dropdown.d.ts +1 -1
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js +8 -7
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js.map +1 -1
- package/dist/components/overlays/kt-modal/kt-modal.js +5 -4
- package/dist/components/overlays/kt-modal/kt-modal.js.map +1 -1
- package/dist/components/overlays/kt-side-panel/kt-side-panel.d.ts +1 -1
- package/dist/components/overlays/kt-side-panel/kt-side-panel.js +24 -23
- package/dist/components/overlays/kt-side-panel/kt-side-panel.js.map +1 -1
- package/dist/custom-elements.json +76 -76
- package/dist/index.d.ts +1 -0
- package/dist/index.js +24 -19
- package/dist/index.js.map +1 -1
- package/dist/internal/kt-element.d.ts +6 -1
- package/dist/internal/strings.d.ts +93 -0
- package/dist/strings/index.d.ts +11 -0
- package/dist/strings/index.js +8 -0
- package/dist/strings/index.js.map +1 -0
- package/dist/tokens/base.css +53 -0
- package/dist/web-types.json +39 -39
- package/package.json +11 -3
- package/dist/chunks/kt-element-B_jjQDhg.js +0 -38
- package/dist/chunks/kt-element-B_jjQDhg.js.map +0 -1
|
@@ -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 } 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 '../../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 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 /** 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')) {\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 ? 'Select an option.' : '');\n }\n }\n\n formResetCallback(): void {\n this.value = this.defaultValue;\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.disabled || 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.disabled ? '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.disabled || 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","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 } 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 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 /** 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 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.disabled || 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.disabled ? '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.disabled || 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","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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"}
|
|
@@ -69,7 +69,7 @@ export declare class KtSubMenuNavigation extends KtElement {
|
|
|
69
69
|
sections: readonly KtNavSection[];
|
|
70
70
|
/** The href of the current page. Marks the matching link active. */
|
|
71
71
|
activeHref: string;
|
|
72
|
-
label: string;
|
|
72
|
+
label: string | undefined;
|
|
73
73
|
/** Drops the card background, for a sidebar that owns its own surface. */
|
|
74
74
|
flush: boolean;
|
|
75
75
|
/** Icons only. Labels, badges and branches are hidden rather than clipped. */
|
|
@@ -2,18 +2,19 @@ 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-mdd5cXZX.js";
|
|
6
6
|
import { e as g } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
7
|
+
import { s as w } from "../../../chunks/index-fzPIgxe2.js";
|
|
7
8
|
import "../../core/kt-icon/kt-icon.js";
|
|
8
9
|
import "../../core/kt-badge/kt-badge.js";
|
|
9
|
-
var
|
|
10
|
+
var A = Object.defineProperty, d = (p, e, t, o) => {
|
|
10
11
|
for (var r = void 0, i = p.length - 1, l; i >= 0; i--)
|
|
11
12
|
(l = p[i]) && (r = l(e, t, r) || r);
|
|
12
|
-
return r &&
|
|
13
|
+
return r && A(e, t, r), r;
|
|
13
14
|
};
|
|
14
15
|
class s extends b {
|
|
15
16
|
constructor() {
|
|
16
|
-
super(...arguments), this.sections = [], this.activeHref = "", this.label =
|
|
17
|
+
super(...arguments), this.sections = [], this.activeHref = "", this.label = void 0, this.flush = !1, this.collapsed = !1, this.overrides = {};
|
|
17
18
|
}
|
|
18
19
|
static {
|
|
19
20
|
this.styles = [
|
|
@@ -230,7 +231,7 @@ class s extends b {
|
|
|
230
231
|
</li>`;
|
|
231
232
|
}
|
|
232
233
|
render() {
|
|
233
|
-
return a`<nav part="nav" aria-label=${this.label}>
|
|
234
|
+
return a`<nav part="nav" aria-label=${this.label ?? w().secondaryNavigation}>
|
|
234
235
|
${this.sections.map(
|
|
235
236
|
(e, t) => a`<div part="section">
|
|
236
237
|
${e.title ? a`<h6 part="title" class="title">${e.title}</h6>` : n}
|
|
@@ -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 '../../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 = 'Secondary navigation';\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}>\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","section","__decorateClass","property","state","defineElement"],"mappings":"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"}
|
|
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":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { css as u, html as l, nothing as p } from "lit";
|
|
2
2
|
import { queryAll as h, property as n } from "lit/decorators.js";
|
|
3
3
|
import { classMap as f } from "lit/directives/class-map.js";
|
|
4
|
-
import { K as c, d as v } from "../../../chunks/kt-element-
|
|
4
|
+
import { K as c, d as v } from "../../../chunks/kt-element-mdd5cXZX.js";
|
|
5
5
|
import { e as m } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
6
6
|
import "../../core/kt-icon/kt-icon.js";
|
|
7
7
|
import "../../feedback/kt-skeleton/kt-skeleton.js";
|
|
@@ -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-mdd5cXZX.js";
|
|
5
5
|
import { e as v } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
6
6
|
import "../../core/kt-icon/kt-icon.js";
|
|
7
7
|
var m = Object.defineProperty, r = (l, e, i, s) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
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-mdd5cXZX.js";
|
|
4
4
|
import { e as p } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
5
5
|
import { KtToggleButton as v } from "../kt-toggle-button/kt-toggle-button.js";
|
|
6
6
|
var f = Object.defineProperty, s = (n, t, e, r) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { css as d, nothing as m, html as c } from "lit";
|
|
2
2
|
import { property as n } from "lit/decorators.js";
|
|
3
|
-
import { K as p, d as u } from "../../../chunks/kt-element-
|
|
3
|
+
import { K as p, d as u } from "../../../chunks/kt-element-mdd5cXZX.js";
|
|
4
4
|
import { e as f } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
5
5
|
import "../../core/kt-icon/kt-icon.js";
|
|
6
6
|
var h = Object.defineProperty, i = (a, o, t, y) => {
|
|
@@ -35,10 +35,10 @@ export declare class KtConfirmDialog extends KtElement {
|
|
|
35
35
|
private dialog;
|
|
36
36
|
private cancelButton;
|
|
37
37
|
open: boolean;
|
|
38
|
-
heading: string;
|
|
38
|
+
heading: string | undefined;
|
|
39
39
|
message: string;
|
|
40
|
-
confirmLabel: string;
|
|
41
|
-
cancelLabel: string;
|
|
40
|
+
confirmLabel: string | undefined;
|
|
41
|
+
cancelLabel: string | undefined;
|
|
42
42
|
/** `danger` gives the confirm button the solid red treatment. */
|
|
43
43
|
variant: KtConfirmVariant;
|
|
44
44
|
updated(changed: PropertyValues<this>): void;
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import { css as
|
|
2
|
-
import { query as
|
|
3
|
-
import { K as
|
|
4
|
-
import { e as
|
|
5
|
-
import { o as
|
|
1
|
+
import { css as h, nothing as c, html as p } from "lit";
|
|
2
|
+
import { query as m, property as o } from "lit/decorators.js";
|
|
3
|
+
import { K as g, d as y } from "../../../chunks/kt-element-mdd5cXZX.js";
|
|
4
|
+
import { e as f } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
5
|
+
import { o as u, c as b, i as v } from "../../../chunks/dialog-CPIfFIlF.js";
|
|
6
|
+
import { s as r } from "../../../chunks/index-fzPIgxe2.js";
|
|
6
7
|
import "../../core/kt-button/kt-button.js";
|
|
7
|
-
var
|
|
8
|
-
for (var i = void 0,
|
|
9
|
-
(
|
|
10
|
-
return i &&
|
|
8
|
+
var k = Object.defineProperty, a = (n, e, l, x) => {
|
|
9
|
+
for (var i = void 0, s = n.length - 1, d; s >= 0; s--)
|
|
10
|
+
(d = n[s]) && (i = d(e, l, i) || i);
|
|
11
|
+
return i && k(e, l, i), i;
|
|
11
12
|
};
|
|
12
|
-
class t extends
|
|
13
|
+
class t extends g {
|
|
13
14
|
constructor() {
|
|
14
|
-
super(...arguments), this.open = !1, this.heading =
|
|
15
|
+
super(...arguments), this.open = !1, this.heading = void 0, this.message = "", this.confirmLabel = void 0, this.cancelLabel = void 0, this.variant = "danger";
|
|
15
16
|
}
|
|
16
17
|
static {
|
|
17
18
|
this.styles = [
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
g.styles,
|
|
20
|
+
h`
|
|
20
21
|
:host {
|
|
21
22
|
display: contents;
|
|
22
23
|
}
|
|
@@ -101,50 +102,52 @@ class t extends p {
|
|
|
101
102
|
];
|
|
102
103
|
}
|
|
103
104
|
updated(e) {
|
|
104
|
-
e.has("open") && (this.open ? (
|
|
105
|
+
e.has("open") && (this.open ? (u(this.dialog), this.cancelButton?.focus()) : b(this.dialog));
|
|
105
106
|
}
|
|
106
107
|
confirm() {
|
|
107
|
-
this.open = !1,
|
|
108
|
+
this.open = !1, f(this, "kt-confirm");
|
|
108
109
|
}
|
|
109
110
|
cancel() {
|
|
110
|
-
this.open = !1,
|
|
111
|
+
this.open = !1, f(this, "kt-cancel");
|
|
111
112
|
}
|
|
112
113
|
/** Escape closes the native dialog; report it as a cancel. */
|
|
113
114
|
onDialogClose() {
|
|
114
115
|
this.open && this.cancel();
|
|
115
116
|
}
|
|
116
117
|
onDialogClick(e) {
|
|
117
|
-
|
|
118
|
+
v(this.dialog, e) && this.cancel();
|
|
118
119
|
}
|
|
119
120
|
render() {
|
|
120
|
-
return
|
|
121
|
+
return p`<dialog
|
|
121
122
|
part="dialog"
|
|
122
123
|
role="alertdialog"
|
|
123
|
-
aria-label=${this.heading}
|
|
124
|
-
aria-describedby=${this.message ? "kt-confirm-message" :
|
|
124
|
+
aria-label=${this.heading ?? r().confirmHeading}
|
|
125
|
+
aria-describedby=${this.message ? "kt-confirm-message" : c}
|
|
125
126
|
@close=${this.onDialogClose}
|
|
126
127
|
@click=${this.onDialogClick}
|
|
127
128
|
>
|
|
128
|
-
<h2>${this.heading}</h2>
|
|
129
|
-
${this.message ?
|
|
129
|
+
<h2>${this.heading ?? r().confirmHeading}</h2>
|
|
130
|
+
${this.message ? p`<p id="kt-confirm-message">${this.message}</p>` : c}
|
|
130
131
|
<slot></slot>
|
|
131
132
|
|
|
132
133
|
<div part="actions" class="actions">
|
|
133
|
-
<kt-button data-cancel variant="dark" @click=${this.cancel}
|
|
134
|
+
<kt-button data-cancel variant="dark" @click=${this.cancel}
|
|
135
|
+
>${this.cancelLabel ?? r().cancel}</kt-button
|
|
136
|
+
>
|
|
134
137
|
<kt-button
|
|
135
138
|
variant=${this.variant === "danger" ? "delete" : "primary"}
|
|
136
139
|
@click=${this.confirm}
|
|
137
|
-
>${this.confirmLabel}</kt-button
|
|
140
|
+
>${this.confirmLabel ?? r().confirm}</kt-button
|
|
138
141
|
>
|
|
139
142
|
</div>
|
|
140
143
|
</dialog>`;
|
|
141
144
|
}
|
|
142
145
|
}
|
|
143
146
|
a([
|
|
144
|
-
|
|
147
|
+
m("dialog")
|
|
145
148
|
], t.prototype, "dialog");
|
|
146
149
|
a([
|
|
147
|
-
|
|
150
|
+
m("kt-button[data-cancel]")
|
|
148
151
|
], t.prototype, "cancelButton");
|
|
149
152
|
a([
|
|
150
153
|
o({ type: Boolean, reflect: !0 })
|
|
@@ -164,7 +167,7 @@ a([
|
|
|
164
167
|
a([
|
|
165
168
|
o({ type: String, reflect: !0 })
|
|
166
169
|
], t.prototype, "variant");
|
|
167
|
-
|
|
170
|
+
y("kt-confirm-dialog", t);
|
|
168
171
|
export {
|
|
169
172
|
t as KtConfirmDialog
|
|
170
173
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-confirm-dialog.js","sources":["../../../../src/components/overlays/kt-confirm-dialog/kt-confirm-dialog.ts"],"sourcesContent":["import { css, html, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport { closeDialog, isBackdropClick, openModal } from '#internal/dialog';\nimport '../../core/kt-button/kt-button.js';\n\nexport type KtConfirmVariant = 'danger' | 'primary';\n\n/**\n * A centred yes/no overlay, for an action worth stopping to think about.\n *\n * Confirmations are for destructive or irreversible work. Editing belongs in a\n * `<kt-side-panel>`, which does not block the page behind it.\n *\n * `role=\"alertdialog\"` and the cancel button takes focus on open, so a stray\n * Enter dismisses rather than confirms.\n *\n * @element kt-confirm-dialog\n *\n * @slot - Extra content between the message and the buttons.\n *\n * @csspart dialog - The `<dialog>`.\n * @csspart actions - The button row.\n *\n * @fires kt-confirm - The confirm button was pressed.\n * @fires kt-cancel - Dismissed, by button, Escape or backdrop.\n *\n * @example\n * ```html\n * <kt-confirm-dialog\n * heading=\"Delete this entity?\"\n * message=\"This action cannot be undone.\"\n * confirm-label=\"Delete\"\n * ></kt-confirm-dialog>\n * ```\n */\nexport class KtConfirmDialog extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: contents;\n }\n\n /*\n * Closed by default (\\`display: none\\`, the native UA default a plain\n * \\`dialog\\` selector here would otherwise override): before this,\n * \\`display: flex\\` applied unconditionally, so a \\`<kt-confirm-dialog>\\`\n * that had never been opened still rendered its \\`<dialog>\\` in normal\n * flow — \\`opacity: 0\\` hides it, but does not stop it from occupying\n * its box or intercepting clicks meant for whatever sits underneath.\n * Verified against a real page: a closed dialog several screens away\n * from where it was declared silently ate clicks on the content\n * behind it. \\`display\\` is already in the transition list below with\n * \\`allow-discrete\\` for exactly this swap — switching \\`dialog[open]\\`\n * to set \\`display: flex\\` is what makes that transition real instead\n * of a no-op, and the close animation (opacity/transform) still plays\n * in full before \\`display\\` flips back to \\`none\\`.\n */\n dialog {\n display: none;\n flex-direction: column;\n gap: var(--gap-modal);\n box-sizing: border-box;\n width: 400px;\n max-width: calc(100vw - 48px);\n padding: var(--padding-modal);\n color: var(--text-body);\n background: var(--surface-card);\n border: var(--border-width) solid var(--border-subtle);\n border-radius: var(--radius-modal);\n transform: translateY(8px);\n opacity: 0;\n transition:\n transform var(--duration-normal) var(--easing-standard),\n opacity var(--duration-normal) var(--easing-standard),\n overlay var(--duration-normal) allow-discrete,\n display var(--duration-normal) allow-discrete;\n }\n\n dialog[open] {\n display: flex;\n transform: translateY(0);\n opacity: 1;\n }\n\n @starting-style {\n dialog[open] {\n transform: translateY(8px);\n opacity: 0;\n }\n }\n\n dialog::backdrop {\n background: var(--color-backdrop, rgba(0, 0, 0, 0.45));\n }\n\n h2 {\n margin: 0;\n color: var(--text-body);\n font: var(--font-title-h6);\n }\n\n p {\n margin: 0;\n color: var(--text-muted);\n font: var(--font-normal-regular);\n }\n\n .actions {\n display: flex;\n justify-content: flex-end;\n gap: var(--gap-button);\n }\n\n @media (prefers-reduced-motion: reduce) {\n dialog {\n transition: none;\n }\n }\n `,\n ];\n\n @query('dialog')\n private dialog!: HTMLDialogElement;\n\n @query('kt-button[data-cancel]')\n private cancelButton!: HTMLElement | null;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ type: String })\n heading
|
|
1
|
+
{"version":3,"file":"kt-confirm-dialog.js","sources":["../../../../src/components/overlays/kt-confirm-dialog/kt-confirm-dialog.ts"],"sourcesContent":["import { css, html, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport { closeDialog, isBackdropClick, openModal } from '#internal/dialog';\nimport { strings } from '#internal/strings';\nimport '../../core/kt-button/kt-button.js';\n\nexport type KtConfirmVariant = 'danger' | 'primary';\n\n/**\n * A centred yes/no overlay, for an action worth stopping to think about.\n *\n * Confirmations are for destructive or irreversible work. Editing belongs in a\n * `<kt-side-panel>`, which does not block the page behind it.\n *\n * `role=\"alertdialog\"` and the cancel button takes focus on open, so a stray\n * Enter dismisses rather than confirms.\n *\n * @element kt-confirm-dialog\n *\n * @slot - Extra content between the message and the buttons.\n *\n * @csspart dialog - The `<dialog>`.\n * @csspart actions - The button row.\n *\n * @fires kt-confirm - The confirm button was pressed.\n * @fires kt-cancel - Dismissed, by button, Escape or backdrop.\n *\n * @example\n * ```html\n * <kt-confirm-dialog\n * heading=\"Delete this entity?\"\n * message=\"This action cannot be undone.\"\n * confirm-label=\"Delete\"\n * ></kt-confirm-dialog>\n * ```\n */\nexport class KtConfirmDialog extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: contents;\n }\n\n /*\n * Closed by default (\\`display: none\\`, the native UA default a plain\n * \\`dialog\\` selector here would otherwise override): before this,\n * \\`display: flex\\` applied unconditionally, so a \\`<kt-confirm-dialog>\\`\n * that had never been opened still rendered its \\`<dialog>\\` in normal\n * flow — \\`opacity: 0\\` hides it, but does not stop it from occupying\n * its box or intercepting clicks meant for whatever sits underneath.\n * Verified against a real page: a closed dialog several screens away\n * from where it was declared silently ate clicks on the content\n * behind it. \\`display\\` is already in the transition list below with\n * \\`allow-discrete\\` for exactly this swap — switching \\`dialog[open]\\`\n * to set \\`display: flex\\` is what makes that transition real instead\n * of a no-op, and the close animation (opacity/transform) still plays\n * in full before \\`display\\` flips back to \\`none\\`.\n */\n dialog {\n display: none;\n flex-direction: column;\n gap: var(--gap-modal);\n box-sizing: border-box;\n width: 400px;\n max-width: calc(100vw - 48px);\n padding: var(--padding-modal);\n color: var(--text-body);\n background: var(--surface-card);\n border: var(--border-width) solid var(--border-subtle);\n border-radius: var(--radius-modal);\n transform: translateY(8px);\n opacity: 0;\n transition:\n transform var(--duration-normal) var(--easing-standard),\n opacity var(--duration-normal) var(--easing-standard),\n overlay var(--duration-normal) allow-discrete,\n display var(--duration-normal) allow-discrete;\n }\n\n dialog[open] {\n display: flex;\n transform: translateY(0);\n opacity: 1;\n }\n\n @starting-style {\n dialog[open] {\n transform: translateY(8px);\n opacity: 0;\n }\n }\n\n dialog::backdrop {\n background: var(--color-backdrop, rgba(0, 0, 0, 0.45));\n }\n\n h2 {\n margin: 0;\n color: var(--text-body);\n font: var(--font-title-h6);\n }\n\n p {\n margin: 0;\n color: var(--text-muted);\n font: var(--font-normal-regular);\n }\n\n .actions {\n display: flex;\n justify-content: flex-end;\n gap: var(--gap-button);\n }\n\n @media (prefers-reduced-motion: reduce) {\n dialog {\n transition: none;\n }\n }\n `,\n ];\n\n @query('dialog')\n private dialog!: HTMLDialogElement;\n\n @query('kt-button[data-cancel]')\n private cancelButton!: HTMLElement | null;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ type: String })\n heading: string | undefined = undefined;\n\n @property({ type: String })\n message = '';\n\n @property({ type: String, attribute: 'confirm-label' })\n confirmLabel: string | undefined = undefined;\n\n @property({ type: String, attribute: 'cancel-label' })\n cancelLabel: string | undefined = undefined;\n\n /** `danger` gives the confirm button the solid red treatment. */\n @property({ type: String, reflect: true })\n variant: KtConfirmVariant = 'danger';\n\n override updated(changed: PropertyValues<this>): void {\n if (!changed.has('open')) return;\n\n if (this.open) {\n openModal(this.dialog);\n // Focus lands on Cancel, not Confirm: an Enter meant for whatever was\n // behind the dialog should not delete anything.\n this.cancelButton?.focus();\n } else {\n closeDialog(this.dialog);\n }\n }\n\n private confirm(): void {\n this.open = false;\n emit(this, 'kt-confirm');\n }\n\n private cancel(): void {\n this.open = false;\n emit(this, 'kt-cancel');\n }\n\n /** Escape closes the native dialog; report it as a cancel. */\n private onDialogClose(): void {\n if (this.open) this.cancel();\n }\n\n private onDialogClick(event: MouseEvent): void {\n if (isBackdropClick(this.dialog, event)) this.cancel();\n }\n\n override render(): TemplateResult {\n return html`<dialog\n part=\"dialog\"\n role=\"alertdialog\"\n aria-label=${this.heading ?? strings().confirmHeading}\n aria-describedby=${this.message ? 'kt-confirm-message' : nothing}\n @close=${this.onDialogClose}\n @click=${this.onDialogClick}\n >\n <h2>${this.heading ?? strings().confirmHeading}</h2>\n ${this.message ? html`<p id=\"kt-confirm-message\">${this.message}</p>` : nothing}\n <slot></slot>\n\n <div part=\"actions\" class=\"actions\">\n <kt-button data-cancel variant=\"dark\" @click=${this.cancel}\n >${this.cancelLabel ?? strings().cancel}</kt-button\n >\n <kt-button\n variant=${this.variant === 'danger' ? 'delete' : 'primary'}\n @click=${this.confirm}\n >${this.confirmLabel ?? strings().confirm}</kt-button\n >\n </div>\n </dialog>`;\n }\n}\n\ndefineElement('kt-confirm-dialog', KtConfirmDialog);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-confirm-dialog': KtConfirmDialog;\n }\n}\n"],"names":["KtConfirmDialog","KtElement","css","changed","openModal","closeDialog","emit","event","isBackdropClick","html","strings","nothing","__decorateClass","query","property","defineElement"],"mappings":";;;;;;;;;;;;AAsCO,MAAMA,UAAwBC,EAAU;AAAA,EAAxC,cAAA;AAAA,UAAA,GAAA,SAAA,GA8FL,KAAA,OAAO,IAGP,KAAA,UAA8B,QAG9B,KAAA,UAAU,IAGV,KAAA,eAAmC,QAGnC,KAAA,cAAkC,QAIlC,KAAA,UAA4B;AAAA,EAAA;AAAA,EA7G5B,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,IAAA;AAAA,EAkFF;AAAA,EA2BS,QAAQC,GAAqC;AACpD,IAAKA,EAAQ,IAAI,MAAM,MAEnB,KAAK,QACPC,EAAU,KAAK,MAAM,GAGrB,KAAK,cAAc,MAAA,KAEnBC,EAAY,KAAK,MAAM;AAAA,EAE3B;AAAA,EAEQ,UAAgB;AACtB,SAAK,OAAO,IACZC,EAAK,MAAM,YAAY;AAAA,EACzB;AAAA,EAEQ,SAAe;AACrB,SAAK,OAAO,IACZA,EAAK,MAAM,WAAW;AAAA,EACxB;AAAA;AAAA,EAGQ,gBAAsB;AAC5B,IAAI,KAAK,QAAM,KAAK,OAAA;AAAA,EACtB;AAAA,EAEQ,cAAcC,GAAyB;AAC7C,IAAIC,EAAgB,KAAK,QAAQD,CAAK,UAAQ,OAAA;AAAA,EAChD;AAAA,EAES,SAAyB;AAChC,WAAOE;AAAA;AAAA;AAAA,mBAGQ,KAAK,WAAWC,EAAA,EAAU,cAAc;AAAA,yBAClC,KAAK,UAAU,uBAAuBC,CAAO;AAAA,eACvD,KAAK,aAAa;AAAA,eAClB,KAAK,aAAa;AAAA;AAAA,YAErB,KAAK,WAAWD,EAAA,EAAU,cAAc;AAAA,QAC5C,KAAK,UAAUD,+BAAkC,KAAK,OAAO,SAASE,CAAO;AAAA;AAAA;AAAA;AAAA,uDAI9B,KAAK,MAAM;AAAA,aACrD,KAAK,eAAeD,EAAA,EAAU,MAAM;AAAA;AAAA;AAAA,oBAG7B,KAAK,YAAY,WAAW,WAAW,SAAS;AAAA,mBACjD,KAAK,OAAO;AAAA,aAClB,KAAK,gBAAgBA,EAAA,EAAU,OAAO;AAAA;AAAA;AAAA;AAAA,EAIjD;AACF;AAjFUE,EAAA;AAAA,EADPC,EAAM,QAAQ;AAAA,GAvFJb,EAwFH,WAAA,QAAA;AAGAY,EAAA;AAAA,EADPC,EAAM,wBAAwB;AAAA,GA1FpBb,EA2FH,WAAA,cAAA;AAGRY,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GA7F/Bd,EA8FX,WAAA,MAAA;AAGAY,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAhGfd,EAiGX,WAAA,SAAA;AAGAY,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAnGfd,EAoGX,WAAA,SAAA;AAGAY,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,QAAQ,WAAW,iBAAiB;AAAA,GAtG3Cd,EAuGX,WAAA,cAAA;AAGAY,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,QAAQ,WAAW,gBAAgB;AAAA,GAzG1Cd,EA0GX,WAAA,aAAA;AAIAY,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA7G9Bd,EA8GX,WAAA,SAAA;AA6DFe,EAAc,qBAAqBf,CAAe;"}
|
|
@@ -41,7 +41,7 @@ export declare class KtDropdown extends KtElement {
|
|
|
41
41
|
/** Which edge of the trigger the panel lines up with. */
|
|
42
42
|
align: KtDropdownAlign;
|
|
43
43
|
disabled: boolean;
|
|
44
|
-
emptyText: string;
|
|
44
|
+
emptyText: string | undefined;
|
|
45
45
|
/** Whether the panel is showing. */
|
|
46
46
|
get isOpen(): boolean;
|
|
47
47
|
connectedCallback(): void;
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { css as v, nothing as b, html as p } from "lit";
|
|
2
2
|
import { query as h, state as f, property as a } from "lit/decorators.js";
|
|
3
3
|
import { classMap as u } from "lit/directives/class-map.js";
|
|
4
|
-
import { K as g, d as y } from "../../../chunks/kt-element-
|
|
4
|
+
import { K as g, d as y } from "../../../chunks/kt-element-mdd5cXZX.js";
|
|
5
5
|
import { e as d } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
6
6
|
import { o as x } from "../../../chunks/listbox-Sm3nvsC6.js";
|
|
7
|
-
|
|
7
|
+
import { s as w } from "../../../chunks/index-fzPIgxe2.js";
|
|
8
|
+
var k = Object.defineProperty, o = (s, t, n, i) => {
|
|
8
9
|
for (var r = void 0, l = s.length - 1, c; l >= 0; l--)
|
|
9
10
|
(c = s[l]) && (r = c(t, n, r) || r);
|
|
10
|
-
return r &&
|
|
11
|
+
return r && k(t, n, r), r;
|
|
11
12
|
};
|
|
12
13
|
const m = 230;
|
|
13
14
|
class e extends g {
|
|
14
15
|
constructor() {
|
|
15
|
-
super(...arguments), this.open = !1, this.placement = "bottom", this.options = [], this.value = null, this.preferredPlacement = "bottom", this.align = "start", this.disabled = !1, this.emptyText =
|
|
16
|
+
super(...arguments), this.open = !1, this.placement = "bottom", this.options = [], this.value = null, this.preferredPlacement = "bottom", this.align = "start", this.disabled = !1, this.emptyText = void 0, this.reposition = () => {
|
|
16
17
|
const n = (this.triggerWrapper ?? this).getBoundingClientRect(), i = window.innerHeight - n.bottom, r = n.top;
|
|
17
18
|
this.placement = this.preferredPlacement === "top" ? r >= m || r >= i ? "top" : "bottom" : i >= m || i >= r ? "bottom" : "top";
|
|
18
19
|
}, this.onDocumentPointerDown = (t) => {
|
|
@@ -23,7 +24,7 @@ class e extends g {
|
|
|
23
24
|
const t = this.triggerSlot?.assignedElements()[0];
|
|
24
25
|
if (!t) return;
|
|
25
26
|
const n = this.panelSlot?.assignedElements()[0]?.getAttribute("role") === "menu", i = this.options.length > 0 || n ? "menu" : void 0;
|
|
26
|
-
if (
|
|
27
|
+
if (D(t)) {
|
|
27
28
|
t.popup = i, t.expanded = this.open;
|
|
28
29
|
return;
|
|
29
30
|
}
|
|
@@ -199,7 +200,7 @@ class e extends g {
|
|
|
199
200
|
</li>`
|
|
200
201
|
)}
|
|
201
202
|
</ul>` : p`<slot name="panel">
|
|
202
|
-
<div class="empty">${this.emptyText}</div>
|
|
203
|
+
<div class="empty">${this.emptyText ?? w().noResults}</div>
|
|
203
204
|
</slot>`}
|
|
204
205
|
</div>`;
|
|
205
206
|
}
|
|
@@ -237,7 +238,7 @@ o([
|
|
|
237
238
|
o([
|
|
238
239
|
a({ type: String, attribute: "empty-text" })
|
|
239
240
|
], e.prototype, "emptyText");
|
|
240
|
-
function
|
|
241
|
+
function D(s) {
|
|
241
242
|
return "popup" in s && "expanded" in s;
|
|
242
243
|
}
|
|
243
244
|
y("kt-dropdown", e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-dropdown.js","sources":["../../../../src/components/overlays/kt-dropdown/kt-dropdown.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property, query, 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 { optionLabel, type KtOption } from '#internal/listbox';\n\nexport type KtDropdownPlacement = 'bottom' | 'top';\nexport type KtDropdownAlign = 'start' | 'end';\n\n/** Panel height plus the 6px offset, used to decide whether it fits below. */\nconst PANEL_SPACE = 224 + 6;\n\n/**\n * A panel anchored to a trigger.\n *\n * The generic overlay: pass `options` for a menu, or slot anything into\n * `panel` for arbitrary content. For choosing a value in a form, reach for\n * `<kt-select>` or `<kt-input-menu>` instead — they carry the listbox\n * semantics this one deliberately does not assume.\n *\n * @element kt-dropdown\n *\n * @slot trigger - What opens the panel.\n * @slot panel - Panel contents, when `options` is not used.\n *\n * @csspart trigger - The trigger wrapper.\n * @csspart panel - The floating panel.\n * @csspart option - A menu row.\n *\n * @fires kt-select - A menu row was chosen. `detail: { value, option }`.\n * @fires kt-open - The panel opened.\n * @fires kt-close - The panel closed.\n */\nexport class KtDropdown extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n position: relative;\n display: inline-block;\n }\n\n .trigger {\n border-radius: var(--radius-input);\n cursor: pointer;\n }\n\n :host([disabled]) .trigger {\n cursor: not-allowed;\n opacity: 0.6;\n }\n\n .panel {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: var(--z-dropdown);\n box-sizing: border-box;\n width: 224px;\n max-height: 224px;\n margin: 0;\n padding: var(--padding-expand);\n background: var(--surface-raised);\n border-radius: var(--radius-input);\n transform: translateY(-6px);\n transform-origin: top left;\n visibility: hidden;\n opacity: 0;\n transition:\n opacity var(--duration-normal) var(--easing-standard),\n transform var(--duration-normal) var(--easing-standard);\n }\n\n .panel.top {\n top: auto;\n bottom: calc(100% + 6px);\n transform: translateY(6px);\n transform-origin: bottom left;\n }\n\n /* Hangs the panel off the trigger's right edge, for a trigger that sits\n at the right of what it belongs to — the caret of a split button. */\n .panel.end {\n right: 0;\n left: auto;\n transform-origin: top right;\n }\n\n .panel.end.top {\n transform-origin: bottom right;\n }\n\n .panel.open {\n visibility: visible;\n opacity: 1;\n transform: translateY(0);\n }\n\n .list {\n display: flex;\n flex-direction: column;\n gap: var(--gap-element);\n max-height: 208px;\n margin: 0;\n padding: 0;\n overflow: auto;\n list-style: none;\n scrollbar-width: thin;\n }\n\n .option {\n padding: var(--padding-expand-item);\n color: var(--text-muted);\n font: var(--font-normal-regular);\n border-radius: var(--radius-input);\n cursor: pointer;\n }\n .option:hover {\n background: var(--surface-hover);\n }\n\n .option.selected {\n color: var(--text-body);\n font-weight: 600;\n background: var(--color-dark-23);\n }\n\n .option.disabled {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .empty {\n padding: var(--padding-expand-item);\n color: var(--text-muted);\n font: var(--font-normal-small);\n cursor: default;\n }\n `,\n ];\n\n @query('.trigger')\n private triggerWrapper!: HTMLElement;\n\n @query('slot[name=\"trigger\"]')\n private triggerSlot?: HTMLSlotElement;\n\n @query('slot[name=\"panel\"]')\n private panelSlot?: HTMLSlotElement;\n\n @state()\n private open = false;\n\n /** Where the panel actually landed, after checking the room available. */\n @state()\n private placement: KtDropdownPlacement = 'bottom';\n\n /** Menu rows. Leave empty and slot into `panel` for custom content. */\n @property({ attribute: false })\n options: readonly KtOption[] = [];\n\n /** Marks one row as current. */\n @property({ type: String })\n value: string | number | null = null;\n\n /** Where to put the panel when there is room on both sides. */\n @property({ type: String, attribute: 'preferred-placement' })\n preferredPlacement: KtDropdownPlacement = 'bottom';\n\n /** Which edge of the trigger the panel lines up with. */\n @property({ type: String, reflect: true })\n align: KtDropdownAlign = 'start';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: String, attribute: 'empty-text' })\n emptyText = 'No results';\n\n /** Whether the panel is showing. */\n get isOpen(): boolean {\n return this.open;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.onDocumentPointerDown);\n document.addEventListener('keydown', this.onDocumentKeyDown);\n window.addEventListener('resize', this.reposition);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('pointerdown', this.onDocumentPointerDown);\n document.removeEventListener('keydown', this.onDocumentKeyDown);\n window.removeEventListener('resize', this.reposition);\n }\n\n /**\n * Flips the panel above the trigger when there is not enough room below,\n * preferring whichever side has more space if neither fits.\n */\n private reposition = (): void => {\n const anchor = this.triggerWrapper ?? this;\n const rect = anchor.getBoundingClientRect();\n const below = window.innerHeight - rect.bottom;\n const above = rect.top;\n\n this.placement =\n this.preferredPlacement === 'top'\n ? above >= PANEL_SPACE || above >= below\n ? 'top'\n : 'bottom'\n : below >= PANEL_SPACE || below >= above\n ? 'bottom'\n : 'top';\n };\n\n private onDocumentPointerDown = (event: Event): void => {\n if (event.composedPath().includes(this)) return;\n this.hide();\n };\n\n private onDocumentKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') this.hide();\n };\n\n override updated(): void {\n this.syncTrigger();\n }\n\n /**\n * Puts the popup state on the slotted trigger — the element that takes focus,\n * so the one a screen reader announces. A `<kt-button>` gets it through its\n * properties and passes it to its inner button; anything else as attributes.\n *\n * Only a menu is announced as one: the built-in list of options, or a\n * slotted panel that says `role=\"menu\"` itself. A panel of free content is a\n * disclosure — `aria-expanded` alone.\n */\n private syncTrigger = (): void => {\n const trigger = this.triggerSlot?.assignedElements()[0];\n if (!trigger) return;\n\n const customMenu = this.panelSlot?.assignedElements()[0]?.getAttribute('role') === 'menu';\n const popup = this.options.length > 0 || customMenu ? 'menu' : undefined;\n if (isPopupTrigger(trigger)) {\n trigger.popup = popup;\n trigger.expanded = this.open;\n return;\n }\n if (popup) trigger.setAttribute('aria-haspopup', popup);\n else trigger.removeAttribute('aria-haspopup');\n trigger.setAttribute('aria-expanded', String(this.open));\n };\n\n /** Opens the panel. */\n show(): void {\n if (this.disabled || this.open) return;\n this.reposition();\n this.open = true;\n emit(this, 'kt-open');\n }\n\n /** Closes the panel. */\n hide(): void {\n if (!this.open) return;\n this.open = false;\n emit(this, 'kt-close');\n }\n\n /** Opens or closes it. */\n toggle(): void {\n if (this.open) this.hide();\n else this.show();\n }\n\n private choose(option: KtOption): void {\n if (option.disabled) return;\n this.value = option.id;\n this.hide();\n emit(this, 'kt-select', { value: option.id, option });\n }\n\n override render(): TemplateResult {\n return html`<div part=\"trigger\" class=\"trigger\" @click=${this.toggle}>\n <slot name=\"trigger\" @slotchange=${this.syncTrigger}></slot>\n </div>\n\n <div\n part=\"panel\"\n class=${classMap({\n panel: true,\n open: this.open,\n top: this.placement === 'top',\n end: this.align === 'end',\n })}\n role=${this.options.length > 0 ? 'menu' : 'group'}\n aria-hidden=${this.open ? 'false' : 'true'}\n >\n ${\n this.options.length > 0\n ? html`<ul class=\"list\">\n ${this.options.map(\n (option) =>\n html`<li\n part=\"option\"\n class=${classMap({\n option: true,\n selected: option.id === this.value,\n disabled: Boolean(option.disabled),\n })}\n role=\"menuitem\"\n aria-disabled=${option.disabled ? 'true' : nothing}\n @click=${() => this.choose(option)}\n >\n ${optionLabel(option)}\n </li>`,\n )}\n </ul>`\n : html`<slot name=\"panel\">\n <div class=\"empty\">${this.emptyText}</div>\n </slot>`\n }\n </div>`;\n }\n}\n\n/** A trigger that takes its popup state as properties, like `<kt-button>`. */\ninterface PopupTrigger extends Element {\n popup: 'menu' | undefined;\n expanded: boolean | undefined;\n}\n\nfunction isPopupTrigger(element: Element): element is PopupTrigger {\n return 'popup' in element && 'expanded' in element;\n}\n\ndefineElement('kt-dropdown', KtDropdown);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-dropdown': KtDropdown;\n }\n}\n"],"names":["PANEL_SPACE","KtDropdown","KtElement","rect","below","above","event","trigger","customMenu","popup","isPopupTrigger","css","emit","option","html","classMap","nothing","optionLabel","__decorateClass","query","state","property","element","defineElement"],"mappings":";;;;;;;;;;;AAWA,MAAMA,IAAc;AAuBb,MAAMC,UAAmBC,EAAU;AAAA,EAAnC,cAAA;AAAA,UAAA,GAAA,SAAA,GAsHL,KAAQ,OAAO,IAIf,KAAQ,YAAiC,UAIzC,KAAA,UAA+B,CAAA,GAI/B,KAAA,QAAgC,MAIhC,KAAA,qBAA0C,UAI1C,KAAA,QAAyB,SAGzB,KAAA,WAAW,IAGX,KAAA,YAAY,cAyBZ,KAAQ,aAAa,MAAY;AAE/B,YAAMC,KADS,KAAK,kBAAkB,MAClB,sBAAA,GACdC,IAAQ,OAAO,cAAcD,EAAK,QAClCE,IAAQF,EAAK;AAEnB,WAAK,YACH,KAAK,uBAAuB,QACxBE,KAASL,KAAeK,KAASD,IAC/B,QACA,WACFA,KAASJ,KAAeI,KAASC,IAC/B,WACA;AAAA,IACV,GAEA,KAAQ,wBAAwB,CAACC,MAAuB;AACtD,MAAIA,EAAM,aAAA,EAAe,SAAS,IAAI,KACtC,KAAK,KAAA;AAAA,IACP,GAEA,KAAQ,oBAAoB,CAACA,MAA+B;AAC1D,MAAIA,EAAM,QAAQ,YAAU,KAAK,KAAA;AAAA,IACnC,GAeA,KAAQ,cAAc,MAAY;AAChC,YAAMC,IAAU,KAAK,aAAa,iBAAA,EAAmB,CAAC;AACtD,UAAI,CAACA,EAAS;AAEd,YAAMC,IAAa,KAAK,WAAW,iBAAA,EAAmB,CAAC,GAAG,aAAa,MAAM,MAAM,QAC7EC,IAAQ,KAAK,QAAQ,SAAS,KAAKD,IAAa,SAAS;AAC/D,UAAIE,EAAeH,CAAO,GAAG;AAC3B,QAAAA,EAAQ,QAAQE,GAChBF,EAAQ,WAAW,KAAK;AACxB;AAAA,MACF;AACA,MAAIE,IAAOF,EAAQ,aAAa,iBAAiBE,CAAK,IACjDF,EAAQ,gBAAgB,eAAe,GAC5CA,EAAQ,aAAa,iBAAiB,OAAO,KAAK,IAAI,CAAC;AAAA,IACzD;AAAA,EAAA;AAAA,EA5NA,OAAA;AAAA,SAAgB,SAAS;AAAA,MACvBL,EAAU;AAAA,MACVS;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,EAuGF;AAAA;AAAA,EAyCA,IAAI,SAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAES,oBAA0B;AACjC,UAAM,kBAAA,GACN,SAAS,iBAAiB,eAAe,KAAK,qBAAqB,GACnE,SAAS,iBAAiB,WAAW,KAAK,iBAAiB,GAC3D,OAAO,iBAAiB,UAAU,KAAK,UAAU;AAAA,EACnD;AAAA,EAES,uBAA6B;AACpC,UAAM,qBAAA,GACN,SAAS,oBAAoB,eAAe,KAAK,qBAAqB,GACtE,SAAS,oBAAoB,WAAW,KAAK,iBAAiB,GAC9D,OAAO,oBAAoB,UAAU,KAAK,UAAU;AAAA,EACtD;AAAA,EA+BS,UAAgB;AACvB,SAAK,YAAA;AAAA,EACP;AAAA;AAAA,EA4BA,OAAa;AACX,IAAI,KAAK,YAAY,KAAK,SAC1B,KAAK,WAAA,GACL,KAAK,OAAO,IACZC,EAAK,MAAM,SAAS;AAAA,EACtB;AAAA;AAAA,EAGA,OAAa;AACX,IAAK,KAAK,SACV,KAAK,OAAO,IACZA,EAAK,MAAM,UAAU;AAAA,EACvB;AAAA;AAAA,EAGA,SAAe;AACb,IAAI,KAAK,OAAM,KAAK,KAAA,SACV,KAAA;AAAA,EACZ;AAAA,EAEQ,OAAOC,GAAwB;AACrC,IAAIA,EAAO,aACX,KAAK,QAAQA,EAAO,IACpB,KAAK,KAAA,GACLD,EAAK,MAAM,aAAa,EAAE,OAAOC,EAAO,IAAI,QAAAA,GAAQ;AAAA,EACtD;AAAA,EAES,SAAyB;AAChC,WAAOC,+CAAkD,KAAK,MAAM;AAAA,2CAC7B,KAAK,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,gBAK3CC,EAAS;AAAA,MACf,OAAO;AAAA,MACP,MAAM,KAAK;AAAA,MACX,KAAK,KAAK,cAAc;AAAA,MACxB,KAAK,KAAK,UAAU;AAAA,IAAA,CACrB,CAAC;AAAA,eACK,KAAK,QAAQ,SAAS,IAAI,SAAS,OAAO;AAAA,sBACnC,KAAK,OAAO,UAAU,MAAM;AAAA;AAAA,UAGxC,KAAK,QAAQ,SAAS,IAClBD;AAAA,kBACI,KAAK,QAAQ;AAAA,MACb,CAACD,MACCC;AAAA;AAAA,8BAEUC,EAAS;AAAA,QACf,QAAQ;AAAA,QACR,UAAUF,EAAO,OAAO,KAAK;AAAA,QAC7B,UAAU,EAAQA,EAAO;AAAA,MAAQ,CAClC,CAAC;AAAA;AAAA,sCAEcA,EAAO,WAAW,SAASG,CAAO;AAAA,+BACzC,MAAM,KAAK,OAAOH,CAAM,CAAC;AAAA;AAAA,wBAEhCI,EAAYJ,CAAM,CAAC;AAAA;AAAA,IAAA,CAE1B;AAAA,uBAEHC;AAAA,qCACuB,KAAK,SAAS;AAAA,sBAE3C;AAAA;AAAA,EAEN;AACF;AAxLUI,EAAA;AAAA,EADPC,EAAM,UAAU;AAAA,GA5GNlB,EA6GH,WAAA,gBAAA;AAGAiB,EAAA;AAAA,EADPC,EAAM,sBAAsB;AAAA,GA/GlBlB,EAgHH,WAAA,aAAA;AAGAiB,EAAA;AAAA,EADPC,EAAM,oBAAoB;AAAA,GAlHhBlB,EAmHH,WAAA,WAAA;AAGAiB,EAAA;AAAA,EADPE,EAAA;AAAM,GArHInB,EAsHH,WAAA,MAAA;AAIAiB,EAAA;AAAA,EADPE,EAAA;AAAM,GAzHInB,EA0HH,WAAA,WAAA;AAIRiB,EAAA;AAAA,EADCG,EAAS,EAAE,WAAW,GAAA,CAAO;AAAA,GA7HnBpB,EA8HX,WAAA,SAAA;AAIAiB,EAAA;AAAA,EADCG,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAjIfpB,EAkIX,WAAA,OAAA;AAIAiB,EAAA;AAAA,EADCG,EAAS,EAAE,MAAM,QAAQ,WAAW,uBAAuB;AAAA,GArIjDpB,EAsIX,WAAA,oBAAA;AAIAiB,EAAA;AAAA,EADCG,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAzI9BpB,EA0IX,WAAA,OAAA;AAGAiB,EAAA;AAAA,EADCG,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GA5I/BpB,EA6IX,WAAA,UAAA;AAGAiB,EAAA;AAAA,EADCG,EAAS,EAAE,MAAM,QAAQ,WAAW,cAAc;AAAA,GA/IxCpB,EAgJX,WAAA,WAAA;AA6JF,SAASS,EAAeY,GAA2C;AACjE,SAAO,WAAWA,KAAW,cAAcA;AAC7C;AAEAC,EAAc,eAAetB,CAAU;"}
|
|
1
|
+
{"version":3,"file":"kt-dropdown.js","sources":["../../../../src/components/overlays/kt-dropdown/kt-dropdown.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property, query, 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 { optionLabel, type KtOption } from '#internal/listbox';\nimport { strings } from '#internal/strings';\n\nexport type KtDropdownPlacement = 'bottom' | 'top';\nexport type KtDropdownAlign = 'start' | 'end';\n\n/** Panel height plus the 6px offset, used to decide whether it fits below. */\nconst PANEL_SPACE = 224 + 6;\n\n/**\n * A panel anchored to a trigger.\n *\n * The generic overlay: pass `options` for a menu, or slot anything into\n * `panel` for arbitrary content. For choosing a value in a form, reach for\n * `<kt-select>` or `<kt-input-menu>` instead — they carry the listbox\n * semantics this one deliberately does not assume.\n *\n * @element kt-dropdown\n *\n * @slot trigger - What opens the panel.\n * @slot panel - Panel contents, when `options` is not used.\n *\n * @csspart trigger - The trigger wrapper.\n * @csspart panel - The floating panel.\n * @csspart option - A menu row.\n *\n * @fires kt-select - A menu row was chosen. `detail: { value, option }`.\n * @fires kt-open - The panel opened.\n * @fires kt-close - The panel closed.\n */\nexport class KtDropdown extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n position: relative;\n display: inline-block;\n }\n\n .trigger {\n border-radius: var(--radius-input);\n cursor: pointer;\n }\n\n :host([disabled]) .trigger {\n cursor: not-allowed;\n opacity: 0.6;\n }\n\n .panel {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: var(--z-dropdown);\n box-sizing: border-box;\n width: 224px;\n max-height: 224px;\n margin: 0;\n padding: var(--padding-expand);\n background: var(--surface-raised);\n border-radius: var(--radius-input);\n transform: translateY(-6px);\n transform-origin: top left;\n visibility: hidden;\n opacity: 0;\n transition:\n opacity var(--duration-normal) var(--easing-standard),\n transform var(--duration-normal) var(--easing-standard);\n }\n\n .panel.top {\n top: auto;\n bottom: calc(100% + 6px);\n transform: translateY(6px);\n transform-origin: bottom left;\n }\n\n /* Hangs the panel off the trigger's right edge, for a trigger that sits\n at the right of what it belongs to — the caret of a split button. */\n .panel.end {\n right: 0;\n left: auto;\n transform-origin: top right;\n }\n\n .panel.end.top {\n transform-origin: bottom right;\n }\n\n .panel.open {\n visibility: visible;\n opacity: 1;\n transform: translateY(0);\n }\n\n .list {\n display: flex;\n flex-direction: column;\n gap: var(--gap-element);\n max-height: 208px;\n margin: 0;\n padding: 0;\n overflow: auto;\n list-style: none;\n scrollbar-width: thin;\n }\n\n .option {\n padding: var(--padding-expand-item);\n color: var(--text-muted);\n font: var(--font-normal-regular);\n border-radius: var(--radius-input);\n cursor: pointer;\n }\n .option:hover {\n background: var(--surface-hover);\n }\n\n .option.selected {\n color: var(--text-body);\n font-weight: 600;\n background: var(--color-dark-23);\n }\n\n .option.disabled {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .empty {\n padding: var(--padding-expand-item);\n color: var(--text-muted);\n font: var(--font-normal-small);\n cursor: default;\n }\n `,\n ];\n\n @query('.trigger')\n private triggerWrapper!: HTMLElement;\n\n @query('slot[name=\"trigger\"]')\n private triggerSlot?: HTMLSlotElement;\n\n @query('slot[name=\"panel\"]')\n private panelSlot?: HTMLSlotElement;\n\n @state()\n private open = false;\n\n /** Where the panel actually landed, after checking the room available. */\n @state()\n private placement: KtDropdownPlacement = 'bottom';\n\n /** Menu rows. Leave empty and slot into `panel` for custom content. */\n @property({ attribute: false })\n options: readonly KtOption[] = [];\n\n /** Marks one row as current. */\n @property({ type: String })\n value: string | number | null = null;\n\n /** Where to put the panel when there is room on both sides. */\n @property({ type: String, attribute: 'preferred-placement' })\n preferredPlacement: KtDropdownPlacement = 'bottom';\n\n /** Which edge of the trigger the panel lines up with. */\n @property({ type: String, reflect: true })\n align: KtDropdownAlign = 'start';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: String, attribute: 'empty-text' })\n emptyText: string | undefined = undefined;\n\n /** Whether the panel is showing. */\n get isOpen(): boolean {\n return this.open;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.onDocumentPointerDown);\n document.addEventListener('keydown', this.onDocumentKeyDown);\n window.addEventListener('resize', this.reposition);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('pointerdown', this.onDocumentPointerDown);\n document.removeEventListener('keydown', this.onDocumentKeyDown);\n window.removeEventListener('resize', this.reposition);\n }\n\n /**\n * Flips the panel above the trigger when there is not enough room below,\n * preferring whichever side has more space if neither fits.\n */\n private reposition = (): void => {\n const anchor = this.triggerWrapper ?? this;\n const rect = anchor.getBoundingClientRect();\n const below = window.innerHeight - rect.bottom;\n const above = rect.top;\n\n this.placement =\n this.preferredPlacement === 'top'\n ? above >= PANEL_SPACE || above >= below\n ? 'top'\n : 'bottom'\n : below >= PANEL_SPACE || below >= above\n ? 'bottom'\n : 'top';\n };\n\n private onDocumentPointerDown = (event: Event): void => {\n if (event.composedPath().includes(this)) return;\n this.hide();\n };\n\n private onDocumentKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') this.hide();\n };\n\n override updated(): void {\n this.syncTrigger();\n }\n\n /**\n * Puts the popup state on the slotted trigger — the element that takes focus,\n * so the one a screen reader announces. A `<kt-button>` gets it through its\n * properties and passes it to its inner button; anything else as attributes.\n *\n * Only a menu is announced as one: the built-in list of options, or a\n * slotted panel that says `role=\"menu\"` itself. A panel of free content is a\n * disclosure — `aria-expanded` alone.\n */\n private syncTrigger = (): void => {\n const trigger = this.triggerSlot?.assignedElements()[0];\n if (!trigger) return;\n\n const customMenu = this.panelSlot?.assignedElements()[0]?.getAttribute('role') === 'menu';\n const popup = this.options.length > 0 || customMenu ? 'menu' : undefined;\n if (isPopupTrigger(trigger)) {\n trigger.popup = popup;\n trigger.expanded = this.open;\n return;\n }\n if (popup) trigger.setAttribute('aria-haspopup', popup);\n else trigger.removeAttribute('aria-haspopup');\n trigger.setAttribute('aria-expanded', String(this.open));\n };\n\n /** Opens the panel. */\n show(): void {\n if (this.disabled || this.open) return;\n this.reposition();\n this.open = true;\n emit(this, 'kt-open');\n }\n\n /** Closes the panel. */\n hide(): void {\n if (!this.open) return;\n this.open = false;\n emit(this, 'kt-close');\n }\n\n /** Opens or closes it. */\n toggle(): void {\n if (this.open) this.hide();\n else this.show();\n }\n\n private choose(option: KtOption): void {\n if (option.disabled) return;\n this.value = option.id;\n this.hide();\n emit(this, 'kt-select', { value: option.id, option });\n }\n\n override render(): TemplateResult {\n return html`<div part=\"trigger\" class=\"trigger\" @click=${this.toggle}>\n <slot name=\"trigger\" @slotchange=${this.syncTrigger}></slot>\n </div>\n\n <div\n part=\"panel\"\n class=${classMap({\n panel: true,\n open: this.open,\n top: this.placement === 'top',\n end: this.align === 'end',\n })}\n role=${this.options.length > 0 ? 'menu' : 'group'}\n aria-hidden=${this.open ? 'false' : 'true'}\n >\n ${\n this.options.length > 0\n ? html`<ul class=\"list\">\n ${this.options.map(\n (option) =>\n html`<li\n part=\"option\"\n class=${classMap({\n option: true,\n selected: option.id === this.value,\n disabled: Boolean(option.disabled),\n })}\n role=\"menuitem\"\n aria-disabled=${option.disabled ? 'true' : nothing}\n @click=${() => this.choose(option)}\n >\n ${optionLabel(option)}\n </li>`,\n )}\n </ul>`\n : html`<slot name=\"panel\">\n <div class=\"empty\">${this.emptyText ?? strings().noResults}</div>\n </slot>`\n }\n </div>`;\n }\n}\n\n/** A trigger that takes its popup state as properties, like `<kt-button>`. */\ninterface PopupTrigger extends Element {\n popup: 'menu' | undefined;\n expanded: boolean | undefined;\n}\n\nfunction isPopupTrigger(element: Element): element is PopupTrigger {\n return 'popup' in element && 'expanded' in element;\n}\n\ndefineElement('kt-dropdown', KtDropdown);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-dropdown': KtDropdown;\n }\n}\n"],"names":["PANEL_SPACE","KtDropdown","KtElement","rect","below","above","event","trigger","customMenu","popup","isPopupTrigger","css","emit","option","html","classMap","nothing","optionLabel","strings","__decorateClass","query","state","property","element","defineElement"],"mappings":"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"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { css as g, nothing as r, html as s } from "lit";
|
|
2
2
|
import { query as f, property as i } from "lit/decorators.js";
|
|
3
|
-
import { K as c, d as m } from "../../../chunks/kt-element-
|
|
3
|
+
import { K as c, d as m } from "../../../chunks/kt-element-mdd5cXZX.js";
|
|
4
4
|
import { e as u } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
5
5
|
import { h as y } from "../../../chunks/slots-BPbIdxAJ.js";
|
|
6
6
|
import { o as h, c as v, i as b } from "../../../chunks/dialog-CPIfFIlF.js";
|
|
7
|
+
import { s as x } from "../../../chunks/index-fzPIgxe2.js";
|
|
7
8
|
import "../../core/kt-button/kt-button.js";
|
|
8
|
-
var
|
|
9
|
+
var k = Object.defineProperty, e = (l, t, d, w) => {
|
|
9
10
|
for (var a = void 0, n = l.length - 1, p; n >= 0; n--)
|
|
10
11
|
(p = l[n]) && (a = p(t, d, a) || a);
|
|
11
|
-
return a &&
|
|
12
|
+
return a && k(t, d, a), a;
|
|
12
13
|
};
|
|
13
14
|
class o extends c {
|
|
14
15
|
constructor() {
|
|
@@ -168,7 +169,7 @@ class o extends c {
|
|
|
168
169
|
variant="secondary-no-bg"
|
|
169
170
|
size="small"
|
|
170
171
|
icon="x"
|
|
171
|
-
label
|
|
172
|
+
label=${x().close}
|
|
172
173
|
@click=${this.requestClose}
|
|
173
174
|
></kt-button>`}
|
|
174
175
|
</div>` : r}
|