kanto-ds 1.5.2 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +13 -11
  2. package/dist/chunks/defaults-Cpeg13O5.js +68 -0
  3. package/dist/chunks/defaults-Cpeg13O5.js.map +1 -0
  4. package/dist/chunks/floating-B33g-M_1.js +63 -0
  5. package/dist/chunks/floating-B33g-M_1.js.map +1 -0
  6. package/dist/chunks/{index-STEEvEP7.js → index-TWJzttLX.js} +38 -15
  7. package/dist/chunks/index-TWJzttLX.js.map +1 -0
  8. package/dist/chunks/kt-calendar-CtwOby1R.js +780 -0
  9. package/dist/chunks/kt-calendar-CtwOby1R.js.map +1 -0
  10. package/dist/chunks/{kt-element-Djx2JcGl.js → kt-element-T0VbIBNp.js} +2 -2
  11. package/dist/chunks/{kt-element-Djx2JcGl.js.map → kt-element-T0VbIBNp.js.map} +1 -1
  12. package/dist/chunks/{listbox-llcUu_V-.js → listbox-LsUEyGhQ.js} +2 -2
  13. package/dist/chunks/{listbox-llcUu_V-.js.map → listbox-LsUEyGhQ.js.map} +1 -1
  14. package/dist/chunks/segmented-field-BBXR4XFL.js +384 -0
  15. package/dist/chunks/segmented-field-BBXR4XFL.js.map +1 -0
  16. package/dist/chunks/typed-date-CPAUNHzr.js +103 -0
  17. package/dist/chunks/typed-date-CPAUNHzr.js.map +1 -0
  18. package/dist/components/core/kt-avatar/kt-avatar.js +2 -2
  19. package/dist/components/core/kt-badge/kt-badge.js +2 -2
  20. package/dist/components/core/kt-button/kt-button.js +1 -1
  21. package/dist/components/core/kt-card/kt-card.js +1 -1
  22. package/dist/components/core/kt-code/kt-code.js +13 -13
  23. package/dist/components/core/kt-code/kt-code.js.map +1 -1
  24. package/dist/components/core/kt-icon/kt-icon.js +2 -2
  25. package/dist/components/core/kt-kbd/kt-kbd.js +5 -5
  26. package/dist/components/core/kt-kbd/kt-kbd.js.map +1 -1
  27. package/dist/components/core/kt-split-button/kt-split-button.js +3 -3
  28. package/dist/components/data/kt-chart/kt-chart.js +3 -3
  29. package/dist/components/data/kt-chart/kt-chart.js.map +1 -1
  30. package/dist/components/data/kt-meter/kt-meter.js +1 -1
  31. package/dist/components/data/kt-pagination/kt-pagination.js +2 -2
  32. package/dist/components/data/kt-stat/kt-stat.js +1 -1
  33. package/dist/components/data/kt-table/kt-table.js +85 -85
  34. package/dist/components/data/kt-table/kt-table.js.map +1 -1
  35. package/dist/components/data/kt-timeline/kt-timeline.js +1 -1
  36. package/dist/components/feedback/kt-alert/kt-alert.js +15 -15
  37. package/dist/components/feedback/kt-alert/kt-alert.js.map +1 -1
  38. package/dist/components/feedback/kt-empty-state/kt-empty-state.js +1 -1
  39. package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +1 -1
  40. package/dist/components/feedback/kt-skeleton/kt-skeleton.js +13 -13
  41. package/dist/components/feedback/kt-skeleton/kt-skeleton.js.map +1 -1
  42. package/dist/components/feedback/kt-toast/kt-toast.js +3 -3
  43. package/dist/components/feedback/kt-toast/kt-toast.js.map +1 -1
  44. package/dist/components/feedback/kt-toast-container/kt-toast-container.js +1 -1
  45. package/dist/components/feedback/kt-tooltip/kt-tooltip.js +1 -1
  46. package/dist/components/forms/kt-calendar/kt-calendar.d.ts +35 -9
  47. package/dist/components/forms/kt-calendar/kt-calendar.js +3 -3
  48. package/dist/components/forms/kt-checkbox/kt-checkbox.js +2 -2
  49. package/dist/components/forms/kt-date-input/kt-date-input.d.ts +65 -0
  50. package/dist/components/forms/kt-date-input/kt-date-input.js +241 -0
  51. package/dist/components/forms/kt-date-input/kt-date-input.js.map +1 -0
  52. package/dist/components/forms/kt-date-picker/kt-date-picker.d.ts +47 -3
  53. package/dist/components/forms/kt-date-picker/kt-date-picker.js +430 -199
  54. package/dist/components/forms/kt-date-picker/kt-date-picker.js.map +1 -1
  55. package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +3 -3
  56. package/dist/components/forms/kt-drag-drop/kt-drag-drop.js.map +1 -1
  57. package/dist/components/forms/kt-form/kt-form.js +2 -2
  58. package/dist/components/forms/kt-input/kt-input.js +10 -10
  59. package/dist/components/forms/kt-input/kt-input.js.map +1 -1
  60. package/dist/components/forms/kt-input-menu/kt-input-menu.js +4 -4
  61. package/dist/components/forms/kt-label-input/kt-label-input.js +1 -1
  62. package/dist/components/forms/kt-multi-select/kt-multi-select.d.ts +113 -0
  63. package/dist/components/forms/kt-multi-select/kt-multi-select.js +532 -0
  64. package/dist/components/forms/kt-multi-select/kt-multi-select.js.map +1 -0
  65. package/dist/components/forms/kt-radio-group/kt-radio-group.js +56 -51
  66. package/dist/components/forms/kt-radio-group/kt-radio-group.js.map +1 -1
  67. package/dist/components/forms/kt-select/kt-select.js +4 -4
  68. package/dist/components/forms/kt-textarea/kt-textarea.js +2 -2
  69. package/dist/components/forms/kt-time-input/kt-time-input.d.ts +48 -0
  70. package/dist/components/forms/kt-time-input/kt-time-input.js +114 -0
  71. package/dist/components/forms/kt-time-input/kt-time-input.js.map +1 -0
  72. package/dist/components/forms/kt-toggle/kt-toggle.js +1 -1
  73. package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +6 -6
  74. package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js.map +1 -1
  75. package/dist/components/navigation/kt-header/kt-header.js +2 -2
  76. package/dist/components/navigation/kt-page-header/kt-page-header.js +1 -1
  77. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +2 -2
  78. package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +2 -2
  79. package/dist/components/navigation/kt-tabs/kt-tabs.js +2 -2
  80. package/dist/components/navigation/kt-tabs/kt-tabs.js.map +1 -1
  81. package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +1 -1
  82. package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +2 -2
  83. package/dist/components/overlays/kt-collapsible/kt-collapsible.js +3 -3
  84. package/dist/components/overlays/kt-collapsible/kt-collapsible.js.map +1 -1
  85. package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +2 -2
  86. package/dist/components/overlays/kt-dropdown/kt-dropdown.js +24 -24
  87. package/dist/components/overlays/kt-dropdown/kt-dropdown.js.map +1 -1
  88. package/dist/components/overlays/kt-modal/kt-modal.js +2 -2
  89. package/dist/components/overlays/kt-side-panel/kt-side-panel.js +2 -2
  90. package/dist/custom-elements.json +2230 -842
  91. package/dist/icons/defaults.d.ts +9 -0
  92. package/dist/icons/index.js +1 -1
  93. package/dist/index.d.ts +9 -1
  94. package/dist/index.js +316 -109
  95. package/dist/index.js.map +1 -1
  96. package/dist/internal/floating.d.ts +3 -0
  97. package/dist/internal/segmented-field.d.ts +114 -0
  98. package/dist/internal/segments.d.ts +30 -0
  99. package/dist/internal/strings.d.ts +30 -0
  100. package/dist/internal/typed-date.d.ts +33 -0
  101. package/dist/react/index.d.ts +23 -0
  102. package/dist/react/index.js +193 -169
  103. package/dist/react/index.js.map +1 -1
  104. package/dist/react/jsx.d.ts +20 -1
  105. package/dist/strings/index.js +1 -1
  106. package/dist/theme/accent.d.ts +51 -0
  107. package/dist/theme/appearance.d.ts +37 -0
  108. package/dist/tokens/README.md +100 -1
  109. package/dist/tokens/accents.css +80 -0
  110. package/dist/tokens/appearance.css +65 -0
  111. package/dist/tokens/base.css +3 -0
  112. package/dist/tokens/colors.css +78 -25
  113. package/dist/tokens/index.css +2 -0
  114. package/dist/tokens/responsive.css +160 -75
  115. package/dist/tokens/spacing.css +47 -28
  116. package/dist/tokens/theme-light.css +124 -38
  117. package/dist/tokens/typography.css +20 -13
  118. package/dist/vscode.css-custom-data.json +36 -1
  119. package/dist/vscode.html-custom-data.json +67 -2
  120. package/dist/vue/index.d.ts +6 -0
  121. package/dist/vue/index.js +11 -8
  122. package/dist/vue/index.js.map +1 -1
  123. package/dist/web-types.json +190 -3
  124. package/package.json +19 -2
  125. package/dist/chunks/defaults-CFrjqae2.js +0 -59
  126. package/dist/chunks/defaults-CFrjqae2.js.map +0 -1
  127. package/dist/chunks/floating-B7_Dahpn.js +0 -54
  128. package/dist/chunks/floating-B7_Dahpn.js.map +0 -1
  129. package/dist/chunks/index-STEEvEP7.js.map +0 -1
  130. package/dist/chunks/kt-calendar-B_hFdD9V.js +0 -640
  131. package/dist/chunks/kt-calendar-B_hFdD9V.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"kt-date-picker.js","sources":["../../../../src/components/forms/kt-date-picker/kt-date-picker.ts"],"sourcesContent":["import { css, html, nothing, type PropertyValues, 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, toggleListener, uniqueId } from '#internal/events';\nimport {\n attachFormInternals,\n setFormValue,\n setValidity,\n type UsableInternals,\n} from '#internal/form-control';\nimport { FloatingController, floatingStyles } from '#internal/floating';\nimport { dateFormat, resolveLocale } from '#internal/locale';\nimport { strings } from '#internal/strings';\nimport { compareDates, parseDate, parseRange, toLocalDate, type PlainDate } from '#internal/date';\nimport '../kt-calendar/kt-calendar.js';\nimport type { KtCalendar } from '../kt-calendar/kt-calendar.js';\nimport '../../core/kt-icon/kt-icon.js';\n\nexport type KtDatePickerSize = 'small' | 'medium' | 'large';\n\n/**\n * A date field with a calendar, for one day or a period.\n *\n * The value is ISO 8601 text, the format a server and a `<input type=\"date\">`\n * already speak: `2026-09-25`, or `2026-09-01/2026-09-25` for a period. What\n * the field shows is the same date formatted for the reader's language, and\n * the calendar starts its weeks on the day their region does.\n *\n * The popup is a `<kt-calendar>`, with its keyboard model and its month and\n * year views: the WAI-ARIA date picker dialog pattern, where Escape closes the\n * dialog and hands focus back to the field, and tabbing out closes it too.\n *\n * @element kt-date-picker\n *\n * @csspart trigger - The field.\n * @csspart panel - The calendar popup.\n * @csspart calendar - The `<kt-calendar>` inside it.\n *\n * @fires kt-change - A date or a whole period was chosen, or the value cleared.\n * `detail: { value }` — the ISO date or interval, or `null`.\n *\n * @example\n * ```html\n * <kt-date-picker label=\"Due date\" name=\"due\" min=\"2026-01-01\"></kt-date-picker>\n * <kt-date-picker range label=\"Report period\" value=\"2026-09-01/2026-09-25\"></kt-date-picker>\n * ```\n */\nexport class KtDatePicker extends KtElement {\n static readonly formAssociated = true;\n\n static override styles = [\n KtElement.styles,\n floatingStyles,\n css`\n :host {\n position: relative;\n display: block;\n --field-height: var(--button-height);\n --day-size: 36px;\n }\n :host([size='small']) {\n --field-height: var(--button-height-small);\n }\n :host([size='large']) {\n --field-height: var(--button-height-large);\n }\n\n .field {\n position: relative;\n }\n\n .trigger {\n display: grid;\n grid-template-columns: 1fr auto;\n align-items: center;\n gap: var(--gap-element);\n width: 100%;\n height: var(--field-height);\n padding: 0 var(--button-padding-x);\n color: var(--text-body);\n font: var(--font-input);\n text-align: left;\n background-color: var(--color-dark-20);\n border: var(--border-width) solid var(--border-field);\n border-radius: var(--radius-input);\n outline: var(--outline-width) solid transparent;\n cursor: pointer;\n transition:\n background-color var(--duration-instant),\n outline-color var(--duration-instant);\n }\n .trigger:hover {\n outline: var(--outline-width) solid var(--color-text-700);\n }\n .trigger:focus-visible,\n .open .trigger {\n background-color: var(--color-dark-12);\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n .error .trigger,\n .error .trigger:hover {\n outline: var(--outline-width) solid var(--color-danger-base);\n }\n :host(:disabled) .trigger {\n color: var(--text-disabled);\n background-color: var(--color-dark-14);\n cursor: not-allowed;\n }\n\n .value {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n .placeholder {\n color: var(--text-muted);\n }\n\n .icons {\n display: inline-flex;\n align-items: center;\n gap: var(--gap-element);\n color: var(--text-muted);\n }\n /* Room for the clear button, which sits over the field, not inside the\n trigger: a button inside a button is not a thing assistive\n technology can operate. */\n .clearable .icons {\n padding-left: calc(18px + var(--gap-element));\n }\n .clear {\n position: absolute;\n top: 50%;\n /* Just left of the calendar icon, in the room .icons keeps for it. */\n right: calc(var(--button-padding-x) + 18px + var(--gap-element));\n display: inline-flex;\n padding: 0;\n color: var(--text-muted);\n background: none;\n border: none;\n border-radius: var(--radius-sub-menu);\n cursor: pointer;\n transform: translateY(-50%);\n }\n .clear:hover {\n color: var(--text-body);\n }\n .clear:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n\n /* Placed from the field by FloatingController. */\n .panel {\n box-sizing: border-box;\n padding: var(--padding-expand);\n background: var(--color-dark-20);\n border-radius: var(--radius-input);\n\n visibility: hidden;\n opacity: 0;\n transform: translateY(-6px);\n pointer-events: none;\n transition:\n opacity var(--duration-fast) var(--easing-standard),\n transform var(--duration-fast) var(--easing-standard),\n visibility 0s linear var(--duration-fast);\n }\n .panel.top:not(.open) {\n transform: translateY(6px);\n }\n .panel.open {\n visibility: visible;\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n transition:\n opacity var(--duration-fast) var(--easing-standard),\n transform var(--duration-fast) var(--easing-standard);\n }\n\n .panel kt-calendar {\n display: block;\n }\n `,\n ];\n\n @query('.trigger')\n private trigger?: HTMLButtonElement;\n\n @query('kt-calendar')\n private calendar?: KtCalendar;\n\n private internals: UsableInternals | null = null;\n private defaultValue: string | null = null;\n private readonly panelId = uniqueId('kt-date-picker-panel');\n\n @state() private open = false;\n @state() private placement: 'bottom' | 'top' = 'bottom';\n\n private floating = new FloatingController(this, {\n panel: () => this.shadowRoot?.querySelector<HTMLElement>('.panel'),\n anchor: () => this.shadowRoot?.querySelector('.trigger'),\n onPlace: (side) => {\n this.placement = side === 'top' ? 'top' : 'bottom';\n },\n });\n\n /** ISO date, or `start/end` interval with `range`. `null` when empty. */\n @property({ type: String, reflect: true })\n value: string | null = null;\n\n /** Choose a period — two dates — instead of one day. */\n @property({ type: Boolean, reflect: true })\n range = false;\n\n /** Earliest date that can be chosen, ISO. */\n @property({ type: String })\n min = '';\n\n /** Latest date that can be chosen, ISO. */\n @property({ type: String })\n max = '';\n\n @property({ type: String })\n name = '';\n\n /** Accessible name, when no `<kt-label-input>` wraps the field. */\n @property({ type: String })\n label = '';\n\n /** Shown while empty. Defaults to the strings registry. */\n @property({ type: String })\n placeholder: string | undefined = undefined;\n\n /**\n * BCP 47 language tag for formatting and for the first day of the week.\n * Empty: the page's `lang`, then the browser's language.\n */\n @property({ type: String })\n locale = '';\n\n @property({ type: String, reflect: true })\n size: KtDatePickerSize = 'medium';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Disabled by an enclosing `<fieldset>`, which leaves `disabled` alone. */\n @state()\n private formDisabled = false;\n\n /** Whether the control is off, by its own `disabled` or by its form. */\n private get inactive(): boolean {\n return this.disabled || this.formDisabled;\n }\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /** Shows a button that empties the field once it holds a value. */\n @property({ type: Boolean })\n clearable = true;\n\n /** Error message. A non-empty value puts the field in its error state. */\n @property({ type: String, reflect: true })\n error = '';\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.internals ??= attachFormInternals(this);\n this.defaultValue = this.value;\n // Back on the document if it was reconnected while open.\n toggleListener(this.open, document, 'pointerdown', this.onDocumentPointerDown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('pointerdown', this.onDocumentPointerDown);\n }\n\n // Untyped: `open` is private, so not among the keys PropertyValues<this> knows.\n override updated(changed: PropertyValues): void {\n // Only an open list closes on an outside click, so only an open one listens.\n if (changed.has('open')) {\n toggleListener(this.open, document, 'pointerdown', this.onDocumentPointerDown);\n }\n this.floating.sync(this.open);\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (\n changed.has('value') ||\n changed.has('range') ||\n changed.has('required') ||\n changed.has('error') ||\n this.stringsChanged(changed)\n ) {\n const complete = this.isComplete();\n setFormValue(this.internals, complete ? this.value : null);\n\n const missing = this.required && !complete;\n setValidity(\n this.internals,\n { valueMissing: missing, customError: Boolean(this.error) },\n this.error || (missing ? strings().dateRequired : ''),\n );\n }\n }\n\n formResetCallback(): void {\n this.value = this.defaultValue;\n this.close(false);\n }\n\n /**\n * Called by the platform when the control's disabled state changes — its\n * own `disabled`, or an ancestor `<fieldset disabled>` it cannot see.\n */\n formDisabledCallback(disabled: boolean): void {\n this.formDisabled = disabled;\n }\n\n formStateRestoreCallback(state: string | null): void {\n this.value = state;\n }\n\n override focus(options?: FocusOptions): void {\n this.trigger?.focus(options);\n }\n\n // --- Reading the value ---\n\n private get resolvedLocale(): string {\n return resolveLocale(this.locale);\n }\n\n private get selection(): { start: PlainDate | null; end: PlainDate | null } {\n return this.range\n ? parseRange(this.value)\n : { start: parseDate(this.value), end: parseDate(this.value) };\n }\n\n private isComplete(): boolean {\n const { start, end } = this.selection;\n return start !== null && end !== null && compareDates(start, end) <= 0;\n }\n\n private display(): string | null {\n const { start, end } = this.selection;\n if (!start || !end) return null;\n const format = dateFormat(this.resolvedLocale, { dateStyle: 'medium' });\n if (!this.range) return format.format(toLocalDate(start));\n return format.formatRange(toLocalDate(start), toLocalDate(end));\n }\n\n // --- Opening and closing ---\n\n private onDocumentPointerDown = (event: Event): void => {\n if (this.open && !event.composedPath().includes(this)) this.close(false);\n };\n\n /** Tabbing out of the calendar closes it; moving within it does not. */\n private onFocusOut = (event: FocusEvent): void => {\n const next = event.relatedTarget as Node | null;\n if (!this.open || !next) return;\n if (this.contains(next) || this.shadowRoot?.contains(next)) return;\n // Focus moving into the calendar's own shadow root is still inside.\n if (event.composedPath().includes(next)) return;\n if (this.calendar?.shadowRoot?.contains(next)) return;\n this.close(false);\n };\n\n private async show(): Promise<void> {\n if (this.inactive || this.open) return;\n this.open = true;\n\n // The calendar is rendered fresh on each opening — on the chosen day,\n // in its day view — and takes focus once it is there.\n await this.updateComplete;\n this.calendar?.focus();\n }\n\n private close(returnFocus: boolean): void {\n if (!this.open) return;\n this.open = false;\n if (returnFocus) this.focus();\n }\n\n private toggle(): void {\n if (this.open) this.close(false);\n else void this.show();\n }\n\n // --- Choosing ---\n\n private onCalendarChange(event: CustomEvent<{ value: string }>): void {\n // The calendar's own event stops here; the picker reports its value.\n event.stopPropagation();\n this.value = event.detail.value;\n this.close(true);\n emit(this, 'kt-change', { value: this.value });\n }\n\n private clear(): void {\n this.value = null;\n emit(this, 'kt-change', { value: null });\n this.focus();\n }\n\n // --- Keyboard ---\n\n private onTriggerKeyDown(event: KeyboardEvent): void {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n void this.show();\n }\n }\n\n private onPanelKeyDown(event: KeyboardEvent): void {\n // The calendar keeps Escape for itself while it shows months or years.\n if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n this.close(true);\n }\n }\n\n // --- Rendering ---\n\n override render(): TemplateResult {\n const shown = this.display();\n const placeholder =\n this.placeholder ?? (this.range ? strings().selectPeriod : strings().selectDate);\n const showClear = this.clearable && this.value !== null && !this.inactive;\n\n return html`${\n this.error\n ? html`<span id=\"error-message\" class=\"visually-hidden\">${this.error}</span>`\n : nothing\n }\n <div\n class=${classMap({\n field: true,\n open: this.open,\n error: Boolean(this.error),\n clearable: showClear,\n })}\n @focusout=${this.onFocusOut}\n >\n <button\n part=\"trigger\"\n type=\"button\"\n class=\"trigger\"\n aria-haspopup=\"dialog\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.panelId}\n aria-label=${this.label ? `${this.label}${shown ? `, ${shown}` : ''}` : nothing}\n aria-invalid=${this.error ? 'true' : nothing}\n aria-describedby=${this.error ? 'error-message' : nothing}\n ?disabled=${this.inactive}\n @click=${this.toggle}\n @keydown=${this.onTriggerKeyDown}\n >\n <span class=${classMap({ value: true, placeholder: !shown })}>\n ${shown ?? placeholder}\n </span>\n <span class=\"icons\"><kt-icon name=\"calendar\" size=\"18\"></kt-icon></span>\n </button>\n ${\n showClear\n ? html`<button\n type=\"button\"\n class=\"clear\"\n aria-label=${strings().clear}\n @click=${this.clear}\n >\n <kt-icon name=\"x\" size=\"18\"></kt-icon>\n </button>`\n : nothing\n }\n\n <div\n part=\"panel\"\n id=${this.panelId}\n popover=\"manual\"\n class=${classMap({\n panel: true,\n floating: true,\n open: this.open,\n top: this.placement === 'top',\n })}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-label=${this.range ? strings().selectPeriod : strings().selectDate}\n @keydown=${this.onPanelKeyDown}\n >\n ${\n this.open\n ? html`<kt-calendar\n part=\"calendar\"\n .value=${this.value}\n ?range=${this.range}\n min=${this.min}\n max=${this.max}\n locale=${this.locale}\n label=${this.label}\n @kt-change=${this.onCalendarChange}\n ></kt-calendar>`\n : nothing\n }\n </div>\n </div>`;\n }\n}\n\ndefineElement('kt-date-picker', KtDatePicker);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-date-picker': KtDatePicker;\n }\n}\n"],"names":["KtDatePicker","KtElement","uniqueId","FloatingController","side","event","next","floatingStyles","css","attachFormInternals","toggleListener","changed","complete","setFormValue","missing","setValidity","strings","disabled","state","options","resolveLocale","parseRange","parseDate","start","end","compareDates","format","dateFormat","toLocalDate","returnFocus","emit","shown","placeholder","showClear","html","nothing","classMap","__decorateClass","query","property","defineElement"],"mappings":"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"}
1
+ {"version":3,"file":"kt-date-picker.js","sources":["../../../../src/components/forms/kt-date-picker/kt-date-picker.ts"],"sourcesContent":["import { css, html, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { live } from 'lit/directives/live.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit, toggleListener, uniqueId } from '#internal/events';\nimport {\n attachFormInternals,\n setFormValue,\n setValidity,\n type UsableInternals,\n} from '#internal/form-control';\nimport { FloatingController, floatingStyles } from '#internal/floating';\nimport { dateFormat, resolveLocale } from '#internal/locale';\nimport { strings } from '#internal/strings';\nimport {\n addDays,\n addMonths,\n compareDates,\n daysInMonth,\n formatDate,\n formatRange,\n parseDate,\n parseRange,\n toLocalDate,\n today,\n type PlainDate,\n} from '#internal/date';\nimport { exampleDate, parseTypedDate, parseTypedRange } from '#internal/typed-date';\nimport '../kt-calendar/kt-calendar.js';\nimport type { KtCalendar } from '../kt-calendar/kt-calendar.js';\nimport '../../core/kt-icon/kt-icon.js';\nimport '../../feedback/kt-tooltip/kt-tooltip.js';\n\nexport type KtDatePickerSize = 'small' | 'medium' | 'large';\n\n/** A ready-made period offered beside the calendar: a label and an ISO interval. */\nexport interface KtDatePreset {\n readonly label: string;\n readonly value: string;\n}\n\n/**\n * The periods a dashboard asks for most, ending today. \"This month\" and \"This\n * year\" run to today, not to the end of the month or year: there is no data\n * in the days still to come.\n */\nfunction defaultPresets(): KtDatePreset[] {\n const s = strings();\n const now = today();\n const firstOfMonth = { ...now, day: 1 };\n const lastMonth = addMonths(firstOfMonth, -1);\n const period = (start: PlainDate, end: PlainDate) => formatRange(start, end);\n return [\n { label: s.presetToday, value: period(now, now) },\n { label: s.presetLast7Days, value: period(addDays(now, -6), now) },\n { label: s.presetLast30Days, value: period(addDays(now, -29), now) },\n { label: s.presetThisMonth, value: period(firstOfMonth, now) },\n {\n label: s.presetLastMonth,\n value: period(lastMonth, {\n ...lastMonth,\n day: daysInMonth(lastMonth.year, lastMonth.month),\n }),\n },\n { label: s.presetThisYear, value: period({ year: now.year, month: 1, day: 1 }, now) },\n ];\n}\n\n/**\n * A date field with a calendar, for one day or a period.\n *\n * The value is ISO 8601 text, the format a server and a `<input type=\"date\">`\n * already speak: `2026-09-25`, or `2026-09-01/2026-09-25` for a period. What\n * the field shows is the same date formatted for the reader's language, and\n * the calendar starts its weeks on the day their region does.\n *\n * The field takes a date typed the way the reader writes it — `25/09/2026` in\n * London, `9/25/2026` in New York, `25 sept.` in Paris, ISO anywhere — on Enter\n * or when it is left. What does not read as a date is flagged, and the value\n * it had is kept.\n *\n * The popup is a `<kt-calendar>`, with its keyboard model and its month and\n * year views: the WAI-ARIA date picker dialog pattern, where Escape closes the\n * dialog and hands focus back to the field, and tabbing out closes it too.\n *\n * @element kt-date-picker\n *\n * @csspart field - The field.\n * @csspart input - The text the date is typed into.\n * @csspart trigger - The button that opens the calendar.\n * @csspart panel - The calendar popup.\n * @csspart presets - The column of ready-made periods, with `range`.\n * @csspart calendar - The `<kt-calendar>` inside it.\n *\n * @fires kt-change - A date or a whole period was chosen, or the value cleared.\n * `detail: { value }` — the ISO date or interval, or `null`.\n *\n * @example\n * ```html\n * <kt-date-picker label=\"Due date\" name=\"due\" min=\"2026-01-01\"></kt-date-picker>\n * <kt-date-picker range label=\"Report period\" value=\"2026-09-01/2026-09-25\"></kt-date-picker>\n * ```\n */\nexport class KtDatePicker extends KtElement {\n static readonly formAssociated = true;\n\n static override styles = [\n KtElement.styles,\n floatingStyles,\n css`\n :host {\n position: relative;\n display: block;\n --field-height: var(--button-height);\n }\n :host([size='small']) {\n --field-height: var(--button-height-small);\n }\n :host([size='large']) {\n --field-height: var(--button-height-large);\n }\n\n /* The field, as kt-input draws one: a fill with a resting hairline, an\n outline on hover and focus that never reflows it. */\n .field {\n display: flex;\n align-items: center;\n gap: 2px;\n height: var(--field-height);\n padding: 0 10px 0 4px;\n color: var(--text-body);\n background-color: var(--color-dark-20);\n border: var(--border-width) solid var(--border-field);\n border-radius: var(--radius-input);\n outline: var(--outline-width) solid transparent;\n transition:\n background-color var(--duration-instant),\n outline-color var(--duration-instant);\n }\n .field:hover {\n outline: var(--outline-width) solid var(--color-text-700);\n }\n .field:focus-within,\n .open .field {\n background-color: var(--color-dark-12);\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n .error .field,\n .error .field:hover,\n .error .field:focus-within {\n outline: var(--outline-width) solid var(--color-danger-base);\n }\n :host(:disabled) .field {\n color: var(--text-disabled);\n background-color: var(--color-dark-14);\n }\n\n /* The calendar button leads: it says what kind of field this is. */\n .trigger,\n .clear {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n padding: 0;\n color: var(--text-muted);\n background: none;\n border: none;\n border-radius: calc(var(--radius-input) - 2px);\n cursor: pointer;\n transition:\n background-color var(--duration-instant),\n color var(--duration-instant);\n }\n .trigger {\n width: calc(var(--field-height) - 10px);\n height: calc(var(--field-height) - 10px);\n }\n .trigger:hover,\n .open .trigger {\n color: var(--text-body);\n background: var(--color-dark-22);\n }\n .clear:hover {\n color: var(--text-body);\n }\n .trigger:focus-visible,\n .clear:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n :host(:disabled) .trigger {\n cursor: not-allowed;\n }\n\n input {\n flex: 1;\n min-width: 0;\n height: 100%;\n padding: 0 4px;\n color: inherit;\n font: var(--font-input);\n background: transparent;\n border: none;\n outline: none;\n }\n input::placeholder {\n color: var(--text-muted);\n }\n .error input {\n color: var(--color-danger-text);\n }\n\n .error-icon {\n flex: none;\n color: var(--color-danger-text);\n }\n\n /* Placed from the field by FloatingController. */\n .panel {\n box-sizing: border-box;\n padding: var(--padding-expand);\n background: var(--surface-popover);\n border-radius: var(--radius-input);\n\n visibility: hidden;\n opacity: 0;\n transform: translateY(-6px);\n pointer-events: none;\n transition:\n opacity var(--duration-fast) var(--easing-standard),\n transform var(--duration-fast) var(--easing-standard),\n visibility 0s linear var(--duration-fast);\n }\n .panel.top:not(.open) {\n transform: translateY(6px);\n }\n .panel.open {\n visibility: visible;\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n transition:\n opacity var(--duration-fast) var(--easing-standard),\n transform var(--duration-fast) var(--easing-standard);\n }\n\n .panel kt-calendar {\n display: block;\n }\n\n .panel-body {\n display: flex;\n gap: 12px;\n }\n\n /* Ready-made periods: the quickest way to a period, so they lead. */\n .presets {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 128px;\n padding-right: 12px;\n border-right: var(--border-width) solid var(--divider-popover);\n }\n .presets button,\n .today {\n height: 32px;\n padding: 0 10px;\n color: var(--text-body);\n font: var(--font-normal-regular);\n text-align: left;\n white-space: nowrap;\n background: none;\n border: none;\n border-radius: var(--radius-input);\n cursor: pointer;\n }\n .presets button:hover:not(:disabled),\n .today:hover:not(:disabled) {\n background: var(--color-dark-22);\n }\n .presets button[aria-pressed='true'] {\n color: var(--color-primary-text);\n font-weight: 600;\n background: var(--color-primary-soft);\n }\n .presets button:disabled,\n .today:disabled {\n color: var(--text-disabled);\n cursor: not-allowed;\n }\n .presets button:focus-visible,\n .today:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n\n /* On a narrow screen the periods wrap in a row above the one month. */\n .panel-body.compact {\n flex-direction: column;\n }\n .compact .presets {\n flex-direction: row;\n flex-wrap: wrap;\n min-width: 0;\n max-width: calc(var(--day-size, 32px) * 7);\n padding: 0 0 8px;\n border-right: none;\n border-bottom: var(--border-width) solid var(--divider-popover);\n }\n\n .footer {\n display: flex;\n justify-content: flex-start;\n margin-top: var(--gap-element);\n padding-top: var(--gap-element);\n border-top: var(--border-width) solid var(--divider-popover);\n }\n .today {\n color: var(--color-primary-text);\n font-weight: 600;\n }\n `,\n ];\n\n @query('input')\n private input?: HTMLInputElement;\n\n @query('kt-calendar')\n private calendar?: KtCalendar;\n\n private internals: UsableInternals | null = null;\n private defaultValue: string | null = null;\n private readonly panelId = uniqueId('kt-date-picker-panel');\n\n @state() private open = false;\n /** What is typed, while it differs from the value shown. */\n @state() private text = '';\n @state() private editing = false;\n /** Why the typed text was turned down, if it was. */\n @state() private typedError = '';\n @state() private focused = false;\n /** Set at each opening on a narrow screen: one month, the periods above it. */\n @state() private compact = false;\n @state() private placement: 'bottom' | 'top' = 'bottom';\n\n private floating = new FloatingController(this, {\n panel: () => this.shadowRoot?.querySelector<HTMLElement>('.panel'),\n anchor: () => this.shadowRoot?.querySelector('.field'),\n onPlace: (side) => {\n this.placement = side === 'top' ? 'top' : 'bottom';\n },\n });\n\n /** ISO date, or `start/end` interval with `range`. `null` when empty. */\n @property({ type: String, reflect: true })\n value: string | null = null;\n\n /** Choose a period — two dates — instead of one day. */\n @property({ type: Boolean, reflect: true })\n range = false;\n\n /** Earliest date that can be chosen, ISO. */\n @property({ type: String })\n min = '';\n\n /** Latest date that can be chosen, ISO. */\n @property({ type: String })\n max = '';\n\n @property({ type: String })\n name = '';\n\n /** Accessible name, when no `<kt-label-input>` wraps the field. */\n @property({ type: String })\n label = '';\n\n /** Shown while empty. Defaults to the strings registry. */\n @property({ type: String })\n placeholder: string | undefined = undefined;\n\n /**\n * BCP 47 language tag for formatting and for the first day of the week.\n * Empty: the page's `lang`, then the browser's language.\n */\n @property({ type: String })\n locale = '';\n\n @property({ type: String, reflect: true })\n size: KtDatePickerSize = 'medium';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Disabled by an enclosing `<fieldset>`, which leaves `disabled` alone. */\n @state()\n private formDisabled = false;\n\n /** Whether the control is off, by its own `disabled` or by its form. */\n private get inactive(): boolean {\n return this.disabled || this.formDisabled;\n }\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /** Shows a button that empties the field once it holds a value. */\n @property({ type: Boolean })\n clearable = true;\n\n /**\n * Ready-made periods offered beside the calendar, with `range`. Unset: the\n * periods a dashboard asks for most — today, the last 7 and 30 days, this\n * month and last, this year. An empty list hides the column.\n */\n @property({ attribute: false })\n presets: readonly KtDatePreset[] | undefined = undefined;\n\n /** Error message. A non-empty value puts the field in its error state. */\n @property({ type: String, reflect: true })\n error = '';\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.internals ??= attachFormInternals(this);\n this.defaultValue = this.value;\n // Back on the document if it was reconnected while open.\n toggleListener(this.open, document, 'pointerdown', this.onDocumentPointerDown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('pointerdown', this.onDocumentPointerDown);\n }\n\n // Untyped: `open` is private, so not among the keys PropertyValues<this> knows.\n override updated(changed: PropertyValues): void {\n // Only an open list closes on an outside click, so only an open one listens.\n if (changed.has('open')) {\n toggleListener(this.open, document, 'pointerdown', this.onDocumentPointerDown);\n }\n this.floating.sync(this.open);\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (\n changed.has('value') ||\n changed.has('range') ||\n changed.has('required') ||\n changed.has('error') ||\n changed.has('typedError' as keyof KtDatePicker) ||\n this.stringsChanged(changed)\n ) {\n const complete = this.isComplete();\n setFormValue(this.internals, complete ? this.value : null);\n\n const missing = this.required && !complete;\n setValidity(\n this.internals,\n {\n valueMissing: missing,\n badInput: Boolean(this.typedError),\n customError: Boolean(this.error),\n },\n this.error || this.typedError || (missing ? strings().dateRequired : ''),\n );\n }\n }\n\n formResetCallback(): void {\n this.value = this.defaultValue;\n this.editing = false;\n this.typedError = '';\n this.close(false);\n }\n\n /**\n * Called by the platform when the control's disabled state changes — its\n * own `disabled`, or an ancestor `<fieldset disabled>` it cannot see.\n */\n formDisabledCallback(disabled: boolean): void {\n this.formDisabled = disabled;\n }\n\n formStateRestoreCallback(state: string | null): void {\n this.value = state;\n }\n\n override focus(options?: FocusOptions): void {\n this.input?.focus(options);\n }\n\n // --- Reading the value ---\n\n private get resolvedLocale(): string {\n return resolveLocale(this.locale);\n }\n\n private get selection(): { start: PlainDate | null; end: PlainDate | null } {\n return this.range\n ? parseRange(this.value)\n : { start: parseDate(this.value), end: parseDate(this.value) };\n }\n\n private isComplete(): boolean {\n const { start, end } = this.selection;\n return start !== null && end !== null && compareDates(start, end) <= 0;\n }\n\n private display(): string | null {\n const { start, end } = this.selection;\n if (!start || !end) return null;\n const format = dateFormat(this.resolvedLocale, { dateStyle: 'medium' });\n if (!this.range) return format.format(toLocalDate(start));\n return format.formatRange(toLocalDate(start), toLocalDate(end));\n }\n\n // --- Opening and closing ---\n\n private onDocumentPointerDown = (event: Event): void => {\n if (this.open && !event.composedPath().includes(this)) this.close(false);\n };\n\n /** Tabbing out of the calendar closes it; moving within it does not. */\n private onFocusOut = (event: FocusEvent): void => {\n const next = event.relatedTarget as Node | null;\n if (!this.open || !next) return;\n if (this.contains(next) || this.shadowRoot?.contains(next)) return;\n // Focus moving into the calendar's own shadow root is still inside.\n if (event.composedPath().includes(next)) return;\n if (this.calendar?.shadowRoot?.contains(next)) return;\n this.close(false);\n };\n\n /** Below this width, a period's two months and their periods do not fit. */\n private static readonly WIDE_ENOUGH = 720;\n\n private async show(): Promise<void> {\n if (this.inactive || this.open) return;\n this.compact = window.innerWidth < KtDatePicker.WIDE_ENOUGH;\n this.open = true;\n\n // The calendar is rendered fresh on each opening — on the chosen day,\n // in its day view — and takes focus once it is there.\n await this.updateComplete;\n this.calendar?.focus();\n }\n\n private close(returnFocus: boolean): void {\n if (!this.open) return;\n this.open = false;\n if (returnFocus) this.focus();\n }\n\n private toggle(): void {\n if (this.open) this.close(true);\n else void this.show();\n }\n\n /** A click in the text opens the calendar, leaving the focus to type. */\n private openForTyping(): void {\n if (this.inactive || this.open) return;\n this.compact = window.innerWidth < KtDatePicker.WIDE_ENOUGH;\n this.open = true;\n }\n\n // --- Choosing ---\n\n private onCalendarChange(event: CustomEvent<{ value: string }>): void {\n // The calendar's own event stops here; the picker reports its value.\n event.stopPropagation();\n this.editing = false;\n this.typedError = '';\n this.value = event.detail.value;\n this.close(true);\n emit(this, 'kt-change', { value: this.value });\n }\n\n /** A preset, or today: committed at once, the calendar closed. */\n private apply(value: string): void {\n this.editing = false;\n this.typedError = '';\n this.close(true);\n if (value === this.value) return;\n this.value = value;\n emit(this, 'kt-change', { value });\n }\n\n /** Whether any of a period falls outside min and max. */\n private outOfBounds(value: string): boolean {\n const { start, end } = parseRange(value);\n const min = parseDate(this.min);\n const max = parseDate(this.max);\n if (!start || !end) return true;\n return (\n (min !== null && compareDates(start, min) < 0) || (max !== null && compareDates(end, max) > 0)\n );\n }\n\n private renderPresets(): TemplateResult | typeof nothing {\n const presets = this.presets ?? defaultPresets();\n if (!this.range || presets.length === 0) return nothing;\n return html`<div\n part=\"presets\"\n class=\"presets\"\n role=\"group\"\n aria-label=${strings().selectPeriod}\n >\n ${presets.map(\n (preset) =>\n html`<button\n type=\"button\"\n aria-pressed=${preset.value === this.value ? 'true' : 'false'}\n ?disabled=${this.outOfBounds(preset.value)}\n @click=${() => this.apply(preset.value)}\n >\n ${preset.label}\n </button>`,\n )}\n </div>`;\n }\n\n private clear(): void {\n this.editing = false;\n this.typedError = '';\n this.value = null;\n emit(this, 'kt-change', { value: null });\n this.focus();\n }\n\n // --- Typing ---\n\n private onInput(event: Event): void {\n this.text = (event.target as HTMLInputElement).value;\n this.editing = true;\n }\n\n /**\n * Reads what was typed into the value. Text that is not a date, or is a date\n * outside min and max, is flagged and the value kept; an empty field empties\n * the value.\n */\n private commitTyped(): void {\n if (!this.editing) return;\n this.editing = false;\n const typed = this.text.trim();\n\n if (!typed) {\n this.typedError = '';\n if (this.value !== null) {\n this.value = null;\n emit(this, 'kt-change', { value: null });\n }\n return;\n }\n\n const locale = this.resolvedLocale;\n const now = today();\n const read = this.range\n ? parseTypedRange(typed, locale, now)\n : (() => {\n const date = parseTypedDate(typed, locale, now);\n return date && { start: date, end: date };\n })();\n if (!read) {\n this.text = typed;\n this.editing = true;\n this.typedError = strings().dateInvalid(exampleDate(locale, now));\n return;\n }\n\n const min = parseDate(this.min);\n const max = parseDate(this.max);\n if ((min && compareDates(read.start, min) < 0) || (max && compareDates(read.end, max) > 0)) {\n this.text = typed;\n this.editing = true;\n this.typedError = strings().dateOutOfRange;\n return;\n }\n\n this.typedError = '';\n const value = this.range ? formatRange(read.start, read.end) : formatDate(read.start);\n if (value !== this.value) {\n this.value = value;\n emit(this, 'kt-change', { value });\n }\n }\n\n // --- Keyboard ---\n\n private onInputKeyDown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'Enter':\n event.preventDefault();\n this.commitTyped();\n if (!this.typedError) this.close(false);\n return;\n case 'Escape':\n // Puts the text back, and closes the calendar if it was open.\n if (!this.editing && !this.open) return;\n event.preventDefault();\n event.stopPropagation();\n this.editing = false;\n this.typedError = '';\n this.close(false);\n return;\n case 'ArrowDown':\n event.preventDefault();\n void this.show();\n }\n }\n\n private onPanelKeyDown(event: KeyboardEvent): void {\n // The calendar keeps Escape for itself while it shows months and years.\n if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n this.close(true);\n }\n }\n\n // --- Rendering ---\n\n override render(): TemplateResult {\n const s = strings();\n const shown = this.display();\n const placeholder = this.placeholder ?? (this.range ? s.selectPeriod : s.selectDate);\n const error = this.error || this.typedError;\n const showClear =\n this.clearable && this.value !== null && !this.inactive && !this.editing && !error;\n\n return html`${\n error ? html`<span id=\"error-message\" class=\"visually-hidden\">${error}</span>` : nothing\n }\n <div\n class=${classMap({ open: this.open, error: Boolean(error) })}\n @focusout=${this.onFocusOut}\n >\n <div part=\"field\" class=\"field\">\n <button\n part=\"trigger\"\n type=\"button\"\n class=\"trigger\"\n tabindex=\"-1\"\n aria-label=${s.openCalendar}\n aria-haspopup=\"dialog\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.panelId}\n ?disabled=${this.inactive}\n @click=${this.toggle}\n >\n <kt-icon name=\"calendar\" size=\"18\"></kt-icon>\n </button>\n <input\n part=\"input\"\n .value=${live(this.editing ? this.text : (shown ?? ''))}\n placeholder=${placeholder}\n autocomplete=\"off\"\n aria-label=${this.label || placeholder}\n aria-invalid=${error ? 'true' : nothing}\n aria-describedby=${error ? 'error-message' : nothing}\n ?disabled=${this.inactive}\n @input=${this.onInput}\n @change=${this.commitTyped}\n @keydown=${this.onInputKeyDown}\n @click=${this.openForTyping}\n @focus=${() => {\n this.focused = true;\n }}\n @blur=${() => {\n this.focused = false;\n }}\n />\n ${\n error\n ? html`<kt-tooltip class=\"error-icon\" text=${error} ?open=${this.focused}>\n <kt-icon name=\"circle-alert\" size=\"18\"></kt-icon>\n </kt-tooltip>`\n : nothing\n }\n ${\n showClear\n ? html`<button type=\"button\" class=\"clear\" aria-label=${s.clear} @click=${this.clear}>\n <kt-icon name=\"x\" size=\"18\"></kt-icon>\n </button>`\n : nothing\n }\n </div>\n\n <div\n part=\"panel\"\n id=${this.panelId}\n popover=\"manual\"\n class=${classMap({\n panel: true,\n floating: true,\n open: this.open,\n top: this.placement === 'top',\n })}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-label=${this.range ? s.selectPeriod : s.selectDate}\n @keydown=${this.onPanelKeyDown}\n >\n ${\n this.open\n ? html`<div class=${classMap({ 'panel-body': true, compact: this.compact })}>\n ${this.renderPresets()}\n <div>\n <kt-calendar\n part=\"calendar\"\n .value=${this.value}\n ?range=${this.range}\n months=${this.range && !this.compact ? 2 : 1}\n min=${this.min}\n max=${this.max}\n locale=${this.locale}\n label=${this.label}\n @kt-change=${this.onCalendarChange}\n ></kt-calendar>\n ${\n this.range\n ? nothing\n : html`<div class=\"footer\">\n <button\n type=\"button\"\n class=\"today\"\n ?disabled=${this.outOfBounds(formatRange(today(), today()))}\n @click=${() => this.apply(formatDate(today()))}\n >\n ${s.presetToday}\n </button>\n </div>`\n }\n </div>\n </div>`\n : nothing\n }\n </div>\n </div>`;\n }\n}\n\ndefineElement('kt-date-picker', KtDatePicker);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-date-picker': KtDatePicker;\n }\n}\n"],"names":["defaultPresets","s","strings","now","today","firstOfMonth","lastMonth","addMonths","period","start","end","formatRange","addDays","daysInMonth","_KtDatePicker","KtElement","uniqueId","FloatingController","side","event","next","floatingStyles","css","attachFormInternals","toggleListener","changed","complete","setFormValue","missing","setValidity","disabled","state","options","resolveLocale","parseRange","parseDate","compareDates","format","dateFormat","toLocalDate","returnFocus","emit","value","min","max","presets","nothing","html","preset","typed","locale","read","parseTypedRange","date","parseTypedDate","exampleDate","formatDate","shown","placeholder","error","showClear","classMap","live","__decorateClass","query","property","KtDatePicker","defineElement"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { css as v, nothing as p, html as c } from "lit";
2
2
  import { query as y, state as f, property as n } from "lit/decorators.js";
3
3
  import { classMap as b } from "lit/directives/class-map.js";
4
- import { K as u, d as x } from "../../../chunks/kt-element-Djx2JcGl.js";
4
+ import { K as u, d as x } from "../../../chunks/kt-element-T0VbIBNp.js";
5
5
  import { e as h } from "../../../chunks/events-r51msXNf.js";
6
6
  import { a as k, s as $, b as w } from "../../../chunks/form-control-B74_EHtG.js";
7
- import { s as l } from "../../../chunks/index-STEEvEP7.js";
7
+ import { s as l } from "../../../chunks/index-TWJzttLX.js";
8
8
  import "../../core/kt-icon/kt-icon.js";
9
9
  import "../../core/kt-button/kt-button.js";
10
10
  const g = ["B", "KB", "MB", "GB", "TB"];
@@ -127,7 +127,7 @@ class i extends u {
127
127
  overflow: hidden;
128
128
  color: var(--color-info-text);
129
129
  background: var(--color-dark-14);
130
- border-radius: 6px;
130
+ border-radius: calc(6px * var(--radius-scale, 1));
131
131
  }
132
132
 
133
133
  .info {
@@ -1 +1 @@
1
- {"version":3,"file":"kt-drag-drop.js","sources":["../../../../src/internal/format.ts","../../../../src/components/forms/kt-drag-drop/kt-drag-drop.ts"],"sourcesContent":["/** Formatting helpers shared by elements that display data. */\n\nconst UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const;\n\n/**\n * A human-readable file size.\n *\n * Uses 1024 steps, matching what every desktop file manager shows, and one\n * decimal above a kilobyte — \"1.4 MB\" reads; \"1468006 B\" does not.\n */\nexport function formatFileSize(bytes: number): string {\n if (!Number.isFinite(bytes) || bytes < 0) return '';\n\n let value = bytes;\n let unit = 0;\n while (value >= 1024 && unit < UNITS.length - 1) {\n value /= 1024;\n unit += 1;\n }\n\n const rounded = unit === 0 ? String(Math.round(value)) : value.toFixed(1);\n return `${rounded} ${UNITS[unit]}`;\n}\n","import { css, html, nothing, type PropertyValues, 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 {\n attachFormInternals,\n setFormValue,\n setValidity,\n type UsableInternals,\n} from '#internal/form-control';\nimport { formatFileSize } from '#internal/format';\nimport { strings } from '#internal/strings';\nimport '../../core/kt-icon/kt-icon.js';\nimport '../../core/kt-button/kt-button.js';\n\n/**\n * A file drop zone.\n *\n * Accepts a drop or a click, lists what was picked with sizes and types, and\n * lets each entry be removed. It holds the files in memory and reports them —\n * uploading is the application's business.\n *\n * @element kt-drag-drop\n *\n * @csspart base - The dashed drop zone.\n * @csspart list - The list of chosen files.\n *\n * @fires kt-files-change - The selection changed. `detail: { files }`.\n * @fires kt-files-rejected - Files were refused. `detail: { files, reason }`.\n *\n * @example\n * ```html\n * <kt-drag-drop accept=\"image/*\" recommended-size=\"800×400px\"></kt-drag-drop>\n * ```\n */\nexport class KtDragDrop extends KtElement {\n static readonly formAssociated = true;\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n user-select: none;\n }\n\n .zone {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--gap-drag-drop);\n padding: var(--padding-drag-drop);\n border: var(--border-width) dashed var(--color-dark-24);\n border-radius: var(--border-radius);\n cursor: pointer;\n transition:\n border-color var(--duration-instant),\n box-shadow var(--duration-instant);\n }\n\n .zone:hover {\n border-color: var(--text-muted);\n }\n\n .zone:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n }\n\n .dragover {\n border-color: var(--color-primary-base);\n box-shadow: 0 0 0 6px var(--color-primary-soft);\n }\n\n .prompt {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--gap-button);\n text-align: center;\n }\n\n .prompt-icon {\n color: var(--text-muted);\n }\n\n .title {\n margin: 0;\n color: var(--color-primary-text);\n font: var(--font-normal-medium);\n }\n\n .hint {\n color: var(--text-muted);\n font: var(--font-normal-small);\n }\n\n input[type='file'] {\n display: none;\n }\n\n .list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n width: 100%;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .item {\n display: flex;\n align-items: center;\n gap: 12px;\n width: 100%;\n padding: 12px;\n background: var(--surface-raised);\n border-radius: var(--border-radius);\n cursor: default;\n transition: background var(--duration-normal) var(--easing-standard);\n }\n .item:hover {\n background: var(--surface-hover);\n }\n\n .preview {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n overflow: hidden;\n color: var(--color-info-text);\n background: var(--color-dark-14);\n border-radius: 6px;\n }\n\n .info {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n }\n\n .name {\n overflow: hidden;\n color: var(--text-body);\n font: var(--font-normal-medium);\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .details {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--text-muted);\n font: var(--font-normal-small);\n }\n `,\n ];\n\n @query('input[type=\"file\"]')\n private fileInput!: HTMLInputElement;\n\n private internals: UsableInternals | null = null;\n\n @state()\n private dragging = false;\n\n @state()\n private files: File[] = [];\n\n /**\n * The prompt above the browse link.\n *\n * Named `heading`, not `title`: an element already has a `title`, and\n * reusing it would put the prompt in a native tooltip on the whole zone.\n */\n @property({ type: String })\n heading: string | undefined = undefined;\n\n /** The clickable-looking part of the prompt. */\n @property({ type: String, attribute: 'link-text' })\n linkText: string | undefined = undefined;\n\n /** Optional hint, e.g. `800×400px`. */\n @property({ type: String, attribute: 'recommended-size' })\n recommendedSize = '';\n\n @property({ type: Boolean })\n multiple = true;\n\n /** Same syntax as the native `accept`: `image/*`, `.pdf,.docx`. */\n @property({ type: String })\n accept = '';\n\n /** Largest accepted file, in bytes. Zero means no limit. */\n @property({ type: Number, attribute: 'max-size' })\n maxSize = 0;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Disabled by an enclosing `<fieldset>`, which leaves `disabled` alone. */\n @state()\n private formDisabled = false;\n\n /** Whether the control is off, by its own `disabled` or by its form. */\n private get inactive(): boolean {\n return this.disabled || this.formDisabled;\n }\n\n /** The files are submitted under this name, as by `<input type=\"file\">`. */\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 }\n\n // Untyped: `files` is private state, which PropertyValues<this> cannot name.\n override willUpdate(changed: PropertyValues): void {\n if (\n changed.has('files') ||\n changed.has('name') ||\n changed.has('required') ||\n this.stringsChanged(changed)\n ) {\n this.syncFormValue();\n }\n }\n\n private syncFormValue(): void {\n // Like a native file input: nothing is submitted without a name or without\n // a file, and each file is its own entry under the one name.\n let value: FormData | null = null;\n if (this.name && this.files.length > 0) {\n value = new FormData();\n for (const file of this.files) value.append(this.name, file);\n }\n setFormValue(this.internals, value);\n\n const missing = this.required && this.files.length === 0;\n setValidity(this.internals, { valueMissing: missing }, missing ? strings().selectFile : '');\n }\n\n formResetCallback(): void {\n this.files = [];\n this.dragging = false;\n }\n\n /**\n * Called by the platform when the control's disabled state changes — its\n * own `disabled`, or an ancestor `<fieldset disabled>` it cannot see.\n */\n formDisabledCallback(disabled: boolean): void {\n this.formDisabled = disabled;\n }\n\n formStateRestoreCallback(state: string | File | FormData | null): void {\n if (!(state instanceof FormData) || !this.name) return;\n this.files = state.getAll(this.name).filter((entry): entry is File => entry instanceof File);\n }\n\n /** The files currently held, newest last. */\n get selectedFiles(): readonly File[] {\n return this.files;\n }\n\n /** Empties the selection without firing a rejection. */\n clear(): void {\n this.files = [];\n emit(this, 'kt-files-change', { files: this.files });\n }\n\n /**\n * `accept` is advisory on a native input — the OS dialog filters, but a\n * dropped file bypasses it entirely — so the same rules are enforced here.\n */\n private accepts(file: File): boolean {\n if (this.maxSize > 0 && file.size > this.maxSize) return false;\n if (!this.accept) return true;\n\n return this.accept\n .split(',')\n .map((pattern) => pattern.trim().toLowerCase())\n .filter(Boolean)\n .some((pattern) => {\n if (pattern.startsWith('.')) return file.name.toLowerCase().endsWith(pattern);\n if (pattern.endsWith('/*')) return file.type.startsWith(pattern.slice(0, -1));\n return file.type.toLowerCase() === pattern;\n });\n }\n\n private addFiles(incoming: FileList | null): void {\n if (!incoming || incoming.length === 0) return;\n\n const candidates = this.multiple ? [...incoming] : [...incoming].slice(0, 1);\n const accepted = candidates.filter((file) => this.accepts(file));\n const rejected = candidates.filter((file) => !this.accepts(file));\n\n if (rejected.length > 0) {\n emit(this, 'kt-files-rejected', {\n files: rejected,\n reason: this.maxSize > 0 && rejected.some((f) => f.size > this.maxSize) ? 'size' : 'type',\n });\n }\n if (accepted.length === 0) return;\n\n this.files = this.multiple ? [...this.files, ...accepted] : accepted;\n emit(this, 'kt-files-change', { files: this.files });\n }\n\n private removeAt(index: number): void {\n this.files = this.files.filter((_, position) => position !== index);\n emit(this, 'kt-files-change', { files: this.files });\n }\n\n private browse(): void {\n if (this.inactive) return;\n this.fileInput?.click();\n }\n\n private onZoneKeyDown(event: KeyboardEvent): void {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n this.browse();\n }\n\n private onDragOver(event: DragEvent): void {\n if (this.inactive) return;\n event.preventDefault();\n this.dragging = true;\n }\n\n private onDrop(event: DragEvent): void {\n if (this.inactive) return;\n event.preventDefault();\n this.dragging = false;\n this.addFiles(event.dataTransfer?.files ?? null);\n }\n\n override render(): TemplateResult {\n return html`<div\n part=\"base\"\n class=${classMap({ zone: true, dragover: this.dragging })}\n role=\"button\"\n tabindex=${this.inactive ? -1 : 0}\n aria-disabled=${this.inactive ? 'true' : nothing}\n aria-label=${`${this.heading ?? strings().dragAndDrop} ${this.linkText ?? strings().browseFiles}`}\n @click=${this.browse}\n @keydown=${this.onZoneKeyDown}\n @dragover=${this.onDragOver}\n @dragleave=${() => {\n this.dragging = false;\n }}\n @drop=${this.onDrop}\n >\n <input\n type=\"file\"\n ?multiple=${this.multiple}\n accept=${this.accept || nothing}\n @click=${(event: Event) => event.stopPropagation()}\n @change=${(event: Event) => this.addFiles((event.target as HTMLInputElement).files)}\n />\n\n <div class=\"prompt\">\n <span class=\"prompt-icon\"><kt-icon name=\"file-up\" size=\"24\"></kt-icon></span>\n <div>\n <p class=\"title\">\n ${this.heading ?? strings().dragAndDrop} ${this.linkText ?? strings().browseFiles}\n </p>\n ${\n this.recommendedSize\n ? html`<div class=\"hint\">${strings().recommendedSize(this.recommendedSize)}</div>`\n : nothing\n }\n </div>\n </div>\n\n ${\n this.files.length > 0\n ? html`<ul\n part=\"list\"\n class=\"list\"\n aria-label=${strings().selectedFiles}\n @click=${(event: Event) => event.stopPropagation()}\n >\n ${this.files.map(\n (file, index) =>\n html`<li class=\"item\">\n <span class=\"preview\"><kt-icon name=\"file\" size=\"24\"></kt-icon></span>\n <span class=\"info\">\n <span class=\"name\" title=${file.name}>${file.name}</span>\n <span class=\"details\">\n <span>${formatFileSize(file.size)}</span>\n ${file.type ? html`<span>•</span><span>${file.type}</span>` : nothing}\n </span>\n </span>\n <kt-button\n variant=\"danger\"\n size=\"small\"\n icon=\"trash-2\"\n label=${strings().remove(file.name)}\n @click=${() => this.removeAt(index)}\n ></kt-button>\n </li>`,\n )}\n </ul>`\n : nothing\n }\n </div>`;\n }\n}\n\ndefineElement('kt-drag-drop', KtDragDrop);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-drag-drop': KtDragDrop;\n }\n}\n"],"names":["UNITS","formatFileSize","bytes","value","unit","KtDragDrop","KtElement","css","attachFormInternals","changed","file","setFormValue","missing","setValidity","strings","disabled","state","entry","emit","pattern","incoming","candidates","accepted","rejected","f","index","_","position","event","html","classMap","nothing","__decorateClass","query","property","defineElement"],"mappings":"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"}
1
+ {"version":3,"file":"kt-drag-drop.js","sources":["../../../../src/internal/format.ts","../../../../src/components/forms/kt-drag-drop/kt-drag-drop.ts"],"sourcesContent":["/** Formatting helpers shared by elements that display data. */\n\nconst UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const;\n\n/**\n * A human-readable file size.\n *\n * Uses 1024 steps, matching what every desktop file manager shows, and one\n * decimal above a kilobyte — \"1.4 MB\" reads; \"1468006 B\" does not.\n */\nexport function formatFileSize(bytes: number): string {\n if (!Number.isFinite(bytes) || bytes < 0) return '';\n\n let value = bytes;\n let unit = 0;\n while (value >= 1024 && unit < UNITS.length - 1) {\n value /= 1024;\n unit += 1;\n }\n\n const rounded = unit === 0 ? String(Math.round(value)) : value.toFixed(1);\n return `${rounded} ${UNITS[unit]}`;\n}\n","import { css, html, nothing, type PropertyValues, 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 {\n attachFormInternals,\n setFormValue,\n setValidity,\n type UsableInternals,\n} from '#internal/form-control';\nimport { formatFileSize } from '#internal/format';\nimport { strings } from '#internal/strings';\nimport '../../core/kt-icon/kt-icon.js';\nimport '../../core/kt-button/kt-button.js';\n\n/**\n * A file drop zone.\n *\n * Accepts a drop or a click, lists what was picked with sizes and types, and\n * lets each entry be removed. It holds the files in memory and reports them —\n * uploading is the application's business.\n *\n * @element kt-drag-drop\n *\n * @csspart base - The dashed drop zone.\n * @csspart list - The list of chosen files.\n *\n * @fires kt-files-change - The selection changed. `detail: { files }`.\n * @fires kt-files-rejected - Files were refused. `detail: { files, reason }`.\n *\n * @example\n * ```html\n * <kt-drag-drop accept=\"image/*\" recommended-size=\"800×400px\"></kt-drag-drop>\n * ```\n */\nexport class KtDragDrop extends KtElement {\n static readonly formAssociated = true;\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n user-select: none;\n }\n\n .zone {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--gap-drag-drop);\n padding: var(--padding-drag-drop);\n border: var(--border-width) dashed var(--color-dark-24);\n border-radius: var(--border-radius);\n cursor: pointer;\n transition:\n border-color var(--duration-instant),\n box-shadow var(--duration-instant);\n }\n\n .zone:hover {\n border-color: var(--text-muted);\n }\n\n .zone:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n }\n\n .dragover {\n border-color: var(--color-primary-base);\n box-shadow: 0 0 0 6px var(--color-primary-soft);\n }\n\n .prompt {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--gap-button);\n text-align: center;\n }\n\n .prompt-icon {\n color: var(--text-muted);\n }\n\n .title {\n margin: 0;\n color: var(--color-primary-text);\n font: var(--font-normal-medium);\n }\n\n .hint {\n color: var(--text-muted);\n font: var(--font-normal-small);\n }\n\n input[type='file'] {\n display: none;\n }\n\n .list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n width: 100%;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .item {\n display: flex;\n align-items: center;\n gap: 12px;\n width: 100%;\n padding: 12px;\n background: var(--surface-raised);\n border-radius: var(--border-radius);\n cursor: default;\n transition: background var(--duration-normal) var(--easing-standard);\n }\n .item:hover {\n background: var(--surface-hover);\n }\n\n .preview {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n overflow: hidden;\n color: var(--color-info-text);\n background: var(--color-dark-14);\n border-radius: calc(6px * var(--radius-scale, 1));\n }\n\n .info {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n }\n\n .name {\n overflow: hidden;\n color: var(--text-body);\n font: var(--font-normal-medium);\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .details {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--text-muted);\n font: var(--font-normal-small);\n }\n `,\n ];\n\n @query('input[type=\"file\"]')\n private fileInput!: HTMLInputElement;\n\n private internals: UsableInternals | null = null;\n\n @state()\n private dragging = false;\n\n @state()\n private files: File[] = [];\n\n /**\n * The prompt above the browse link.\n *\n * Named `heading`, not `title`: an element already has a `title`, and\n * reusing it would put the prompt in a native tooltip on the whole zone.\n */\n @property({ type: String })\n heading: string | undefined = undefined;\n\n /** The clickable-looking part of the prompt. */\n @property({ type: String, attribute: 'link-text' })\n linkText: string | undefined = undefined;\n\n /** Optional hint, e.g. `800×400px`. */\n @property({ type: String, attribute: 'recommended-size' })\n recommendedSize = '';\n\n @property({ type: Boolean })\n multiple = true;\n\n /** Same syntax as the native `accept`: `image/*`, `.pdf,.docx`. */\n @property({ type: String })\n accept = '';\n\n /** Largest accepted file, in bytes. Zero means no limit. */\n @property({ type: Number, attribute: 'max-size' })\n maxSize = 0;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Disabled by an enclosing `<fieldset>`, which leaves `disabled` alone. */\n @state()\n private formDisabled = false;\n\n /** Whether the control is off, by its own `disabled` or by its form. */\n private get inactive(): boolean {\n return this.disabled || this.formDisabled;\n }\n\n /** The files are submitted under this name, as by `<input type=\"file\">`. */\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 }\n\n // Untyped: `files` is private state, which PropertyValues<this> cannot name.\n override willUpdate(changed: PropertyValues): void {\n if (\n changed.has('files') ||\n changed.has('name') ||\n changed.has('required') ||\n this.stringsChanged(changed)\n ) {\n this.syncFormValue();\n }\n }\n\n private syncFormValue(): void {\n // Like a native file input: nothing is submitted without a name or without\n // a file, and each file is its own entry under the one name.\n let value: FormData | null = null;\n if (this.name && this.files.length > 0) {\n value = new FormData();\n for (const file of this.files) value.append(this.name, file);\n }\n setFormValue(this.internals, value);\n\n const missing = this.required && this.files.length === 0;\n setValidity(this.internals, { valueMissing: missing }, missing ? strings().selectFile : '');\n }\n\n formResetCallback(): void {\n this.files = [];\n this.dragging = false;\n }\n\n /**\n * Called by the platform when the control's disabled state changes — its\n * own `disabled`, or an ancestor `<fieldset disabled>` it cannot see.\n */\n formDisabledCallback(disabled: boolean): void {\n this.formDisabled = disabled;\n }\n\n formStateRestoreCallback(state: string | File | FormData | null): void {\n if (!(state instanceof FormData) || !this.name) return;\n this.files = state.getAll(this.name).filter((entry): entry is File => entry instanceof File);\n }\n\n /** The files currently held, newest last. */\n get selectedFiles(): readonly File[] {\n return this.files;\n }\n\n /** Empties the selection without firing a rejection. */\n clear(): void {\n this.files = [];\n emit(this, 'kt-files-change', { files: this.files });\n }\n\n /**\n * `accept` is advisory on a native input — the OS dialog filters, but a\n * dropped file bypasses it entirely — so the same rules are enforced here.\n */\n private accepts(file: File): boolean {\n if (this.maxSize > 0 && file.size > this.maxSize) return false;\n if (!this.accept) return true;\n\n return this.accept\n .split(',')\n .map((pattern) => pattern.trim().toLowerCase())\n .filter(Boolean)\n .some((pattern) => {\n if (pattern.startsWith('.')) return file.name.toLowerCase().endsWith(pattern);\n if (pattern.endsWith('/*')) return file.type.startsWith(pattern.slice(0, -1));\n return file.type.toLowerCase() === pattern;\n });\n }\n\n private addFiles(incoming: FileList | null): void {\n if (!incoming || incoming.length === 0) return;\n\n const candidates = this.multiple ? [...incoming] : [...incoming].slice(0, 1);\n const accepted = candidates.filter((file) => this.accepts(file));\n const rejected = candidates.filter((file) => !this.accepts(file));\n\n if (rejected.length > 0) {\n emit(this, 'kt-files-rejected', {\n files: rejected,\n reason: this.maxSize > 0 && rejected.some((f) => f.size > this.maxSize) ? 'size' : 'type',\n });\n }\n if (accepted.length === 0) return;\n\n this.files = this.multiple ? [...this.files, ...accepted] : accepted;\n emit(this, 'kt-files-change', { files: this.files });\n }\n\n private removeAt(index: number): void {\n this.files = this.files.filter((_, position) => position !== index);\n emit(this, 'kt-files-change', { files: this.files });\n }\n\n private browse(): void {\n if (this.inactive) return;\n this.fileInput?.click();\n }\n\n private onZoneKeyDown(event: KeyboardEvent): void {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n this.browse();\n }\n\n private onDragOver(event: DragEvent): void {\n if (this.inactive) return;\n event.preventDefault();\n this.dragging = true;\n }\n\n private onDrop(event: DragEvent): void {\n if (this.inactive) return;\n event.preventDefault();\n this.dragging = false;\n this.addFiles(event.dataTransfer?.files ?? null);\n }\n\n override render(): TemplateResult {\n return html`<div\n part=\"base\"\n class=${classMap({ zone: true, dragover: this.dragging })}\n role=\"button\"\n tabindex=${this.inactive ? -1 : 0}\n aria-disabled=${this.inactive ? 'true' : nothing}\n aria-label=${`${this.heading ?? strings().dragAndDrop} ${this.linkText ?? strings().browseFiles}`}\n @click=${this.browse}\n @keydown=${this.onZoneKeyDown}\n @dragover=${this.onDragOver}\n @dragleave=${() => {\n this.dragging = false;\n }}\n @drop=${this.onDrop}\n >\n <input\n type=\"file\"\n ?multiple=${this.multiple}\n accept=${this.accept || nothing}\n @click=${(event: Event) => event.stopPropagation()}\n @change=${(event: Event) => this.addFiles((event.target as HTMLInputElement).files)}\n />\n\n <div class=\"prompt\">\n <span class=\"prompt-icon\"><kt-icon name=\"file-up\" size=\"24\"></kt-icon></span>\n <div>\n <p class=\"title\">\n ${this.heading ?? strings().dragAndDrop} ${this.linkText ?? strings().browseFiles}\n </p>\n ${\n this.recommendedSize\n ? html`<div class=\"hint\">${strings().recommendedSize(this.recommendedSize)}</div>`\n : nothing\n }\n </div>\n </div>\n\n ${\n this.files.length > 0\n ? html`<ul\n part=\"list\"\n class=\"list\"\n aria-label=${strings().selectedFiles}\n @click=${(event: Event) => event.stopPropagation()}\n >\n ${this.files.map(\n (file, index) =>\n html`<li class=\"item\">\n <span class=\"preview\"><kt-icon name=\"file\" size=\"24\"></kt-icon></span>\n <span class=\"info\">\n <span class=\"name\" title=${file.name}>${file.name}</span>\n <span class=\"details\">\n <span>${formatFileSize(file.size)}</span>\n ${file.type ? html`<span>•</span><span>${file.type}</span>` : nothing}\n </span>\n </span>\n <kt-button\n variant=\"danger\"\n size=\"small\"\n icon=\"trash-2\"\n label=${strings().remove(file.name)}\n @click=${() => this.removeAt(index)}\n ></kt-button>\n </li>`,\n )}\n </ul>`\n : nothing\n }\n </div>`;\n }\n}\n\ndefineElement('kt-drag-drop', KtDragDrop);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-drag-drop': KtDragDrop;\n }\n}\n"],"names":["UNITS","formatFileSize","bytes","value","unit","KtDragDrop","KtElement","css","attachFormInternals","changed","file","setFormValue","missing","setValidity","strings","disabled","state","entry","emit","pattern","incoming","candidates","accepted","rejected","f","index","_","position","event","html","classMap","nothing","__decorateClass","query","property","defineElement"],"mappings":";;;;;;;;;AAEA,MAAMA,IAAQ,CAAC,KAAK,MAAM,MAAM,MAAM,IAAI;AAQnC,SAASC,EAAeC,GAAuB;AACpD,MAAI,CAAC,OAAO,SAASA,CAAK,KAAKA,IAAQ,EAAG,QAAO;AAEjD,MAAIC,IAAQD,GACRE,IAAO;AACX,SAAOD,KAAS,QAAQC,IAAOJ,EAAM,SAAS;AAC5C,IAAAG,KAAS,MACTC,KAAQ;AAIV,SAAO,GADSA,MAAS,IAAI,OAAO,KAAK,MAAMD,CAAK,CAAC,IAAIA,EAAM,QAAQ,CAAC,CACvD,IAAIH,EAAMI,CAAI,CAAC;AAClC;;;;;;ACcO,MAAMC,UAAmBC,EAAU;AAAA,EAAnC,cAAA;AAAA,UAAA,GAAA,SAAA,GAqIL,KAAQ,YAAoC,MAG5C,KAAQ,WAAW,IAGnB,KAAQ,QAAgB,CAAA,GASxB,KAAA,UAA8B,QAI9B,KAAA,WAA+B,QAI/B,KAAA,kBAAkB,IAGlB,KAAA,WAAW,IAIX,KAAA,SAAS,IAIT,KAAA,UAAU,GAGV,KAAA,WAAW,IAIX,KAAQ,eAAe,IASvB,KAAA,OAAO,IAGP,KAAA,WAAW;AAAA,EAAA;AAAA,EAzLX,OAAA;AAAA,SAAgB,iBAAiB;AAAA,EAAA;AAAA,EACjC,OAAA;AAAA,SAAgB,SAAS;AAAA,MACvBA,EAAU;AAAA,MACVC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA;AAAA,EA4HF;AAAA;AAAA,EAiDA,IAAY,WAAoB;AAC9B,WAAO,KAAK,YAAY,KAAK;AAAA,EAC/B;AAAA,EASS,oBAA0B;AACjC,UAAM,kBAAA,GACN,KAAK,cAAcC,EAAoB,IAAI;AAAA,EAC7C;AAAA;AAAA,EAGS,WAAWC,GAA+B;AACjD,KACEA,EAAQ,IAAI,OAAO,KACnBA,EAAQ,IAAI,MAAM,KAClBA,EAAQ,IAAI,UAAU,KACtB,KAAK,eAAeA,CAAO,MAE3B,KAAK,cAAA;AAAA,EAET;AAAA,EAEQ,gBAAsB;AAG5B,QAAIN,IAAyB;AAC7B,QAAI,KAAK,QAAQ,KAAK,MAAM,SAAS,GAAG;AACtC,MAAAA,IAAQ,IAAI,SAAA;AACZ,iBAAWO,KAAQ,KAAK,SAAa,OAAO,KAAK,MAAMA,CAAI;AAAA,IAC7D;AACA,IAAAC,EAAa,KAAK,WAAWR,CAAK;AAElC,UAAMS,IAAU,KAAK,YAAY,KAAK,MAAM,WAAW;AACvD,IAAAC,EAAY,KAAK,WAAW,EAAE,cAAcD,KAAWA,IAAUE,EAAA,EAAU,aAAa,EAAE;AAAA,EAC5F;AAAA,EAEA,oBAA0B;AACxB,SAAK,QAAQ,CAAA,GACb,KAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,qBAAqBC,GAAyB;AAC5C,SAAK,eAAeA;AAAA,EACtB;AAAA,EAEA,yBAAyBC,GAA8C;AACrE,IAAI,EAAEA,aAAiB,aAAa,CAAC,KAAK,SAC1C,KAAK,QAAQA,EAAM,OAAO,KAAK,IAAI,EAAE,OAAO,CAACC,MAAyBA,aAAiB,IAAI;AAAA,EAC7F;AAAA;AAAA,EAGA,IAAI,gBAAiC;AACnC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,QAAQ,CAAA,GACbC,EAAK,MAAM,mBAAmB,EAAE,OAAO,KAAK,OAAO;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,QAAQR,GAAqB;AACnC,WAAI,KAAK,UAAU,KAAKA,EAAK,OAAO,KAAK,UAAgB,KACpD,KAAK,SAEH,KAAK,OACT,MAAM,GAAG,EACT,IAAI,CAACS,MAAYA,EAAQ,OAAO,YAAA,CAAa,EAC7C,OAAO,OAAO,EACd,KAAK,CAACA,MACDA,EAAQ,WAAW,GAAG,IAAUT,EAAK,KAAK,YAAA,EAAc,SAASS,CAAO,IACxEA,EAAQ,SAAS,IAAI,IAAUT,EAAK,KAAK,WAAWS,EAAQ,MAAM,GAAG,EAAE,CAAC,IACrET,EAAK,KAAK,YAAA,MAAkBS,CACpC,IAVsB;AAAA,EAW3B;AAAA,EAEQ,SAASC,GAAiC;AAChD,QAAI,CAACA,KAAYA,EAAS,WAAW,EAAG;AAExC,UAAMC,IAAa,KAAK,WAAW,CAAC,GAAGD,CAAQ,IAAI,CAAC,GAAGA,CAAQ,EAAE,MAAM,GAAG,CAAC,GACrEE,IAAWD,EAAW,OAAO,CAACX,MAAS,KAAK,QAAQA,CAAI,CAAC,GACzDa,IAAWF,EAAW,OAAO,CAACX,MAAS,CAAC,KAAK,QAAQA,CAAI,CAAC;AAQhE,IANIa,EAAS,SAAS,KACpBL,EAAK,MAAM,qBAAqB;AAAA,MAC9B,OAAOK;AAAA,MACP,QAAQ,KAAK,UAAU,KAAKA,EAAS,KAAK,CAACC,MAAMA,EAAE,OAAO,KAAK,OAAO,IAAI,SAAS;AAAA,IAAA,CACpF,GAECF,EAAS,WAAW,MAExB,KAAK,QAAQ,KAAK,WAAW,CAAC,GAAG,KAAK,OAAO,GAAGA,CAAQ,IAAIA,GAC5DJ,EAAK,MAAM,mBAAmB,EAAE,OAAO,KAAK,OAAO;AAAA,EACrD;AAAA,EAEQ,SAASO,GAAqB;AACpC,SAAK,QAAQ,KAAK,MAAM,OAAO,CAACC,GAAGC,MAAaA,MAAaF,CAAK,GAClEP,EAAK,MAAM,mBAAmB,EAAE,OAAO,KAAK,OAAO;AAAA,EACrD;AAAA,EAEQ,SAAe;AACrB,IAAI,KAAK,YACT,KAAK,WAAW,MAAA;AAAA,EAClB;AAAA,EAEQ,cAAcU,GAA4B;AAChD,IAAIA,EAAM,QAAQ,WAAWA,EAAM,QAAQ,QAC3CA,EAAM,eAAA,GACN,KAAK,OAAA;AAAA,EACP;AAAA,EAEQ,WAAWA,GAAwB;AACzC,IAAI,KAAK,aACTA,EAAM,eAAA,GACN,KAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,OAAOA,GAAwB;AACrC,IAAI,KAAK,aACTA,EAAM,eAAA,GACN,KAAK,WAAW,IAChB,KAAK,SAASA,EAAM,cAAc,SAAS,IAAI;AAAA,EACjD;AAAA,EAES,SAAyB;AAChC,WAAOC;AAAA;AAAA,cAEGC,EAAS,EAAE,MAAM,IAAM,UAAU,KAAK,UAAU,CAAC;AAAA;AAAA,iBAE9C,KAAK,WAAW,KAAK,CAAC;AAAA,sBACjB,KAAK,WAAW,SAASC,CAAO;AAAA,mBACnC,GAAG,KAAK,WAAWjB,EAAA,EAAU,WAAW,IAAI,KAAK,YAAYA,EAAA,EAAU,WAAW,EAAE;AAAA,eACxF,KAAK,MAAM;AAAA,iBACT,KAAK,aAAa;AAAA,kBACjB,KAAK,UAAU;AAAA,mBACd,MAAM;AACjB,WAAK,WAAW;AAAA,IAClB,CAAC;AAAA,cACO,KAAK,MAAM;AAAA;AAAA;AAAA;AAAA,oBAIL,KAAK,QAAQ;AAAA,iBAChB,KAAK,UAAUiB,CAAO;AAAA,iBACtB,CAACH,MAAiBA,EAAM,gBAAA,CAAiB;AAAA,kBACxC,CAACA,MAAiB,KAAK,SAAUA,EAAM,OAA4B,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAO7E,KAAK,WAAWd,IAAU,WAAW,IAAI,KAAK,YAAYA,EAAA,EAAU,WAAW;AAAA;AAAA,YAGjF,KAAK,kBACDe,sBAAyBf,EAAA,EAAU,gBAAgB,KAAK,eAAe,CAAC,WACxEiB,CACN;AAAA;AAAA;AAAA;AAAA,QAKF,KAAK,MAAM,SAAS,IAChBF;AAAA;AAAA;AAAA,2BAGef,EAAA,EAAU,aAAa;AAAA,uBAC3B,CAACc,MAAiBA,EAAM,gBAAA,CAAiB;AAAA;AAAA,gBAEhD,KAAK,MAAM;AAAA,MACX,CAAClB,GAAMe,MACLI;AAAA;AAAA;AAAA,iDAG+BnB,EAAK,IAAI,IAAIA,EAAK,IAAI;AAAA;AAAA,gCAEvCT,EAAeS,EAAK,IAAI,CAAC;AAAA,0BAC/BA,EAAK,OAAOmB,wBAA2BnB,EAAK,IAAI,YAAYqB,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAO/DjB,EAAA,EAAU,OAAOJ,EAAK,IAAI,CAAC;AAAA,+BAC1B,MAAM,KAAK,SAASe,CAAK,CAAC;AAAA;AAAA;AAAA,IAAA,CAG1C;AAAA,qBAEHM,CACN;AAAA;AAAA,EAEJ;AACF;AA/PUC,EAAA;AAAA,EADPC,EAAM,oBAAoB;AAAA,GAlIhB5B,EAmIH,WAAA,WAAA;AAKA2B,EAAA;AAAA,EADPhB,EAAA;AAAM,GAvIIX,EAwIH,WAAA,UAAA;AAGA2B,EAAA;AAAA,EADPhB,EAAA;AAAM,GA1IIX,EA2IH,WAAA,OAAA;AASR2B,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAnJf7B,EAoJX,WAAA,SAAA;AAIA2B,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,QAAQ,WAAW,aAAa;AAAA,GAvJvC7B,EAwJX,WAAA,UAAA;AAIA2B,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,QAAQ,WAAW,oBAAoB;AAAA,GA3J9C7B,EA4JX,WAAA,iBAAA;AAGA2B,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,QAAA,CAAS;AAAA,GA9JhB7B,EA+JX,WAAA,UAAA;AAIA2B,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAlKf7B,EAmKX,WAAA,QAAA;AAIA2B,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,QAAQ,WAAW,YAAY;AAAA,GAtKtC7B,EAuKX,WAAA,SAAA;AAGA2B,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAzK/B7B,EA0KX,WAAA,UAAA;AAIQ2B,EAAA;AAAA,EADPhB,EAAA;AAAM,GA7KIX,EA8KH,WAAA,cAAA;AASR2B,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAtLf7B,EAuLX,WAAA,MAAA;AAGA2B,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAzL/B7B,EA0LX,WAAA,UAAA;AA0MF8B,EAAc,gBAAgB9B,CAAU;"}
@@ -1,8 +1,8 @@
1
1
  import { css as f, nothing as h, html as d } from "lit";
2
2
  import { queryAssignedElements as c, state as g, property as a } from "lit/decorators.js";
3
- import { K as p, d as m } from "../../../chunks/kt-element-Djx2JcGl.js";
3
+ import { K as p, d as m } from "../../../chunks/kt-element-T0VbIBNp.js";
4
4
  import { h as y } from "../../../chunks/slots-BPbIdxAJ.js";
5
- import { s as b } from "../../../chunks/index-STEEvEP7.js";
5
+ import { s as b } from "../../../chunks/index-TWJzttLX.js";
6
6
  import "../../feedback/kt-skeleton/kt-skeleton.js";
7
7
  var u = Object.defineProperty, s = (r, e, o, v) => {
8
8
  for (var i = void 0, l = r.length - 1, n; l >= 0; l--)
@@ -1,12 +1,12 @@
1
- import { css as v, nothing as s, html as d } from "lit";
1
+ import { css as x, nothing as s, html as d } from "lit";
2
2
  import { query as P, state as m, property as l } from "lit/decorators.js";
3
3
  import { classMap as y } from "lit/directives/class-map.js";
4
4
  import { live as w } from "lit/directives/live.js";
5
- import { K as g, d as $ } from "../../../chunks/kt-element-Djx2JcGl.js";
5
+ import { K as g, d as $ } from "../../../chunks/kt-element-T0VbIBNp.js";
6
6
  import { t as C, e as c } from "../../../chunks/events-r51msXNf.js";
7
7
  import { a as S, s as b, b as E } from "../../../chunks/form-control-B74_EHtG.js";
8
- import { F as O, f as z } from "../../../chunks/floating-B7_Dahpn.js";
9
- import { s as u } from "../../../chunks/index-STEEvEP7.js";
8
+ import { F as O, f as z } from "../../../chunks/floating-B33g-M_1.js";
9
+ import { s as u } from "../../../chunks/index-TWJzttLX.js";
10
10
  import "../../core/kt-icon/kt-icon.js";
11
11
  import "../../feedback/kt-tooltip/kt-tooltip.js";
12
12
  const D = [
@@ -141,15 +141,15 @@ function B(n, e) {
141
141
  const t = e?.trunkPrefix;
142
142
  return t && n.startsWith(t) ? t : void 0;
143
143
  }
144
- function x(n) {
144
+ function v(n) {
145
145
  return n.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase();
146
146
  }
147
147
  function N(n, e) {
148
- const t = x(e.trim());
148
+ const t = v(e.trim());
149
149
  if (!t) return n;
150
150
  const o = t.replace(/^\+/, "");
151
151
  return n.filter(
152
- (a) => x(a.name).includes(t) || o !== "" && a.dialCode.startsWith(o) || a.id === t
152
+ (a) => v(a.name).includes(t) || o !== "" && a.dialCode.startsWith(o) || a.id === t
153
153
  );
154
154
  }
155
155
  var q = Object.defineProperty, i = (n, e, t, o) => {
@@ -174,7 +174,7 @@ class r extends g {
174
174
  this.styles = [
175
175
  g.styles,
176
176
  z,
177
- v`
177
+ x`
178
178
  :host {
179
179
  display: block;
180
180
  }
@@ -281,7 +281,7 @@ class r extends g {
281
281
  .icon-button:focus-visible {
282
282
  outline: var(--outline-width) solid var(--color-primary-base);
283
283
  outline-offset: 2px;
284
- border-radius: 2px;
284
+ border-radius: calc(2px * var(--radius-scale, 1));
285
285
  }
286
286
 
287
287
  .clear {
@@ -346,7 +346,7 @@ class r extends g {
346
346
  width: 280px;
347
347
  max-height: 225px;
348
348
  padding: var(--padding-expand);
349
- background: var(--color-dark-20);
349
+ background: var(--surface-popover);
350
350
  border-radius: var(--radius-input);
351
351
  }
352
352