kanto-ds 1.0.1 → 1.2.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 +20 -2
- package/dist/chunks/form-control-CxjBTt1c.js.map +1 -1
- package/dist/chunks/kt-element-B_jjQDhg.js +38 -0
- package/dist/chunks/kt-element-B_jjQDhg.js.map +1 -0
- package/dist/components/core/kt-avatar/kt-avatar.js +9 -6
- package/dist/components/core/kt-avatar/kt-avatar.js.map +1 -1
- package/dist/components/core/kt-badge/kt-badge.js +17 -17
- package/dist/components/core/kt-badge/kt-badge.js.map +1 -1
- package/dist/components/core/kt-button/kt-button.d.ts +7 -0
- package/dist/components/core/kt-button/kt-button.js +68 -60
- package/dist/components/core/kt-button/kt-button.js.map +1 -1
- package/dist/components/core/kt-card/kt-card.js +1 -1
- package/dist/components/core/kt-code/kt-code.js +12 -12
- 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 +14 -14
- package/dist/components/core/kt-kbd/kt-kbd.js.map +1 -1
- package/dist/components/core/kt-split-button/kt-split-button.js +3 -3
- package/dist/components/core/kt-split-button/kt-split-button.js.map +1 -1
- package/dist/components/data/kt-chart/kt-chart.js +1 -1
- package/dist/components/data/kt-meter/kt-meter.js +1 -1
- package/dist/components/data/kt-pagination/kt-pagination.js +1 -1
- package/dist/components/data/kt-stat/kt-stat.js +5 -5
- package/dist/components/data/kt-stat/kt-stat.js.map +1 -1
- package/dist/components/data/kt-table/kt-table.js +2 -2
- package/dist/components/data/kt-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 +26 -26
- 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 +2 -2
- package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js.map +1 -1
- package/dist/components/feedback/kt-skeleton/kt-skeleton.js +1 -1
- package/dist/components/feedback/kt-toast/kt-toast.js +22 -22
- 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 +11 -1
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +69 -36
- 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 +95 -91
- package/dist/components/forms/kt-input/kt-input.js.map +1 -1
- package/dist/components/forms/kt-input-menu/kt-input-menu.d.ts +10 -1
- package/dist/components/forms/kt-input-menu/kt-input-menu.js +83 -53
- 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 +2 -2
- package/dist/components/forms/kt-label-input/kt-label-input.js.map +1 -1
- package/dist/components/forms/kt-select/kt-select.js +2 -2
- package/dist/components/forms/kt-select/kt-select.js.map +1 -1
- package/dist/components/forms/kt-textarea/kt-textarea.js +15 -13
- package/dist/components/forms/kt-textarea/kt-textarea.js.map +1 -1
- package/dist/components/forms/kt-toggle/kt-toggle.js +8 -7
- package/dist/components/forms/kt-toggle/kt-toggle.js.map +1 -1
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +1 -1
- package/dist/components/navigation/kt-header/kt-header.js +1 -1
- package/dist/components/navigation/kt-page-header/kt-page-header.js +18 -18
- package/dist/components/navigation/kt-page-header/kt-page-header.js.map +1 -1
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.d.ts +10 -1
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +88 -62
- 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.js +5 -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 +3 -3
- package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js.map +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.js +1 -1
- package/dist/components/overlays/kt-dropdown/kt-dropdown.d.ts +13 -0
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js +74 -59
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js.map +1 -1
- package/dist/components/overlays/kt-modal/kt-modal.js +1 -1
- package/dist/components/overlays/kt-side-panel/kt-side-panel.js +1 -1
- package/dist/custom-elements.json +11791 -0
- package/dist/index.js +1 -1
- package/dist/internal/form-control.d.ts +7 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react/jsx.d.ts +213 -0
- package/dist/react/jsx.js +2 -0
- package/dist/react/jsx.js.map +1 -0
- package/dist/tokens/README.md +7 -3
- package/dist/tokens/colors.css +24 -5
- package/dist/tokens/theme-light.css +18 -0
- package/dist/vscode.css-custom-data.json +154 -0
- package/dist/vscode.html-custom-data.json +1136 -0
- package/dist/web-types.json +3186 -0
- package/package.json +28 -9
- package/dist/chunks/kt-element-CcMLO5e8.js +0 -28
- package/dist/chunks/kt-element-CcMLO5e8.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-input.js","sources":["../../../../src/internal/countries.ts","../../../../src/components/forms/kt-input/kt-input.ts"],"sourcesContent":["/**\n * Country data for the phone mode of `<kt-input>`.\n *\n * Deliberately a short list rather than all 195: an exhaustive picker is a\n * worse experience than a handful of entries and a search box. Applications\n * that need more pass their own list to the element.\n */\n\nexport interface KtCountry {\n /** ISO 3166-1 alpha-2, lowercase. */\n readonly id: string;\n readonly name: string;\n /** International dialling code, without the leading `+`. */\n readonly dialCode: string;\n /** Placeholder showing the local format. */\n readonly format: string;\n}\n\nexport const DEFAULT_COUNTRIES: readonly KtCountry[] = [\n { id: 'us', name: 'United States', dialCode: '1', format: '123-456-7890' },\n { id: 'gb', name: 'United Kingdom', dialCode: '44', format: '7123 456789' },\n { id: 'de', name: 'Germany', dialCode: '49', format: '1234 567890' },\n { id: 'fr', name: 'France', dialCode: '33', format: '1 23 45 67 89' },\n { id: 'be', name: 'Belgium', dialCode: '32', format: '1 23 45 67 89' },\n { id: 'ch', name: 'Switzerland', dialCode: '41', format: '12 345 67 89' },\n];\n\nconst REGIONAL_INDICATOR_A = 0x1f1e6;\nconst LETTER_A = 'A'.charCodeAt(0);\n\n/**\n * The flag emoji for a country code, built from regional indicator symbols.\n *\n * This is the one place emoji appear in a Kanto interface. They are here\n * because no flag icon set ships with the system, and a country picker without\n * flags is markedly slower to scan.\n */\nexport function flagEmoji(id: string): string {\n if (!/^[a-z]{2}$/i.test(id)) return '';\n return String.fromCodePoint(\n ...[...id.toUpperCase()].map(\n (letter) => REGIONAL_INDICATOR_A + letter.charCodeAt(0) - LETTER_A,\n ),\n );\n}\n\n/** Keeps only the digits — what gets stored and submitted. */\nexport function digitsOnly(value: string): string {\n return value.replace(/\\D/g, '');\n}\n\n/**\n * Groups digits for display, per country.\n *\n * North American numbers read as `123 456 7890`, French ones as\n * `6 12 34 56 78` — a single leading digit, then pairs. Everything else falls\n * back to groups of three.\n */\nexport function formatNationalNumber(digits: string, country: KtCountry | undefined): string {\n if (!digits) return '';\n\n const groups: string[] = [];\n let rest = digits;\n\n if (country?.id === 'fr') {\n groups.push(rest.slice(0, 1));\n rest = rest.slice(1);\n while (rest) {\n groups.push(rest.slice(0, 2));\n rest = rest.slice(2);\n }\n } else if (country?.id === 'us' || country?.id === 'ca') {\n for (const size of [3, 3, 4]) {\n if (!rest) break;\n groups.push(rest.slice(0, size));\n rest = rest.slice(size);\n }\n if (rest) groups.push(rest);\n } else {\n while (rest) {\n groups.push(rest.slice(0, 3));\n rest = rest.slice(3);\n }\n }\n\n return groups.filter(Boolean).join(' ');\n}\n\n/** Filters by name, dial code or country code — whatever the user types. */\nexport function searchCountries(\n countries: readonly KtCountry[],\n query: string,\n): readonly KtCountry[] {\n const needle = query.trim().toLowerCase();\n if (!needle) return countries;\n\n return countries.filter(\n (country) =>\n country.name.toLowerCase().includes(needle) ||\n country.dialCode.includes(needle.replace(/^\\+/, '')) ||\n country.id === needle,\n );\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 { live } from 'lit/directives/live.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 {\n DEFAULT_COUNTRIES,\n digitsOnly,\n flagEmoji,\n formatNationalNumber,\n searchCountries,\n type KtCountry,\n} from '#internal/countries';\nimport '../../core/kt-icon/kt-icon.js';\n\nexport type KtInputSize = 'small' | 'medium' | 'large';\n\n/** Icon size inside a field, at every field size. */\nconst ICON_SIZE = 18;\n\n/**\n * A single-line text field.\n *\n * Borderless by design: the field is a fill on `--color-dark-12` that gains a\n * 2px *outline* — grey on hover, primary on focus, danger on error. An outline\n * sits outside the box, so nothing reflows when the state changes.\n *\n * The element is form-associated: it serialises into `FormData` under its\n * `name`, resets with the form, and reports validity like a native input.\n *\n * @element kt-input\n *\n * @csspart base - The field container.\n * @csspart control - The native `<input>`.\n * @csspart actions - The trailing icon row.\n *\n * @fires kt-input - On every keystroke. `detail: { value }`.\n * @fires kt-change - When the value is committed (blur or Enter). `detail: { value }`.\n * @fires kt-clear - The clear button was pressed.\n *\n * @example\n * ```html\n * <kt-input placeholder=\"Search everything...\" icon=\"search\"></kt-input>\n * <kt-input type=\"password\" name=\"password\"></kt-input>\n * <kt-input error=\"Invalid email address\" value=\"not-an-address\"></kt-input>\n * ```\n */\nexport class KtInput extends KtElement {\n static readonly formAssociated = true;\n\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n }\n\n .field {\n position: relative;\n display: inline-flex;\n align-items: center;\n width: 100%;\n height: var(--button-height);\n padding: 0 var(--button-padding-x);\n gap: var(--gap-button);\n background-color: var(--surface-field);\n border-radius: var(--radius-input);\n /* A resting hairline. A field is a fill on --surface-field, which is\n one ramp step from the page in dark and almost the same colour in\n light — so on a card or inside a modal it simply disappeared and\n read as a bare native control.\n\n A border rather than an outline, because the control inside fills\n the field exactly and a coincident outline is painted over by the\n native widget. A border insets the control by its own width, so it\n cannot be covered. box-sizing: border-box keeps the outer size.\n\n The hover and focus rings stay outlines on top of it, and the\n transparent resting outline is what they animate from: without it\n outline-color starts at the initial value, which resolves to the\n text colour, and hover flashed near-white before settling. */\n border: var(--border-width) solid var(--border-field);\n outline: var(--outline-width) solid transparent;\n transition: outline-color var(--duration-instant);\n }\n\n /* Outline, never border: it sits outside the box, so hover and focus\n change nothing about the layout. */\n .field:hover {\n outline: var(--outline-width) solid var(--color-text-700);\n }\n .field:focus-within {\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n\n .small {\n height: var(--button-height-small);\n }\n .large {\n height: var(--button-height-large);\n }\n\n .error,\n .error:hover,\n .error:focus-within {\n outline: var(--outline-width) solid var(--color-danger-base);\n }\n .error input {\n color: var(--color-danger-base);\n }\n\n .disabled {\n background-color: var(--color-dark-14);\n pointer-events: none;\n }\n .disabled input {\n color: var(--text-disabled);\n }\n\n input {\n width: 100%;\n min-width: 0;\n padding: 0;\n color: var(--text-body);\n font: var(--font-input);\n background: transparent;\n border: none;\n outline: none;\n }\n\n input::placeholder {\n color: var(--color-text-500);\n }\n\n /* The clear button is ours; the browser's is redundant. */\n input::-webkit-search-cancel-button {\n display: none;\n }\n\n .actions {\n display: flex;\n flex: none;\n align-items: center;\n gap: var(--gap-button);\n }\n\n .icon-button {\n display: inline-flex;\n align-items: center;\n padding: 0;\n color: var(--text-body);\n background: none;\n border: none;\n cursor: pointer;\n }\n\n .icon-button:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n border-radius: 2px;\n }\n\n .clear {\n transition: transform var(--duration-instant) ease-in-out;\n }\n .clear:hover {\n transform: rotate(90deg);\n }\n\n .adornment {\n display: flex;\n align-items: center;\n color: var(--text-muted);\n }\n\n .error-icon {\n color: var(--color-danger-base);\n }\n\n /* === PHONE MODE === */\n .country {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n gap: var(--gap-element);\n height: 100%;\n margin-right: var(--button-padding-x);\n padding: 0 var(--button-padding-x) 0 0;\n color: var(--text-body);\n background: none;\n border: none;\n border-right: var(--border-width) solid var(--color-dark-16);\n cursor: pointer;\n font: var(--font-normal-regular);\n user-select: none;\n }\n\n .country:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: -2px;\n }\n\n .chevron {\n display: inline-flex;\n transform-origin: 50% 50%;\n transition: transform var(--duration-fast) ease-in-out;\n }\n .chevron.open {\n transform: scaleY(-1);\n }\n\n .dial {\n color: var(--text-muted);\n }\n\n .country-panel {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: var(--z-dropdown);\n display: flex;\n flex-direction: column;\n gap: var(--gap-element);\n width: 280px;\n max-height: 225px;\n padding: var(--padding-expand);\n background: var(--color-dark-20);\n border-radius: var(--radius-input);\n }\n\n .country-search {\n width: 100%;\n height: var(--button-height-small);\n padding: 0 12px;\n color: var(--text-body);\n font: var(--font-normal-regular);\n background: var(--color-dark-12);\n border: none;\n border-radius: var(--radius-input);\n outline: none;\n }\n\n .country-list {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: var(--gap-element);\n margin: 0;\n padding: 0;\n overflow-y: auto;\n list-style: none;\n scrollbar-width: thin;\n }\n\n .country-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: var(--radius-input);\n cursor: pointer;\n font: var(--font-normal-regular);\n }\n .country-item:hover,\n .country-item[aria-selected='true'] {\n background: var(--color-dark-23);\n }\n\n .country-name {\n flex: 1;\n }\n\n .country-empty {\n padding: 8px 12px;\n color: var(--text-muted);\n font: var(--font-normal-small);\n }\n `,\n ];\n\n @query('input')\n private input!: HTMLInputElement;\n\n private internals: UsableInternals | null = null;\n\n /** True while a `password` field is showing its contents. */\n @state()\n private passwordVisible = false;\n\n @state()\n private countryOpen = false;\n\n @state()\n private countryQuery = '';\n\n /** The field's value. The `value` attribute seeds it and acts as the reset value. */\n @property({ type: String })\n value = '';\n\n @property({ type: String })\n name = '';\n\n /** Any native input type. `password` adds the reveal toggle. */\n @property({ type: String })\n type = 'text';\n\n @property({ type: String })\n placeholder = '';\n\n /** Field height: 32 / 40 / 48px at the desktop scale. */\n @property({ type: String, reflect: true })\n size: KtInputSize = 'medium';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /** Trailing Lucide icon, kebab-case. */\n @property({ type: String })\n icon = '';\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 /** Shows the clear button once there is something to clear. */\n @property({ type: Boolean })\n clearable = true;\n\n /** Accessible name, when no `<kt-label-input>` wraps the field. */\n @property({ type: String })\n label = '';\n\n @property({ type: String })\n autocomplete = '';\n\n @property({ type: Number })\n maxlength?: number;\n\n /**\n * Countries offered in phone mode. Replace it to widen the list.\n */\n @property({ attribute: false })\n countries: readonly KtCountry[] = DEFAULT_COUNTRIES;\n\n /** Selected country in phone mode, as an ISO 3166-1 alpha-2 code. */\n @property({ type: String })\n country = 'us';\n\n /** The value the enclosing form resets to. */\n private defaultValue = '';\n\n override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.closeCountryPanel);\n this.internals ??= attachFormInternals(this);\n this.defaultValue = this.value;\n setFormValue(this.internals, this.formValue);\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (\n changed.has('value') ||\n changed.has('required') ||\n changed.has('error') ||\n changed.has('country')\n ) {\n setFormValue(this.internals, this.value);\n this.refreshValidity();\n }\n }\n\n private refreshValidity(): void {\n const missing = this.required && this.value.length === 0;\n const message = this.error || (missing ? 'This field is required.' : '');\n setValidity(\n this.internals,\n { valueMissing: missing, customError: Boolean(this.error) },\n message,\n );\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('pointerdown', this.closeCountryPanel);\n }\n\n /** Called by the platform when the enclosing form is reset. */\n formResetCallback(): void {\n this.value = this.defaultValue;\n this.passwordVisible = false;\n }\n\n /** Called by the platform when the browser restores a session. */\n formStateRestoreCallback(state: string): void {\n this.value = state;\n }\n\n override focus(options?: FocusOptions): void {\n this.input?.focus(options);\n }\n\n override blur(): void {\n this.input?.blur();\n }\n\n /** Selects the field's contents, as `HTMLInputElement.select()` does. */\n select(): void {\n this.input?.select();\n }\n\n /** Phone mode: the country picker, digit-only storage and grouped display. */\n private get isPhone(): boolean {\n return this.type === 'tel';\n }\n\n private get selectedCountry(): KtCountry | undefined {\n return this.countries.find((candidate) => candidate.id === this.country);\n }\n\n /**\n * What the form receives. In phone mode that is the full international\n * number — submitting national digits alone would throw away the country\n * the user picked.\n */\n private get formValue(): string {\n if (!this.isPhone || !this.value) return this.value;\n return `+${this.selectedCountry?.dialCode ?? ''}${this.value}`;\n }\n\n private get displayValue(): string {\n return this.isPhone ? formatNationalNumber(this.value, this.selectedCountry) : this.value;\n }\n\n private get showClear(): boolean {\n return this.clearable && this.value.length > 0 && !this.readonly && !this.disabled;\n }\n\n private get resolvedType(): string {\n // Phone mode renders grouped digits, which type=\"tel\" would not accept\n // back; the value is normalised to digits on input either way.\n if (this.isPhone) return 'text';\n if (this.type !== 'password') return this.type;\n return this.passwordVisible ? 'text' : 'password';\n }\n\n private onInput(event: Event): void {\n const raw = (event.target as HTMLInputElement).value;\n this.value = this.isPhone ? digitsOnly(raw) : raw;\n emit(this, 'kt-input', { value: this.value });\n }\n\n private toggleCountryPanel(): void {\n this.countryOpen = !this.countryOpen;\n this.countryQuery = '';\n }\n\n private selectCountry(country: KtCountry): void {\n this.country = country.id;\n this.countryOpen = false;\n this.countryQuery = '';\n emit(this, 'kt-country-change', { country: country.id, dialCode: country.dialCode });\n this.focus();\n }\n\n private closeCountryPanel = (event: Event): void => {\n if (event.composedPath().includes(this)) return;\n this.countryOpen = false;\n };\n\n private onCountryKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Escape' && this.countryOpen) {\n event.stopPropagation();\n this.countryOpen = false;\n this.shadowRoot?.querySelector<HTMLButtonElement>('.country')?.focus();\n }\n }\n\n private renderCountryPicker(): TemplateResult {\n const selected = this.selectedCountry;\n const matches = searchCountries(this.countries, this.countryQuery);\n\n return html`<button\n type=\"button\"\n class=\"country\"\n aria-haspopup=\"listbox\"\n aria-expanded=${this.countryOpen ? 'true' : 'false'}\n aria-label=${`Country code: ${selected?.name ?? 'none'}`}\n ?disabled=${this.disabled || this.readonly}\n @click=${this.toggleCountryPanel}\n >\n <span aria-hidden=\"true\">${flagEmoji(this.country)}</span>\n <span class=\"dial\">+${selected?.dialCode ?? ''}</span>\n <span class=${classMap({ chevron: true, open: this.countryOpen })}>\n <kt-icon name=\"chevron-down\" size=\"14\"></kt-icon>\n </span>\n </button>\n ${\n this.countryOpen\n ? html`<div class=\"country-panel\" @pointerdown=${(e: Event) => e.stopPropagation()}>\n <input\n class=\"country-search\"\n placeholder=\"Search country or dial code\"\n .value=${this.countryQuery}\n aria-label=\"Search country or dial code\"\n @input=${(e: Event) => {\n this.countryQuery = (e.target as HTMLInputElement).value;\n }}\n />\n <ul class=\"country-list\" role=\"listbox\">\n ${\n matches.length === 0\n ? html`<li class=\"country-empty\">No country found</li>`\n : matches.map(\n (candidate) =>\n html`<li\n class=\"country-item\"\n role=\"option\"\n aria-selected=${candidate.id === this.country ? 'true' : 'false'}\n @click=${() => this.selectCountry(candidate)}\n >\n <span aria-hidden=\"true\">${flagEmoji(candidate.id)}</span>\n <span class=\"country-name\">${candidate.name}</span>\n <span class=\"dial\">+${candidate.dialCode}</span>\n </li>`,\n )\n }\n </ul>\n </div>`\n : nothing\n }`;\n }\n\n private onChange(event: Event): void {\n // The native change event does not cross the shadow boundary; re-emit it\n // under a name consumers can actually listen for.\n event.stopPropagation();\n emit(this, 'kt-change', { value: this.value });\n }\n\n private clear(): void {\n this.value = '';\n emit(this, 'kt-clear');\n emit(this, 'kt-input', { value: '' });\n emit(this, 'kt-change', { value: '' });\n this.focus();\n }\n\n private togglePassword(): void {\n this.passwordVisible = !this.passwordVisible;\n }\n\n /** Clicking the padding around the input should focus it, as on a native field. */\n private onFieldPointerDown(event: PointerEvent): void {\n if (event.target === this.input) return;\n if ((event.target as HTMLElement).closest('button')) return;\n event.preventDefault();\n this.focus();\n }\n\n override render(): TemplateResult {\n const hasActions =\n this.type === 'password' || Boolean(this.icon) || Boolean(this.error) || this.showClear;\n\n return html`<div\n part=\"base\"\n class=${classMap({\n field: true,\n [this.size]: true,\n error: Boolean(this.error),\n disabled: this.disabled,\n })}\n @pointerdown=${this.onFieldPointerDown}\n @keydown=${this.onCountryKeyDown}\n >\n ${this.isPhone ? this.renderCountryPicker() : nothing}\n\n <input\n part=\"control\"\n type=${this.resolvedType}\n name=${this.name || nothing}\n .value=${live(this.displayValue)}\n placeholder=${this.placeholder || this.selectedCountry?.format || nothing}\n autocomplete=${this.autocomplete || nothing}\n inputmode=${this.isPhone ? 'tel' : nothing}\n maxlength=${this.maxlength ?? nothing}\n aria-label=${this.label || nothing}\n aria-invalid=${this.error ? 'true' : nothing}\n aria-errormessage=${this.error || nothing}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?required=${this.required}\n @input=${this.onInput}\n @change=${this.onChange}\n />\n\n ${\n hasActions\n ? html`<div part=\"actions\" class=\"actions\">\n ${\n this.type === 'password'\n ? html`<button\n type=\"button\"\n class=\"icon-button\"\n tabindex=\"-1\"\n aria-label=${this.passwordVisible ? 'Hide password' : 'Show password'}\n @click=${this.togglePassword}\n >\n <kt-icon\n name=${this.passwordVisible ? 'eye-off' : 'eye'}\n size=${ICON_SIZE}\n ></kt-icon>\n </button>`\n : nothing\n }\n ${\n this.icon\n ? html`<span class=\"adornment\">\n <kt-icon name=${this.icon} size=${ICON_SIZE}></kt-icon>\n </span>`\n : nothing\n }\n ${\n this.error\n ? html`<span class=\"adornment error-icon\" title=${this.error}>\n <kt-icon name=\"circle-alert\" size=${ICON_SIZE} label=${this.error}></kt-icon>\n </span>`\n : nothing\n }\n ${\n this.showClear\n ? html`<button\n type=\"button\"\n class=\"icon-button clear\"\n tabindex=\"-1\"\n aria-label=\"Clear\"\n @click=${this.clear}\n >\n <kt-icon name=\"x\" size=${ICON_SIZE}></kt-icon>\n </button>`\n : nothing\n }\n </div>`\n : nothing\n }\n </div>`;\n }\n}\n\ndefineElement('kt-input', KtInput);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-input': KtInput;\n }\n}\n"],"names":["DEFAULT_COUNTRIES","REGIONAL_INDICATOR_A","LETTER_A","flagEmoji","id","letter","digitsOnly","value","formatNationalNumber","digits","country","groups","rest","size","searchCountries","countries","query","needle","ICON_SIZE","KtInput","KtElement","event","css","attachFormInternals","setFormValue","changed","missing","message","setValidity","state","options","candidate","raw","emit","selected","matches","html","classMap","e","nothing","hasActions","live","__decorateClass","property","defineElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"kt-input.js","sources":["../../../../src/internal/countries.ts","../../../../src/components/forms/kt-input/kt-input.ts"],"sourcesContent":["/**\n * Country data for the phone mode of `<kt-input>`.\n *\n * Deliberately a short list rather than all 195: an exhaustive picker is a\n * worse experience than a handful of entries and a search box. Applications\n * that need more pass their own list to the element.\n */\n\nexport interface KtCountry {\n /** ISO 3166-1 alpha-2, lowercase. */\n readonly id: string;\n readonly name: string;\n /** International dialling code, without the leading `+`. */\n readonly dialCode: string;\n /** Placeholder showing the local format. */\n readonly format: string;\n}\n\nexport const DEFAULT_COUNTRIES: readonly KtCountry[] = [\n { id: 'us', name: 'United States', dialCode: '1', format: '123-456-7890' },\n { id: 'gb', name: 'United Kingdom', dialCode: '44', format: '7123 456789' },\n { id: 'de', name: 'Germany', dialCode: '49', format: '1234 567890' },\n { id: 'fr', name: 'France', dialCode: '33', format: '1 23 45 67 89' },\n { id: 'be', name: 'Belgium', dialCode: '32', format: '1 23 45 67 89' },\n { id: 'ch', name: 'Switzerland', dialCode: '41', format: '12 345 67 89' },\n];\n\nconst REGIONAL_INDICATOR_A = 0x1f1e6;\nconst LETTER_A = 'A'.charCodeAt(0);\n\n/**\n * The flag emoji for a country code, built from regional indicator symbols.\n *\n * This is the one place emoji appear in a Kanto interface. They are here\n * because no flag icon set ships with the system, and a country picker without\n * flags is markedly slower to scan.\n */\nexport function flagEmoji(id: string): string {\n if (!/^[a-z]{2}$/i.test(id)) return '';\n return String.fromCodePoint(\n ...[...id.toUpperCase()].map(\n (letter) => REGIONAL_INDICATOR_A + letter.charCodeAt(0) - LETTER_A,\n ),\n );\n}\n\n/** Keeps only the digits — what gets stored and submitted. */\nexport function digitsOnly(value: string): string {\n return value.replace(/\\D/g, '');\n}\n\n/**\n * Groups digits for display, per country.\n *\n * North American numbers read as `123 456 7890`, French ones as\n * `6 12 34 56 78` — a single leading digit, then pairs. Everything else falls\n * back to groups of three.\n */\nexport function formatNationalNumber(digits: string, country: KtCountry | undefined): string {\n if (!digits) return '';\n\n const groups: string[] = [];\n let rest = digits;\n\n if (country?.id === 'fr') {\n groups.push(rest.slice(0, 1));\n rest = rest.slice(1);\n while (rest) {\n groups.push(rest.slice(0, 2));\n rest = rest.slice(2);\n }\n } else if (country?.id === 'us' || country?.id === 'ca') {\n for (const size of [3, 3, 4]) {\n if (!rest) break;\n groups.push(rest.slice(0, size));\n rest = rest.slice(size);\n }\n if (rest) groups.push(rest);\n } else {\n while (rest) {\n groups.push(rest.slice(0, 3));\n rest = rest.slice(3);\n }\n }\n\n return groups.filter(Boolean).join(' ');\n}\n\n/** Filters by name, dial code or country code — whatever the user types. */\nexport function searchCountries(\n countries: readonly KtCountry[],\n query: string,\n): readonly KtCountry[] {\n const needle = query.trim().toLowerCase();\n if (!needle) return countries;\n\n return countries.filter(\n (country) =>\n country.name.toLowerCase().includes(needle) ||\n country.dialCode.includes(needle.replace(/^\\+/, '')) ||\n country.id === needle,\n );\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 { live } from 'lit/directives/live.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 {\n DEFAULT_COUNTRIES,\n digitsOnly,\n flagEmoji,\n formatNationalNumber,\n searchCountries,\n type KtCountry,\n} from '#internal/countries';\nimport '../../core/kt-icon/kt-icon.js';\n\nexport type KtInputSize = 'small' | 'medium' | 'large';\n\n/** Icon size inside a field, at every field size. */\nconst ICON_SIZE = 18;\n\n/**\n * A single-line text field.\n *\n * Borderless by design: the field is a fill on `--color-dark-12` that gains a\n * 2px *outline* — grey on hover, primary on focus, danger on error. An outline\n * sits outside the box, so nothing reflows when the state changes.\n *\n * The element is form-associated: it serialises into `FormData` under its\n * `name`, resets with the form, and reports validity like a native input.\n *\n * @element kt-input\n *\n * @csspart base - The field container.\n * @csspart control - The native `<input>`.\n * @csspart actions - The trailing icon row.\n *\n * @fires kt-input - On every keystroke. `detail: { value }`.\n * @fires kt-change - When the value is committed (blur or Enter). `detail: { value }`.\n * @fires kt-clear - The clear button was pressed.\n *\n * @example\n * ```html\n * <kt-input placeholder=\"Search everything...\" icon=\"search\"></kt-input>\n * <kt-input type=\"password\" name=\"password\"></kt-input>\n * <kt-input error=\"Invalid email address\" value=\"not-an-address\"></kt-input>\n * ```\n */\nexport class KtInput extends KtElement {\n static readonly formAssociated = true;\n\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n }\n\n .field {\n position: relative;\n display: inline-flex;\n align-items: center;\n width: 100%;\n height: var(--button-height);\n padding: 0 var(--button-padding-x);\n gap: var(--gap-button);\n background-color: var(--surface-field);\n border-radius: var(--radius-input);\n /* A resting hairline. A field is a fill on --surface-field, which is\n one ramp step from the page in dark and almost the same colour in\n light — so on a card or inside a modal it simply disappeared and\n read as a bare native control.\n\n A border rather than an outline, because the control inside fills\n the field exactly and a coincident outline is painted over by the\n native widget. A border insets the control by its own width, so it\n cannot be covered. box-sizing: border-box keeps the outer size.\n\n The hover and focus rings stay outlines on top of it, and the\n transparent resting outline is what they animate from: without it\n outline-color starts at the initial value, which resolves to the\n text colour, and hover flashed near-white before settling. */\n border: var(--border-width) solid var(--border-field);\n outline: var(--outline-width) solid transparent;\n transition: outline-color var(--duration-instant);\n }\n\n /* Outline, never border: it sits outside the box, so hover and focus\n change nothing about the layout. */\n .field:hover {\n outline: var(--outline-width) solid var(--color-text-700);\n }\n .field:focus-within {\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n\n .small {\n height: var(--button-height-small);\n }\n .large {\n height: var(--button-height-large);\n }\n\n .error,\n .error:hover,\n .error:focus-within {\n outline: var(--outline-width) solid var(--color-danger-base);\n }\n .error input {\n color: var(--color-danger-text);\n }\n\n .disabled {\n background-color: var(--color-dark-14);\n pointer-events: none;\n }\n .disabled input {\n color: var(--text-disabled);\n }\n\n input {\n width: 100%;\n min-width: 0;\n padding: 0;\n color: var(--text-body);\n font: var(--font-input);\n background: transparent;\n border: none;\n outline: none;\n }\n\n input::placeholder {\n color: var(--text-muted);\n }\n\n /* The clear button is ours; the browser's is redundant. */\n input::-webkit-search-cancel-button {\n display: none;\n }\n\n .actions {\n display: flex;\n flex: none;\n align-items: center;\n gap: var(--gap-button);\n }\n\n .icon-button {\n display: inline-flex;\n align-items: center;\n padding: 0;\n color: var(--text-body);\n background: none;\n border: none;\n cursor: pointer;\n }\n\n .icon-button:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n border-radius: 2px;\n }\n\n .clear {\n transition: transform var(--duration-instant) ease-in-out;\n }\n .clear:hover {\n transform: rotate(90deg);\n }\n\n .adornment {\n display: flex;\n align-items: center;\n color: var(--text-muted);\n }\n\n .error-icon {\n color: var(--color-danger-text);\n }\n\n /* === PHONE MODE === */\n .country {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n gap: var(--gap-element);\n height: 100%;\n margin-right: var(--button-padding-x);\n padding: 0 var(--button-padding-x) 0 0;\n color: var(--text-body);\n background: none;\n border: none;\n border-right: var(--border-width) solid var(--color-dark-16);\n cursor: pointer;\n font: var(--font-normal-regular);\n user-select: none;\n }\n\n .country:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: -2px;\n }\n\n .chevron {\n display: inline-flex;\n transform-origin: 50% 50%;\n transition: transform var(--duration-fast) ease-in-out;\n }\n .chevron.open {\n transform: scaleY(-1);\n }\n\n .dial {\n color: var(--text-muted);\n }\n\n .country-panel {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: var(--z-dropdown);\n display: flex;\n flex-direction: column;\n gap: var(--gap-element);\n width: 280px;\n max-height: 225px;\n padding: var(--padding-expand);\n background: var(--color-dark-20);\n border-radius: var(--radius-input);\n }\n\n .country-search {\n width: 100%;\n height: var(--button-height-small);\n padding: 0 12px;\n color: var(--text-body);\n font: var(--font-normal-regular);\n background: var(--color-dark-12);\n border: none;\n border-radius: var(--radius-input);\n outline: none;\n }\n\n .country-list {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: var(--gap-element);\n margin: 0;\n padding: 0;\n overflow-y: auto;\n list-style: none;\n scrollbar-width: thin;\n }\n\n .country-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: var(--radius-input);\n cursor: pointer;\n font: var(--font-normal-regular);\n }\n .country-item:hover,\n .country-item[aria-selected='true'] {\n background: var(--color-dark-23);\n }\n\n .country-name {\n flex: 1;\n }\n\n .country-empty {\n padding: 8px 12px;\n color: var(--text-muted);\n font: var(--font-normal-small);\n }\n `,\n ];\n\n @query('input')\n private input!: HTMLInputElement;\n\n private internals: UsableInternals | null = null;\n\n /** True while a `password` field is showing its contents. */\n @state()\n private passwordVisible = false;\n\n @state()\n private countryOpen = false;\n\n @state()\n private countryQuery = '';\n\n /** The field's value. The `value` attribute seeds it and acts as the reset value. */\n @property({ type: String })\n value = '';\n\n @property({ type: String })\n name = '';\n\n /** Any native input type. `password` adds the reveal toggle. */\n @property({ type: String })\n type = 'text';\n\n @property({ type: String })\n placeholder = '';\n\n /** Field height: 32 / 40 / 48px at the desktop scale. */\n @property({ type: String, reflect: true })\n size: KtInputSize = 'medium';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /** Trailing Lucide icon, kebab-case. */\n @property({ type: String })\n icon = '';\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 /** Shows the clear button once there is something to clear. */\n @property({ type: Boolean })\n clearable = true;\n\n /** Accessible name, when no `<kt-label-input>` wraps the field. */\n @property({ type: String })\n label = '';\n\n @property({ type: String })\n autocomplete = '';\n\n @property({ type: Number })\n maxlength?: number;\n\n /**\n * Countries offered in phone mode. Replace it to widen the list.\n */\n @property({ attribute: false })\n countries: readonly KtCountry[] = DEFAULT_COUNTRIES;\n\n /** Selected country in phone mode, as an ISO 3166-1 alpha-2 code. */\n @property({ type: String })\n country = 'us';\n\n /** The value the enclosing form resets to. */\n private defaultValue = '';\n\n override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.closeCountryPanel);\n this.internals ??= attachFormInternals(this);\n this.defaultValue = this.value;\n setFormValue(this.internals, this.formValue);\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (\n changed.has('value') ||\n changed.has('required') ||\n changed.has('error') ||\n changed.has('country')\n ) {\n setFormValue(this.internals, this.value);\n this.refreshValidity();\n }\n }\n\n private refreshValidity(): void {\n const missing = this.required && this.value.length === 0;\n const message = this.error || (missing ? 'This field is required.' : '');\n setValidity(\n this.internals,\n { valueMissing: missing, customError: Boolean(this.error) },\n message,\n );\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('pointerdown', this.closeCountryPanel);\n }\n\n /** Called by the platform when the enclosing form is reset. */\n formResetCallback(): void {\n this.value = this.defaultValue;\n this.passwordVisible = false;\n }\n\n /** Called by the platform when the browser restores a session. */\n formStateRestoreCallback(state: string): void {\n this.value = state;\n }\n\n override focus(options?: FocusOptions): void {\n this.input?.focus(options);\n }\n\n override blur(): void {\n this.input?.blur();\n }\n\n /** Selects the field's contents, as `HTMLInputElement.select()` does. */\n select(): void {\n this.input?.select();\n }\n\n /** Phone mode: the country picker, digit-only storage and grouped display. */\n private get isPhone(): boolean {\n return this.type === 'tel';\n }\n\n private get selectedCountry(): KtCountry | undefined {\n return this.countries.find((candidate) => candidate.id === this.country);\n }\n\n /**\n * What the form receives. In phone mode that is the full international\n * number — submitting national digits alone would throw away the country\n * the user picked.\n */\n private get formValue(): string {\n if (!this.isPhone || !this.value) return this.value;\n return `+${this.selectedCountry?.dialCode ?? ''}${this.value}`;\n }\n\n private get displayValue(): string {\n return this.isPhone ? formatNationalNumber(this.value, this.selectedCountry) : this.value;\n }\n\n private get showClear(): boolean {\n return this.clearable && this.value.length > 0 && !this.readonly && !this.disabled;\n }\n\n private get resolvedType(): string {\n // Phone mode renders grouped digits, which type=\"tel\" would not accept\n // back; the value is normalised to digits on input either way.\n if (this.isPhone) return 'text';\n if (this.type !== 'password') return this.type;\n return this.passwordVisible ? 'text' : 'password';\n }\n\n private onInput(event: Event): void {\n const raw = (event.target as HTMLInputElement).value;\n this.value = this.isPhone ? digitsOnly(raw) : raw;\n emit(this, 'kt-input', { value: this.value });\n }\n\n private toggleCountryPanel(): void {\n this.countryOpen = !this.countryOpen;\n this.countryQuery = '';\n }\n\n private selectCountry(country: KtCountry): void {\n this.country = country.id;\n this.countryOpen = false;\n this.countryQuery = '';\n emit(this, 'kt-country-change', { country: country.id, dialCode: country.dialCode });\n this.focus();\n }\n\n private closeCountryPanel = (event: Event): void => {\n if (event.composedPath().includes(this)) return;\n this.countryOpen = false;\n };\n\n private onCountryKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Escape' && this.countryOpen) {\n event.stopPropagation();\n this.countryOpen = false;\n this.shadowRoot?.querySelector<HTMLButtonElement>('.country')?.focus();\n }\n }\n\n private renderCountryPicker(): TemplateResult {\n const selected = this.selectedCountry;\n const matches = searchCountries(this.countries, this.countryQuery);\n\n return html`<button\n type=\"button\"\n class=\"country\"\n aria-haspopup=\"listbox\"\n aria-expanded=${this.countryOpen ? 'true' : 'false'}\n aria-label=${`Country code: ${selected?.name ?? 'none'}`}\n ?disabled=${this.disabled || this.readonly}\n @click=${this.toggleCountryPanel}\n >\n <span aria-hidden=\"true\">${flagEmoji(this.country)}</span>\n <span class=\"dial\">+${selected?.dialCode ?? ''}</span>\n <span class=${classMap({ chevron: true, open: this.countryOpen })}>\n <kt-icon name=\"chevron-down\" size=\"14\"></kt-icon>\n </span>\n </button>\n ${\n this.countryOpen\n ? html`<div class=\"country-panel\" @pointerdown=${(e: Event) => e.stopPropagation()}>\n <input\n class=\"country-search\"\n placeholder=\"Search country or dial code\"\n .value=${this.countryQuery}\n aria-label=\"Search country or dial code\"\n @input=${(e: Event) => {\n this.countryQuery = (e.target as HTMLInputElement).value;\n }}\n />\n <ul class=\"country-list\" role=\"listbox\">\n ${\n matches.length === 0\n ? html`<li class=\"country-empty\">No country found</li>`\n : matches.map(\n (candidate) =>\n html`<li\n class=\"country-item\"\n role=\"option\"\n aria-selected=${candidate.id === this.country ? 'true' : 'false'}\n @click=${() => this.selectCountry(candidate)}\n >\n <span aria-hidden=\"true\">${flagEmoji(candidate.id)}</span>\n <span class=\"country-name\">${candidate.name}</span>\n <span class=\"dial\">+${candidate.dialCode}</span>\n </li>`,\n )\n }\n </ul>\n </div>`\n : nothing\n }`;\n }\n\n private onChange(event: Event): void {\n // The native change event does not cross the shadow boundary; re-emit it\n // under a name consumers can actually listen for.\n event.stopPropagation();\n emit(this, 'kt-change', { value: this.value });\n }\n\n private clear(): void {\n this.value = '';\n emit(this, 'kt-clear');\n emit(this, 'kt-input', { value: '' });\n emit(this, 'kt-change', { value: '' });\n this.focus();\n }\n\n private togglePassword(): void {\n this.passwordVisible = !this.passwordVisible;\n }\n\n /** Clicking the padding around the input should focus it, as on a native field. */\n private onFieldPointerDown(event: PointerEvent): void {\n if (event.target === this.input) return;\n if ((event.target as HTMLElement).closest('button')) return;\n event.preventDefault();\n this.focus();\n }\n\n override render(): TemplateResult {\n const hasActions =\n this.type === 'password' || Boolean(this.icon) || Boolean(this.error) || this.showClear;\n\n return html`<div\n part=\"base\"\n class=${classMap({\n field: true,\n [this.size]: true,\n error: Boolean(this.error),\n disabled: this.disabled,\n })}\n @pointerdown=${this.onFieldPointerDown}\n @keydown=${this.onCountryKeyDown}\n >\n ${\n // The icon only shows that something is wrong; this is what gets read\n // out. aria-describedby rather than aria-errormessage, which most\n // screen readers still ignore.\n this.error\n ? html`<span id=\"error-message\" class=\"visually-hidden\">${this.error}</span>`\n : nothing\n }\n ${this.isPhone ? this.renderCountryPicker() : nothing}\n\n <input\n part=\"control\"\n type=${this.resolvedType}\n name=${this.name || nothing}\n .value=${live(this.displayValue)}\n placeholder=${this.placeholder || this.selectedCountry?.format || nothing}\n autocomplete=${this.autocomplete || nothing}\n inputmode=${this.isPhone ? 'tel' : nothing}\n maxlength=${this.maxlength ?? nothing}\n aria-label=${this.label || nothing}\n aria-invalid=${this.error ? 'true' : nothing}\n aria-describedby=${this.error ? 'error-message' : nothing}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?required=${this.required}\n @input=${this.onInput}\n @change=${this.onChange}\n />\n\n ${\n hasActions\n ? html`<div part=\"actions\" class=\"actions\">\n ${\n this.type === 'password'\n ? html`<button\n type=\"button\"\n class=\"icon-button\"\n tabindex=\"-1\"\n aria-label=${this.passwordVisible ? 'Hide password' : 'Show password'}\n @click=${this.togglePassword}\n >\n <kt-icon\n name=${this.passwordVisible ? 'eye-off' : 'eye'}\n size=${ICON_SIZE}\n ></kt-icon>\n </button>`\n : nothing\n }\n ${\n this.icon\n ? html`<span class=\"adornment\">\n <kt-icon name=${this.icon} size=${ICON_SIZE}></kt-icon>\n </span>`\n : nothing\n }\n ${\n this.error\n ? html`<span class=\"adornment error-icon\" title=${this.error}>\n <kt-icon name=\"circle-alert\" size=${ICON_SIZE} label=${this.error}></kt-icon>\n </span>`\n : nothing\n }\n ${\n this.showClear\n ? html`<button\n type=\"button\"\n class=\"icon-button clear\"\n tabindex=\"-1\"\n aria-label=\"Clear\"\n @click=${this.clear}\n >\n <kt-icon name=\"x\" size=${ICON_SIZE}></kt-icon>\n </button>`\n : nothing\n }\n </div>`\n : nothing\n }\n </div>`;\n }\n}\n\ndefineElement('kt-input', KtInput);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-input': KtInput;\n }\n}\n"],"names":["DEFAULT_COUNTRIES","REGIONAL_INDICATOR_A","LETTER_A","flagEmoji","id","letter","digitsOnly","value","formatNationalNumber","digits","country","groups","rest","size","searchCountries","countries","query","needle","ICON_SIZE","KtInput","KtElement","event","css","attachFormInternals","setFormValue","changed","missing","message","setValidity","state","options","candidate","raw","emit","selected","matches","html","classMap","e","nothing","hasActions","live","__decorateClass","property","defineElement"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type TemplateResult } from 'lit';
|
|
1
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
2
|
import { KtElement } from '#internal/kt-element';
|
|
3
3
|
import { type KtOption } from '#internal/listbox';
|
|
4
4
|
import '../../core/kt-icon/kt-icon.js';
|
|
@@ -19,8 +19,11 @@ import '../../core/kt-icon/kt-icon.js';
|
|
|
19
19
|
* @fires kt-filter - The query changed. `detail: { query }`.
|
|
20
20
|
*/
|
|
21
21
|
export declare class KtInputMenu extends KtElement {
|
|
22
|
+
static readonly formAssociated = true;
|
|
22
23
|
static styles: import("lit").CSSResultGroup[];
|
|
23
24
|
private input;
|
|
25
|
+
private internals;
|
|
26
|
+
private defaultValue;
|
|
24
27
|
private readonly listId;
|
|
25
28
|
private open;
|
|
26
29
|
private query;
|
|
@@ -28,12 +31,18 @@ export declare class KtInputMenu extends KtElement {
|
|
|
28
31
|
options: readonly KtOption[];
|
|
29
32
|
value: string | number | null;
|
|
30
33
|
placeholder: string;
|
|
34
|
+
name: string;
|
|
31
35
|
disabled: boolean;
|
|
36
|
+
required: boolean;
|
|
32
37
|
error: string;
|
|
33
38
|
label: string;
|
|
34
39
|
emptyText: string;
|
|
35
40
|
connectedCallback(): void;
|
|
36
41
|
disconnectedCallback(): void;
|
|
42
|
+
willUpdate(changed: PropertyValues<this>): void;
|
|
43
|
+
formResetCallback(): void;
|
|
44
|
+
formStateRestoreCallback(state: string): void;
|
|
45
|
+
focus(options?: FocusOptions): void;
|
|
37
46
|
get selectedOption(): KtOption | undefined;
|
|
38
47
|
/** Options after the current query, which is what the keyboard walks. */
|
|
39
48
|
private get visibleOptions();
|
|
@@ -1,27 +1,31 @@
|
|
|
1
|
-
import { css as
|
|
1
|
+
import { css as y, nothing as a, html as l } from "lit";
|
|
2
2
|
import { query as g, state as v, property as s } from "lit/decorators.js";
|
|
3
|
-
import { classMap as
|
|
3
|
+
import { classMap as d } from "lit/directives/class-map.js";
|
|
4
4
|
import { live as x } from "lit/directives/live.js";
|
|
5
|
-
import { K as f, d as w } from "../../../chunks/kt-element-
|
|
6
|
-
import { u as k, e as
|
|
7
|
-
import { a as $,
|
|
5
|
+
import { K as f, d as w } from "../../../chunks/kt-element-B_jjQDhg.js";
|
|
6
|
+
import { u as k, e as p } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
7
|
+
import { a as $, s as I, b as q } from "../../../chunks/form-control-CxjBTt1c.js";
|
|
8
|
+
import { a as D, b as E, o as m, f as c, l as O, n as C } from "../../../chunks/listbox-Sm3nvsC6.js";
|
|
8
9
|
import "../../core/kt-icon/kt-icon.js";
|
|
9
|
-
var
|
|
10
|
-
for (var
|
|
11
|
-
(b =
|
|
12
|
-
return
|
|
10
|
+
var S = Object.defineProperty, i = (h, t, o, r) => {
|
|
11
|
+
for (var n = void 0, u = h.length - 1, b; u >= 0; u--)
|
|
12
|
+
(b = h[u]) && (n = b(t, o, n) || n);
|
|
13
|
+
return n && S(t, o, n), n;
|
|
13
14
|
};
|
|
14
15
|
class e extends f {
|
|
15
16
|
constructor() {
|
|
16
|
-
super(...arguments), this.listId = k("kt-input-menu-list"), this.open = !1, this.query = "", this.activeIndex = -1, this.options = [], this.value = null, this.placeholder = "", this.disabled = !1, this.error = "", this.label = "", this.emptyText = "No options available", this.onDocumentPointerDown = (t) => {
|
|
17
|
+
super(...arguments), this.internals = null, this.defaultValue = null, this.listId = k("kt-input-menu-list"), this.open = !1, this.query = "", this.activeIndex = -1, this.options = [], this.value = null, this.placeholder = "", this.name = "", this.disabled = !1, this.required = !1, this.error = "", this.label = "", this.emptyText = "No options available", this.onDocumentPointerDown = (t) => {
|
|
17
18
|
t.composedPath().includes(this) || this.close();
|
|
18
19
|
};
|
|
19
20
|
}
|
|
21
|
+
static {
|
|
22
|
+
this.formAssociated = !0;
|
|
23
|
+
}
|
|
20
24
|
static {
|
|
21
25
|
this.styles = [
|
|
22
26
|
f.styles,
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
D,
|
|
28
|
+
y`
|
|
25
29
|
:host {
|
|
26
30
|
position: relative;
|
|
27
31
|
display: block;
|
|
@@ -93,7 +97,7 @@ class e extends f {
|
|
|
93
97
|
}
|
|
94
98
|
|
|
95
99
|
input::placeholder {
|
|
96
|
-
color: var(--
|
|
100
|
+
color: var(--text-muted);
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
.icon-button {
|
|
@@ -124,17 +128,37 @@ class e extends f {
|
|
|
124
128
|
];
|
|
125
129
|
}
|
|
126
130
|
connectedCallback() {
|
|
127
|
-
super.connectedCallback(), document.addEventListener("pointerdown", this.onDocumentPointerDown);
|
|
131
|
+
super.connectedCallback(), this.internals ??= $(this), this.defaultValue = this.value, document.addEventListener("pointerdown", this.onDocumentPointerDown);
|
|
128
132
|
}
|
|
129
133
|
disconnectedCallback() {
|
|
130
134
|
super.disconnectedCallback(), document.removeEventListener("pointerdown", this.onDocumentPointerDown);
|
|
131
135
|
}
|
|
136
|
+
willUpdate(t) {
|
|
137
|
+
if (t.has("value") || t.has("required") || t.has("error")) {
|
|
138
|
+
I(this.internals, this.value === null ? null : String(this.value));
|
|
139
|
+
const o = this.required && this.value === null;
|
|
140
|
+
q(
|
|
141
|
+
this.internals,
|
|
142
|
+
{ valueMissing: o, customError: !!this.error },
|
|
143
|
+
this.error || (o ? "Select an option." : "")
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
formResetCallback() {
|
|
148
|
+
this.value = this.defaultValue, this.close();
|
|
149
|
+
}
|
|
150
|
+
formStateRestoreCallback(t) {
|
|
151
|
+
this.value = t;
|
|
152
|
+
}
|
|
153
|
+
focus(t) {
|
|
154
|
+
this.input?.focus(t);
|
|
155
|
+
}
|
|
132
156
|
get selectedOption() {
|
|
133
157
|
return this.options.find((t) => t.id === this.value);
|
|
134
158
|
}
|
|
135
159
|
/** Options after the current query, which is what the keyboard walks. */
|
|
136
160
|
get visibleOptions() {
|
|
137
|
-
return
|
|
161
|
+
return E(this.options, this.query);
|
|
138
162
|
}
|
|
139
163
|
/**
|
|
140
164
|
* While filtering, the field shows the query; otherwise it shows the chosen
|
|
@@ -144,48 +168,48 @@ class e extends f {
|
|
|
144
168
|
get displayValue() {
|
|
145
169
|
if (this.open && this.query) return this.query;
|
|
146
170
|
const t = this.selectedOption;
|
|
147
|
-
return t ?
|
|
171
|
+
return t ? m(t) : this.query;
|
|
148
172
|
}
|
|
149
173
|
openList() {
|
|
150
|
-
this.disabled || this.open || (this.open = !0, this.activeIndex =
|
|
174
|
+
this.disabled || this.open || (this.open = !0, this.activeIndex = c(this.visibleOptions));
|
|
151
175
|
}
|
|
152
176
|
close() {
|
|
153
177
|
this.open = !1, this.query = "", this.activeIndex = -1;
|
|
154
178
|
}
|
|
155
179
|
onInput(t) {
|
|
156
|
-
this.query = t.target.value, this.open = !0, this.activeIndex =
|
|
180
|
+
this.query = t.target.value, this.open = !0, this.activeIndex = c(this.visibleOptions), p(this, "kt-filter", { query: this.query });
|
|
157
181
|
}
|
|
158
182
|
choose(t) {
|
|
159
|
-
t.disabled || (this.value = t.id, this.close(),
|
|
183
|
+
t.disabled || (this.value = t.id, this.close(), p(this, "kt-change", { value: t.id, option: t }));
|
|
160
184
|
}
|
|
161
185
|
clear(t) {
|
|
162
|
-
t.stopPropagation(), this.value = null, this.query = "",
|
|
186
|
+
t.stopPropagation(), this.value = null, this.query = "", p(this, "kt-change", { value: null, option: null }), this.input?.focus();
|
|
163
187
|
}
|
|
164
188
|
onKeyDown(t) {
|
|
165
|
-
const
|
|
189
|
+
const o = this.visibleOptions;
|
|
166
190
|
switch (t.key) {
|
|
167
191
|
case "ArrowDown":
|
|
168
192
|
case "ArrowUp":
|
|
169
193
|
if (t.preventDefault(), !this.open) return this.openList();
|
|
170
|
-
this.activeIndex =
|
|
171
|
-
|
|
194
|
+
this.activeIndex = C(
|
|
195
|
+
o,
|
|
172
196
|
this.activeIndex,
|
|
173
197
|
t.key === "ArrowDown" ? 1 : -1
|
|
174
198
|
);
|
|
175
199
|
return;
|
|
176
200
|
case "Home":
|
|
177
201
|
if (!this.open) return;
|
|
178
|
-
t.preventDefault(), this.activeIndex =
|
|
202
|
+
t.preventDefault(), this.activeIndex = c(o);
|
|
179
203
|
return;
|
|
180
204
|
case "End":
|
|
181
205
|
if (!this.open) return;
|
|
182
|
-
t.preventDefault(), this.activeIndex =
|
|
206
|
+
t.preventDefault(), this.activeIndex = O(o);
|
|
183
207
|
return;
|
|
184
208
|
case "Enter": {
|
|
185
209
|
if (!this.open) return;
|
|
186
210
|
t.preventDefault();
|
|
187
|
-
const
|
|
188
|
-
|
|
211
|
+
const r = o[this.activeIndex];
|
|
212
|
+
r && this.choose(r);
|
|
189
213
|
return;
|
|
190
214
|
}
|
|
191
215
|
case "Escape":
|
|
@@ -200,9 +224,9 @@ class e extends f {
|
|
|
200
224
|
return `${this.listId}-option-${t}`;
|
|
201
225
|
}
|
|
202
226
|
render() {
|
|
203
|
-
const t = this.visibleOptions,
|
|
227
|
+
const t = this.visibleOptions, o = this.selectedOption !== void 0 && !this.disabled;
|
|
204
228
|
return l`<div
|
|
205
|
-
class=${
|
|
229
|
+
class=${d({ open: this.open, error: !!this.error })}
|
|
206
230
|
@keydown=${this.onKeyDown}
|
|
207
231
|
>
|
|
208
232
|
<div part="control" class="control" @click=${this.openList}>
|
|
@@ -222,7 +246,7 @@ class e extends f {
|
|
|
222
246
|
@input=${this.onInput}
|
|
223
247
|
/>
|
|
224
248
|
|
|
225
|
-
${
|
|
249
|
+
${o ? l`<button
|
|
226
250
|
type="button"
|
|
227
251
|
class="icon-button clear"
|
|
228
252
|
aria-label="Clear"
|
|
@@ -237,8 +261,8 @@ class e extends f {
|
|
|
237
261
|
class="icon-button toggle"
|
|
238
262
|
aria-label=${this.open ? "Close list" : "Open list"}
|
|
239
263
|
tabindex="-1"
|
|
240
|
-
@click=${(
|
|
241
|
-
|
|
264
|
+
@click=${(r) => {
|
|
265
|
+
r.stopPropagation(), this.open ? this.close() : this.openList();
|
|
242
266
|
}}
|
|
243
267
|
>
|
|
244
268
|
<kt-icon name="chevron-down" size="18"></kt-icon>
|
|
@@ -248,62 +272,68 @@ class e extends f {
|
|
|
248
272
|
<ul
|
|
249
273
|
part="popup"
|
|
250
274
|
id=${this.listId}
|
|
251
|
-
class=${
|
|
275
|
+
class=${d({ popup: !0, open: this.open })}
|
|
252
276
|
role="listbox"
|
|
253
277
|
aria-label=${this.label || this.placeholder}
|
|
254
278
|
>
|
|
255
279
|
${t.length === 0 ? l`<li class="empty">${this.emptyText}</li>` : t.map(
|
|
256
|
-
(
|
|
280
|
+
(r, n) => l`<li
|
|
257
281
|
part="option"
|
|
258
|
-
id=${this.optionId(
|
|
259
|
-
class=${
|
|
282
|
+
id=${this.optionId(n)}
|
|
283
|
+
class=${d({
|
|
260
284
|
option: !0,
|
|
261
|
-
selected:
|
|
262
|
-
active:
|
|
263
|
-
disabled: !!
|
|
285
|
+
selected: r.id === this.value,
|
|
286
|
+
active: n === this.activeIndex,
|
|
287
|
+
disabled: !!r.disabled
|
|
264
288
|
})}
|
|
265
289
|
role="option"
|
|
266
|
-
aria-selected=${
|
|
267
|
-
@click=${() => this.choose(
|
|
290
|
+
aria-selected=${r.id === this.value ? "true" : "false"}
|
|
291
|
+
@click=${() => this.choose(r)}
|
|
268
292
|
>
|
|
269
|
-
${
|
|
293
|
+
${m(r)}
|
|
270
294
|
</li>`
|
|
271
295
|
)}
|
|
272
296
|
</ul>
|
|
273
297
|
</div>`;
|
|
274
298
|
}
|
|
275
299
|
}
|
|
276
|
-
|
|
300
|
+
i([
|
|
277
301
|
g("input")
|
|
278
302
|
], e.prototype, "input");
|
|
279
|
-
|
|
303
|
+
i([
|
|
280
304
|
v()
|
|
281
305
|
], e.prototype, "open");
|
|
282
|
-
|
|
306
|
+
i([
|
|
283
307
|
v()
|
|
284
308
|
], e.prototype, "query");
|
|
285
|
-
|
|
309
|
+
i([
|
|
286
310
|
v()
|
|
287
311
|
], e.prototype, "activeIndex");
|
|
288
|
-
|
|
312
|
+
i([
|
|
289
313
|
s({ attribute: !1 })
|
|
290
314
|
], e.prototype, "options");
|
|
291
|
-
|
|
315
|
+
i([
|
|
292
316
|
s({ type: String })
|
|
293
317
|
], e.prototype, "value");
|
|
294
|
-
|
|
318
|
+
i([
|
|
295
319
|
s({ type: String })
|
|
296
320
|
], e.prototype, "placeholder");
|
|
297
|
-
|
|
321
|
+
i([
|
|
322
|
+
s({ type: String })
|
|
323
|
+
], e.prototype, "name");
|
|
324
|
+
i([
|
|
298
325
|
s({ type: Boolean, reflect: !0 })
|
|
299
326
|
], e.prototype, "disabled");
|
|
300
|
-
|
|
327
|
+
i([
|
|
328
|
+
s({ type: Boolean, reflect: !0 })
|
|
329
|
+
], e.prototype, "required");
|
|
330
|
+
i([
|
|
301
331
|
s({ type: String, reflect: !0 })
|
|
302
332
|
], e.prototype, "error");
|
|
303
|
-
|
|
333
|
+
i([
|
|
304
334
|
s({ type: String })
|
|
305
335
|
], e.prototype, "label");
|
|
306
|
-
|
|
336
|
+
i([
|
|
307
337
|
s({ type: String, attribute: "empty-text" })
|
|
308
338
|
], e.prototype, "emptyText");
|
|
309
339
|
w("kt-input-menu", e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-input-menu.js","sources":["../../../../src/components/forms/kt-input-menu/kt-input-menu.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 { live } from 'lit/directives/live.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit, uniqueId } from '#internal/events';\nimport {\n filterOptions,\n firstEnabledIndex,\n lastEnabledIndex,\n listboxStyles,\n nextEnabledIndex,\n optionLabel,\n type KtOption,\n} from '#internal/listbox';\nimport '../../core/kt-icon/kt-icon.js';\n\n/**\n * A combobox: type to narrow the list, then pick.\n *\n * Reach for it over `<kt-select>` once the list is long enough that scanning it\n * is slower than typing three letters — somewhere around twenty options.\n *\n * @element kt-input-menu\n *\n * @csspart control - The field.\n * @csspart input - The native `<input>`.\n * @csspart popup - The option list.\n * @csspart option - An option row.\n *\n * @fires kt-change - An option was chosen or cleared. `detail: { value, option }`.\n * @fires kt-filter - The query changed. `detail: { query }`.\n */\nexport class KtInputMenu extends KtElement {\n static override styles = [\n KtElement.styles,\n listboxStyles,\n css`\n :host {\n position: relative;\n display: block;\n --field-height: var(--button-height);\n }\n\n .control {\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\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 background-color: var(--color-dark-20);\n border: none;\n border-radius: var(--radius-input);\n /* A resting hairline. A field is a fill on --surface-field, which is\n one ramp step from the page in dark and almost the same colour in\n light — so on a card or inside a modal it simply disappeared and\n read as a bare native control.\n\n A border rather than an outline, because the control inside fills\n the field exactly and a coincident outline is painted over by the\n native widget. A border insets the control by its own width, so it\n cannot be covered. box-sizing: border-box keeps the outer size.\n\n The hover and focus rings stay outlines on top of it, and the\n transparent resting outline is what they animate from: without it\n outline-color starts at the initial value, which resolves to the\n text colour, and hover flashed near-white before settling. */\n border: var(--border-width) solid var(--border-field);\n outline: var(--outline-width) solid transparent;\n cursor: text;\n transition:\n background-color var(--duration-instant),\n outline-color var(--duration-instant);\n }\n\n .control:hover {\n outline: var(--outline-width) solid var(--color-text-700);\n }\n .control:focus-within {\n background-color: var(--color-dark-12);\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n\n .error .control,\n .error .control:hover,\n .error .control:focus-within {\n outline: var(--outline-width) solid var(--color-danger-base);\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: 0.6;\n }\n\n input {\n width: 100%;\n min-width: 0;\n color: var(--text-body);\n font: var(--font-input);\n background: transparent;\n border: none;\n outline: none;\n }\n\n input::placeholder {\n color: var(--color-text-500);\n }\n\n .icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n color: inherit;\n background: transparent;\n border: none;\n cursor: pointer;\n }\n\n .clear {\n transition: transform var(--duration-instant) ease-in-out;\n }\n .clear:hover {\n transform: rotate(90deg);\n }\n\n .toggle {\n transition: transform var(--duration-fast) ease-in-out;\n }\n .open .toggle {\n transform: scaleY(-1);\n }\n `,\n ];\n\n @query('input')\n private input!: HTMLInputElement;\n\n private readonly listId = uniqueId('kt-input-menu-list');\n\n @state()\n private open = false;\n\n @state()\n private query = '';\n\n @state()\n private activeIndex = -1;\n\n @property({ attribute: false })\n options: readonly KtOption[] = [];\n\n @property({ type: String })\n value: string | number | null = null;\n\n @property({ type: String })\n placeholder = '';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: String, reflect: true })\n error = '';\n\n @property({ type: String })\n label = '';\n\n @property({ type: String, attribute: 'empty-text' })\n emptyText = 'No options available';\n\n override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.onDocumentPointerDown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('pointerdown', this.onDocumentPointerDown);\n }\n\n get selectedOption(): KtOption | undefined {\n return this.options.find((option) => option.id === this.value);\n }\n\n /** Options after the current query, which is what the keyboard walks. */\n private get visibleOptions(): readonly KtOption[] {\n return filterOptions(this.options, this.query);\n }\n\n /**\n * While filtering, the field shows the query; otherwise it shows the chosen\n * option. Keeping the two in one input is what makes it a combobox rather\n * than a search box that happens to sit above a list.\n */\n private get displayValue(): string {\n if (this.open && this.query) return this.query;\n const selected = this.selectedOption;\n return selected ? optionLabel(selected) : this.query;\n }\n\n private onDocumentPointerDown = (event: Event): void => {\n if (event.composedPath().includes(this)) return;\n this.close();\n };\n\n private openList(): void {\n if (this.disabled || this.open) return;\n this.open = true;\n this.activeIndex = firstEnabledIndex(this.visibleOptions);\n }\n\n private close(): void {\n this.open = false;\n this.query = '';\n this.activeIndex = -1;\n }\n\n private onInput(event: Event): void {\n this.query = (event.target as HTMLInputElement).value;\n this.open = true;\n this.activeIndex = firstEnabledIndex(this.visibleOptions);\n emit(this, 'kt-filter', { query: this.query });\n }\n\n private choose(option: KtOption): void {\n if (option.disabled) return;\n this.value = option.id;\n this.close();\n emit(this, 'kt-change', { value: option.id, option });\n }\n\n private clear(event: Event): void {\n event.stopPropagation();\n this.value = null;\n this.query = '';\n emit(this, 'kt-change', { value: null, option: null });\n this.input?.focus();\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n const options = this.visibleOptions;\n\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n event.preventDefault();\n if (!this.open) return this.openList();\n this.activeIndex = nextEnabledIndex(\n options,\n this.activeIndex,\n event.key === 'ArrowDown' ? 1 : -1,\n );\n return;\n case 'Home':\n if (!this.open) return;\n event.preventDefault();\n this.activeIndex = firstEnabledIndex(options);\n return;\n case 'End':\n if (!this.open) return;\n event.preventDefault();\n this.activeIndex = lastEnabledIndex(options);\n return;\n case 'Enter': {\n if (!this.open) return;\n event.preventDefault();\n const option = options[this.activeIndex];\n if (option) this.choose(option);\n return;\n }\n case 'Escape':\n if (!this.open) return;\n event.stopPropagation();\n this.close();\n return;\n case 'Tab':\n this.close();\n }\n }\n\n private optionId(index: number): string {\n return `${this.listId}-option-${index}`;\n }\n\n override render(): TemplateResult {\n const options = this.visibleOptions;\n const showClear = this.selectedOption !== undefined && !this.disabled;\n\n return html`<div\n class=${classMap({ open: this.open, error: Boolean(this.error) })}\n @keydown=${this.onKeyDown}\n >\n <div part=\"control\" class=\"control\" @click=${this.openList}>\n <input\n part=\"input\"\n role=\"combobox\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.listId}\n aria-autocomplete=\"list\"\n aria-activedescendant=${\n this.open && this.activeIndex >= 0 ? this.optionId(this.activeIndex) : nothing\n }\n aria-label=${this.label || nothing}\n aria-invalid=${this.error ? 'true' : nothing}\n placeholder=${this.placeholder || nothing}\n .value=${live(this.displayValue)}\n ?disabled=${this.disabled}\n @focus=${this.openList}\n @input=${this.onInput}\n />\n\n ${\n showClear\n ? html`<button\n type=\"button\"\n class=\"icon-button clear\"\n aria-label=\"Clear\"\n tabindex=\"-1\"\n @click=${this.clear}\n >\n <kt-icon name=\"x\" size=\"18\"></kt-icon>\n </button>`\n : nothing\n }\n\n <button\n type=\"button\"\n class=\"icon-button toggle\"\n aria-label=${this.open ? 'Close list' : 'Open list'}\n tabindex=\"-1\"\n @click=${(event: Event) => {\n event.stopPropagation();\n if (this.open) this.close();\n else this.openList();\n }}\n >\n <kt-icon name=\"chevron-down\" size=\"18\"></kt-icon>\n </button>\n </div>\n\n <ul\n part=\"popup\"\n id=${this.listId}\n class=${classMap({ popup: true, open: this.open })}\n role=\"listbox\"\n aria-label=${this.label || this.placeholder}\n >\n ${\n options.length === 0\n ? html`<li class=\"empty\">${this.emptyText}</li>`\n : options.map(\n (option, index) =>\n html`<li\n part=\"option\"\n id=${this.optionId(index)}\n class=${classMap({\n option: true,\n selected: option.id === this.value,\n active: index === this.activeIndex,\n disabled: Boolean(option.disabled),\n })}\n role=\"option\"\n aria-selected=${option.id === this.value ? 'true' : 'false'}\n @click=${() => this.choose(option)}\n >\n ${optionLabel(option)}\n </li>`,\n )\n }\n </ul>\n </div>`;\n }\n}\n\ndefineElement('kt-input-menu', KtInputMenu);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-input-menu': KtInputMenu;\n }\n}\n"],"names":["KtInputMenu","KtElement","uniqueId","event","listboxStyles","css","option","filterOptions","selected","optionLabel","firstEnabledIndex","emit","options","nextEnabledIndex","lastEnabledIndex","index","showClear","html","classMap","nothing","live","__decorateClass","query","state","property","defineElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"kt-input-menu.js","sources":["../../../../src/components/forms/kt-input-menu/kt-input-menu.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, uniqueId } from '#internal/events';\nimport {\n attachFormInternals,\n setFormValue,\n setValidity,\n type UsableInternals,\n} from '#internal/form-control';\nimport {\n filterOptions,\n firstEnabledIndex,\n lastEnabledIndex,\n listboxStyles,\n nextEnabledIndex,\n optionLabel,\n type KtOption,\n} from '#internal/listbox';\nimport '../../core/kt-icon/kt-icon.js';\n\n/**\n * A combobox: type to narrow the list, then pick.\n *\n * Reach for it over `<kt-select>` once the list is long enough that scanning it\n * is slower than typing three letters — somewhere around twenty options.\n *\n * @element kt-input-menu\n *\n * @csspart control - The field.\n * @csspart input - The native `<input>`.\n * @csspart popup - The option list.\n * @csspart option - An option row.\n *\n * @fires kt-change - An option was chosen or cleared. `detail: { value, option }`.\n * @fires kt-filter - The query changed. `detail: { query }`.\n */\nexport class KtInputMenu extends KtElement {\n static readonly formAssociated = true;\n\n static override styles = [\n KtElement.styles,\n listboxStyles,\n css`\n :host {\n position: relative;\n display: block;\n --field-height: var(--button-height);\n }\n\n .control {\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\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 background-color: var(--color-dark-20);\n border: none;\n border-radius: var(--radius-input);\n /* A resting hairline. A field is a fill on --surface-field, which is\n one ramp step from the page in dark and almost the same colour in\n light — so on a card or inside a modal it simply disappeared and\n read as a bare native control.\n\n A border rather than an outline, because the control inside fills\n the field exactly and a coincident outline is painted over by the\n native widget. A border insets the control by its own width, so it\n cannot be covered. box-sizing: border-box keeps the outer size.\n\n The hover and focus rings stay outlines on top of it, and the\n transparent resting outline is what they animate from: without it\n outline-color starts at the initial value, which resolves to the\n text colour, and hover flashed near-white before settling. */\n border: var(--border-width) solid var(--border-field);\n outline: var(--outline-width) solid transparent;\n cursor: text;\n transition:\n background-color var(--duration-instant),\n outline-color var(--duration-instant);\n }\n\n .control:hover {\n outline: var(--outline-width) solid var(--color-text-700);\n }\n .control:focus-within {\n background-color: var(--color-dark-12);\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n\n .error .control,\n .error .control:hover,\n .error .control:focus-within {\n outline: var(--outline-width) solid var(--color-danger-base);\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: 0.6;\n }\n\n input {\n width: 100%;\n min-width: 0;\n color: var(--text-body);\n font: var(--font-input);\n background: transparent;\n border: none;\n outline: none;\n }\n\n input::placeholder {\n color: var(--text-muted);\n }\n\n .icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n color: inherit;\n background: transparent;\n border: none;\n cursor: pointer;\n }\n\n .clear {\n transition: transform var(--duration-instant) ease-in-out;\n }\n .clear:hover {\n transform: rotate(90deg);\n }\n\n .toggle {\n transition: transform var(--duration-fast) ease-in-out;\n }\n .open .toggle {\n transform: scaleY(-1);\n }\n `,\n ];\n\n @query('input')\n private input!: HTMLInputElement;\n\n private internals: UsableInternals | null = null;\n private defaultValue: string | number | null = null;\n private readonly listId = uniqueId('kt-input-menu-list');\n\n @state()\n private open = false;\n\n @state()\n private query = '';\n\n @state()\n private activeIndex = -1;\n\n @property({ attribute: false })\n options: readonly KtOption[] = [];\n\n @property({ type: String })\n value: string | number | null = null;\n\n @property({ type: String })\n placeholder = '';\n\n @property({ type: String })\n name = '';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n @property({ type: String, reflect: true })\n error = '';\n\n @property({ type: String })\n label = '';\n\n @property({ type: String, attribute: 'empty-text' })\n emptyText = 'No options available';\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.internals ??= attachFormInternals(this);\n this.defaultValue = this.value;\n document.addEventListener('pointerdown', this.onDocumentPointerDown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('pointerdown', this.onDocumentPointerDown);\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has('value') || changed.has('required') || changed.has('error')) {\n // The option id is what is submitted, never the label the field shows:\n // the label is for people, the id is for the server.\n setFormValue(this.internals, this.value === null ? null : String(this.value));\n\n const missing = this.required && this.value === null;\n setValidity(\n this.internals,\n { valueMissing: missing, customError: Boolean(this.error) },\n this.error || (missing ? 'Select an option.' : ''),\n );\n }\n }\n\n formResetCallback(): void {\n this.value = this.defaultValue;\n this.close();\n }\n\n formStateRestoreCallback(state: string): void {\n this.value = state;\n }\n\n override focus(options?: FocusOptions): void {\n this.input?.focus(options);\n }\n\n get selectedOption(): KtOption | undefined {\n return this.options.find((option) => option.id === this.value);\n }\n\n /** Options after the current query, which is what the keyboard walks. */\n private get visibleOptions(): readonly KtOption[] {\n return filterOptions(this.options, this.query);\n }\n\n /**\n * While filtering, the field shows the query; otherwise it shows the chosen\n * option. Keeping the two in one input is what makes it a combobox rather\n * than a search box that happens to sit above a list.\n */\n private get displayValue(): string {\n if (this.open && this.query) return this.query;\n const selected = this.selectedOption;\n return selected ? optionLabel(selected) : this.query;\n }\n\n private onDocumentPointerDown = (event: Event): void => {\n if (event.composedPath().includes(this)) return;\n this.close();\n };\n\n private openList(): void {\n if (this.disabled || this.open) return;\n this.open = true;\n this.activeIndex = firstEnabledIndex(this.visibleOptions);\n }\n\n private close(): void {\n this.open = false;\n this.query = '';\n this.activeIndex = -1;\n }\n\n private onInput(event: Event): void {\n this.query = (event.target as HTMLInputElement).value;\n this.open = true;\n this.activeIndex = firstEnabledIndex(this.visibleOptions);\n emit(this, 'kt-filter', { query: this.query });\n }\n\n private choose(option: KtOption): void {\n if (option.disabled) return;\n this.value = option.id;\n this.close();\n emit(this, 'kt-change', { value: option.id, option });\n }\n\n private clear(event: Event): void {\n event.stopPropagation();\n this.value = null;\n this.query = '';\n emit(this, 'kt-change', { value: null, option: null });\n this.input?.focus();\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n const options = this.visibleOptions;\n\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n event.preventDefault();\n if (!this.open) return this.openList();\n this.activeIndex = nextEnabledIndex(\n options,\n this.activeIndex,\n event.key === 'ArrowDown' ? 1 : -1,\n );\n return;\n case 'Home':\n if (!this.open) return;\n event.preventDefault();\n this.activeIndex = firstEnabledIndex(options);\n return;\n case 'End':\n if (!this.open) return;\n event.preventDefault();\n this.activeIndex = lastEnabledIndex(options);\n return;\n case 'Enter': {\n if (!this.open) return;\n event.preventDefault();\n const option = options[this.activeIndex];\n if (option) this.choose(option);\n return;\n }\n case 'Escape':\n if (!this.open) return;\n event.stopPropagation();\n this.close();\n return;\n case 'Tab':\n this.close();\n }\n }\n\n private optionId(index: number): string {\n return `${this.listId}-option-${index}`;\n }\n\n override render(): TemplateResult {\n const options = this.visibleOptions;\n const showClear = this.selectedOption !== undefined && !this.disabled;\n\n return html`<div\n class=${classMap({ open: this.open, error: Boolean(this.error) })}\n @keydown=${this.onKeyDown}\n >\n <div part=\"control\" class=\"control\" @click=${this.openList}>\n <input\n part=\"input\"\n role=\"combobox\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.listId}\n aria-autocomplete=\"list\"\n aria-activedescendant=${\n this.open && this.activeIndex >= 0 ? this.optionId(this.activeIndex) : nothing\n }\n aria-label=${this.label || nothing}\n aria-invalid=${this.error ? 'true' : nothing}\n placeholder=${this.placeholder || nothing}\n .value=${live(this.displayValue)}\n ?disabled=${this.disabled}\n @focus=${this.openList}\n @input=${this.onInput}\n />\n\n ${\n showClear\n ? html`<button\n type=\"button\"\n class=\"icon-button clear\"\n aria-label=\"Clear\"\n tabindex=\"-1\"\n @click=${this.clear}\n >\n <kt-icon name=\"x\" size=\"18\"></kt-icon>\n </button>`\n : nothing\n }\n\n <button\n type=\"button\"\n class=\"icon-button toggle\"\n aria-label=${this.open ? 'Close list' : 'Open list'}\n tabindex=\"-1\"\n @click=${(event: Event) => {\n event.stopPropagation();\n if (this.open) this.close();\n else this.openList();\n }}\n >\n <kt-icon name=\"chevron-down\" size=\"18\"></kt-icon>\n </button>\n </div>\n\n <ul\n part=\"popup\"\n id=${this.listId}\n class=${classMap({ popup: true, open: this.open })}\n role=\"listbox\"\n aria-label=${this.label || this.placeholder}\n >\n ${\n options.length === 0\n ? html`<li class=\"empty\">${this.emptyText}</li>`\n : options.map(\n (option, index) =>\n html`<li\n part=\"option\"\n id=${this.optionId(index)}\n class=${classMap({\n option: true,\n selected: option.id === this.value,\n active: index === this.activeIndex,\n disabled: Boolean(option.disabled),\n })}\n role=\"option\"\n aria-selected=${option.id === this.value ? 'true' : 'false'}\n @click=${() => this.choose(option)}\n >\n ${optionLabel(option)}\n </li>`,\n )\n }\n </ul>\n </div>`;\n }\n}\n\ndefineElement('kt-input-menu', KtInputMenu);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-input-menu': KtInputMenu;\n }\n}\n"],"names":["KtInputMenu","KtElement","uniqueId","event","listboxStyles","css","attachFormInternals","changed","setFormValue","missing","setValidity","state","options","option","filterOptions","selected","optionLabel","firstEnabledIndex","emit","nextEnabledIndex","lastEnabledIndex","index","showClear","html","classMap","nothing","live","__decorateClass","query","property","defineElement"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { css as p, html as i } from "lit";
|
|
2
2
|
import { query as d, property as f } from "lit/decorators.js";
|
|
3
|
-
import { K as u, d as c } from "../../../chunks/kt-element-
|
|
3
|
+
import { K as u, d as c } from "../../../chunks/kt-element-B_jjQDhg.js";
|
|
4
4
|
var b = Object.defineProperty, a = (r, t, s, h) => {
|
|
5
5
|
for (var e = void 0, o = r.length - 1, n; o >= 0; o--)
|
|
6
6
|
(n = r[o]) && (e = n(t, s, e) || e);
|
|
@@ -28,7 +28,7 @@ class l extends u {
|
|
|
28
28
|
|
|
29
29
|
.required {
|
|
30
30
|
margin-left: 2px;
|
|
31
|
-
color: var(--color-danger-
|
|
31
|
+
color: var(--color-danger-text);
|
|
32
32
|
}
|
|
33
33
|
`
|
|
34
34
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-label-input.js","sources":["../../../../src/components/forms/kt-label-input/kt-label-input.ts"],"sourcesContent":["import { css, html, type TemplateResult } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\n\n/** Anything that can take an accessible name from the label. */\ninterface Labelable extends HTMLElement {\n label?: string;\n focus(): void;\n}\n\n/**\n * A label above a form control, with a red asterisk when it is required.\n *\n * Native label association does not cross a shadow boundary — `for` and\n * implicit wrapping both need the label and the control in the same tree — so\n * this element passes its text down to the slotted control's `label` property\n * instead, which becomes the control's `aria-label`. Clicking the label still\n * focuses the control, as it would natively.\n *\n * @element kt-label-input\n *\n * @slot - The form control to label.\n *\n * @csspart label - The `<label>`.\n *\n * @example\n * ```html\n * <kt-label-input label=\"Adresse e-mail\" required>\n * <kt-input name=\"email\" type=\"email\" required></kt-input>\n * </kt-label-input>\n * ```\n */\nexport class KtLabelInput extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--gap-button);\n }\n\n label {\n color: var(--text-body);\n font: var(--font-normal-medium);\n cursor: default;\n }\n\n .required {\n margin-left: 2px;\n color: var(--color-danger-
|
|
1
|
+
{"version":3,"file":"kt-label-input.js","sources":["../../../../src/components/forms/kt-label-input/kt-label-input.ts"],"sourcesContent":["import { css, html, type TemplateResult } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\n\n/** Anything that can take an accessible name from the label. */\ninterface Labelable extends HTMLElement {\n label?: string;\n focus(): void;\n}\n\n/**\n * A label above a form control, with a red asterisk when it is required.\n *\n * Native label association does not cross a shadow boundary — `for` and\n * implicit wrapping both need the label and the control in the same tree — so\n * this element passes its text down to the slotted control's `label` property\n * instead, which becomes the control's `aria-label`. Clicking the label still\n * focuses the control, as it would natively.\n *\n * @element kt-label-input\n *\n * @slot - The form control to label.\n *\n * @csspart label - The `<label>`.\n *\n * @example\n * ```html\n * <kt-label-input label=\"Adresse e-mail\" required>\n * <kt-input name=\"email\" type=\"email\" required></kt-input>\n * </kt-label-input>\n * ```\n */\nexport class KtLabelInput extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--gap-button);\n }\n\n label {\n color: var(--text-body);\n font: var(--font-normal-medium);\n cursor: default;\n }\n\n .required {\n margin-left: 2px;\n color: var(--color-danger-text);\n }\n `,\n ];\n\n @query('slot')\n private defaultSlot!: HTMLSlotElement;\n\n /** The label text. */\n @property({ type: String })\n label = '';\n\n /** Appends a red asterisk and marks the control required for screen readers. */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n private get control(): Labelable | undefined {\n return this.defaultSlot\n ?.assignedElements({ flatten: true })\n .find((element): element is Labelable => element instanceof HTMLElement);\n }\n\n private labelControl(): void {\n const control = this.control;\n if (!control) return;\n\n if ('label' in control) control.label = this.label;\n else control.setAttribute('aria-label', this.label);\n }\n\n override updated(): void {\n this.labelControl();\n }\n\n private focusControl(): void {\n this.control?.focus();\n }\n\n override render(): TemplateResult {\n return html`<label part=\"label\" @click=${this.focusControl}>\n ${this.label}${\n this.required ? html`<span class=\"required\" aria-hidden=\"true\">*</span>` : ''\n }\n </label>\n <slot @slotchange=${this.labelControl}></slot>`;\n }\n}\n\ndefineElement('kt-label-input', KtLabelInput);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-label-input': KtLabelInput;\n }\n}\n"],"names":["KtLabelInput","KtElement","css","element","control","html","__decorateClass","query","property","defineElement"],"mappings":";;;;;;;;AAgCO,MAAMA,UAAqBC,EAAU;AAAA,EAArC,cAAA;AAAA,UAAA,GAAA,SAAA,GA4BL,KAAA,QAAQ,IAIR,KAAA,WAAW;AAAA,EAAA;AAAA,EA/BX,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,IAAA;AAAA,EAkBF;AAAA,EAaA,IAAY,UAAiC;AAC3C,WAAO,KAAK,aACR,iBAAiB,EAAE,SAAS,IAAM,EACnC,KAAK,CAACC,MAAkCA,aAAmB,WAAW;AAAA,EAC3E;AAAA,EAEQ,eAAqB;AAC3B,UAAMC,IAAU,KAAK;AACrB,IAAKA,MAED,WAAWA,IAASA,EAAQ,QAAQ,KAAK,QACxCA,EAAQ,aAAa,cAAc,KAAK,KAAK;AAAA,EACpD;AAAA,EAES,UAAgB;AACvB,SAAK,aAAA;AAAA,EACP;AAAA,EAEQ,eAAqB;AAC3B,SAAK,SAAS,MAAA;AAAA,EAChB;AAAA,EAES,SAAyB;AAChC,WAAOC,+BAAkC,KAAK,YAAY;AAAA,UACpD,KAAK,KAAK,GACV,KAAK,WAAWA,wDAA2D,EAC7E;AAAA;AAAA,0BAEkB,KAAK,YAAY;AAAA,EACzC;AACF;AAxCUC,EAAA;AAAA,EADPC,EAAM,MAAM;AAAA,GAvBFP,EAwBH,WAAA,aAAA;AAIRM,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA3BfR,EA4BX,WAAA,OAAA;AAIAM,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GA/B/BR,EAgCX,WAAA,UAAA;AAkCFS,EAAc,kBAAkBT,CAAY;"}
|