@nysds/nys-select 1.15.0 → 1.15.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.
- package/dist/nys-select.js +32 -28
- package/dist/nys-select.js.map +1 -1
- package/package.json +5 -5
- package/dist/index.d.ts +0 -2
- package/dist/nys-option.d.ts +0 -34
- package/dist/nys-select.d.ts +0 -116
- package/dist/nys-select.figma.d.ts +0 -1
package/dist/nys-select.js
CHANGED
|
@@ -6,15 +6,15 @@ import { ifDefined as b } from "lit/directives/if-defined.js";
|
|
|
6
6
|
* █ █ █ █▄▄▄█ ▀▀▀▄▄ █ █ ▀▀▀▄▄
|
|
7
7
|
* █ ▀█ █ █▄▄▄█ █▄▄▀ █▄▄▄█
|
|
8
8
|
*
|
|
9
|
-
* Select Component
|
|
9
|
+
* Select Component v1.15.1
|
|
10
10
|
* Part of the New York State Design System
|
|
11
11
|
* Repository: https://github.com/its-hcd/nysds
|
|
12
12
|
* License: MIT
|
|
13
13
|
*/
|
|
14
14
|
var m = Object.defineProperty, p = (y, e, t, d) => {
|
|
15
|
-
for (var
|
|
16
|
-
(r = y[s]) && (
|
|
17
|
-
return
|
|
15
|
+
for (var l = void 0, s = y.length - 1, r; s >= 0; s--)
|
|
16
|
+
(r = y[s]) && (l = r(e, t, l) || l);
|
|
17
|
+
return l && m(e, t, l), l;
|
|
18
18
|
};
|
|
19
19
|
class c extends f {
|
|
20
20
|
constructor() {
|
|
@@ -59,9 +59,9 @@ p([
|
|
|
59
59
|
customElements.define("nys-option", c);
|
|
60
60
|
const g = ':host{--_nys-select-width: 100%;--_nys-select-height: var(--nys-size-500, 40px);--_nys-select-font-family: var( --nys-font-family-ui, var( --nys-font-family-sans, "Proxima Nova", "Helvetica Neue", "Helvetica", "Arial", sans-serif ) );--_nys-select-font-size: var(--nys-font-size-ui-md, 16px);--_nys-select-font-weight: var(--nys-font-weight-regular, 400);--_nys-select-line-height: var(--nys-font-lineheight-ui-md, 24px);--_nys-select-gap: var(--nys-space-50, 4px);--_nys-select-border-radius: var(--nys-radius-md, 4px);--_nys-select-padding: var(--nys-space-100, 8px) var(--nys-space-400, 32px) var(--nys-space-100, 8px) var(--nys-space-100, 8px);--_nys-select-color: var(--nys-color-text, #1b1b1b);--_nys-select-color--error: var( --nys-color-danger, var(--nys-color-red-600, #b52c2c) );--_nys-select-background-color: var(--nys-color-ink-reverse, #ffffff);--_nys-select-background-color--disabled: var( --nys-color-neutral-10, #f6f6f6 );--_nys-select-color--disabled: var(--nys-color-text-disabled, #bec0c1);--_nys-select-border-width: var(--nys-border-width-sm, 1px);--_nys-select-border-color: var(--nys-color-neutral-400, #909395);--_nys-select-border-color--hover: var(--nys-color-neutral-900, #1b1b1b);--_nys-select-border-color--focus: var(--nys-color-focus, #004dd1);--_nys-select-border-color--disabled: var(--nys-color-neutral-200, #bec0c1);--_nys-select-border-default: var(--nys-border-width-sm, 1px) solid var(--nys-color-neutral-400, #909395);--_nys-select-border-focus: var(--nys-border-width-sm, 1px) solid var(--nys-color-focus, var(--nys-color-blue-600, #004dd1));--_nys-select-border-disabled: var(--nys-border-width-sm, 1px) solid var(--nys-color-neutral-200, #bec0c1);--_nys-select-border-hover: var(--nys-border-width-sm, 1px) solid var(--nys-color-neutral-900, #1b1b1b)}.nys-select{display:flex;flex-direction:column;gap:var(--_nys-select-gap);font-family:var(--_nys-select-font-family)}.nys-select__select{color:var(--_nys-select-color);font-weight:var(--_nys-select-font-weight);font-family:var(--_nys-select-font-family);border-radius:var(--_nys-select-border-radius);border:solid var(--_nys-select-border-width) var(--_nys-select-border-color);font-size:var(--_nys-select-font-size);padding:var(--_nys-select-padding);width:var(--_nys-select-width);height:var(--_nys-select-height);max-width:100%;text-indent:1px;background:var(--_nys-select-background-color);appearance:none;text-overflow:ellipsis}.nys-select__selectwrapper{position:relative;display:inline-block;width:var(--_nys-select-width);max-width:100%}.nys-select__icon{color:var(--_nys-select-color);position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none}:host([width=sm]){--_nys-select-width: var(--nys-select-form-width-sm, 88px)}:host([width=md]){--_nys-select-width: var(--nys-select-form-width-md, 200px)}:host([width=lg]){--_nys-select-width: var(--nys-select-form-width-lg, 384px)}:host([width=full]){--_nys-select-width: 100%;flex:1}.nys-select__select:hover:not(:disabled){cursor:pointer;border-color:var(--_nys-select-border-color--hover);outline:solid var(--_nys-select-border-width) var(--_nys-select-border-color--hover)}.nys-select__select:focus{border-color:var(--_nys-select-border-color--focus);outline:solid var(--_nys-select-border-width) var(--_nys-select-border-color--focus)}.nys-select__select:disabled{background-color:var(--_nys-select-background-color--disabled);border-color:var(--_nys-select-border-color--disabled);cursor:not-allowed;color:var(--_nys-select-color--disabled)}.nys-select__select:disabled~.nys-select__icon{color:var(--_nys-select-color--disabled)}:host([showError]){--_nys-select-border-default: var(--nys-border-width-sm, 1px) solid var(--_nys-select-color--error)}';
|
|
61
61
|
var w = Object.defineProperty, a = (y, e, t, d) => {
|
|
62
|
-
for (var
|
|
63
|
-
(r = y[s]) && (
|
|
64
|
-
return
|
|
62
|
+
for (var l = void 0, s = y.length - 1, r; s >= 0; s--)
|
|
63
|
+
(r = y[s]) && (l = r(e, t, l) || l);
|
|
64
|
+
return l && w(e, t, l), l;
|
|
65
65
|
};
|
|
66
66
|
let E = 0;
|
|
67
67
|
const u = class u extends f {
|
|
@@ -113,8 +113,8 @@ const u = class u extends f {
|
|
|
113
113
|
return;
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
|
-
const
|
|
117
|
-
|
|
116
|
+
const l = Array.from(t.options).find((s) => s.selected);
|
|
117
|
+
l && (this.value = l.value, this._internals.setFormValue(this.value));
|
|
118
118
|
}
|
|
119
119
|
/**
|
|
120
120
|
* Form Integration
|
|
@@ -184,11 +184,15 @@ const u = class u extends f {
|
|
|
184
184
|
}
|
|
185
185
|
// Handle focus event
|
|
186
186
|
_handleFocus() {
|
|
187
|
-
this.dispatchEvent(
|
|
187
|
+
this.dispatchEvent(
|
|
188
|
+
new Event("nys-focus", { bubbles: !0, composed: !0 })
|
|
189
|
+
);
|
|
188
190
|
}
|
|
189
191
|
// Handle blur event
|
|
190
192
|
_handleBlur() {
|
|
191
|
-
this._hasUserInteracted || (this._hasUserInteracted = !0), this._validate(), this.dispatchEvent(
|
|
193
|
+
this._hasUserInteracted || (this._hasUserInteracted = !0), this._validate(), this.dispatchEvent(
|
|
194
|
+
new Event("nys-blur", { bubbles: !0, composed: !0 })
|
|
195
|
+
);
|
|
192
196
|
}
|
|
193
197
|
// Check if the current value matches any option, and if so, set it as selected
|
|
194
198
|
updated(e) {
|
|
@@ -246,52 +250,52 @@ u.styles = _(g), u.shadowRootOptions = {
|
|
|
246
250
|
...f.shadowRootOptions,
|
|
247
251
|
delegatesFocus: !0
|
|
248
252
|
}, u.formAssociated = !0;
|
|
249
|
-
let
|
|
253
|
+
let i = u;
|
|
250
254
|
a([
|
|
251
255
|
o({ type: String, reflect: !0 })
|
|
252
|
-
],
|
|
256
|
+
], i.prototype, "id");
|
|
253
257
|
a([
|
|
254
258
|
o({ type: String, reflect: !0 })
|
|
255
|
-
],
|
|
259
|
+
], i.prototype, "name");
|
|
256
260
|
a([
|
|
257
261
|
o({ type: String })
|
|
258
|
-
],
|
|
262
|
+
], i.prototype, "label");
|
|
259
263
|
a([
|
|
260
264
|
o({ type: String })
|
|
261
|
-
],
|
|
265
|
+
], i.prototype, "description");
|
|
262
266
|
a([
|
|
263
267
|
o({ type: String })
|
|
264
|
-
],
|
|
268
|
+
], i.prototype, "value");
|
|
265
269
|
a([
|
|
266
270
|
o({ type: Boolean, reflect: !0 })
|
|
267
|
-
],
|
|
271
|
+
], i.prototype, "disabled");
|
|
268
272
|
a([
|
|
269
273
|
o({ type: Boolean, reflect: !0 })
|
|
270
|
-
],
|
|
274
|
+
], i.prototype, "required");
|
|
271
275
|
a([
|
|
272
276
|
o({ type: Boolean, reflect: !0 })
|
|
273
|
-
],
|
|
277
|
+
], i.prototype, "optional");
|
|
274
278
|
a([
|
|
275
279
|
o({ type: String })
|
|
276
|
-
],
|
|
280
|
+
], i.prototype, "tooltip");
|
|
277
281
|
a([
|
|
278
282
|
o({ type: String, reflect: !0 })
|
|
279
|
-
],
|
|
283
|
+
], i.prototype, "form");
|
|
280
284
|
a([
|
|
281
285
|
o({ type: Boolean, reflect: !0 })
|
|
282
|
-
],
|
|
286
|
+
], i.prototype, "inverted");
|
|
283
287
|
a([
|
|
284
288
|
o({ type: Boolean, reflect: !0 })
|
|
285
|
-
],
|
|
289
|
+
], i.prototype, "showError");
|
|
286
290
|
a([
|
|
287
291
|
o({ type: String })
|
|
288
|
-
],
|
|
292
|
+
], i.prototype, "errorMessage");
|
|
289
293
|
a([
|
|
290
294
|
o({ type: String, reflect: !0 })
|
|
291
|
-
],
|
|
292
|
-
customElements.get("nys-select") || customElements.define("nys-select",
|
|
295
|
+
], i.prototype, "width");
|
|
296
|
+
customElements.get("nys-select") || customElements.define("nys-select", i);
|
|
293
297
|
export {
|
|
294
298
|
c as NysOption,
|
|
295
|
-
|
|
299
|
+
i as NysSelect
|
|
296
300
|
};
|
|
297
301
|
//# sourceMappingURL=nys-select.js.map
|
package/dist/nys-select.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nys-select.js","sources":["../src/nys-option.ts","../src/nys-select.ts"],"sourcesContent":["import { LitElement, html } from \"lit\";\nimport { property } from \"lit/decorators.js\";\n\n/**\n * An option item for use within `nys-select`. Wraps a native `<option>` element.\n *\n * Place inside `nys-select`. Set `value` for form submission and `label` for display text.\n * Alternatively, slot text content which auto-populates the label.\n *\n * @summary Option item for nys-select dropdown.\n * @element nys-option\n *\n * @slot - Option label text. Auto-populates the `label` prop if provided.\n *\n * @example Basic options\n * ```html\n * <nys-select>\n * <nys-option value=\"ny\">New York</nys-option>\n * <nys-option value=\"ca\" disabled>California</nys-option>\n * </nys-select>\n * ```\n */\nexport class NysOption extends LitElement {\n /** Prevents selection of this option. */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Pre-selects this option. */\n @property({ type: Boolean, reflect: true }) selected = false;\n\n /** Value submitted when this option is selected. */\n @property({ type: String }) value = \"\";\n\n /** Display text for the option. Auto-populated from slot content if not set. */\n @property({ type: String }) label = \"\";\n\n /** Hides the option from the dropdown list. */\n @property({ type: Boolean, reflect: true }) hidden = false;\n\n firstUpdated() {\n const slot = this.shadowRoot?.querySelector(\"slot\");\n if (slot) {\n slot.addEventListener(\"slotchange\", () => {\n const assignedNodes = slot.assignedNodes({ flatten: true });\n if (assignedNodes.length > 0) {\n this.label = assignedNodes[0].textContent?.trim() || \"\";\n }\n });\n }\n }\n\n render() {\n return html`\n <option\n ?disabled=${this.disabled}\n ?selected=${this.selected}\n value=${this.value}\n label=${this.label}\n ?hidden=${this.hidden}\n >\n <slot>${this.label}</slot>\n </option>\n `;\n }\n}\n\ncustomElements.define(\"nys-option\", NysOption);\n","import { LitElement, html, unsafeCSS } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { NysOption } from \"./nys-option\";\n// @ts-ignore: SCSS module imported via bundler as inline\nimport styles from \"./nys-select.scss?inline\";\n\nlet selectIdCounter = 0;\n\n/**\n * A dropdown for selecting a single option from a list. Supports native `<option>` and `<optgroup>` elements.\n * Form-associated with validation via ElementInternals.\n *\n * Use when users must choose one option from 7+ items. For fewer options, consider `nys-radiobutton`.\n * For multiple selections, use `nys-checkbox` group instead.\n *\n * @summary Dropdown select for choosing one option from a list.\n * @element nys-select\n *\n * @slot - Default slot for `<option>` and `<optgroup>` elements.\n * @slot description - Custom HTML description content below the label.\n *\n * @fires nys-change - Fired when selection changes. Detail: `{id, value}`.\n * @fires nys-focus - Fired when select gains focus.\n * @fires nys-blur - Fired when select loses focus. Triggers validation.\n *\n * @example Basic select\n * ```html\n * <nys-select label=\"Select borough\">\n * <option value=\"bronx\">The Bronx</option>\n * <option value=\"brooklyn\">Brooklyn</option>\n * <option value=\"manhattan\">Manhattan</option>\n * </nys-select>\n * ```\n *\n * @example With option groups\n * ```html\n * <nys-select label=\"Select service\">\n * <optgroup label=\"Transportation\">\n * <option value=\"mta\">MTA</option>\n * <option value=\"dmv\">DMV</option>\n * </optgroup>\n * </nys-select>\n * ```\n */\n\nexport class NysSelect extends LitElement {\n static styles = unsafeCSS(styles);\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n /** Unique identifier. Auto-generated if not provided. */\n @property({ type: String, reflect: true }) id = \"\";\n\n /** Name for form submission. */\n @property({ type: String, reflect: true }) name = \"\";\n\n /** Visible label text. Required for accessibility. */\n @property({ type: String }) label = \"\";\n\n /** Helper text below label. Use slot for custom HTML. */\n @property({ type: String }) description = \"\";\n\n /** Currently selected option value. */\n @property({ type: String }) value = \"\";\n\n /** Prevents interaction. */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Marks as required. Shows \"Required\" flag and validates on blur. */\n @property({ type: Boolean, reflect: true }) required = false;\n\n /** Shows \"Optional\" flag. Use when most fields are required. */\n @property({ type: Boolean, reflect: true }) optional = false;\n\n /** Tooltip text shown on hover/focus of info icon. */\n @property({ type: String }) tooltip = \"\";\n\n /** Form `id` to associate with when select is outside form element. */\n @property({ type: String, reflect: true }) form: string | null = null;\n\n /** Adjusts colors for dark backgrounds. */\n @property({ type: Boolean, reflect: true }) inverted = false;\n\n /** Shows error message when true. Set by validation or manually. */\n @property({ type: Boolean, reflect: true }) showError = false;\n\n /** Error message text. Shown only when `showError` is true. */\n @property({ type: String }) errorMessage = \"\";\n\n /**\n * Select width: `sm` (88px), `md` (200px), `lg` (384px), `full` (100%, default).\n * @default \"full\"\n */\n @property({ type: String, reflect: true }) width:\n | \"sm\"\n | \"md\"\n | \"lg\"\n | \"full\" = \"full\";\n\n private _originalErrorMessage = \"\";\n\n private _hasUserInteracted = false; // need this flag for \"eager mode\"\n private _internals: ElementInternals;\n\n /**\n * Lifecycle methods\n * --------------------------------------------------------------------------\n */\n\n static formAssociated = true; // allows use of elementInternals' API\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // Generate a unique ID if one is not provided\n connectedCallback() {\n super.connectedCallback();\n if (!this.id) {\n this.id = `nys-select-${Date.now()}-${selectIdCounter++}`;\n }\n\n this._originalErrorMessage = this.errorMessage ?? \"\";\n this.addEventListener(\"invalid\", this._handleInvalid);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener(\"invalid\", this._handleInvalid);\n }\n\n firstUpdated() {\n //read in slotted options\n const slot = this.shadowRoot?.querySelector(\n 'slot:not([name=\"description\"])',\n ) as HTMLSlotElement | null;\n\n if (slot) {\n this._handleSlotChange();\n }\n\n // This ensures our element always participates in the form\n this._setValue();\n }\n\n private _handleSlotChange() {\n const slot = this.shadowRoot?.querySelector(\n 'slot:not([name=\"description\"])',\n ) as HTMLSlotElement | null;\n const select = this.shadowRoot?.querySelector(\"select\");\n\n if (!slot || !select) return;\n\n // Clean up any previously cloned <option> or <optgroup> elements so we don't get duplicates\n Array.from(select.children).forEach((child) => {\n if (!(child as HTMLElement).hasAttribute(\"data-native\")) {\n child.remove();\n }\n });\n\n const assignedElements = slot.assignedElements({ flatten: true });\n\n assignedElements.forEach((node) => {\n // ---- Handle <nys-option> ----\n if (node instanceof NysOption) {\n const optionElement = document.createElement(\"option\");\n optionElement.value = node.value;\n optionElement.textContent =\n node.label || node.textContent?.trim() || \"\";\n optionElement.disabled = node.disabled;\n optionElement.selected = node.selected;\n select.appendChild(optionElement);\n return;\n }\n\n // ---- Handle native <option> ----\n if (node.tagName === \"OPTION\") {\n const original = node as HTMLOptionElement;\n const optionClone = original.cloneNode(true) as HTMLOptionElement;\n\n optionClone.setAttribute(\"data-native\", \"true\");\n optionClone.disabled = original.disabled;\n optionClone.selected = original.selected;\n\n select.appendChild(optionClone);\n return;\n }\n\n // ---- Handle <optgroup> ----\n if (node.tagName === \"OPTGROUP\") {\n const groupClone = document.createElement(\"optgroup\");\n groupClone.label = (node as HTMLOptGroupElement).label;\n if ((node as HTMLOptGroupElement).disabled) {\n groupClone.disabled = true;\n }\n\n // iterate children inside optgroup (could be nys-option or native option)\n Array.from(node.children).forEach((child) => {\n if (child instanceof NysOption) {\n const option = document.createElement(\"option\");\n option.value = child.value;\n option.textContent = child.label || child.textContent?.trim() || \"\";\n option.disabled = child.disabled;\n option.selected = child.selected;\n groupClone.appendChild(option);\n } else if (child.tagName === \"OPTION\") {\n const optionClone = child.cloneNode(true) as HTMLOptionElement;\n groupClone.appendChild(optionClone);\n }\n });\n\n select.appendChild(groupClone);\n return;\n }\n });\n\n // Sync initial selected state into component value\n const selectedOption = Array.from(select.options).find((o) => o.selected);\n\n if (selectedOption) {\n this.value = selectedOption.value;\n this._internals.setFormValue(this.value);\n }\n }\n\n /**\n * Form Integration\n * --------------------------------------------------------------------------\n */\n\n private _setValue() {\n this._internals.setFormValue(this.value);\n this._manageRequire(); // Check validation when value is set\n }\n\n private _manageRequire() {\n const select = this.shadowRoot?.querySelector(\"select\");\n if (!select) return;\n\n const message = this.errorMessage || \"This field is required.\";\n const isInvalid = this.required && !this.value;\n\n if (isInvalid) {\n this._internals.ariaRequired = \"true\"; // Screen readers should announce error\n this._internals.setValidity({ valueMissing: true }, message, select);\n } else {\n this._internals.ariaRequired = \"false\"; // Reset when valid\n this._internals.setValidity({});\n this._hasUserInteracted = false; // Reset the interaction flag, make lazy again\n }\n }\n\n private _setValidityMessage(message: string = \"\") {\n const select = this.shadowRoot?.querySelector(\"select\");\n if (!select) return;\n\n // Toggle the HTML <div> tag error message\n this.showError = !!message;\n\n // If user sets errorMessage, this will always override the native validation message\n if (this._originalErrorMessage?.trim() && message !== \"\") {\n this.errorMessage = this._originalErrorMessage;\n } else {\n this.errorMessage = message;\n }\n\n const validityState = message ? { customError: true } : {};\n this._internals.setValidity(validityState, this.errorMessage, select);\n }\n\n private _validate() {\n const select = this.shadowRoot?.querySelector(\"select\");\n if (!select) return;\n\n // Get the native validation state\n let message = select.validationMessage;\n this._manageRequire(); // Makes sure the required state is checked\n\n this._setValidityMessage(message);\n }\n\n // This callback is automatically called when the parent form is reset.\n public formResetCallback() {\n this.value = \"\";\n const select = this.shadowRoot?.querySelector(\"select\");\n if (select) {\n select.value = \"\";\n Array.from(select.options).forEach((other) => (other.selected = false));\n }\n\n // Reset validation UI\n this.showError = false;\n this.errorMessage = \"\";\n this._internals.setValidity({});\n\n // Re-render UI\n this.requestUpdate();\n }\n\n /**\n * Functions\n * --------------------------------------------------------------------------\n */\n // This helper function is called to perform the element's native validation.\n checkValidity(): boolean {\n const select = this.shadowRoot?.querySelector(\"select\");\n return select ? select.checkValidity() : true;\n }\n\n private _handleInvalid(event: Event) {\n event.preventDefault();\n this._hasUserInteracted = true; // Start aggressive mode due to form submission\n this._validate();\n this.showError = true;\n\n const select = this.shadowRoot?.querySelector(\"select\");\n if (select) {\n // Focus only if this is the first invalid element (top-down approach)\n const form = this._internals.form;\n if (form) {\n const elements = Array.from(form.elements) as Array<\n HTMLElement & { checkValidity?: () => boolean }\n >;\n // Find the first element in the form that is invalid\n const firstInvalidElement = elements.find(\n (element) =>\n typeof element.checkValidity === \"function\" &&\n !element.checkValidity(),\n );\n if (firstInvalidElement === this) {\n select.focus();\n }\n } else {\n // If not part of a form, simply focus.\n select.focus();\n }\n }\n }\n\n /**\n * Event Handlers\n * --------------------------------------------------------------------------\n */\n\n // Handle change event to bubble up selected value\n private _handleChange(e: Event) {\n const select = e.target as HTMLSelectElement;\n this.value = select.value;\n this._internals.setFormValue(this.value);\n\n // Clear error immediately if value is now valid\n if (this.required && this.value) {\n this.showError = false;\n this.errorMessage = \"\";\n this._internals.setValidity({});\n }\n\n // Validate aggressively if the user has already interacted\n if (this._hasUserInteracted) {\n this._validate();\n }\n\n this.dispatchEvent(\n new CustomEvent(\"nys-change\", {\n detail: { id: this.id, value: this.value },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // Handle focus event\n private _handleFocus() {\n this.dispatchEvent(new Event(\"nys-focus\"));\n }\n\n // Handle blur event\n private _handleBlur() {\n if (!this._hasUserInteracted) {\n this._hasUserInteracted = true;\n }\n this._validate();\n this.dispatchEvent(new Event(\"nys-blur\"));\n }\n\n // Check if the current value matches any option, and if so, set it as selected\n updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n\n // This ensures the value is set correctly after the component renders\n if (changedProperties.has(\"value\")) {\n const selectElement = this.shadowRoot?.querySelector(\"select\");\n if (selectElement) {\n selectElement.value = this.value;\n }\n }\n }\n\n render() {\n return html`\n <div class=\"nys-select\">\n <nys-label\n for=${this.id + \"--native\"}\n label=${this.label}\n description=${this.description}\n flag=${this.required ? \"required\" : this.optional ? \"optional\" : \"\"}\n tooltip=${this.tooltip}\n ?inverted=${this.inverted}\n >\n <slot name=\"description\" slot=\"description\">${this.description}</slot>\n </nys-label>\n <div class=\"nys-select__selectwrapper\">\n <select\n class=\"nys-select__select\"\n name=${this.name}\n id=${this.id + \"--native\"}\n form=${ifDefined(this.form || undefined)}\n ?disabled=${this.disabled}\n ?required=${this.required}\n aria-disabled=\"${this.disabled}\"\n aria-label=\"${[this.label, this.description]\n .filter(Boolean)\n .join(\" \")}\"\n .value=${this.value}\n @focus=\"${this._handleFocus}\"\n @blur=\"${this._handleBlur}\"\n @change=\"${this._handleChange}\"\n >\n <option data-native hidden disabled value=\"\"></option>\n </select>\n <slot style=\"display: none;\"></slot>\n <nys-icon\n name=\"chevron_down\"\n size=\"2xl\"\n class=\"nys-select__icon\"\n ></nys-icon>\n </div>\n <nys-errormessage\n ?showError=${this.showError}\n errorMessage=${this.errorMessage}\n ></nys-errormessage>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"nys-select\")) {\n customElements.define(\"nys-select\", NysSelect);\n}\n"],"names":["NysOption","LitElement","slot","assignedNodes","html","__decorateClass","property","selectIdCounter","_NysSelect","select","child","node","optionElement","original","optionClone","groupClone","option","selectedOption","o","message","validityState","other","event","form","element","changedProperties","selectElement","ifDefined","unsafeCSS","styles","NysSelect"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nys-select.js","sources":["../src/nys-option.ts","../src/nys-select.ts"],"sourcesContent":["import { LitElement, html } from \"lit\";\nimport { property } from \"lit/decorators.js\";\n\n/**\n * An option item for use within `nys-select`. Wraps a native `<option>` element.\n *\n * Place inside `nys-select`. Set `value` for form submission and `label` for display text.\n * Alternatively, slot text content which auto-populates the label.\n *\n * @summary Option item for nys-select dropdown.\n * @element nys-option\n *\n * @slot - Option label text. Auto-populates the `label` prop if provided.\n *\n * @example Basic options\n * ```html\n * <nys-select>\n * <nys-option value=\"ny\">New York</nys-option>\n * <nys-option value=\"ca\" disabled>California</nys-option>\n * </nys-select>\n * ```\n */\nexport class NysOption extends LitElement {\n /** Prevents selection of this option. */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Pre-selects this option. */\n @property({ type: Boolean, reflect: true }) selected = false;\n\n /** Value submitted when this option is selected. */\n @property({ type: String }) value = \"\";\n\n /** Display text for the option. Auto-populated from slot content if not set. */\n @property({ type: String }) label = \"\";\n\n /** Hides the option from the dropdown list. */\n @property({ type: Boolean, reflect: true }) hidden = false;\n\n firstUpdated() {\n const slot = this.shadowRoot?.querySelector(\"slot\");\n if (slot) {\n slot.addEventListener(\"slotchange\", () => {\n const assignedNodes = slot.assignedNodes({ flatten: true });\n if (assignedNodes.length > 0) {\n this.label = assignedNodes[0].textContent?.trim() || \"\";\n }\n });\n }\n }\n\n render() {\n return html`\n <option\n ?disabled=${this.disabled}\n ?selected=${this.selected}\n value=${this.value}\n label=${this.label}\n ?hidden=${this.hidden}\n >\n <slot>${this.label}</slot>\n </option>\n `;\n }\n}\n\ncustomElements.define(\"nys-option\", NysOption);\n","import { LitElement, html, unsafeCSS } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { NysOption } from \"./nys-option\";\n// @ts-ignore: SCSS module imported via bundler as inline\nimport styles from \"./nys-select.scss?inline\";\n\nlet selectIdCounter = 0;\n\n/**\n * A dropdown for selecting a single option from a list. Supports native `<option>` and `<optgroup>` elements.\n * Form-associated with validation via ElementInternals.\n *\n * Use when users must choose one option from 7+ items. For fewer options, consider `nys-radiobutton`.\n * For multiple selections, use `nys-checkbox` group instead.\n *\n * @summary Dropdown select for choosing one option from a list.\n * @element nys-select\n *\n * @slot - Default slot for `<option>` and `<optgroup>` elements.\n * @slot description - Custom HTML description content below the label.\n *\n * @fires nys-change - Fired when selection changes. Detail: `{id, value}`.\n * @fires nys-focus - Fired when select gains focus.\n * @fires nys-blur - Fired when select loses focus. Triggers validation.\n *\n * @example Basic select\n * ```html\n * <nys-select label=\"Select borough\">\n * <option value=\"bronx\">The Bronx</option>\n * <option value=\"brooklyn\">Brooklyn</option>\n * <option value=\"manhattan\">Manhattan</option>\n * </nys-select>\n * ```\n *\n * @example With option groups\n * ```html\n * <nys-select label=\"Select service\">\n * <optgroup label=\"Transportation\">\n * <option value=\"mta\">MTA</option>\n * <option value=\"dmv\">DMV</option>\n * </optgroup>\n * </nys-select>\n * ```\n */\n\nexport class NysSelect extends LitElement {\n static styles = unsafeCSS(styles);\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n /** Unique identifier. Auto-generated if not provided. */\n @property({ type: String, reflect: true }) id = \"\";\n\n /** Name for form submission. */\n @property({ type: String, reflect: true }) name = \"\";\n\n /** Visible label text. Required for accessibility. */\n @property({ type: String }) label = \"\";\n\n /** Helper text below label. Use slot for custom HTML. */\n @property({ type: String }) description = \"\";\n\n /** Currently selected option value. */\n @property({ type: String }) value = \"\";\n\n /** Prevents interaction. */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Marks as required. Shows \"Required\" flag and validates on blur. */\n @property({ type: Boolean, reflect: true }) required = false;\n\n /** Shows \"Optional\" flag. Use when most fields are required. */\n @property({ type: Boolean, reflect: true }) optional = false;\n\n /** Tooltip text shown on hover/focus of info icon. */\n @property({ type: String }) tooltip = \"\";\n\n /** Form `id` to associate with when select is outside form element. */\n @property({ type: String, reflect: true }) form: string | null = null;\n\n /** Adjusts colors for dark backgrounds. */\n @property({ type: Boolean, reflect: true }) inverted = false;\n\n /** Shows error message when true. Set by validation or manually. */\n @property({ type: Boolean, reflect: true }) showError = false;\n\n /** Error message text. Shown only when `showError` is true. */\n @property({ type: String }) errorMessage = \"\";\n\n /**\n * Select width: `sm` (88px), `md` (200px), `lg` (384px), `full` (100%, default).\n * @default \"full\"\n */\n @property({ type: String, reflect: true }) width:\n | \"sm\"\n | \"md\"\n | \"lg\"\n | \"full\" = \"full\";\n\n private _originalErrorMessage = \"\";\n\n private _hasUserInteracted = false; // need this flag for \"eager mode\"\n private _internals: ElementInternals;\n\n /**\n * Lifecycle methods\n * --------------------------------------------------------------------------\n */\n\n static formAssociated = true; // allows use of elementInternals' API\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // Generate a unique ID if one is not provided\n connectedCallback() {\n super.connectedCallback();\n if (!this.id) {\n this.id = `nys-select-${Date.now()}-${selectIdCounter++}`;\n }\n\n this._originalErrorMessage = this.errorMessage ?? \"\";\n this.addEventListener(\"invalid\", this._handleInvalid);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener(\"invalid\", this._handleInvalid);\n }\n\n firstUpdated() {\n //read in slotted options\n const slot = this.shadowRoot?.querySelector(\n 'slot:not([name=\"description\"])',\n ) as HTMLSlotElement | null;\n\n if (slot) {\n this._handleSlotChange();\n }\n\n // This ensures our element always participates in the form\n this._setValue();\n }\n\n private _handleSlotChange() {\n const slot = this.shadowRoot?.querySelector(\n 'slot:not([name=\"description\"])',\n ) as HTMLSlotElement | null;\n const select = this.shadowRoot?.querySelector(\"select\");\n\n if (!slot || !select) return;\n\n // Clean up any previously cloned <option> or <optgroup> elements so we don't get duplicates\n Array.from(select.children).forEach((child) => {\n if (!(child as HTMLElement).hasAttribute(\"data-native\")) {\n child.remove();\n }\n });\n\n const assignedElements = slot.assignedElements({ flatten: true });\n\n assignedElements.forEach((node) => {\n // ---- Handle <nys-option> ----\n if (node instanceof NysOption) {\n const optionElement = document.createElement(\"option\");\n optionElement.value = node.value;\n optionElement.textContent =\n node.label || node.textContent?.trim() || \"\";\n optionElement.disabled = node.disabled;\n optionElement.selected = node.selected;\n select.appendChild(optionElement);\n return;\n }\n\n // ---- Handle native <option> ----\n if (node.tagName === \"OPTION\") {\n const original = node as HTMLOptionElement;\n const optionClone = original.cloneNode(true) as HTMLOptionElement;\n\n optionClone.setAttribute(\"data-native\", \"true\");\n optionClone.disabled = original.disabled;\n optionClone.selected = original.selected;\n\n select.appendChild(optionClone);\n return;\n }\n\n // ---- Handle <optgroup> ----\n if (node.tagName === \"OPTGROUP\") {\n const groupClone = document.createElement(\"optgroup\");\n groupClone.label = (node as HTMLOptGroupElement).label;\n if ((node as HTMLOptGroupElement).disabled) {\n groupClone.disabled = true;\n }\n\n // iterate children inside optgroup (could be nys-option or native option)\n Array.from(node.children).forEach((child) => {\n if (child instanceof NysOption) {\n const option = document.createElement(\"option\");\n option.value = child.value;\n option.textContent = child.label || child.textContent?.trim() || \"\";\n option.disabled = child.disabled;\n option.selected = child.selected;\n groupClone.appendChild(option);\n } else if (child.tagName === \"OPTION\") {\n const optionClone = child.cloneNode(true) as HTMLOptionElement;\n groupClone.appendChild(optionClone);\n }\n });\n\n select.appendChild(groupClone);\n return;\n }\n });\n\n // Sync initial selected state into component value\n const selectedOption = Array.from(select.options).find((o) => o.selected);\n\n if (selectedOption) {\n this.value = selectedOption.value;\n this._internals.setFormValue(this.value);\n }\n }\n\n /**\n * Form Integration\n * --------------------------------------------------------------------------\n */\n\n private _setValue() {\n this._internals.setFormValue(this.value);\n this._manageRequire(); // Check validation when value is set\n }\n\n private _manageRequire() {\n const select = this.shadowRoot?.querySelector(\"select\");\n if (!select) return;\n\n const message = this.errorMessage || \"This field is required.\";\n const isInvalid = this.required && !this.value;\n\n if (isInvalid) {\n this._internals.ariaRequired = \"true\"; // Screen readers should announce error\n this._internals.setValidity({ valueMissing: true }, message, select);\n } else {\n this._internals.ariaRequired = \"false\"; // Reset when valid\n this._internals.setValidity({});\n this._hasUserInteracted = false; // Reset the interaction flag, make lazy again\n }\n }\n\n private _setValidityMessage(message: string = \"\") {\n const select = this.shadowRoot?.querySelector(\"select\");\n if (!select) return;\n\n // Toggle the HTML <div> tag error message\n this.showError = !!message;\n\n // If user sets errorMessage, this will always override the native validation message\n if (this._originalErrorMessage?.trim() && message !== \"\") {\n this.errorMessage = this._originalErrorMessage;\n } else {\n this.errorMessage = message;\n }\n\n const validityState = message ? { customError: true } : {};\n this._internals.setValidity(validityState, this.errorMessage, select);\n }\n\n private _validate() {\n const select = this.shadowRoot?.querySelector(\"select\");\n if (!select) return;\n\n // Get the native validation state\n let message = select.validationMessage;\n this._manageRequire(); // Makes sure the required state is checked\n\n this._setValidityMessage(message);\n }\n\n // This callback is automatically called when the parent form is reset.\n public formResetCallback() {\n this.value = \"\";\n const select = this.shadowRoot?.querySelector(\"select\");\n if (select) {\n select.value = \"\";\n Array.from(select.options).forEach((other) => (other.selected = false));\n }\n\n // Reset validation UI\n this.showError = false;\n this.errorMessage = \"\";\n this._internals.setValidity({});\n\n // Re-render UI\n this.requestUpdate();\n }\n\n /**\n * Functions\n * --------------------------------------------------------------------------\n */\n // This helper function is called to perform the element's native validation.\n checkValidity(): boolean {\n const select = this.shadowRoot?.querySelector(\"select\");\n return select ? select.checkValidity() : true;\n }\n\n private _handleInvalid(event: Event) {\n event.preventDefault();\n this._hasUserInteracted = true; // Start aggressive mode due to form submission\n this._validate();\n this.showError = true;\n\n const select = this.shadowRoot?.querySelector(\"select\");\n if (select) {\n // Focus only if this is the first invalid element (top-down approach)\n const form = this._internals.form;\n if (form) {\n const elements = Array.from(form.elements) as Array<\n HTMLElement & { checkValidity?: () => boolean }\n >;\n // Find the first element in the form that is invalid\n const firstInvalidElement = elements.find(\n (element) =>\n typeof element.checkValidity === \"function\" &&\n !element.checkValidity(),\n );\n if (firstInvalidElement === this) {\n select.focus();\n }\n } else {\n // If not part of a form, simply focus.\n select.focus();\n }\n }\n }\n\n /**\n * Event Handlers\n * --------------------------------------------------------------------------\n */\n\n // Handle change event to bubble up selected value\n private _handleChange(e: Event) {\n const select = e.target as HTMLSelectElement;\n this.value = select.value;\n this._internals.setFormValue(this.value);\n\n // Clear error immediately if value is now valid\n if (this.required && this.value) {\n this.showError = false;\n this.errorMessage = \"\";\n this._internals.setValidity({});\n }\n\n // Validate aggressively if the user has already interacted\n if (this._hasUserInteracted) {\n this._validate();\n }\n\n this.dispatchEvent(\n new CustomEvent(\"nys-change\", {\n detail: { id: this.id, value: this.value },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // Handle focus event\n private _handleFocus() {\n this.dispatchEvent(\n new Event(\"nys-focus\", { bubbles: true, composed: true }),\n );\n }\n\n // Handle blur event\n private _handleBlur() {\n if (!this._hasUserInteracted) {\n this._hasUserInteracted = true;\n }\n this._validate();\n this.dispatchEvent(\n new Event(\"nys-blur\", { bubbles: true, composed: true }),\n );\n }\n\n // Check if the current value matches any option, and if so, set it as selected\n updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n\n // This ensures the value is set correctly after the component renders\n if (changedProperties.has(\"value\")) {\n const selectElement = this.shadowRoot?.querySelector(\"select\");\n if (selectElement) {\n selectElement.value = this.value;\n }\n }\n }\n\n render() {\n return html`\n <div class=\"nys-select\">\n <nys-label\n for=${this.id + \"--native\"}\n label=${this.label}\n description=${this.description}\n flag=${this.required ? \"required\" : this.optional ? \"optional\" : \"\"}\n tooltip=${this.tooltip}\n ?inverted=${this.inverted}\n >\n <slot name=\"description\" slot=\"description\">${this.description}</slot>\n </nys-label>\n <div class=\"nys-select__selectwrapper\">\n <select\n class=\"nys-select__select\"\n name=${this.name}\n id=${this.id + \"--native\"}\n form=${ifDefined(this.form || undefined)}\n ?disabled=${this.disabled}\n ?required=${this.required}\n aria-disabled=\"${this.disabled}\"\n aria-label=\"${[this.label, this.description]\n .filter(Boolean)\n .join(\" \")}\"\n .value=${this.value}\n @focus=\"${this._handleFocus}\"\n @blur=\"${this._handleBlur}\"\n @change=\"${this._handleChange}\"\n >\n <option data-native hidden disabled value=\"\"></option>\n </select>\n <slot style=\"display: none;\"></slot>\n <nys-icon\n name=\"chevron_down\"\n size=\"2xl\"\n class=\"nys-select__icon\"\n ></nys-icon>\n </div>\n <nys-errormessage\n ?showError=${this.showError}\n errorMessage=${this.errorMessage}\n ></nys-errormessage>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"nys-select\")) {\n customElements.define(\"nys-select\", NysSelect);\n}\n"],"names":["NysOption","LitElement","slot","assignedNodes","html","__decorateClass","property","selectIdCounter","_NysSelect","select","child","node","optionElement","original","optionClone","groupClone","option","selectedOption","o","message","validityState","other","event","form","element","changedProperties","selectElement","ifDefined","unsafeCSS","styles","NysSelect"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nysds/nys-select",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.1",
|
|
4
4
|
"description": "The Select component from the NYS Design System.",
|
|
5
5
|
"module": "dist/nys-select.js",
|
|
6
6
|
"exports": {
|
|
@@ -15,16 +15,16 @@
|
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"dev": "tsc --emitDeclarationOnly && vite",
|
|
18
|
-
"build": "
|
|
18
|
+
"build": "vite build",
|
|
19
19
|
"test": "vite build && wtr",
|
|
20
20
|
"build:watch": "tsc --emitDeclarationOnly && vite build --watch",
|
|
21
21
|
"test:watch": "vite build && wtr --watch",
|
|
22
22
|
"lit-analyze": "lit-analyzer '**/*.ts'"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@nysds/nys-icon": "^1.15.
|
|
26
|
-
"@nysds/nys-label": "^1.15.
|
|
27
|
-
"@nysds/nys-errormessage": "^1.15.
|
|
25
|
+
"@nysds/nys-icon": "^1.15.1",
|
|
26
|
+
"@nysds/nys-label": "^1.15.1",
|
|
27
|
+
"@nysds/nys-errormessage": "^1.15.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"lit": "^3.3.1",
|
package/dist/index.d.ts
DELETED
package/dist/nys-option.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { LitElement } from "lit";
|
|
2
|
-
/**
|
|
3
|
-
* An option item for use within `nys-select`. Wraps a native `<option>` element.
|
|
4
|
-
*
|
|
5
|
-
* Place inside `nys-select`. Set `value` for form submission and `label` for display text.
|
|
6
|
-
* Alternatively, slot text content which auto-populates the label.
|
|
7
|
-
*
|
|
8
|
-
* @summary Option item for nys-select dropdown.
|
|
9
|
-
* @element nys-option
|
|
10
|
-
*
|
|
11
|
-
* @slot - Option label text. Auto-populates the `label` prop if provided.
|
|
12
|
-
*
|
|
13
|
-
* @example Basic options
|
|
14
|
-
* ```html
|
|
15
|
-
* <nys-select>
|
|
16
|
-
* <nys-option value="ny">New York</nys-option>
|
|
17
|
-
* <nys-option value="ca" disabled>California</nys-option>
|
|
18
|
-
* </nys-select>
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
export declare class NysOption extends LitElement {
|
|
22
|
-
/** Prevents selection of this option. */
|
|
23
|
-
disabled: boolean;
|
|
24
|
-
/** Pre-selects this option. */
|
|
25
|
-
selected: boolean;
|
|
26
|
-
/** Value submitted when this option is selected. */
|
|
27
|
-
value: string;
|
|
28
|
-
/** Display text for the option. Auto-populated from slot content if not set. */
|
|
29
|
-
label: string;
|
|
30
|
-
/** Hides the option from the dropdown list. */
|
|
31
|
-
hidden: boolean;
|
|
32
|
-
firstUpdated(): void;
|
|
33
|
-
render(): import("lit-html").TemplateResult<1>;
|
|
34
|
-
}
|
package/dist/nys-select.d.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { LitElement } from "lit";
|
|
2
|
-
/**
|
|
3
|
-
* A dropdown for selecting a single option from a list. Supports native `<option>` and `<optgroup>` elements.
|
|
4
|
-
* Form-associated with validation via ElementInternals.
|
|
5
|
-
*
|
|
6
|
-
* Use when users must choose one option from 7+ items. For fewer options, consider `nys-radiobutton`.
|
|
7
|
-
* For multiple selections, use `nys-checkbox` group instead.
|
|
8
|
-
*
|
|
9
|
-
* @summary Dropdown select for choosing one option from a list.
|
|
10
|
-
* @element nys-select
|
|
11
|
-
*
|
|
12
|
-
* @slot - Default slot for `<option>` and `<optgroup>` elements.
|
|
13
|
-
* @slot description - Custom HTML description content below the label.
|
|
14
|
-
*
|
|
15
|
-
* @fires nys-change - Fired when selection changes. Detail: `{id, value}`.
|
|
16
|
-
* @fires nys-focus - Fired when select gains focus.
|
|
17
|
-
* @fires nys-blur - Fired when select loses focus. Triggers validation.
|
|
18
|
-
*
|
|
19
|
-
* @example Basic select
|
|
20
|
-
* ```html
|
|
21
|
-
* <nys-select label="Select borough">
|
|
22
|
-
* <option value="bronx">The Bronx</option>
|
|
23
|
-
* <option value="brooklyn">Brooklyn</option>
|
|
24
|
-
* <option value="manhattan">Manhattan</option>
|
|
25
|
-
* </nys-select>
|
|
26
|
-
* ```
|
|
27
|
-
*
|
|
28
|
-
* @example With option groups
|
|
29
|
-
* ```html
|
|
30
|
-
* <nys-select label="Select service">
|
|
31
|
-
* <optgroup label="Transportation">
|
|
32
|
-
* <option value="mta">MTA</option>
|
|
33
|
-
* <option value="dmv">DMV</option>
|
|
34
|
-
* </optgroup>
|
|
35
|
-
* </nys-select>
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
export declare class NysSelect extends LitElement {
|
|
39
|
-
static styles: import("lit").CSSResult;
|
|
40
|
-
static shadowRootOptions: {
|
|
41
|
-
delegatesFocus: boolean;
|
|
42
|
-
clonable?: boolean;
|
|
43
|
-
customElementRegistry?: CustomElementRegistry;
|
|
44
|
-
mode: ShadowRootMode;
|
|
45
|
-
serializable?: boolean;
|
|
46
|
-
slotAssignment?: SlotAssignmentMode;
|
|
47
|
-
};
|
|
48
|
-
/** Unique identifier. Auto-generated if not provided. */
|
|
49
|
-
id: string;
|
|
50
|
-
/** Name for form submission. */
|
|
51
|
-
name: string;
|
|
52
|
-
/** Visible label text. Required for accessibility. */
|
|
53
|
-
label: string;
|
|
54
|
-
/** Helper text below label. Use slot for custom HTML. */
|
|
55
|
-
description: string;
|
|
56
|
-
/** Currently selected option value. */
|
|
57
|
-
value: string;
|
|
58
|
-
/** Prevents interaction. */
|
|
59
|
-
disabled: boolean;
|
|
60
|
-
/** Marks as required. Shows "Required" flag and validates on blur. */
|
|
61
|
-
required: boolean;
|
|
62
|
-
/** Shows "Optional" flag. Use when most fields are required. */
|
|
63
|
-
optional: boolean;
|
|
64
|
-
/** Tooltip text shown on hover/focus of info icon. */
|
|
65
|
-
tooltip: string;
|
|
66
|
-
/** Form `id` to associate with when select is outside form element. */
|
|
67
|
-
form: string | null;
|
|
68
|
-
/** Adjusts colors for dark backgrounds. */
|
|
69
|
-
inverted: boolean;
|
|
70
|
-
/** Shows error message when true. Set by validation or manually. */
|
|
71
|
-
showError: boolean;
|
|
72
|
-
/** Error message text. Shown only when `showError` is true. */
|
|
73
|
-
errorMessage: string;
|
|
74
|
-
/**
|
|
75
|
-
* Select width: `sm` (88px), `md` (200px), `lg` (384px), `full` (100%, default).
|
|
76
|
-
* @default "full"
|
|
77
|
-
*/
|
|
78
|
-
width: "sm" | "md" | "lg" | "full";
|
|
79
|
-
private _originalErrorMessage;
|
|
80
|
-
private _hasUserInteracted;
|
|
81
|
-
private _internals;
|
|
82
|
-
/**
|
|
83
|
-
* Lifecycle methods
|
|
84
|
-
* --------------------------------------------------------------------------
|
|
85
|
-
*/
|
|
86
|
-
static formAssociated: boolean;
|
|
87
|
-
constructor();
|
|
88
|
-
connectedCallback(): void;
|
|
89
|
-
disconnectedCallback(): void;
|
|
90
|
-
firstUpdated(): void;
|
|
91
|
-
private _handleSlotChange;
|
|
92
|
-
/**
|
|
93
|
-
* Form Integration
|
|
94
|
-
* --------------------------------------------------------------------------
|
|
95
|
-
*/
|
|
96
|
-
private _setValue;
|
|
97
|
-
private _manageRequire;
|
|
98
|
-
private _setValidityMessage;
|
|
99
|
-
private _validate;
|
|
100
|
-
formResetCallback(): void;
|
|
101
|
-
/**
|
|
102
|
-
* Functions
|
|
103
|
-
* --------------------------------------------------------------------------
|
|
104
|
-
*/
|
|
105
|
-
checkValidity(): boolean;
|
|
106
|
-
private _handleInvalid;
|
|
107
|
-
/**
|
|
108
|
-
* Event Handlers
|
|
109
|
-
* --------------------------------------------------------------------------
|
|
110
|
-
*/
|
|
111
|
-
private _handleChange;
|
|
112
|
-
private _handleFocus;
|
|
113
|
-
private _handleBlur;
|
|
114
|
-
updated(changedProperties: Map<string, unknown>): void;
|
|
115
|
-
render(): import("lit-html").TemplateResult<1>;
|
|
116
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|