@nysds/nys-combobox 1.19.3 → 1.20.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.
@@ -0,0 +1 @@
1
+ export * from "./nys-combobox";
@@ -0,0 +1,295 @@
1
+ import { NysFormControlElement } from "@nysds/internals";
2
+ import "@nysds/nys-label";
3
+ import "@nysds/nys-errormessage";
4
+ import "@nysds/nys-icon";
5
+ import "@nysds/nys-button";
6
+ /**
7
+ * `<nys-combobox>` is a form-enabled combo box combining text input with a filterable dropdown.
8
+ *
9
+ * Features:
10
+ * - Type to filter options
11
+ * - Keyboard navigation (Arrow keys, Enter, Escape)
12
+ * - Mouse and keyboard interaction
13
+ * - Clears non-selected text on blur
14
+ * - Clear button when value is selected
15
+ * - Integrates with forms via ElementInternals
16
+ * - Supports native <option> and <optgroup> elements
17
+ * - Accessible per W3C ARIA Authoring Practices
18
+ *
19
+ * @slot description - Optional custom description content below the label.
20
+ * @slot default - Options (<option>, <optgroup>) to populate the dropdown
21
+ *
22
+ * @fires nys-change - Fired when selection changes. Detail: `{ id, value }`.
23
+ * @fires nys-input - Fired on input change. Detail: `{ id, value }`.
24
+ * @fires nys-focus - Fired when combobox receives focus.
25
+ * @fires nys-blur - Fired when combobox loses focus.
26
+ *
27
+ *
28
+ * @example Basic
29
+ * ```html
30
+ * <nys-combobox label="Select your favorite fruit">
31
+ * <option value="apple">Apple</option>
32
+ * <option value="banana">Banana</option>
33
+ * <option value="cherry">Cherry</option>
34
+ * <option value="date">Date</option>
35
+ * <option value="elderberry">Elderberry</option>
36
+ * <option value="fig">Fig</option>
37
+ * <option value="grape">Grape</option>
38
+ * <option value="honeydew">Honeydew</option>
39
+ * <option value="kiwi">Kiwi</option>
40
+ * <option value="lemon">Lemon</option>
41
+ * <option value="mango">Mango</option>
42
+ * <option value="nectarine">Nectarine</option>
43
+ * <option value="orange">Orange</option>
44
+ * <option value="papaya">Papaya</option>
45
+ * <option value="quince">Quince</option>
46
+ * <option value="raspberry">Raspberry</option>
47
+ * <option value="strawberry">Strawberry</option>
48
+ * <option value="tangerine">Tangerine</option>
49
+ * <option value="watermelon">Watermelon</option>
50
+ * </nys-combobox>
51
+ * ```
52
+ *
53
+ * @example Default Value
54
+ * ```html
55
+ * <nys-combobox label="Select your favorite fruit" value="mango">
56
+ * <option value="apple">Apple</option>
57
+ * <option value="banana">Banana</option>
58
+ * <option value="mango" selected>Mango</option>
59
+ * <option value="orange">Orange</option>
60
+ * <option value="strawberry">Strawberry</option>
61
+ * </nys-combobox>
62
+ * ```
63
+ *
64
+ * @example Option Group
65
+ * ```html
66
+ * <nys-combobox label="Select a fruit" description="Fruits organized by category">
67
+ * <optgroup label="Citrus">
68
+ * <option value="lemon">Lemon</option>
69
+ * <option value="lime">Lime</option>
70
+ * <option value="orange">Orange</option>
71
+ * <option value="grapefruit">Grapefruit</option>
72
+ * <option value="tangerine">Tangerine</option>
73
+ * </optgroup>
74
+ * <optgroup label="Berries">
75
+ * <option value="strawberry">Strawberry</option>
76
+ * <option value="blueberry">Blueberry</option>
77
+ * <option value="raspberry">Raspberry</option>
78
+ * <option value="blackberry">Blackberry</option>
79
+ * <option value="cranberry">Cranberry</option>
80
+ * </optgroup>
81
+ * <optgroup label="Tropical">
82
+ * <option value="mango">Mango</option>
83
+ * <option value="pineapple">Pineapple</option>
84
+ * <option value="papaya">Papaya</option>
85
+ * <option value="coconut">Coconut</option>
86
+ * <option value="passionfruit">Passionfruit</option>
87
+ * </optgroup>
88
+ * <optgroup label="Stone Fruits">
89
+ * <option value="peach">Peach</option>
90
+ * <option value="plum">Plum</option>
91
+ * <option value="cherry">Cherry</option>
92
+ * <option value="apricot">Apricot</option>
93
+ * <option value="nectarine">Nectarine</option>
94
+ * </optgroup>
95
+ * </nys-combobox>
96
+ * ```
97
+ *
98
+ * @example Disabled
99
+ * ```html
100
+ * <nys-combobox label="Select your favorite fruit" disabled>
101
+ * <option value="apple">Apple</option>
102
+ * <option value="banana">Banana</option>
103
+ * <option value="orange">Orange</option>
104
+ * <option value="strawberry">Strawberry</option>
105
+ * </nys-combobox>
106
+ * ```
107
+ *
108
+ * @example Required
109
+ * ```html
110
+ * <nys-combobox label="Select your favorite fruit" required>
111
+ * <option value="apple">Apple</option>
112
+ * <option value="banana">Banana</option>
113
+ * <option value="orange">Orange</option>
114
+ * <option value="strawberry">Strawberry</option>
115
+ * </nys-combobox>
116
+ * ```
117
+ *
118
+ * @example Optional
119
+ * ```html
120
+ * <nys-combobox label="Select your favorite fruit" optional>
121
+ * <option value="apple">Apple</option>
122
+ * <option value="banana">Banana</option>
123
+ * <option value="orange">Orange</option>
124
+ * <option value="strawberry">Strawberry</option>
125
+ * </nys-combobox>
126
+ * ```
127
+ *
128
+ * @example Width Medium
129
+ * ```html
130
+ * <nys-combobox label="Select your favorite fruit" width="md">
131
+ * <option value="apple">Apple</option>
132
+ * <option value="banana">Banana</option>
133
+ * <option value="orange">Orange</option>
134
+ * <option value="strawberry">Strawberry</option>
135
+ * </nys-combobox>
136
+ * ```
137
+ *
138
+ * @example Width Large
139
+ * ```html
140
+ * <nys-combobox label="Select your favorite fruit" width="lg">
141
+ * <option value="apple">Apple</option>
142
+ * <option value="banana">Banana</option>
143
+ * <option value="orange">Orange</option>
144
+ * <option value="strawberry">Strawberry</option>
145
+ * </nys-combobox>
146
+ * ```
147
+ *
148
+ * @example Description
149
+ * ```html
150
+ * <nys-combobox label="Select your favorite fruit" description="Choose from the list of available fruits.">
151
+ * <option value="apple">Apple</option>
152
+ * <option value="banana">Banana</option>
153
+ * <option value="orange">Orange</option>
154
+ * <option value="strawberry">Strawberry</option>
155
+ * </nys-combobox>
156
+ * ```d
157
+ *
158
+ * @example Description Slot
159
+ * ```html
160
+ * <nys-combobox label="Select your favorite fruit">
161
+ * <label slot="description">This is a description slot</label>
162
+ * <option value="apple">Apple</option>
163
+ * <option value="banana">Banana</option>
164
+ * <option value="orange">Orange</option>
165
+ * <option value="strawberry">Strawberry</option>
166
+ * </nys-combobox>
167
+ * ```
168
+ *
169
+ * @example Error Message
170
+ * ```html
171
+ * <nys-combobox label="Select your favorite fruit" showError errorMessage="Please select a fruit">
172
+ * <option value="apple">Apple</option>
173
+ * <option value="banana">Banana</option>
174
+ * <option value="orange">Orange</option>
175
+ * <option value="strawberry">Strawberry</option>
176
+ * </nys-combobox>
177
+ * ```
178
+ *
179
+ * @example Disabled Options
180
+ * ```html
181
+ * <nys-combobox label="Select your favorite fruit" description="Some fruits are out of season">
182
+ * <option value="apple">Apple</option>
183
+ * <option value="banana">Banana</option>
184
+ * <option value="cherry" disabled>Cherry (Out of season)</option>
185
+ * <option value="mango">Mango</option>
186
+ * <option value="strawberry" disabled>Strawberry (Out of season)</option>
187
+ * <option value="orange">Orange</option>
188
+ * </nys-combobox>
189
+ * ```
190
+ */
191
+ export declare class NysCombobox extends NysFormControlElement {
192
+ static styles: import("lit").CSSResult;
193
+ static shadowRootOptions: {
194
+ delegatesFocus: boolean;
195
+ clonable?: boolean;
196
+ customElementRegistry?: CustomElementRegistry;
197
+ mode: ShadowRootMode;
198
+ serializable?: boolean;
199
+ slotAssignment?: SlotAssignmentMode;
200
+ };
201
+ id: string;
202
+ name: string;
203
+ label: string;
204
+ description: string;
205
+ value: string;
206
+ disabled: boolean;
207
+ required: boolean;
208
+ optional: boolean;
209
+ tooltip: string;
210
+ form: string | null;
211
+ width: "md" | "lg" | "full";
212
+ inverted: boolean;
213
+ showError: boolean;
214
+ errorMessage: string;
215
+ private _isOpen;
216
+ private _filterText;
217
+ private _highlightedIndex;
218
+ private _options;
219
+ private _filteredOptions;
220
+ private _dropdownAbove;
221
+ private _announcement;
222
+ private _input;
223
+ private _listbox?;
224
+ private _originalErrorMessage;
225
+ private _hasUserInteracted;
226
+ private _selectedLabel;
227
+ private _defaultValue;
228
+ private _hasResolvedSlottedValue;
229
+ /**
230
+ * Lifecycle methods
231
+ * --------------------------------------------------------------------------
232
+ * Form association, ElementInternals, and id generation are provided by
233
+ * NysFormControlElement (@nysds/internals).
234
+ */
235
+ connectedCallback(): void;
236
+ disconnectedCallback(): void;
237
+ firstUpdated(): void;
238
+ willUpdate(changedProperties: Map<string | number | symbol, unknown>): void;
239
+ updated(changedProperties: Map<string | number | symbol, unknown>): void;
240
+ /**
241
+ * Slot handling
242
+ * --------------------------------------------------------------------------
243
+ */
244
+ private _handleSlotChange;
245
+ /**
246
+ * Form Integration
247
+ * --------------------------------------------------------------------------
248
+ */
249
+ private _setValue;
250
+ private _manageRequire;
251
+ private _setValidityMessage;
252
+ private _validate;
253
+ formResetCallback(): void;
254
+ checkValidity(): boolean;
255
+ private _handleInvalid;
256
+ /**
257
+ * Dropdown positioning
258
+ * --------------------------------------------------------------------------
259
+ */
260
+ private _positionDropdown;
261
+ /**
262
+ * Filtering
263
+ * --------------------------------------------------------------------------
264
+ */
265
+ private _filterOptions;
266
+ /**
267
+ * Keyboard navigation
268
+ * --------------------------------------------------------------------------
269
+ */
270
+ private _scrollToHighlighted;
271
+ private _handleKeyDown;
272
+ private _moveHighlight;
273
+ /**
274
+ * Event Handlers
275
+ * --------------------------------------------------------------------------
276
+ */
277
+ private _handleInput;
278
+ private _handleFocus;
279
+ private _handleBlur;
280
+ private _handleDocumentClick;
281
+ private _handleIconClick;
282
+ private _handleClearClick;
283
+ private _handleOptionClick;
284
+ private _handleOptionMouseEnter;
285
+ private _selectOption;
286
+ private _handleChange;
287
+ private _openDropdown;
288
+ private _closeDropdown;
289
+ /**
290
+ * Render helpers
291
+ * --------------------------------------------------------------------------
292
+ */
293
+ private _renderOptions;
294
+ render(): import("lit-html").TemplateResult<1>;
295
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,65 +1,149 @@
1
- import { LitElement as y, unsafeCSS as x, html as h } from "lit";
2
- import { property as a, state as d, query as v } from "lit/decorators.js";
3
- import { ifDefined as m } from "lit/directives/if-defined.js";
1
+ import { LitElement as v, unsafeCSS as g, html as u } from "lit";
2
+ import { property as a, state as p, query as m } from "lit/decorators.js";
3
+ import { ifDefined as y } from "lit/directives/if-defined.js";
4
+ import "@nysds/nys-label";
5
+ import "@nysds/nys-errormessage";
6
+ import "@nysds/nys-icon";
7
+ import "@nysds/nys-button";
4
8
  /*!
5
9
  * █▄ █ █ █ █▀▀▀█ █▀▀▄ █▀▀▀█
6
10
  * █ █ █ █▄▄▄█ ▀▀▀▄▄ █ █ ▀▀▀▄▄
7
11
  * █ ▀█ █ █▄▄▄█ █▄▄▀ █▄▄▄█
8
12
  *
9
- * Combobox Component v1.19.3
13
+ * Combobox Component v1.20.0
10
14
  * Part of the New York State Design System
11
15
  * Repository: https://github.com/its-hcd/nysds
12
16
  * License: MIT
13
17
  */
14
- const g = ':host{--_nys-combobox-width: 100%;--_nys-combobox-height: var(--nys-size-500, 40px);--_nys-combobox-border-radius: var(--nys-radius-md, 4px);--_nys-combobox-border-width: var(--nys-border-width-sm, 1px);--_nys-combobox-border-color: var(--nys-color-neutral-400, #909395);--_nys-combobox-color: var( --nys-color-text, var(--nys-color-neutral-900, #1b1b1b) );--_nys-combobox-padding: var(--nys-space-100, 8px) var(--nys-space-150, 12px);--_nys-combobox-gap: var(--nys-space-50, 4px);--_nys-combobox-background-color: var( --nys-color-ink-reverse, var(--nys-color-white, #ffffff) );--_nys-combobox-outline-color--hover: var(--nys-color-neutral-900, #1b1b1b);--_nys-combobox-outline-width: var(--nys-border-width-sm, 1px);--_nys-combobox-outline-color--focus: var(--nys-color-focus, #004dd1);--_nys-combobox-background-color--disabled: var( --nys-color-neutral-10, #f6f6f6 );--_nys-combobox-border-color--disabled: var(--nys-color-neutral-200, #bec0c1);--_nys-combobox-color--disabled: var( --nys-color-text-disabled, var(--nys-color-neutral-200, #bec0c1) );--_nys-combobox-background-color--dropdown: var( --nys-color-ink-reverse, var(--nys-color-white, #ffffff) );--_nys-combobox-border-color--dropdown: var(--nys-color-neutral-400, #909395);--_nys-combobox-shadow--dropdown: var( --nys-shadow-lg, 0 4px 8px rgba(0, 0, 0, .1) );--_nys-combobox-max-height--dropdown: var(--nys-size-3000, 300px);--_nys-combobox-padding--option: var(--nys-space-100, 8px) var(--nys-space-150, 12px);--_nys-combobox-background-color--option--hover: var( --nys-color-neutral-10, #f6f6f6 );--_nys-combobox-background-color--option--active: var( --nys-color-neutral-50, #ededed );--_nys-combobox-background-color--option--disabled: var( --nys-color-white, #ffffff );--_nys-combobox-color--option--disabled: var( --nys-color-text-disabled, #bec0c1 );--_nys-combobox-background-color--option--selected: var( --nys-theme-weaker, #eff6fb );--_nys-combobox-border-color--option--selected: var( --nys-color-theme-mid, #457aa5 );--_nys-combobox-font-family: var( --nys-font-family-ui, var( --nys-font-family-sans, "Proxima Nova", "Helvetica Neue", "Helvetica", "Arial", sans-serif ) );--_nys-combobox-font-size: var(--nys-font-size-ui-md, 16px);--_nys-combobox-font-weight: var(--nys-font-weight-regular, 400);--_nys-combobox-line-height: var(--nys-font-lineheight-ui-md, 24px);--_nys-combobox-letter-spacing: var( --nys-font-letterspacing-ui-md, var(--nys-font-letterspacing-400, .044px) )}:host([width=sm]){--_nys-combobox-width: var(--nys-form-width-sm, 88px)}:host([width=md]){--_nys-combobox-width: var(--nys-form-width-md, 200px)}:host([width=lg]){--_nys-combobox-width: var(--nys-form-width-lg, 384px)}:host([width=full]){--_nys-combobox-width: 100%;flex:1}:host([showError]){--_nys-combobox-border-color: var(--nys-color-danger, #b52c2c)}:host([inverted]){--_nys-combobox-outline-color--focus: var(--nys-color-focus-reverse, #7aa5e7)}.nys-combobox{font-weight:var(--_nys-combobox-font-weight);font-family:var(--_nys-combobox-font-family);font-size:var(--_nys-combobox-font-size);line-height:var(--_nys-combobox-line-height);letter-spacing:var(--_nys-combobox-letter-spacing);color:var(--_nys-combobox-color);gap:var(--_nys-combobox-gap);display:flex;flex-direction:column;position:relative}.nys-combobox__container{width:var(--_nys-combobox-width);max-width:100%;position:relative}.nys-combobox__input-wrapper{position:relative;display:flex;align-items:center;background-color:var(--_nys-combobox-background-color);border-radius:var(--_nys-combobox-border-radius)}.nys-combobox__input{color:var(--_nys-combobox-color);border-radius:var(--_nys-combobox-border-radius);border:solid var(--_nys-combobox-border-color) var(--_nys-combobox-border-width);outline-color:transparent;outline-width:var(--_nys-combobox-outline-width);outline-style:solid;padding:var(--_nys-combobox-padding);padding-right:calc(var(--nys-size-400, 32px) + var(--nys-space-100, 8px));width:100%;height:var(--_nys-combobox-height);box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;background-color:transparent;font:inherit;cursor:text}.nys-combobox__input:not(:placeholder-shown){padding-right:calc(var(--nys-size-400, 32px) * 2 + var(--nys-space-100, 8px))}.nys-combobox__input:hover:not(:disabled):not(:focus):not([readonly]){outline-color:var(--_nys-combobox-outline-color--hover);border-color:var(--_nys-combobox-outline-color--hover)}.nys-combobox__input:focus:not([readonly]){outline-color:var(--_nys-combobox-outline-color--focus);border-color:var(--_nys-combobox-outline-color--focus);caret-color:var(--_nys-combobox-outline-color--focus)}.nys-combobox__input:disabled{background-color:var(--_nys-combobox-background-color--disabled);border-color:var(--_nys-combobox-border-color--disabled);color:var(--_nys-combobox-color--disabled);cursor:not-allowed}.nys-combobox__buttons{display:flex;position:absolute;right:var(--nys-space-150, 12px);gap:var(--nys-space-150, 12px)}.nys-combobox__buttons nys-button{--_nys-button-padding--y: var(--nys-space-50, 4px);--_nys-button-padding--x: var(--nys-space-50, 4px);--_nys-button-height: var(--nys-size-300, 32px);--_nys-button-width: var(--nys-size-400, 32px)}.nys-combobox__buttons .nys-combobox__chevron{border-inline-start:solid var(--nys-color-neutral-200, #bec0c1) var(--nys-border-width-sm, 1px);padding-inline-start:var(--nys-space-150, 12px)}.nys-combobox__listbox{position:absolute;left:0;right:0;top:calc(100% + var(--nys-space-50, 4px));background-color:var(--_nys-combobox-background-color--dropdown);border:solid var(--_nys-combobox-border-color--dropdown) var(--_nys-combobox-border-width);border-radius:var(--_nys-combobox-border-radius);box-shadow:var(--_nys-combobox-shadow--dropdown);max-height:var(--_nys-combobox-max-height--dropdown);overflow-y:auto;z-index:1000;box-sizing:border-box}.nys-combobox__listbox--above{top:auto;bottom:calc(100% + var(--nys-space-50, 4px))}.nys-combobox__option{padding:var(--_nys-combobox-padding--option);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease;border-bottom:var(--nys-border-width-sm, 1px) solid var(--nys-color-neutral-50, #ededed);background-color:var(--_nys-combobox-background-color)}.nys-combobox__option:hover:not([disabled]):not(.nys-combobox__option--selected){background-color:var(--_nys-combobox-background-color--option--hover)}.nys-combobox__option:active:not([disabled]):not(.nys-combobox__option--selected){background-color:var(--_nys-combobox-background-color--option--active)}.nys-combobox__option--selected:not([disabled]){background-color:var(--_nys-combobox-background-color--option--selected);border:var(--_nys-combobox-border-color--option--selected) solid 1px}.nys-combobox__option--focused:not([disabled]):not(:hover){outline:var(--_nys-combobox-outline-color--focus) solid 2px;outline-offset:-2px}.nys-combobox__option[disabled]{background-color:var(--_nys-combobox-background-color--option--disabled);color:var(--_nys-combobox-color--option--disabled);cursor:not-allowed}.nys-combobox__optgroup{padding:var(--nys-space-100, 8px) var(--nys-space-150, 12px);border-bottom:var(--nys-border-width-sm, 1px) solid var(--nys-color-neutral-50, #ededed);-webkit-user-select:none;user-select:none;color:var(--nys-color-text);font-family:var(--nys-font-family-ui, "Proxima Nova");font-size:var(--nys-font-size-ui-md, 16px);font-style:normal;font-weight:700;line-height:var(--nys-font-lineheight-ui-md, 24px);letter-spacing:var(--nys-font-letterspacing-ui-md, .044px)}.nys-combobox__optgroup~.nys-combobox__option{padding-left:var(--nys-space-300, 24px)}.nys-combobox__no-results{background-color:var(--_nys-combobox-background-color);padding:var(--_nys-combobox-padding--option);color:var(--_nys-combobox-color);cursor:not-allowed}.nys-combobox__listbox::-webkit-scrollbar{width:var(--nys-space-100, 8px)}.nys-combobox__listbox::-webkit-scrollbar-track{background:var(--nys-color-neutral-50, #eeeeee);border-radius:var(--_nys-combobox-border-radius)}.nys-combobox__listbox::-webkit-scrollbar-thumb{background:var(--nys-color-neutral-300, #a7a9ab);border-radius:var(--_nys-combobox-border-radius)}.nys-combobox__listbox::-webkit-scrollbar-thumb:hover{background:var(--nys-color-neutral-400, #909395)}';
15
- var w = Object.defineProperty, r = (u, o, s, e) => {
16
- for (var t = void 0, n = u.length - 1, l; n >= 0; n--)
17
- (l = u[n]) && (t = l(o, s, t) || t);
18
- return t && w(o, s, t), t;
18
+ /*!
19
+ * New York State Design System v1.20.0
20
+ * Description: A design system for New York State's digital products.
21
+ * Repository: https://github.com/its-hcd/nysds
22
+ * License: MIT
23
+ */
24
+ let w = 0;
25
+ function k(d) {
26
+ return `${d}-${Date.now()}-${w++}`;
27
+ }
28
+ const $ = (d) => {
29
+ class o extends d {
30
+ get idPrefix() {
31
+ return this.localName || "nys-element";
32
+ }
33
+ ensureId() {
34
+ this.id || (this.id = k(this.idPrefix));
35
+ }
36
+ connectedCallback() {
37
+ super.connectedCallback(), this.ensureId();
38
+ }
39
+ }
40
+ return o;
41
+ }, O = (d) => {
42
+ class o extends $(d) {
43
+ constructor() {
44
+ super(...arguments), this.__internals = null;
45
+ }
46
+ get internals() {
47
+ if (this.__internals) return this.__internals;
48
+ if (typeof this.attachInternals == "function")
49
+ try {
50
+ this.__internals = this.attachInternals();
51
+ } catch {
52
+ this.__internals = null;
53
+ }
54
+ return this.__internals;
55
+ }
56
+ get defaultRole() {
57
+ return null;
58
+ }
59
+ setHostAria(e, t) {
60
+ const i = this.internals;
61
+ if (i && e in i) {
62
+ i[e] = t;
63
+ return;
64
+ }
65
+ const r = I(e);
66
+ t === null ? this.removeAttribute(r) : this.setAttribute(r, t);
67
+ }
68
+ reflectDefaultSemantics() {
69
+ const e = this.defaultRole;
70
+ e && this.setHostAria("role", e);
71
+ }
72
+ connectedCallback() {
73
+ super.connectedCallback(), this.reflectDefaultSemantics();
74
+ }
75
+ }
76
+ return o;
19
77
  };
20
- let k = 0;
21
- const p = class p extends y {
78
+ function I(d) {
79
+ if (d === "role") return "role";
80
+ const o = d.replace(/^aria/, "");
81
+ return "aria-" + o.charAt(0).toLowerCase() + o.slice(1);
82
+ }
83
+ const V = (d) => {
84
+ const o = class extends O(d) {
85
+ setFormValue(t) {
86
+ this.internals?.setFormValue(t ?? null);
87
+ }
88
+ setValidityFromState(t, i, r) {
89
+ const c = this.internals;
90
+ if (!c) return;
91
+ const h = Object.values(t).some(Boolean);
92
+ h ? c.setValidity(t, i ?? "Invalid value", r) : c.setValidity({}), this.setHostAria("ariaInvalid", h ? "true" : "false");
93
+ }
94
+ clearValidity() {
95
+ this.internals?.setValidity({}), this.setHostAria("ariaInvalid", "false");
96
+ }
97
+ checkValidity() {
98
+ return this.internals?.checkValidity() ?? !0;
99
+ }
100
+ reportValidity() {
101
+ return this.internals?.reportValidity() ?? !0;
102
+ }
103
+ formResetCallback() {
104
+ this.clearValidity();
105
+ }
106
+ };
107
+ return o.formAssociated = !0, o;
108
+ }, E = /* @__PURE__ */ V(v), C = ':host{--_nys-combobox-width: 100%;--_nys-combobox-height: var(--nys-size-500, 40px);--_nys-combobox-border-radius: var(--nys-radius-md, 4px);--_nys-combobox-border-width: var(--nys-border-width-sm, 1px);--_nys-combobox-border-color: var(--nys-color-neutral-400, #909395);--_nys-combobox-color: var( --nys-color-text, var(--nys-color-neutral-900, #1b1b1b) );--_nys-combobox-padding: var(--nys-space-100, 8px) var(--nys-space-150, 12px);--_nys-combobox-gap: var(--nys-space-50, 4px);--_nys-combobox-background-color: var( --nys-color-ink-reverse, var(--nys-color-white, #ffffff) );--_nys-combobox-outline-color--hover: var(--nys-color-neutral-900, #1b1b1b);--_nys-combobox-outline-width: var(--nys-border-width-sm, 1px);--_nys-combobox-outline-color--focus: var(--nys-color-focus, #004dd1);--_nys-combobox-background-color--disabled: var( --nys-color-neutral-10, #f6f6f6 );--_nys-combobox-border-color--disabled: var(--nys-color-neutral-200, #bec0c1);--_nys-combobox-color--disabled: var( --nys-color-text-disabled, var(--nys-color-neutral-200, #bec0c1) );--_nys-combobox-background-color--dropdown: var( --nys-color-ink-reverse, var(--nys-color-white, #ffffff) );--_nys-combobox-border-color--dropdown: var(--nys-color-neutral-400, #909395);--_nys-combobox-shadow--dropdown: var( --nys-shadow-lg, 0 4px 8px rgba(0, 0, 0, .1) );--_nys-combobox-max-height--dropdown: var(--nys-size-3000, 300px);--_nys-combobox-padding--option: var(--nys-space-100, 8px) var(--nys-space-150, 12px);--_nys-combobox-background-color--option--hover: var( --nys-color-neutral-10, #f6f6f6 );--_nys-combobox-background-color--option--active: var( --nys-color-neutral-50, #ededed );--_nys-combobox-background-color--option--disabled: var( --nys-color-white, #ffffff );--_nys-combobox-color--option--disabled: var( --nys-color-text-disabled, #bec0c1 );--_nys-combobox-background-color--option--selected: var( --nys-theme-weaker, #eff6fb );--_nys-combobox-border-color--option--selected: var( --nys-color-theme-mid, #457aa5 );--_nys-combobox-font-family: var( --nys-font-family-ui, var( --nys-font-family-sans, "Proxima Nova", "Helvetica Neue", "Helvetica", "Arial", sans-serif ) );--_nys-combobox-font-size: var(--nys-font-size-ui-md, 16px);--_nys-combobox-font-weight: var(--nys-font-weight-regular, 400);--_nys-combobox-line-height: var(--nys-font-lineheight-ui-md, 24px);--_nys-combobox-letter-spacing: var( --nys-font-letterspacing-ui-md, var(--nys-font-letterspacing-400, .044px) )}:host([width=sm]){--_nys-combobox-width: var(--nys-form-width-sm, 88px)}:host([width=md]){--_nys-combobox-width: var(--nys-form-width-md, 200px)}:host([width=lg]){--_nys-combobox-width: var(--nys-form-width-lg, 384px)}:host([width=full]){--_nys-combobox-width: 100%;flex:1}:host([showError]){--_nys-combobox-border-color: var(--nys-color-danger, #b52c2c)}:host([inverted]){--_nys-combobox-outline-color--focus: var(--nys-color-focus-reverse, #7aa5e7)}.nys-combobox{font-weight:var(--_nys-combobox-font-weight);font-family:var(--_nys-combobox-font-family);font-size:var(--_nys-combobox-font-size);line-height:var(--_nys-combobox-line-height);letter-spacing:var(--_nys-combobox-letter-spacing);color:var(--_nys-combobox-color);gap:var(--_nys-combobox-gap);display:flex;flex-direction:column;position:relative}.nys-combobox__container{width:var(--_nys-combobox-width);max-width:100%;position:relative}.nys-combobox__input-wrapper{position:relative;display:flex;align-items:center;background-color:var(--_nys-combobox-background-color);border-radius:var(--_nys-combobox-border-radius)}.nys-combobox__input{color:var(--_nys-combobox-color);border-radius:var(--_nys-combobox-border-radius);border:solid var(--_nys-combobox-border-color) var(--_nys-combobox-border-width);outline-color:transparent;outline-width:var(--_nys-combobox-outline-width);outline-style:solid;padding:var(--_nys-combobox-padding);padding-right:calc(var(--nys-size-400, 32px) + var(--nys-space-100, 8px));width:100%;height:var(--_nys-combobox-height);box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;background-color:transparent;font:inherit;cursor:text}.nys-combobox__input:not(:placeholder-shown){padding-right:calc(var(--nys-size-400, 32px) * 2 + var(--nys-space-100, 8px))}.nys-combobox__input:hover:not(:disabled):not(:focus):not([readonly]){outline-color:var(--_nys-combobox-outline-color--hover);border-color:var(--_nys-combobox-outline-color--hover)}.nys-combobox__input:focus:not([readonly]){outline-color:var(--_nys-combobox-outline-color--focus);border-color:var(--_nys-combobox-outline-color--focus);caret-color:var(--_nys-combobox-outline-color--focus)}.nys-combobox__input:disabled{background-color:var(--_nys-combobox-background-color--disabled);border-color:var(--_nys-combobox-border-color--disabled);color:var(--_nys-combobox-color--disabled);cursor:not-allowed}.nys-combobox__buttons{display:flex;position:absolute;right:var(--nys-space-150, 12px);gap:var(--nys-space-150, 12px)}.nys-combobox__buttons nys-button{--_nys-button-padding--y: var(--nys-space-50, 4px);--_nys-button-padding--x: var(--nys-space-50, 4px);--_nys-button-height: var(--nys-size-300, 32px);--_nys-button-width: var(--nys-size-400, 32px)}.nys-combobox__buttons .nys-combobox__chevron{border-inline-start:solid var(--nys-color-neutral-200, #bec0c1) var(--nys-border-width-sm, 1px);padding-inline-start:var(--nys-space-150, 12px)}.nys-combobox__listbox{position:absolute;left:0;right:0;top:calc(100% + var(--nys-space-50, 4px));background-color:var(--_nys-combobox-background-color--dropdown);border:solid var(--_nys-combobox-border-color--dropdown) var(--_nys-combobox-border-width);border-radius:var(--_nys-combobox-border-radius);box-shadow:var(--_nys-combobox-shadow--dropdown);max-height:var(--_nys-combobox-max-height--dropdown);overflow-y:auto;z-index:1000;box-sizing:border-box}.nys-combobox__listbox--above{top:auto;bottom:calc(100% + var(--nys-space-50, 4px))}.nys-combobox__option{padding:var(--_nys-combobox-padding--option);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease;border-bottom:var(--nys-border-width-sm, 1px) solid var(--nys-color-neutral-50, #ededed);background-color:var(--_nys-combobox-background-color)}.nys-combobox__option:hover:not([disabled]):not(.nys-combobox__option--selected){background-color:var(--_nys-combobox-background-color--option--hover)}.nys-combobox__option:active:not([disabled]):not(.nys-combobox__option--selected){background-color:var(--_nys-combobox-background-color--option--active)}.nys-combobox__option--selected:not([disabled]){background-color:var(--_nys-combobox-background-color--option--selected);border:var(--_nys-combobox-border-color--option--selected) solid 1px}.nys-combobox__option--focused:not([disabled]):not(:hover){outline:var(--_nys-combobox-outline-color--focus) solid 2px;outline-offset:-2px}.nys-combobox__option[disabled]{background-color:var(--_nys-combobox-background-color--option--disabled);color:var(--_nys-combobox-color--option--disabled);cursor:not-allowed}.nys-combobox__optgroup{padding:var(--nys-space-100, 8px) var(--nys-space-150, 12px);border-bottom:var(--nys-border-width-sm, 1px) solid var(--nys-color-neutral-50, #ededed);-webkit-user-select:none;user-select:none;color:var(--nys-color-text);font-family:var(--nys-font-family-ui, "Proxima Nova");font-size:var(--nys-font-size-ui-md, 16px);font-style:normal;font-weight:700;line-height:var(--nys-font-lineheight-ui-md, 24px);letter-spacing:var(--nys-font-letterspacing-ui-md, .044px)}.nys-combobox__optgroup~.nys-combobox__option{padding-left:var(--nys-space-300, 24px)}.nys-combobox__no-results{background-color:var(--_nys-combobox-background-color);padding:var(--_nys-combobox-padding--option);color:var(--_nys-combobox-color);cursor:not-allowed}.nys-combobox__listbox::-webkit-scrollbar{width:var(--nys-space-100, 8px)}.nys-combobox__listbox::-webkit-scrollbar-track{background:var(--nys-color-neutral-50, #eeeeee);border-radius:var(--_nys-combobox-border-radius)}.nys-combobox__listbox::-webkit-scrollbar-thumb{background:var(--nys-color-neutral-300, #a7a9ab);border-radius:var(--_nys-combobox-border-radius)}.nys-combobox__listbox::-webkit-scrollbar-thumb:hover{background:var(--nys-color-neutral-400, #909395)}';
109
+ var D = Object.defineProperty, l = (d, o, s, e) => {
110
+ for (var t = void 0, i = d.length - 1, r; i >= 0; i--)
111
+ (r = d[i]) && (t = r(o, s, t) || t);
112
+ return t && D(o, s, t), t;
113
+ };
114
+ const f = class f extends E {
22
115
  constructor() {
23
- super(), this.id = "", this.name = "", this.label = "", this.description = "", this.value = "", this.disabled = !1, this.required = !1, this.optional = !1, this.tooltip = "", this.form = null, this.width = "full", this.inverted = !1, this.showError = !1, this.errorMessage = "", this._isOpen = !1, this._filterText = "", this._highlightedIndex = -1, this._options = [], this._filteredOptions = [], this._dropdownAbove = !1, this._announcement = "", this._originalErrorMessage = "", this._hasUserInteracted = !1, this._selectedLabel = "", this._defaultValue = "", this._handleDocumentClick = (o) => {
116
+ super(...arguments), this.id = "", this.name = "", this.label = "", this.description = "", this.value = "", this.disabled = !1, this.required = !1, this.optional = !1, this.tooltip = "", this.form = null, this.width = "full", this.inverted = !1, this.showError = !1, this.errorMessage = "", this._isOpen = !1, this._filterText = "", this._highlightedIndex = -1, this._options = [], this._filteredOptions = [], this._dropdownAbove = !1, this._announcement = "", this._originalErrorMessage = "", this._hasUserInteracted = !1, this._selectedLabel = "", this._defaultValue = "", this._hasResolvedSlottedValue = !1, this._handleDocumentClick = (o) => {
24
117
  o.target === this || this.shadowRoot?.contains(o.target) || this._closeDropdown();
25
- }, this._internals = this.attachInternals();
118
+ };
26
119
  }
120
+ /**
121
+ * Lifecycle methods
122
+ * --------------------------------------------------------------------------
123
+ * Form association, ElementInternals, and id generation are provided by
124
+ * NysFormControlElement (@nysds/internals).
125
+ */
27
126
  connectedCallback() {
28
- super.connectedCallback(), this.id || (this.id = `nys-combobox-${Date.now()}-${k++}`), this._originalErrorMessage = this.errorMessage ?? "", this.addEventListener("invalid", this._handleInvalid), document.addEventListener("click", this._handleDocumentClick);
127
+ super.connectedCallback(), this._originalErrorMessage = this.errorMessage ?? "", this.addEventListener("invalid", this._handleInvalid), document.addEventListener("click", this._handleDocumentClick);
29
128
  }
30
129
  disconnectedCallback() {
31
130
  super.disconnectedCallback(), this.removeEventListener("invalid", this._handleInvalid), document.removeEventListener("click", this._handleDocumentClick);
32
131
  }
33
132
  firstUpdated() {
34
- this._handleSlotChange();
35
- const o = this.shadowRoot?.querySelector(
36
- 'slot:not([name="description"])'
37
- );
38
- if (!this.value && o) {
39
- const s = o.assignedElements({ flatten: !0 });
40
- for (const e of s)
41
- if (e.tagName === "OPTION" && e.selected) {
42
- this.value = e.value;
43
- break;
44
- } else if (e.tagName === "OPTGROUP") {
45
- for (const t of e.children)
46
- if (t.tagName === "OPTION" && t.selected) {
47
- this.value = t.value;
48
- break;
49
- }
50
- if (this.value) break;
51
- }
52
- }
53
133
  this._setValue(), this._defaultValue = this.value;
54
134
  }
55
- updated(o) {
135
+ // Derive display state from `value` before rendering, not after, so Lit
136
+ // doesn't have to schedule a second update (see lit.dev/msg/change-in-update).
137
+ willUpdate(o) {
56
138
  if (o.has("value")) {
57
139
  const s = this._options.find((e) => e.value === this.value);
58
- this._selectedLabel = s ? s.label : "", this._filterText = this._selectedLabel, this._setValue();
140
+ this._selectedLabel = s ? s.label : "", this._filterText = this._selectedLabel;
59
141
  }
60
- o.has("_isOpen") && this._isOpen && (this._positionDropdown(), this.updateComplete.then(() => {
61
- this._scrollToHighlighted();
62
- }));
142
+ }
143
+ updated(o) {
144
+ o.has("value") && this._setValue(), o.has("_isOpen") && this._isOpen && this.updateComplete.then(() => {
145
+ this._positionDropdown(), this._scrollToHighlighted();
146
+ });
63
147
  }
64
148
  /**
65
149
  * Slot handling
@@ -71,31 +155,32 @@ const p = class p extends y {
71
155
  );
72
156
  if (!o) return;
73
157
  const s = o.assignedElements({ flatten: !0 }), e = [];
74
- if (s.forEach((t) => {
75
- if (t.tagName === "OPTION") {
76
- const n = t;
158
+ let t = "";
159
+ if (s.forEach((i) => {
160
+ if (i.tagName === "OPTION") {
161
+ const r = i;
77
162
  e.push({
78
- value: n.value,
79
- label: n.textContent?.trim() || n.value,
80
- disabled: n.disabled
81
- });
82
- } else if (t.tagName === "OPTGROUP") {
83
- const n = t, l = n.label;
84
- Array.from(n.children).forEach((_) => {
85
- if (_.tagName === "OPTION") {
86
- const c = _;
163
+ value: r.value,
164
+ label: r.textContent?.trim() || r.value,
165
+ disabled: r.disabled
166
+ }), r.selected && !t && (t = r.value);
167
+ } else if (i.tagName === "OPTGROUP") {
168
+ const r = i, c = r.label;
169
+ Array.from(r.children).forEach((h) => {
170
+ if (h.tagName === "OPTION") {
171
+ const b = h;
87
172
  e.push({
88
- value: c.value,
89
- label: c.textContent?.trim() || c.value,
90
- disabled: c.disabled || n.disabled,
91
- group: l
92
- });
173
+ value: b.value,
174
+ label: b.textContent?.trim() || b.value,
175
+ disabled: b.disabled || r.disabled,
176
+ group: c
177
+ }), b.selected && !t && (t = b.value);
93
178
  }
94
179
  });
95
180
  }
96
- }), this._options = e, this._filteredOptions = e, this.value) {
97
- const t = this._options.find((n) => n.value === this.value);
98
- t && (this._selectedLabel = t.label, this._filterText = t.label);
181
+ }), this._options = e, this._filteredOptions = e, this._hasResolvedSlottedValue || (this._hasResolvedSlottedValue = !0, !this.value && t && (this.value = t), this._defaultValue = this.value), this.value) {
182
+ const i = this._options.find((r) => r.value === this.value);
183
+ i && (this._selectedLabel = i.label, this._filterText = i.label);
99
184
  }
100
185
  }
101
186
  /**
@@ -103,16 +188,18 @@ const p = class p extends y {
103
188
  * --------------------------------------------------------------------------
104
189
  */
105
190
  _setValue() {
106
- this._internals.setFormValue(this.value), this._manageRequire();
191
+ this.setFormValue(this.value), this._manageRequire();
107
192
  }
108
193
  _manageRequire() {
109
194
  const o = this.errorMessage || "This field is required";
110
- this.required && (!this.value || this.value?.trim() === "") ? (this._internals.ariaInvalid = "true", this._internals.setValidity({ valueMissing: !0 }, o, this._input)) : (this._internals.ariaInvalid = "false", this._internals.setValidity({}), this._hasUserInteracted = !1);
195
+ this.required && (!this.value || this.value?.trim() === "") ? this.setValidityFromState({ valueMissing: !0 }, o, this._input) : (this.clearValidity(), this._hasUserInteracted = !1);
111
196
  }
112
197
  _setValidityMessage(o = "") {
113
- this.showError = !!o, this._originalErrorMessage?.trim() && o !== "" ? this.errorMessage = this._originalErrorMessage : this.errorMessage = o;
114
- const s = o ? { customError: !0 } : {};
115
- this._internals.setValidity(s, this.errorMessage, this._input);
198
+ this.showError = !!o, this._originalErrorMessage?.trim() && o !== "" ? this.errorMessage = this._originalErrorMessage : this.errorMessage = o, o ? this.setValidityFromState(
199
+ { customError: !0 },
200
+ this.errorMessage,
201
+ this._input
202
+ ) : this.clearValidity();
116
203
  }
117
204
  _validate() {
118
205
  if (!this._input) return;
@@ -122,16 +209,16 @@ const p = class p extends y {
122
209
  o.valueMissing || e ? s = "This field is required" : s = this._input.validationMessage, this._setValidityMessage(s);
123
210
  }
124
211
  formResetCallback() {
125
- this.value = this._defaultValue, this._filterText = this._defaultValue ? this._options.find((o) => o.value === this._defaultValue)?.label ?? "" : "", this._selectedLabel = this._filterText, this._input && (this._input.value = this._filterText), this._internals.setFormValue(this.value), this.showError = !1, this.errorMessage = "", this._internals.setValidity({}), this.requestUpdate();
212
+ this.value = this._defaultValue, this._filterText = this._defaultValue ? this._options.find((o) => o.value === this._defaultValue)?.label ?? "" : "", this._selectedLabel = this._filterText, this._input && (this._input.value = this._filterText), this.setFormValue(this.value), this.showError = !1, this.errorMessage = "", this.clearValidity(), this.requestUpdate();
126
213
  }
127
214
  checkValidity() {
128
215
  return this._input ? this._input.checkValidity() : !0;
129
216
  }
130
217
  _handleInvalid(o) {
131
218
  if (o.preventDefault(), this._hasUserInteracted = !0, this._validate(), this._input) {
132
- const s = this._internals.form;
219
+ const s = this.internals?.form;
133
220
  s ? Array.from(s.elements).find(
134
- (n) => typeof n.checkValidity == "function" && !n.checkValidity()
221
+ (i) => typeof i.checkValidity == "function" && !i.checkValidity()
135
222
  ) === this && this._input.focus() : this._input.focus();
136
223
  }
137
224
  }
@@ -141,8 +228,8 @@ const p = class p extends y {
141
228
  */
142
229
  _positionDropdown() {
143
230
  if (!this._listbox || !this._input) return;
144
- const o = this._input.getBoundingClientRect(), s = this._listbox.offsetHeight, t = window.innerHeight - o.bottom, n = o.top;
145
- this._dropdownAbove = t < s && n > t;
231
+ const o = this._input.getBoundingClientRect(), s = this._listbox.offsetHeight, t = window.innerHeight - o.bottom, i = o.top;
232
+ this._dropdownAbove = t < s && i > t;
146
233
  }
147
234
  /**
148
235
  * Filtering
@@ -189,15 +276,15 @@ const p = class p extends y {
189
276
  }
190
277
  }
191
278
  _moveHighlight(o) {
192
- if (this._filteredOptions.filter((b) => !b.disabled).length === 0) return;
279
+ if (this._filteredOptions.filter((_) => !_.disabled).length === 0) return;
193
280
  let e = this._highlightedIndex + o;
194
281
  for (e < 0 ? e = this._filteredOptions.length - 1 : e >= this._filteredOptions.length && (e = 0); this._filteredOptions[e]?.disabled; )
195
282
  e += o, e < 0 && (e = this._filteredOptions.length - 1), e >= this._filteredOptions.length && (e = 0);
196
283
  this._highlightedIndex = e, this._scrollToHighlighted();
197
- const t = this._filteredOptions[e], n = this._filteredOptions[e - o], l = this._filteredOptions.filter(
198
- (b) => !b.disabled
199
- ), _ = l.findIndex((b) => b.value === t.value) + 1, c = t.value === this.value ? "selected" : "unselected", f = t.group && t.group !== n?.group ? `${t.group}, ` : "";
200
- this._announcement = `${f} ${t.label} ${_} of ${l.length}, ${c}`;
284
+ const t = this._filteredOptions[e], i = this._filteredOptions[e - o], r = this._filteredOptions.filter(
285
+ (_) => !_.disabled
286
+ ), c = r.findIndex((_) => _.value === t.value) + 1, h = t.value === this.value ? "selected" : "unselected", x = t.group && t.group !== i?.group ? `${t.group}, ` : "";
287
+ this._announcement = `${x} ${t.label} ${c} of ${r.length}, ${h}`;
201
288
  }
202
289
  /**
203
290
  * Event Handlers
@@ -230,7 +317,7 @@ const p = class p extends y {
230
317
  this.disabled || (this._isOpen ? this._closeDropdown() : (this._input.focus(), this._openDropdown()));
231
318
  }
232
319
  _handleClearClick(o) {
233
- o.stopPropagation(), this.value = "", this._filterText = "", this._selectedLabel = "", this._filterOptions(""), this._internals.setFormValue(""), this._closeDropdown(), this._input.focus(), this._handleChange();
320
+ o.stopPropagation(), this.value = "", this._filterText = "", this._selectedLabel = "", this._filterOptions(""), this.setFormValue(""), this._closeDropdown(), this._input.focus(), this._handleChange();
234
321
  }
235
322
  _handleOptionClick(o) {
236
323
  o.disabled || this._selectOption(o);
@@ -239,7 +326,7 @@ const p = class p extends y {
239
326
  this._highlightedIndex = o;
240
327
  }
241
328
  _selectOption(o) {
242
- this.value = o.value, this._selectedLabel = o.label, this._filterText = o.label, this._internals.setFormValue(this.value), this._input.focus(), this._closeDropdown(), this._filterOptions(""), this._setValidityMessage(""), this._hasUserInteracted && this._validate(), this._handleChange();
329
+ this.value = o.value, this._selectedLabel = o.label, this._filterText = o.label, this.setFormValue(this.value), this._input.focus(), this._closeDropdown(), this._filterOptions(""), this._setValidityMessage(""), this._hasUserInteracted && this._validate(), this._handleChange();
243
330
  }
244
331
  _handleChange() {
245
332
  this.dispatchEvent(
@@ -266,19 +353,19 @@ const p = class p extends y {
266
353
  let o = "";
267
354
  const s = [];
268
355
  return this._filteredOptions.forEach((e, t) => {
269
- e.group && e.group !== o && (o = e.group, s.push(h`
356
+ e.group && e.group !== o && (o = e.group, s.push(u`
270
357
  <div class="nys-combobox__optgroup" role="presentation">
271
358
  ${e.group}
272
359
  </div>
273
360
  `));
274
- const n = t === this._highlightedIndex, l = e.value === this.value;
275
- s.push(h`
361
+ const i = t === this._highlightedIndex, r = e.value === this.value;
362
+ s.push(u`
276
363
  <div
277
- class="nys-combobox__option ${n ? "nys-combobox__option--focused" : ""} ${l ? "nys-combobox__option--selected" : ""}"
364
+ class="nys-combobox__option ${i ? "nys-combobox__option--focused" : ""} ${r ? "nys-combobox__option--selected" : ""}"
278
365
  role="option"
279
366
  id="${this.id}--option-${t}"
280
367
  data-index="${t}"
281
- aria-selected="${l}"
368
+ aria-selected="${r}"
282
369
  aria-disabled="${e.disabled || !1}"
283
370
  ?disabled=${e.disabled}
284
371
  @click=${() => this._handleOptionClick(e)}
@@ -287,16 +374,17 @@ const p = class p extends y {
287
374
  ${e.label}
288
375
  </div>
289
376
  `);
290
- }), s.length === 0 ? h`
377
+ }), s.length === 0 ? u`
291
378
  <div class="nys-combobox__no-results" role="option">
292
379
  No results found
293
380
  </div>
294
381
  ` : s;
295
382
  }
296
383
  render() {
297
- return h`
384
+ return u`
298
385
  <div class="nys-combobox">
299
386
  <nys-label
387
+ id="${this.id}--label"
300
388
  label=${this.label}
301
389
  description=${this.description}
302
390
  flag=${this.required ? "required" : this.optional ? "optional" : ""}
@@ -323,19 +411,29 @@ const p = class p extends y {
323
411
  ?required=${this.required}
324
412
  aria-required=${this.required}
325
413
  aria-disabled="${this.disabled}"
326
- aria-label="${[this.label, this.description].filter(Boolean).join(" ")}"
414
+ aria-labelledby=${y(
415
+ this.label ? this.id + "--label" : void 0
416
+ )}
417
+ aria-label=${y(
418
+ !this.label && this.description ? this.description : void 0
419
+ )}
420
+ aria-invalid=${this.showError ? "true" : "false"}
421
+ aria-errormessage=${this.id + "--error"}
422
+ aria-describedby=${y(
423
+ this.showError ? this.id + "--error" : void 0
424
+ )}
327
425
  .value=${this._filterText}
328
- form=${m(this.form || void 0)}
426
+ form=${y(this.form || void 0)}
329
427
  @input=${this._handleInput}
330
428
  @focus="${this._handleFocus}"
331
429
  @blur="${this._handleBlur}"
332
430
  @keydown="${this._handleKeyDown}"
333
431
  />
334
432
  <div class="nys-combobox__buttons">
335
- ${this.value ? h`
433
+ ${this.value ? u`
336
434
  <nys-button
337
435
  class="nys-combobox__clear"
338
- ariaLabel="clear selection"
436
+ label="Clear selection"
339
437
  variant="ghost"
340
438
  size="sm"
341
439
  circle
@@ -351,7 +449,7 @@ const p = class p extends y {
351
449
  ` : ""}
352
450
  <nys-button
353
451
  class="nys-combobox__chevron"
354
- ariaLabel="toggle dropdown"
452
+ label="Toggle dropdown"
355
453
  variant="ghost"
356
454
  size="sm"
357
455
  circle
@@ -366,7 +464,7 @@ const p = class p extends y {
366
464
  </nys-button>
367
465
  </div>
368
466
  </div>
369
- ${this._isOpen ? h`
467
+ ${this._isOpen ? u`
370
468
  <div
371
469
  class="nys-combobox__listbox ${this._dropdownAbove ? "nys-combobox__listbox--above" : ""}"
372
470
  id="${this.id}--listbox"
@@ -382,6 +480,7 @@ const p = class p extends y {
382
480
  @slotchange=${this._handleSlotChange}
383
481
  ></slot>
384
482
  <nys-errormessage
483
+ id=${this.id + "--error"}
385
484
  ?showError=${this.showError}
386
485
  errorMessage=${this.errorMessage}
387
486
  ></nys-errormessage>
@@ -396,82 +495,82 @@ const p = class p extends y {
396
495
  `;
397
496
  }
398
497
  };
399
- p.styles = x(g), p.shadowRootOptions = {
400
- ...y.shadowRootOptions,
498
+ f.styles = g(C), f.shadowRootOptions = {
499
+ ...v.shadowRootOptions,
401
500
  delegatesFocus: !0
402
- }, p.formAssociated = !0;
403
- let i = p;
404
- r([
501
+ };
502
+ let n = f;
503
+ l([
405
504
  a({ type: String, reflect: !0 })
406
- ], i.prototype, "id");
407
- r([
505
+ ], n.prototype, "id");
506
+ l([
408
507
  a({ type: String, reflect: !0 })
409
- ], i.prototype, "name");
410
- r([
508
+ ], n.prototype, "name");
509
+ l([
411
510
  a({ type: String })
412
- ], i.prototype, "label");
413
- r([
511
+ ], n.prototype, "label");
512
+ l([
414
513
  a({ type: String })
415
- ], i.prototype, "description");
416
- r([
514
+ ], n.prototype, "description");
515
+ l([
417
516
  a({ type: String })
418
- ], i.prototype, "value");
419
- r([
517
+ ], n.prototype, "value");
518
+ l([
420
519
  a({ type: Boolean, reflect: !0 })
421
- ], i.prototype, "disabled");
422
- r([
520
+ ], n.prototype, "disabled");
521
+ l([
423
522
  a({ type: Boolean, reflect: !0 })
424
- ], i.prototype, "required");
425
- r([
523
+ ], n.prototype, "required");
524
+ l([
426
525
  a({ type: Boolean, reflect: !0 })
427
- ], i.prototype, "optional");
428
- r([
526
+ ], n.prototype, "optional");
527
+ l([
429
528
  a({ type: String })
430
- ], i.prototype, "tooltip");
431
- r([
529
+ ], n.prototype, "tooltip");
530
+ l([
432
531
  a({ type: String, reflect: !0 })
433
- ], i.prototype, "form");
434
- r([
532
+ ], n.prototype, "form");
533
+ l([
435
534
  a({ type: String, reflect: !0 })
436
- ], i.prototype, "width");
437
- r([
535
+ ], n.prototype, "width");
536
+ l([
438
537
  a({ type: Boolean, reflect: !0 })
439
- ], i.prototype, "inverted");
440
- r([
538
+ ], n.prototype, "inverted");
539
+ l([
441
540
  a({ type: Boolean, reflect: !0 })
442
- ], i.prototype, "showError");
443
- r([
541
+ ], n.prototype, "showError");
542
+ l([
444
543
  a({ type: String })
445
- ], i.prototype, "errorMessage");
446
- r([
447
- d()
448
- ], i.prototype, "_isOpen");
449
- r([
450
- d()
451
- ], i.prototype, "_filterText");
452
- r([
453
- d()
454
- ], i.prototype, "_highlightedIndex");
455
- r([
456
- d()
457
- ], i.prototype, "_options");
458
- r([
459
- d()
460
- ], i.prototype, "_filteredOptions");
461
- r([
462
- d()
463
- ], i.prototype, "_dropdownAbove");
464
- r([
465
- d()
466
- ], i.prototype, "_announcement");
467
- r([
468
- v("input")
469
- ], i.prototype, "_input");
470
- r([
471
- v(".nys-combobox__listbox")
472
- ], i.prototype, "_listbox");
473
- customElements.get("nys-combobox") || customElements.define("nys-combobox", i);
544
+ ], n.prototype, "errorMessage");
545
+ l([
546
+ p()
547
+ ], n.prototype, "_isOpen");
548
+ l([
549
+ p()
550
+ ], n.prototype, "_filterText");
551
+ l([
552
+ p()
553
+ ], n.prototype, "_highlightedIndex");
554
+ l([
555
+ p()
556
+ ], n.prototype, "_options");
557
+ l([
558
+ p()
559
+ ], n.prototype, "_filteredOptions");
560
+ l([
561
+ p()
562
+ ], n.prototype, "_dropdownAbove");
563
+ l([
564
+ p()
565
+ ], n.prototype, "_announcement");
566
+ l([
567
+ m("input")
568
+ ], n.prototype, "_input");
569
+ l([
570
+ m(".nys-combobox__listbox")
571
+ ], n.prototype, "_listbox");
572
+ customElements.get("nys-combobox") || customElements.define("nys-combobox", n);
474
573
  export {
475
- i as NysCombobox
574
+ n as NysCombobox
476
575
  };
477
576
  //# sourceMappingURL=nys-combobox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nys-combobox.js","sources":["../src/nys-combobox.ts"],"sourcesContent":["import { LitElement, html, unsafeCSS } from \"lit\";\nimport { property, state, query } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\n// @ts-ignore: SCSS module imported via bundler as inline\nimport styles from \"./nys-combobox.scss?inline\";\n\nlet comboboxIdCounter = 0;\n\ninterface ComboboxOption {\n value: string;\n label: string;\n disabled?: boolean;\n group?: string;\n}\n\n/**\n * `<nys-combobox>` is a form-enabled combo box combining text input with a filterable dropdown.\n *\n * Features:\n * - Type to filter options\n * - Keyboard navigation (Arrow keys, Enter, Escape)\n * - Mouse and keyboard interaction\n * - Clears non-selected text on blur\n * - Clear button when value is selected\n * - Integrates with forms via ElementInternals\n * - Supports native <option> and <optgroup> elements\n * - Accessible per W3C ARIA Authoring Practices\n *\n * @slot description - Optional custom description content below the label.\n * @slot default - Options (<option>, <optgroup>) to populate the dropdown\n *\n * @fires nys-change - Fired when selection changes. Detail: `{ id, value }`.\n * @fires nys-input - Fired on input change. Detail: `{ id, value }`.\n * @fires nys-focus - Fired when combobox receives focus.\n * @fires nys-blur - Fired when combobox loses focus.\n *\n *\n * @example Basic\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"cherry\">Cherry</option>\n * <option value=\"date\">Date</option>\n * <option value=\"elderberry\">Elderberry</option>\n * <option value=\"fig\">Fig</option>\n * <option value=\"grape\">Grape</option>\n * <option value=\"honeydew\">Honeydew</option>\n * <option value=\"kiwi\">Kiwi</option>\n * <option value=\"lemon\">Lemon</option>\n * <option value=\"mango\">Mango</option>\n * <option value=\"nectarine\">Nectarine</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"papaya\">Papaya</option>\n * <option value=\"quince\">Quince</option>\n * <option value=\"raspberry\">Raspberry</option>\n * <option value=\"strawberry\">Strawberry</option>\n * <option value=\"tangerine\">Tangerine</option>\n * <option value=\"watermelon\">Watermelon</option>\n * </nys-combobox>\n * ```\n *\n * @example Default Value\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" value=\"mango\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"mango\" selected>Mango</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Option Group\n * ```html\n * <nys-combobox label=\"Select a fruit\" description=\"Fruits organized by category\">\n * <optgroup label=\"Citrus\">\n * <option value=\"lemon\">Lemon</option>\n * <option value=\"lime\">Lime</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"grapefruit\">Grapefruit</option>\n * <option value=\"tangerine\">Tangerine</option>\n * </optgroup>\n * <optgroup label=\"Berries\">\n * <option value=\"strawberry\">Strawberry</option>\n * <option value=\"blueberry\">Blueberry</option>\n * <option value=\"raspberry\">Raspberry</option>\n * <option value=\"blackberry\">Blackberry</option>\n * <option value=\"cranberry\">Cranberry</option>\n * </optgroup>\n * <optgroup label=\"Tropical\">\n * <option value=\"mango\">Mango</option>\n * <option value=\"pineapple\">Pineapple</option>\n * <option value=\"papaya\">Papaya</option>\n * <option value=\"coconut\">Coconut</option>\n * <option value=\"passionfruit\">Passionfruit</option>\n * </optgroup>\n * <optgroup label=\"Stone Fruits\">\n * <option value=\"peach\">Peach</option>\n * <option value=\"plum\">Plum</option>\n * <option value=\"cherry\">Cherry</option>\n * <option value=\"apricot\">Apricot</option>\n * <option value=\"nectarine\">Nectarine</option>\n * </optgroup>\n * </nys-combobox>\n * ```\n *\n * @example Disabled\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" disabled>\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Required\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" required>\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Optional\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" optional>\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Width Medium\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" width=\"md\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Width Large\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" width=\"lg\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Description\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" description=\"Choose from the list of available fruits.\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```d\n *\n * @example Description Slot\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\">\n * <label slot=\"description\">This is a description slot</label>\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Error Message\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" showError errorMessage=\"Please select a fruit\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Disabled Options\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" description=\"Some fruits are out of season\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"cherry\" disabled>Cherry (Out of season)</option>\n * <option value=\"mango\">Mango</option>\n * <option value=\"strawberry\" disabled>Strawberry (Out of season)</option>\n * <option value=\"orange\">Orange</option>\n * </nys-combobox>\n * ```\n */\nexport class NysCombobox extends LitElement {\n static styles = unsafeCSS(styles);\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n @property({ type: String, reflect: true }) id = \"\";\n @property({ type: String, reflect: true }) name = \"\";\n @property({ type: String }) label = \"\";\n @property({ type: String }) description = \"\";\n @property({ type: String }) value = \"\";\n @property({ type: Boolean, reflect: true }) disabled = false;\n @property({ type: Boolean, reflect: true }) required = false;\n @property({ type: Boolean, reflect: true }) optional = false;\n @property({ type: String }) tooltip = \"\";\n @property({ type: String, reflect: true }) form: string | null = null;\n @property({ type: String, reflect: true }) width: \"md\" | \"lg\" | \"full\" =\n \"full\";\n @property({ type: Boolean, reflect: true }) inverted = false;\n @property({ type: Boolean, reflect: true }) showError = false;\n @property({ type: String }) errorMessage = \"\";\n\n @state() private _isOpen = false;\n @state() private _filterText = \"\";\n @state() private _highlightedIndex = -1;\n @state() private _options: ComboboxOption[] = [];\n @state() private _filteredOptions: ComboboxOption[] = [];\n @state() private _dropdownAbove = false;\n @state() private _announcement = \"\";\n\n @query(\"input\") private _input!: HTMLInputElement;\n @query(\".nys-combobox__listbox\") private _listbox?: HTMLElement;\n\n private _originalErrorMessage = \"\";\n private _hasUserInteracted = false;\n private _internals: ElementInternals;\n private _selectedLabel = \"\";\n private _defaultValue = \"\";\n\n /**\n * Lifecycle methods\n * --------------------------------------------------------------------------\n */\n static formAssociated = true;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n connectedCallback() {\n super.connectedCallback();\n if (!this.id) {\n this.id = `nys-combobox-${Date.now()}-${comboboxIdCounter++}`;\n }\n\n this._originalErrorMessage = this.errorMessage ?? \"\";\n this.addEventListener(\"invalid\", this._handleInvalid);\n document.addEventListener(\"click\", this._handleDocumentClick);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener(\"invalid\", this._handleInvalid);\n document.removeEventListener(\"click\", this._handleDocumentClick);\n }\n\n firstUpdated() {\n this._handleSlotChange();\n\n // If a selected option was found and no explicit value was set, use it\n const slot = this.shadowRoot?.querySelector(\n 'slot:not([name=\"description\"])',\n ) as HTMLSlotElement | null;\n\n if (!this.value && slot) {\n const assignedElements = slot.assignedElements({ flatten: true });\n for (const node of assignedElements) {\n if (node.tagName === \"OPTION\" && (node as HTMLOptionElement).selected) {\n this.value = (node as HTMLOptionElement).value;\n break;\n } else if (node.tagName === \"OPTGROUP\") {\n for (const child of (node as HTMLOptGroupElement).children) {\n if (\n child.tagName === \"OPTION\" &&\n (child as HTMLOptionElement).selected\n ) {\n this.value = (child as HTMLOptionElement).value;\n break;\n }\n }\n if (this.value) break;\n }\n }\n }\n\n this._setValue();\n this._defaultValue = this.value; // ← capture after resolving selected option\n }\n\n updated(changedProperties: Map<string | number | symbol, unknown>) {\n if (changedProperties.has(\"value\")) {\n const option = this._options.find((opt) => opt.value === this.value);\n this._selectedLabel = option ? option.label : \"\";\n this._filterText = this._selectedLabel;\n\n this._setValue();\n }\n\n if (changedProperties.has(\"_isOpen\") && this._isOpen) {\n this._positionDropdown();\n this.updateComplete.then(() => {\n this._scrollToHighlighted();\n });\n }\n }\n\n /**\n * Slot handling\n * --------------------------------------------------------------------------\n */\n private _handleSlotChange() {\n const slot = this.shadowRoot?.querySelector(\n 'slot:not([name=\"description\"])',\n ) as HTMLSlotElement | null;\n\n if (!slot) return;\n\n const assignedElements = slot.assignedElements({ flatten: true });\n const options: ComboboxOption[] = [];\n\n assignedElements.forEach((node) => {\n if (node.tagName === \"OPTION\") {\n const option = node as HTMLOptionElement;\n options.push({\n value: option.value,\n label: option.textContent?.trim() || option.value,\n disabled: option.disabled,\n });\n } else if (node.tagName === \"OPTGROUP\") {\n const group = node as HTMLOptGroupElement;\n const groupLabel = group.label;\n\n Array.from(group.children).forEach((child) => {\n if (child.tagName === \"OPTION\") {\n const option = child as HTMLOptionElement;\n options.push({\n value: option.value,\n label: option.textContent?.trim() || option.value,\n disabled: option.disabled || group.disabled,\n group: groupLabel,\n });\n }\n });\n }\n });\n\n this._options = options;\n this._filteredOptions = options;\n\n // Set initial display text if value exists\n if (this.value) {\n const option = this._options.find((opt) => opt.value === this.value);\n if (option) {\n this._selectedLabel = option.label;\n this._filterText = option.label;\n }\n }\n }\n\n /**\n * Form Integration\n * --------------------------------------------------------------------------\n */\n private _setValue() {\n this._internals.setFormValue(this.value);\n this._manageRequire();\n }\n\n private _manageRequire() {\n const message = this.errorMessage || \"This field is required\";\n const isInvalid =\n this.required && (!this.value || this.value?.trim() === \"\");\n\n if (isInvalid) {\n this._internals.ariaInvalid = \"true\";\n this._internals.setValidity({ valueMissing: true }, message, this._input);\n } else {\n this._internals.ariaInvalid = \"false\";\n this._internals.setValidity({});\n this._hasUserInteracted = false;\n }\n }\n\n private _setValidityMessage(message: string = \"\") {\n this.showError = !!message;\n\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, this._input);\n }\n\n private _validate() {\n if (!this._input) return;\n\n const validity = this._input.validity;\n let message = \"\";\n\n const isInvalid =\n this._input && !this._options.some((opt) => opt.value === this.value);\n\n if (validity.valueMissing || isInvalid) {\n message = \"This field is required\";\n } else {\n message = this._input.validationMessage;\n }\n\n this._setValidityMessage(message);\n }\n\n formResetCallback() {\n this.value = this._defaultValue;\n this._filterText = this._defaultValue\n ? (this._options.find((opt) => opt.value === this._defaultValue)?.label ??\n \"\")\n : \"\";\n this._selectedLabel = this._filterText;\n\n if (this._input) {\n this._input.value = this._filterText;\n }\n\n this._internals.setFormValue(this.value);\n\n // Reset validation UI\n this.showError = false;\n this.errorMessage = \"\";\n this._internals.setValidity({});\n\n this.requestUpdate();\n }\n checkValidity(): boolean {\n return this._input ? this._input.checkValidity() : true;\n }\n\n private _handleInvalid(event: Event) {\n event.preventDefault();\n this._hasUserInteracted = true;\n this._validate();\n\n if (this._input) {\n const form = this._internals.form;\n if (form) {\n const elements = Array.from(form.elements) as Array<\n HTMLElement & { checkValidity?: () => boolean }\n >;\n const firstInvalidElement = elements.find(\n (element) =>\n typeof element.checkValidity === \"function\" &&\n !element.checkValidity(),\n );\n if (firstInvalidElement === this) {\n this._input.focus();\n }\n } else {\n this._input.focus();\n }\n }\n }\n\n /**\n * Dropdown positioning\n * --------------------------------------------------------------------------\n */\n private _positionDropdown() {\n if (!this._listbox || !this._input) return;\n\n const inputRect = this._input.getBoundingClientRect();\n const listboxHeight = this._listbox.offsetHeight;\n const viewportHeight = window.innerHeight;\n const spaceBelow = viewportHeight - inputRect.bottom;\n const spaceAbove = inputRect.top;\n\n // Show above if not enough space below and more space above\n this._dropdownAbove = spaceBelow < listboxHeight && spaceAbove > spaceBelow;\n }\n\n /**\n * Filtering\n * --------------------------------------------------------------------------\n */\n private _filterOptions(searchText: string) {\n if (!searchText) {\n this._filteredOptions = this._options;\n return;\n }\n\n const search = searchText.toLowerCase();\n this._filteredOptions = this._options.filter((option) =>\n option.label.toLowerCase().includes(search),\n );\n }\n\n /**\n * Keyboard navigation\n * --------------------------------------------------------------------------\n */\n private _scrollToHighlighted() {\n if (!this._listbox || this._highlightedIndex < 0) return;\n\n const highlighted = this._listbox.querySelector(\n `[data-index=\"${this._highlightedIndex}\"]`,\n ) as HTMLElement;\n\n if (highlighted) {\n highlighted.scrollIntoView({ block: \"nearest\" });\n }\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n if (!this._isOpen) {\n this._openDropdown();\n } else {\n this._moveHighlight(1);\n }\n break;\n\n case \"ArrowUp\":\n event.preventDefault();\n if (!this._isOpen) {\n this._openDropdown();\n } else {\n this._moveHighlight(-1);\n }\n break;\n\n case \"Enter\":\n event.preventDefault();\n if (this._isOpen && this._highlightedIndex >= 0) {\n this._selectOption(this._filteredOptions[this._highlightedIndex]);\n }\n break;\n\n case \"Escape\":\n event.preventDefault();\n this._closeDropdown();\n this._filterText = this._selectedLabel;\n break;\n\n case \"Tab\":\n if (this._isOpen) {\n this._closeDropdown();\n this._filterText = this._selectedLabel;\n }\n break;\n }\n }\n\n private _moveHighlight(direction: number) {\n const enabledOptions = this._filteredOptions.filter((opt) => !opt.disabled);\n if (enabledOptions.length === 0) return;\n\n let newIndex = this._highlightedIndex + direction;\n\n // Wrap around\n if (newIndex < 0) {\n newIndex = this._filteredOptions.length - 1;\n } else if (newIndex >= this._filteredOptions.length) {\n newIndex = 0;\n }\n\n // Skip disabled options\n while (this._filteredOptions[newIndex]?.disabled) {\n newIndex += direction;\n if (newIndex < 0) newIndex = this._filteredOptions.length - 1;\n if (newIndex >= this._filteredOptions.length) newIndex = 0;\n }\n\n this._highlightedIndex = newIndex;\n this._scrollToHighlighted();\n\n const option = this._filteredOptions[newIndex];\n const prevOption = this._filteredOptions[newIndex - direction];\n const enabledFiltered = this._filteredOptions.filter(\n (opt) => !opt.disabled,\n );\n const position =\n enabledFiltered.findIndex((opt) => opt.value === option.value) + 1;\n const isSelected = option.value === this.value ? \"selected\" : \"unselected\";\n const groupChanged = option.group && option.group !== prevOption?.group;\n const groupPrefix = groupChanged ? `${option.group}, ` : \"\";\n this._announcement = `${groupPrefix} ${option.label} ${position} of ${enabledFiltered.length}, ${isSelected}`;\n }\n\n /**\n * Event Handlers\n * --------------------------------------------------------------------------\n */\n private _handleInput(event: Event) {\n const input = event.target as HTMLInputElement;\n this._filterText = input.value;\n this._filterOptions(this._filterText);\n\n if (!this._isOpen) {\n this._openDropdown();\n }\n\n this._highlightedIndex = 0;\n\n const count = this._filteredOptions.filter((opt) => !opt.disabled).length;\n this._announcement =\n count > 0 ? `${count} options available` : \"No results found\";\n\n if (this._hasUserInteracted) {\n this._validate();\n }\n\n this.dispatchEvent(\n new CustomEvent(\"nys-input\", {\n detail: { id: this.id, value: this._filterText },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private _handleFocus() {\n this.dispatchEvent(\n new Event(\"nys-focus\", { bubbles: true, composed: true }),\n );\n }\n\n private _handleBlur(event: FocusEvent) {\n // Check if focus moved to the listbox\n const relatedTarget = event.relatedTarget as HTMLElement;\n if (relatedTarget && this._listbox?.contains(relatedTarget)) {\n return;\n }\n\n // If no valid selection, clear the input\n if (!this.value || this._filterText !== this._selectedLabel) {\n this._filterText = this._selectedLabel;\n this._filterOptions(\"\");\n }\n\n this._closeDropdown();\n\n if (!this._hasUserInteracted) {\n this._hasUserInteracted = true;\n }\n this._validate();\n\n this.dispatchEvent(\n new Event(\"nys-blur\", { bubbles: true, composed: true }),\n );\n }\n\n private _handleDocumentClick = (event: MouseEvent) => {\n // Don't close if click is on the combobox host element or inside shadow DOM\n if (\n event.target === this ||\n this.shadowRoot?.contains(event.target as Node)\n ) {\n return;\n }\n this._closeDropdown();\n };\n\n private _handleIconClick() {\n if (this.disabled) return;\n\n if (this._isOpen) {\n this._closeDropdown();\n } else {\n this._input.focus();\n this._openDropdown();\n }\n }\n\n private _handleClearClick(event: Event) {\n event.stopPropagation();\n this.value = \"\";\n this._filterText = \"\";\n this._selectedLabel = \"\";\n this._filterOptions(\"\");\n this._internals.setFormValue(\"\");\n this._closeDropdown();\n this._input.focus();\n\n this._handleChange();\n }\n\n private _handleOptionClick(option: ComboboxOption) {\n if (option.disabled) return;\n this._selectOption(option);\n }\n\n private _handleOptionMouseEnter(index: number) {\n this._highlightedIndex = index;\n }\n\n private _selectOption(option: ComboboxOption) {\n this.value = option.value;\n this._selectedLabel = option.label;\n this._filterText = option.label;\n this._internals.setFormValue(this.value);\n this._input.focus();\n this._closeDropdown();\n this._filterOptions(\"\");\n\n this._setValidityMessage(\"\");\n\n if (this._hasUserInteracted) {\n this._validate();\n }\n\n this._handleChange();\n }\n\n private _handleChange() {\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 private _openDropdown() {\n this._isOpen = true;\n this._highlightedIndex = this._filteredOptions.findIndex(\n (opt) => opt.value === this.value,\n );\n if (this._highlightedIndex < 0) this._highlightedIndex = 0;\n }\n\n private _closeDropdown() {\n this._isOpen = false;\n this._highlightedIndex = -1;\n }\n\n /**\n * Render helpers\n * --------------------------------------------------------------------------\n */\n private _renderOptions() {\n let currentGroup = \"\";\n const elements: any[] = [];\n\n this._filteredOptions.forEach((option, index) => {\n if (option.group && option.group !== currentGroup) {\n currentGroup = option.group;\n elements.push(html`\n <div class=\"nys-combobox__optgroup\" role=\"presentation\">\n ${option.group}\n </div>\n `);\n }\n\n const isFocused = index === this._highlightedIndex;\n const isSelected = option.value === this.value;\n\n elements.push(html`\n <div\n class=\"nys-combobox__option ${isFocused\n ? \"nys-combobox__option--focused\"\n : \"\"} ${isSelected ? \"nys-combobox__option--selected\" : \"\"}\"\n role=\"option\"\n id=\"${this.id}--option-${index}\"\n data-index=\"${index}\"\n aria-selected=\"${isSelected}\"\n aria-disabled=\"${option.disabled || false}\"\n ?disabled=${option.disabled}\n @click=${() => this._handleOptionClick(option)}\n @mouseenter=${() => this._handleOptionMouseEnter(index)}\n >\n ${option.label}\n </div>\n `);\n });\n\n if (elements.length === 0) {\n return html`\n <div class=\"nys-combobox__no-results\" role=\"option\">\n No results found\n </div>\n `;\n }\n\n return elements;\n }\n\n render() {\n return html`\n <div class=\"nys-combobox\">\n <nys-label\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\n class=\"nys-combobox__container ${this._isOpen\n ? \"nys-combobox__container--open\"\n : \"\"}\"\n >\n <div class=\"nys-combobox__input-wrapper\">\n <input\n class=\"nys-combobox__input\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"${this._isOpen}\"\n aria-controls=\"${this.id}--listbox\"\n aria-activedescendant=\"${this._highlightedIndex >= 0\n ? `${this.id}--option-${this._highlightedIndex}`\n : \"\"}\"\n name=${this.name}\n id=${this.id + \"--native\"}\n ?disabled=${this.disabled}\n ?required=${this.required}\n aria-required=${this.required}\n aria-disabled=\"${this.disabled}\"\n aria-label=\"${[this.label, this.description]\n .filter(Boolean)\n .join(\" \")}\"\n .value=${this._filterText}\n form=${ifDefined(this.form || undefined)}\n @input=${this._handleInput}\n @focus=\"${this._handleFocus}\"\n @blur=\"${this._handleBlur}\"\n @keydown=\"${this._handleKeyDown}\"\n />\n <div class=\"nys-combobox__buttons\">\n ${this.value\n ? html`\n <nys-button\n class=\"nys-combobox__clear\"\n ariaLabel=\"clear selection\"\n variant=\"ghost\"\n size=\"sm\"\n circle\n @nys-click=${this._handleClearClick}\n ?disabled=${this.disabled}\n >\n <nys-icon\n slot=\"suffix-icon\"\n size=\"20\"\n name=\"close\"\n ></nys-icon>\n </nys-button>\n `\n : \"\"}\n <nys-button\n class=\"nys-combobox__chevron\"\n ariaLabel=\"toggle dropdown\"\n variant=\"ghost\"\n size=\"sm\"\n circle\n @nys-click=${this._handleIconClick}\n ?disabled=${this.disabled}\n >\n <nys-icon\n slot=\"suffix-icon\"\n size=\"20\"\n name=\"chevron_down\"\n ></nys-icon>\n </nys-button>\n </div>\n </div>\n ${this._isOpen\n ? html`\n <div\n class=\"nys-combobox__listbox ${this._dropdownAbove\n ? \"nys-combobox__listbox--above\"\n : \"\"}\"\n id=\"${this.id}--listbox\"\n role=\"listbox\"\n tabindex=\"-1\"\n >\n ${this._renderOptions()}\n </div>\n `\n : \"\"}\n </div>\n <slot\n style=\"display: none;\"\n @slotchange=${this._handleSlotChange}\n ></slot>\n <nys-errormessage\n ?showError=${this.showError}\n errorMessage=${this.errorMessage}\n ></nys-errormessage>\n <div\n aria-live=\"polite\"\n aria-atomic=\"true\"\n style=\"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;\"\n >\n ${this._announcement}\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"nys-combobox\")) {\n customElements.define(\"nys-combobox\", NysCombobox);\n}\n"],"names":["comboboxIdCounter","_NysCombobox","LitElement","event","slot","assignedElements","node","child","changedProperties","option","opt","options","group","groupLabel","message","validityState","validity","isInvalid","form","element","inputRect","listboxHeight","spaceBelow","spaceAbove","searchText","search","highlighted","direction","newIndex","prevOption","enabledFiltered","position","isSelected","groupPrefix","input","count","relatedTarget","index","currentGroup","elements","html","isFocused","ifDefined","unsafeCSS","styles","NysCombobox","__decorateClass","property","state","query"],"mappings":"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"}
1
+ {"version":3,"file":"nys-combobox.js","sources":["../../internals/dist/index.js","../src/nys-combobox.ts"],"sourcesContent":["import { LitElement as u } from \"lit\";\n/*!\n * New York State Design System v1.20.0\n * Description: A design system for New York State's digital products.\n * Repository: https://github.com/its-hcd/nysds\n * License: MIT\n */\nlet y = 0;\nfunction f(e) {\n return `${e}-${Date.now()}-${y++}`;\n}\nconst p = {\n labelledby: \"ariaLabelledByElements\",\n describedby: \"ariaDescribedByElements\"\n}, A = {\n labelledby: \"ariaLabel\",\n describedby: \"ariaDescription\"\n};\nfunction R(e) {\n return \"ariaDescribedByElements\" in e;\n}\nfunction _(e) {\n return e === \"errormessage\" ? \"aria-errormessage\" : `aria-${e}`;\n}\nfunction d(e) {\n return e.filter((t) => !!t);\n}\nfunction E(e) {\n return e.map((t) => (t.id || (t.id = f(\"nys-ref\")), t.id));\n}\nfunction V(e, t, n) {\n const i = d(n), r = _(t);\n i.length ? e.setAttribute(r, E(i).join(\" \")) : e.removeAttribute(r);\n}\nfunction x(e, t, n, i, r) {\n const s = d(i), a = p[n], l = t;\n if (a && R(t)) {\n l[a] = s.length ? s : null;\n return;\n }\n const o = A[n];\n if (!o) return;\n const c = r ?? (s.length ? s.map((m) => m.textContent?.trim() ?? \"\").filter(Boolean).join(\" \") : \"\");\n o in l ? l[o] = c || null : c ? e.setAttribute(\n n === \"labelledby\" ? \"aria-label\" : \"aria-description\",\n c\n ) : e.removeAttribute(\n n === \"labelledby\" ? \"aria-label\" : \"aria-description\"\n );\n}\nconst g = {\n labelledby: \"ariaLabelledByElements\",\n describedby: \"ariaDescribedByElements\"\n}, C = {\n labelledby: \"aria-label\",\n describedby: \"aria-description\"\n};\nfunction L(e, t, n) {\n const i = d(n), r = g[t], s = C[t], a = e;\n if (r && r in e && (a[r] = i.length ? i : null), !s) return;\n const l = i.map((o) => o.textContent?.trim() ?? \"\").filter(Boolean).join(\" \");\n l ? e.setAttribute(s, l) : e.removeAttribute(s);\n}\nconst b = (e) => {\n class t extends e {\n get idPrefix() {\n return this.localName || \"nys-element\";\n }\n ensureId() {\n this.id || (this.id = f(this.idPrefix));\n }\n connectedCallback() {\n super.connectedCallback(), this.ensureId();\n }\n }\n return t;\n}, P = /* @__PURE__ */ b(u), h = (e) => {\n class t extends b(e) {\n constructor() {\n super(...arguments), this.__internals = null;\n }\n get internals() {\n if (this.__internals) return this.__internals;\n if (typeof this.attachInternals == \"function\")\n try {\n this.__internals = this.attachInternals();\n } catch {\n this.__internals = null;\n }\n return this.__internals;\n }\n get defaultRole() {\n return null;\n }\n setHostAria(i, r) {\n const s = this.internals;\n if (s && i in s) {\n s[i] = r;\n return;\n }\n const a = v(i);\n r === null ? this.removeAttribute(a) : this.setAttribute(a, r);\n }\n reflectDefaultSemantics() {\n const i = this.defaultRole;\n i && this.setHostAria(\"role\", i);\n }\n connectedCallback() {\n super.connectedCallback(), this.reflectDefaultSemantics();\n }\n }\n return t;\n};\nfunction v(e) {\n if (e === \"role\") return \"role\";\n const t = e.replace(/^aria/, \"\");\n return \"aria-\" + t.charAt(0).toLowerCase() + t.slice(1);\n}\nconst T = /* @__PURE__ */ h(u), I = (e) => {\n const n = class n extends h(e) {\n setFormValue(r) {\n this.internals?.setFormValue(r ?? null);\n }\n setValidityFromState(r, s, a) {\n const l = this.internals;\n if (!l) return;\n const o = Object.values(r).some(Boolean);\n o ? l.setValidity(r, s ?? \"Invalid value\", a) : l.setValidity({}), this.setHostAria(\"ariaInvalid\", o ? \"true\" : \"false\");\n }\n clearValidity() {\n this.internals?.setValidity({}), this.setHostAria(\"ariaInvalid\", \"false\");\n }\n checkValidity() {\n return this.internals?.checkValidity() ?? !0;\n }\n reportValidity() {\n return this.internals?.reportValidity() ?? !0;\n }\n formResetCallback() {\n this.clearValidity();\n }\n };\n n.formAssociated = !0;\n let t = n;\n return t;\n}, w = /* @__PURE__ */ I(u);\nfunction O(e) {\n const t = e.tagName.toLowerCase(), n = /* @__PURE__ */ new Set(), i = (r) => {\n r.querySelectorAll(\"*\").forEach((s) => {\n const a = s.tagName.toLowerCase();\n a.startsWith(\"nys-\") && a !== t && !customElements.get(a) && n.add(a), s.shadowRoot && i(s.shadowRoot);\n });\n };\n return e.shadowRoot && i(e.shadowRoot), i(e), [...n].sort();\n}\nexport {\n I as FormControlMixin,\n b as IdentifiedMixin,\n P as NysElement,\n w as NysFormControlElement,\n T as NysReflectsAriaElement,\n h as ReflectsAriaMixin,\n V as associateControl,\n L as associateControlRefs,\n x as associateHost,\n O as findUnregisteredChildren,\n f as generateId,\n R as supportsElementRefs\n};\n//# sourceMappingURL=index.js.map\n","import { LitElement, html, unsafeCSS } from \"lit\";\nimport { property, state, query } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { NysFormControlElement } from \"@nysds/internals\";\n// These internal elements are rendered inside this component's shadow DOM, so\n// they must be registered whenever nys-combobox is used. Importing them here\n// (intentional side effect) guarantees the visible label and error message —\n// which the accessible name/error association depends on — always render. It\n// also guarantees the clear/toggle nys-buttons upgrade, since their accessible\n// name lands on nys-button's real inner <button>, which only exists once\n// nys-button renders.\nimport \"@nysds/nys-label\";\nimport \"@nysds/nys-errormessage\";\nimport \"@nysds/nys-icon\";\nimport \"@nysds/nys-button\";\n// @ts-ignore: SCSS module imported via bundler as inline\nimport styles from \"./nys-combobox.scss?inline\";\n\ninterface ComboboxOption {\n value: string;\n label: string;\n disabled?: boolean;\n group?: string;\n}\n\n/**\n * `<nys-combobox>` is a form-enabled combo box combining text input with a filterable dropdown.\n *\n * Features:\n * - Type to filter options\n * - Keyboard navigation (Arrow keys, Enter, Escape)\n * - Mouse and keyboard interaction\n * - Clears non-selected text on blur\n * - Clear button when value is selected\n * - Integrates with forms via ElementInternals\n * - Supports native <option> and <optgroup> elements\n * - Accessible per W3C ARIA Authoring Practices\n *\n * @slot description - Optional custom description content below the label.\n * @slot default - Options (<option>, <optgroup>) to populate the dropdown\n *\n * @fires nys-change - Fired when selection changes. Detail: `{ id, value }`.\n * @fires nys-input - Fired on input change. Detail: `{ id, value }`.\n * @fires nys-focus - Fired when combobox receives focus.\n * @fires nys-blur - Fired when combobox loses focus.\n *\n *\n * @example Basic\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"cherry\">Cherry</option>\n * <option value=\"date\">Date</option>\n * <option value=\"elderberry\">Elderberry</option>\n * <option value=\"fig\">Fig</option>\n * <option value=\"grape\">Grape</option>\n * <option value=\"honeydew\">Honeydew</option>\n * <option value=\"kiwi\">Kiwi</option>\n * <option value=\"lemon\">Lemon</option>\n * <option value=\"mango\">Mango</option>\n * <option value=\"nectarine\">Nectarine</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"papaya\">Papaya</option>\n * <option value=\"quince\">Quince</option>\n * <option value=\"raspberry\">Raspberry</option>\n * <option value=\"strawberry\">Strawberry</option>\n * <option value=\"tangerine\">Tangerine</option>\n * <option value=\"watermelon\">Watermelon</option>\n * </nys-combobox>\n * ```\n *\n * @example Default Value\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" value=\"mango\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"mango\" selected>Mango</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Option Group\n * ```html\n * <nys-combobox label=\"Select a fruit\" description=\"Fruits organized by category\">\n * <optgroup label=\"Citrus\">\n * <option value=\"lemon\">Lemon</option>\n * <option value=\"lime\">Lime</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"grapefruit\">Grapefruit</option>\n * <option value=\"tangerine\">Tangerine</option>\n * </optgroup>\n * <optgroup label=\"Berries\">\n * <option value=\"strawberry\">Strawberry</option>\n * <option value=\"blueberry\">Blueberry</option>\n * <option value=\"raspberry\">Raspberry</option>\n * <option value=\"blackberry\">Blackberry</option>\n * <option value=\"cranberry\">Cranberry</option>\n * </optgroup>\n * <optgroup label=\"Tropical\">\n * <option value=\"mango\">Mango</option>\n * <option value=\"pineapple\">Pineapple</option>\n * <option value=\"papaya\">Papaya</option>\n * <option value=\"coconut\">Coconut</option>\n * <option value=\"passionfruit\">Passionfruit</option>\n * </optgroup>\n * <optgroup label=\"Stone Fruits\">\n * <option value=\"peach\">Peach</option>\n * <option value=\"plum\">Plum</option>\n * <option value=\"cherry\">Cherry</option>\n * <option value=\"apricot\">Apricot</option>\n * <option value=\"nectarine\">Nectarine</option>\n * </optgroup>\n * </nys-combobox>\n * ```\n *\n * @example Disabled\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" disabled>\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Required\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" required>\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Optional\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" optional>\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Width Medium\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" width=\"md\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Width Large\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" width=\"lg\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Description\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" description=\"Choose from the list of available fruits.\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```d\n *\n * @example Description Slot\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\">\n * <label slot=\"description\">This is a description slot</label>\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Error Message\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" showError errorMessage=\"Please select a fruit\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"orange\">Orange</option>\n * <option value=\"strawberry\">Strawberry</option>\n * </nys-combobox>\n * ```\n *\n * @example Disabled Options\n * ```html\n * <nys-combobox label=\"Select your favorite fruit\" description=\"Some fruits are out of season\">\n * <option value=\"apple\">Apple</option>\n * <option value=\"banana\">Banana</option>\n * <option value=\"cherry\" disabled>Cherry (Out of season)</option>\n * <option value=\"mango\">Mango</option>\n * <option value=\"strawberry\" disabled>Strawberry (Out of season)</option>\n * <option value=\"orange\">Orange</option>\n * </nys-combobox>\n * ```\n */\nexport class NysCombobox extends NysFormControlElement {\n static styles = unsafeCSS(styles);\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n @property({ type: String, reflect: true }) id = \"\";\n @property({ type: String, reflect: true }) name = \"\";\n @property({ type: String }) label = \"\";\n @property({ type: String }) description = \"\";\n @property({ type: String }) value = \"\";\n @property({ type: Boolean, reflect: true }) disabled = false;\n @property({ type: Boolean, reflect: true }) required = false;\n @property({ type: Boolean, reflect: true }) optional = false;\n @property({ type: String }) tooltip = \"\";\n @property({ type: String, reflect: true }) form: string | null = null;\n @property({ type: String, reflect: true }) width: \"md\" | \"lg\" | \"full\" =\n \"full\";\n @property({ type: Boolean, reflect: true }) inverted = false;\n @property({ type: Boolean, reflect: true }) showError = false;\n @property({ type: String }) errorMessage = \"\";\n\n @state() private _isOpen = false;\n @state() private _filterText = \"\";\n @state() private _highlightedIndex = -1;\n @state() private _options: ComboboxOption[] = [];\n @state() private _filteredOptions: ComboboxOption[] = [];\n @state() private _dropdownAbove = false;\n @state() private _announcement = \"\";\n\n @query(\"input\") private _input!: HTMLInputElement;\n @query(\".nys-combobox__listbox\") private _listbox?: HTMLElement;\n\n private _originalErrorMessage = \"\";\n private _hasUserInteracted = false;\n private _selectedLabel = \"\";\n private _defaultValue = \"\";\n private _hasResolvedSlottedValue = false;\n\n /**\n * Lifecycle methods\n * --------------------------------------------------------------------------\n * Form association, ElementInternals, and id generation are provided by\n * NysFormControlElement (@nysds/internals).\n */\n connectedCallback() {\n // super.connectedCallback() (NysFormControlElement) assigns an id when one\n // is not provided and reflects default semantics.\n super.connectedCallback();\n this._originalErrorMessage = this.errorMessage ?? \"\";\n this.addEventListener(\"invalid\", this._handleInvalid);\n document.addEventListener(\"click\", this._handleDocumentClick);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener(\"invalid\", this._handleInvalid);\n document.removeEventListener(\"click\", this._handleDocumentClick);\n }\n\n firstUpdated() {\n // Slotted options are read in `_handleSlotChange`, which the slot's\n // `slotchange` event fires once its nodes are assigned. It also resolves an\n // option marked `selected` into `value` and captures `_defaultValue`.\n this._setValue();\n this._defaultValue = this.value;\n }\n\n // Derive display state from `value` before rendering, not after, so Lit\n // doesn't have to schedule a second update (see lit.dev/msg/change-in-update).\n willUpdate(changedProperties: Map<string | number | symbol, unknown>) {\n if (changedProperties.has(\"value\")) {\n const option = this._options.find((opt) => opt.value === this.value);\n this._selectedLabel = option ? option.label : \"\";\n this._filterText = this._selectedLabel;\n }\n }\n\n updated(changedProperties: Map<string | number | symbol, unknown>) {\n if (changedProperties.has(\"value\")) {\n this._setValue();\n }\n\n if (changedProperties.has(\"_isOpen\") && this._isOpen) {\n // Positioning measures the rendered listbox, so it has to wait for this\n // update to settle before it may flip `_dropdownAbove`.\n this.updateComplete.then(() => {\n this._positionDropdown();\n this._scrollToHighlighted();\n });\n }\n }\n\n /**\n * Slot handling\n * --------------------------------------------------------------------------\n */\n private _handleSlotChange() {\n const slot = this.shadowRoot?.querySelector(\n 'slot:not([name=\"description\"])',\n ) as HTMLSlotElement | null;\n\n if (!slot) return;\n\n const assignedElements = slot.assignedElements({ flatten: true });\n const options: ComboboxOption[] = [];\n let markupSelected = \"\";\n\n assignedElements.forEach((node) => {\n if (node.tagName === \"OPTION\") {\n const option = node as HTMLOptionElement;\n options.push({\n value: option.value,\n label: option.textContent?.trim() || option.value,\n disabled: option.disabled,\n });\n if (option.selected && !markupSelected) {\n markupSelected = option.value;\n }\n } else if (node.tagName === \"OPTGROUP\") {\n const group = node as HTMLOptGroupElement;\n const groupLabel = group.label;\n\n Array.from(group.children).forEach((child) => {\n if (child.tagName === \"OPTION\") {\n const option = child as HTMLOptionElement;\n options.push({\n value: option.value,\n label: option.textContent?.trim() || option.value,\n disabled: option.disabled || group.disabled,\n group: groupLabel,\n });\n if (option.selected && !markupSelected) {\n markupSelected = option.value;\n }\n }\n });\n }\n });\n\n this._options = options;\n this._filteredOptions = options;\n\n // The first time options arrive, adopt an option marked `selected` unless\n // an explicit value was already set, and use the result as the reset baseline.\n if (!this._hasResolvedSlottedValue) {\n this._hasResolvedSlottedValue = true;\n\n if (!this.value && markupSelected) {\n this.value = markupSelected;\n }\n this._defaultValue = this.value;\n }\n\n // Set initial display text if value exists\n if (this.value) {\n const option = this._options.find((opt) => opt.value === this.value);\n if (option) {\n this._selectedLabel = option.label;\n this._filterText = option.label;\n }\n }\n }\n\n /**\n * Form Integration\n * --------------------------------------------------------------------------\n */\n private _setValue() {\n this.setFormValue(this.value);\n this._manageRequire();\n }\n\n private _manageRequire() {\n const message = this.errorMessage || \"This field is required\";\n const isInvalid =\n this.required && (!this.value || this.value?.trim() === \"\");\n\n if (isInvalid) {\n this.setValidityFromState({ valueMissing: true }, message, this._input);\n } else {\n this.clearValidity();\n this._hasUserInteracted = false;\n }\n }\n\n private _setValidityMessage(message: string = \"\") {\n this.showError = !!message;\n\n if (this._originalErrorMessage?.trim() && message !== \"\") {\n this.errorMessage = this._originalErrorMessage;\n } else {\n this.errorMessage = message;\n }\n\n if (message) {\n this.setValidityFromState(\n { customError: true },\n this.errorMessage,\n this._input,\n );\n } else {\n this.clearValidity();\n }\n }\n\n private _validate() {\n if (!this._input) return;\n\n const validity = this._input.validity;\n let message = \"\";\n\n const isInvalid =\n this._input && !this._options.some((opt) => opt.value === this.value);\n\n if (validity.valueMissing || isInvalid) {\n message = \"This field is required\";\n } else {\n message = this._input.validationMessage;\n }\n\n this._setValidityMessage(message);\n }\n\n formResetCallback() {\n this.value = this._defaultValue;\n this._filterText = this._defaultValue\n ? (this._options.find((opt) => opt.value === this._defaultValue)?.label ??\n \"\")\n : \"\";\n this._selectedLabel = this._filterText;\n\n if (this._input) {\n this._input.value = this._filterText;\n }\n\n this.setFormValue(this.value);\n\n // Reset validation UI\n this.showError = false;\n this.errorMessage = \"\";\n this.clearValidity();\n\n this.requestUpdate();\n }\n checkValidity(): boolean {\n return this._input ? this._input.checkValidity() : true;\n }\n\n private _handleInvalid(event: Event) {\n event.preventDefault();\n this._hasUserInteracted = true;\n this._validate();\n\n if (this._input) {\n const form = this.internals?.form;\n if (form) {\n const elements = Array.from(form.elements) as Array<\n HTMLElement & { checkValidity?: () => boolean }\n >;\n const firstInvalidElement = elements.find(\n (element) =>\n typeof element.checkValidity === \"function\" &&\n !element.checkValidity(),\n );\n if (firstInvalidElement === this) {\n this._input.focus();\n }\n } else {\n this._input.focus();\n }\n }\n }\n\n /**\n * Dropdown positioning\n * --------------------------------------------------------------------------\n */\n private _positionDropdown() {\n if (!this._listbox || !this._input) return;\n\n const inputRect = this._input.getBoundingClientRect();\n const listboxHeight = this._listbox.offsetHeight;\n const viewportHeight = window.innerHeight;\n const spaceBelow = viewportHeight - inputRect.bottom;\n const spaceAbove = inputRect.top;\n\n // Show above if not enough space below and more space above\n this._dropdownAbove = spaceBelow < listboxHeight && spaceAbove > spaceBelow;\n }\n\n /**\n * Filtering\n * --------------------------------------------------------------------------\n */\n private _filterOptions(searchText: string) {\n if (!searchText) {\n this._filteredOptions = this._options;\n return;\n }\n\n const search = searchText.toLowerCase();\n this._filteredOptions = this._options.filter((option) =>\n option.label.toLowerCase().includes(search),\n );\n }\n\n /**\n * Keyboard navigation\n * --------------------------------------------------------------------------\n */\n private _scrollToHighlighted() {\n if (!this._listbox || this._highlightedIndex < 0) return;\n\n const highlighted = this._listbox.querySelector(\n `[data-index=\"${this._highlightedIndex}\"]`,\n ) as HTMLElement;\n\n if (highlighted) {\n highlighted.scrollIntoView({ block: \"nearest\" });\n }\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n if (!this._isOpen) {\n this._openDropdown();\n } else {\n this._moveHighlight(1);\n }\n break;\n\n case \"ArrowUp\":\n event.preventDefault();\n if (!this._isOpen) {\n this._openDropdown();\n } else {\n this._moveHighlight(-1);\n }\n break;\n\n case \"Enter\":\n event.preventDefault();\n if (this._isOpen && this._highlightedIndex >= 0) {\n this._selectOption(this._filteredOptions[this._highlightedIndex]);\n }\n break;\n\n case \"Escape\":\n event.preventDefault();\n this._closeDropdown();\n this._filterText = this._selectedLabel;\n break;\n\n case \"Tab\":\n if (this._isOpen) {\n this._closeDropdown();\n this._filterText = this._selectedLabel;\n }\n break;\n }\n }\n\n private _moveHighlight(direction: number) {\n const enabledOptions = this._filteredOptions.filter((opt) => !opt.disabled);\n if (enabledOptions.length === 0) return;\n\n let newIndex = this._highlightedIndex + direction;\n\n // Wrap around\n if (newIndex < 0) {\n newIndex = this._filteredOptions.length - 1;\n } else if (newIndex >= this._filteredOptions.length) {\n newIndex = 0;\n }\n\n // Skip disabled options\n while (this._filteredOptions[newIndex]?.disabled) {\n newIndex += direction;\n if (newIndex < 0) newIndex = this._filteredOptions.length - 1;\n if (newIndex >= this._filteredOptions.length) newIndex = 0;\n }\n\n this._highlightedIndex = newIndex;\n this._scrollToHighlighted();\n\n const option = this._filteredOptions[newIndex];\n const prevOption = this._filteredOptions[newIndex - direction];\n const enabledFiltered = this._filteredOptions.filter(\n (opt) => !opt.disabled,\n );\n const position =\n enabledFiltered.findIndex((opt) => opt.value === option.value) + 1;\n const isSelected = option.value === this.value ? \"selected\" : \"unselected\";\n const groupChanged = option.group && option.group !== prevOption?.group;\n const groupPrefix = groupChanged ? `${option.group}, ` : \"\";\n this._announcement = `${groupPrefix} ${option.label} ${position} of ${enabledFiltered.length}, ${isSelected}`;\n }\n\n /**\n * Event Handlers\n * --------------------------------------------------------------------------\n */\n private _handleInput(event: Event) {\n const input = event.target as HTMLInputElement;\n this._filterText = input.value;\n this._filterOptions(this._filterText);\n\n if (!this._isOpen) {\n this._openDropdown();\n }\n\n this._highlightedIndex = 0;\n\n const count = this._filteredOptions.filter((opt) => !opt.disabled).length;\n this._announcement =\n count > 0 ? `${count} options available` : \"No results found\";\n\n if (this._hasUserInteracted) {\n this._validate();\n }\n\n this.dispatchEvent(\n new CustomEvent(\"nys-input\", {\n detail: { id: this.id, value: this._filterText },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private _handleFocus() {\n this.dispatchEvent(\n new Event(\"nys-focus\", { bubbles: true, composed: true }),\n );\n }\n\n private _handleBlur(event: FocusEvent) {\n // Check if focus moved to the listbox\n const relatedTarget = event.relatedTarget as HTMLElement;\n if (relatedTarget && this._listbox?.contains(relatedTarget)) {\n return;\n }\n\n // If no valid selection, clear the input\n if (!this.value || this._filterText !== this._selectedLabel) {\n this._filterText = this._selectedLabel;\n this._filterOptions(\"\");\n }\n\n this._closeDropdown();\n\n if (!this._hasUserInteracted) {\n this._hasUserInteracted = true;\n }\n this._validate();\n\n this.dispatchEvent(\n new Event(\"nys-blur\", { bubbles: true, composed: true }),\n );\n }\n\n private _handleDocumentClick = (event: MouseEvent) => {\n // Don't close if click is on the combobox host element or inside shadow DOM\n if (\n event.target === this ||\n this.shadowRoot?.contains(event.target as Node)\n ) {\n return;\n }\n this._closeDropdown();\n };\n\n private _handleIconClick() {\n if (this.disabled) return;\n\n if (this._isOpen) {\n this._closeDropdown();\n } else {\n this._input.focus();\n this._openDropdown();\n }\n }\n\n private _handleClearClick(event: Event) {\n event.stopPropagation();\n this.value = \"\";\n this._filterText = \"\";\n this._selectedLabel = \"\";\n this._filterOptions(\"\");\n this.setFormValue(\"\");\n this._closeDropdown();\n this._input.focus();\n\n this._handleChange();\n }\n\n private _handleOptionClick(option: ComboboxOption) {\n if (option.disabled) return;\n this._selectOption(option);\n }\n\n private _handleOptionMouseEnter(index: number) {\n this._highlightedIndex = index;\n }\n\n private _selectOption(option: ComboboxOption) {\n this.value = option.value;\n this._selectedLabel = option.label;\n this._filterText = option.label;\n this.setFormValue(this.value);\n this._input.focus();\n this._closeDropdown();\n this._filterOptions(\"\");\n\n this._setValidityMessage(\"\");\n\n if (this._hasUserInteracted) {\n this._validate();\n }\n\n this._handleChange();\n }\n\n private _handleChange() {\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 private _openDropdown() {\n this._isOpen = true;\n this._highlightedIndex = this._filteredOptions.findIndex(\n (opt) => opt.value === this.value,\n );\n if (this._highlightedIndex < 0) this._highlightedIndex = 0;\n }\n\n private _closeDropdown() {\n this._isOpen = false;\n this._highlightedIndex = -1;\n }\n\n /**\n * Render helpers\n * --------------------------------------------------------------------------\n */\n private _renderOptions() {\n let currentGroup = \"\";\n const elements: any[] = [];\n\n this._filteredOptions.forEach((option, index) => {\n if (option.group && option.group !== currentGroup) {\n currentGroup = option.group;\n elements.push(html`\n <div class=\"nys-combobox__optgroup\" role=\"presentation\">\n ${option.group}\n </div>\n `);\n }\n\n const isFocused = index === this._highlightedIndex;\n const isSelected = option.value === this.value;\n\n elements.push(html`\n <div\n class=\"nys-combobox__option ${isFocused\n ? \"nys-combobox__option--focused\"\n : \"\"} ${isSelected ? \"nys-combobox__option--selected\" : \"\"}\"\n role=\"option\"\n id=\"${this.id}--option-${index}\"\n data-index=\"${index}\"\n aria-selected=\"${isSelected}\"\n aria-disabled=\"${option.disabled || false}\"\n ?disabled=${option.disabled}\n @click=${() => this._handleOptionClick(option)}\n @mouseenter=${() => this._handleOptionMouseEnter(index)}\n >\n ${option.label}\n </div>\n `);\n });\n\n if (elements.length === 0) {\n return html`\n <div class=\"nys-combobox__no-results\" role=\"option\">\n No results found\n </div>\n `;\n }\n\n return elements;\n }\n\n render() {\n return html`\n <div class=\"nys-combobox\">\n <nys-label\n id=\"${this.id}--label\"\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\n class=\"nys-combobox__container ${this._isOpen\n ? \"nys-combobox__container--open\"\n : \"\"}\"\n >\n <div class=\"nys-combobox__input-wrapper\">\n <input\n class=\"nys-combobox__input\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"${this._isOpen}\"\n aria-controls=\"${this.id}--listbox\"\n aria-activedescendant=\"${this._highlightedIndex >= 0\n ? `${this.id}--option-${this._highlightedIndex}`\n : \"\"}\"\n name=${this.name}\n id=${this.id + \"--native\"}\n ?disabled=${this.disabled}\n ?required=${this.required}\n aria-required=${this.required}\n aria-disabled=\"${this.disabled}\"\n aria-labelledby=${ifDefined(\n this.label ? this.id + \"--label\" : undefined,\n )}\n aria-label=${ifDefined(\n !this.label && this.description ? this.description : undefined,\n )}\n aria-invalid=${this.showError ? \"true\" : \"false\"}\n aria-errormessage=${this.id + \"--error\"}\n aria-describedby=${ifDefined(\n this.showError ? this.id + \"--error\" : undefined,\n )}\n .value=${this._filterText}\n form=${ifDefined(this.form || undefined)}\n @input=${this._handleInput}\n @focus=\"${this._handleFocus}\"\n @blur=\"${this._handleBlur}\"\n @keydown=\"${this._handleKeyDown}\"\n />\n <div class=\"nys-combobox__buttons\">\n ${this.value\n ? html`\n <nys-button\n class=\"nys-combobox__clear\"\n label=\"Clear selection\"\n variant=\"ghost\"\n size=\"sm\"\n circle\n @nys-click=${this._handleClearClick}\n ?disabled=${this.disabled}\n >\n <nys-icon\n slot=\"suffix-icon\"\n size=\"20\"\n name=\"close\"\n ></nys-icon>\n </nys-button>\n `\n : \"\"}\n <nys-button\n class=\"nys-combobox__chevron\"\n label=\"Toggle dropdown\"\n variant=\"ghost\"\n size=\"sm\"\n circle\n @nys-click=${this._handleIconClick}\n ?disabled=${this.disabled}\n >\n <nys-icon\n slot=\"suffix-icon\"\n size=\"20\"\n name=\"chevron_down\"\n ></nys-icon>\n </nys-button>\n </div>\n </div>\n ${this._isOpen\n ? html`\n <div\n class=\"nys-combobox__listbox ${this._dropdownAbove\n ? \"nys-combobox__listbox--above\"\n : \"\"}\"\n id=\"${this.id}--listbox\"\n role=\"listbox\"\n tabindex=\"-1\"\n >\n ${this._renderOptions()}\n </div>\n `\n : \"\"}\n </div>\n <slot\n style=\"display: none;\"\n @slotchange=${this._handleSlotChange}\n ></slot>\n <nys-errormessage\n id=${this.id + \"--error\"}\n ?showError=${this.showError}\n errorMessage=${this.errorMessage}\n ></nys-errormessage>\n <div\n aria-live=\"polite\"\n aria-atomic=\"true\"\n style=\"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;\"\n >\n ${this._announcement}\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"nys-combobox\")) {\n customElements.define(\"nys-combobox\", NysCombobox);\n}\n"],"names":["LitElement","unsafeCSS","html","property","state","query","ifDefined","y","f","e","b","t","h","i","r","s","a","v","I","n","l","o","w","u","_NysCombobox","NysFormControlElement","event","changedProperties","option","opt","slot","assignedElements","options","markupSelected","node","group","groupLabel","child","message","validity","isInvalid","form","element","inputRect","listboxHeight","spaceBelow","spaceAbove","searchText","search","highlighted","direction","newIndex","prevOption","enabledFiltered","position","isSelected","groupPrefix","input","count","relatedTarget","index","currentGroup","elements","isFocused","styles","NysCombobox","__decorateClass"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nysds/nys-combobox",
3
- "version": "1.19.3",
3
+ "version": "1.20.0",
4
4
  "description": "The Combobox component from the NYS Design System.",
5
5
  "module": "dist/nys-combobox.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,7 +22,14 @@
22
22
  "test:watch": "vite build && wtr --watch",
23
23
  "lit-analyze": "lit-analyzer 'src/**/*.ts'"
24
24
  },
25
+ "dependencies": {
26
+ "@nysds/nys-label": "^1.20.0",
27
+ "@nysds/nys-errormessage": "^1.20.0",
28
+ "@nysds/nys-icon": "^1.20.0",
29
+ "@nysds/nys-button": "^1.20.0"
30
+ },
25
31
  "devDependencies": {
32
+ "@nysds/internals": "^1.20.0",
26
33
  "lit": "^3.3.1",
27
34
  "typescript": "^5.9.3",
28
35
  "vite": "^7.3.1"