taga11y 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +309 -0
- package/dist/a11y.d.ts +8 -0
- package/dist/a11y.d.ts.map +1 -0
- package/dist/core/dropdown.d.ts +63 -0
- package/dist/core/dropdown.d.ts.map +1 -0
- package/dist/core/input.d.ts +42 -0
- package/dist/core/input.d.ts.map +1 -0
- package/dist/core/keyboard.d.ts +37 -0
- package/dist/core/keyboard.d.ts.map +1 -0
- package/dist/core/selection.d.ts +24 -0
- package/dist/core/selection.d.ts.map +1 -0
- package/dist/dom/chips.d.ts +6 -0
- package/dist/dom/chips.d.ts.map +1 -0
- package/dist/dom/listbox.d.ts +5 -0
- package/dist/dom/listbox.d.ts.map +1 -0
- package/dist/dom/render.d.ts +24 -0
- package/dist/dom/render.d.ts.map +1 -0
- package/dist/i18n.d.ts +44 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/index.d.ts +212 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/locales/ar.json +28 -0
- package/dist/locales/pt.json +21 -0
- package/dist/react/index.d.ts +46 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react.cjs +1 -0
- package/dist/react.mjs +83 -0
- package/dist/taga11y.cjs +1 -0
- package/dist/taga11y.css +2 -0
- package/dist/taga11y.iife.js +1 -0
- package/dist/taga11y.mjs +829 -0
- package/dist/types.d.ts +201 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/debounce.d.ts +5 -0
- package/dist/utils/debounce.d.ts.map +1 -0
- package/dist/utils/filter.d.ts +5 -0
- package/dist/utils/filter.d.ts.map +1 -0
- package/dist/utils/id.d.ts +11 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/vue/index.d.ts +155 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue.cjs +1 -0
- package/dist/vue.mjs +127 -0
- package/package.json +111 -0
- package/src/a11y.ts +85 -0
- package/src/aria-notify.d.ts +9 -0
- package/src/core/dropdown.ts +331 -0
- package/src/core/input.ts +172 -0
- package/src/core/keyboard.ts +200 -0
- package/src/core/selection.ts +78 -0
- package/src/dom/chips.ts +80 -0
- package/src/dom/listbox.ts +49 -0
- package/src/dom/render.ts +154 -0
- package/src/i18n.ts +131 -0
- package/src/index.ts +900 -0
- package/src/react/index.tsx +223 -0
- package/src/styles/index.css +367 -0
- package/src/types.ts +224 -0
- package/src/utils/debounce.ts +27 -0
- package/src/utils/filter.ts +14 -0
- package/src/utils/id.ts +30 -0
- package/src/vite-env.d.ts +1 -0
- package/src/vue/index.ts +145 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import './styles/index.css';
|
|
2
|
+
import type { TagData, Taga11yOptions, SuggestionItem, SuggestionsSource, I18nOptions, I18nStrings, Taga11yEventMap } from './types.js';
|
|
3
|
+
export type { TagData, Taga11yOptions, SuggestionItem, SuggestionsSource, I18nOptions, I18nStrings, };
|
|
4
|
+
export type { PluralForms, I18nKey } from './types.js';
|
|
5
|
+
export type { Taga11yEventMap, Taga11yAddDetail, Taga11yRemoveDetail, Taga11yClearDetail, Taga11yChangeDetail, Taga11yPasteDetail, Taga11yDestroyDetail, } from './types.js';
|
|
6
|
+
export declare class Taga11y {
|
|
7
|
+
private readonly _input;
|
|
8
|
+
private readonly _ids;
|
|
9
|
+
private readonly _originalName;
|
|
10
|
+
private readonly _originalId;
|
|
11
|
+
private readonly _originalValue;
|
|
12
|
+
private readonly _originalParent;
|
|
13
|
+
private readonly _originalNextSibling;
|
|
14
|
+
private _dom;
|
|
15
|
+
private _selection;
|
|
16
|
+
private _dropdown;
|
|
17
|
+
private _inputMgr;
|
|
18
|
+
private _keyboard;
|
|
19
|
+
private _opts;
|
|
20
|
+
private readonly _strings;
|
|
21
|
+
private readonly _locale;
|
|
22
|
+
private _initialSnapshot;
|
|
23
|
+
private _formResetHandler;
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new taga11y instance and immediately initialises it.
|
|
26
|
+
*
|
|
27
|
+
* @param input - The native `<input>` element to enhance.
|
|
28
|
+
* @param options - Configuration options for the widget.
|
|
29
|
+
* @throws If `suggestions` defines both `once` and `query` keys.
|
|
30
|
+
*/
|
|
31
|
+
constructor(input: HTMLInputElement, options?: Taga11yOptions);
|
|
32
|
+
/**
|
|
33
|
+
* Initialises the widget: builds the DOM structure, wires up managers,
|
|
34
|
+
* pre-populates tags from the original input value, and sets up form
|
|
35
|
+
* reset handling.
|
|
36
|
+
*
|
|
37
|
+
* Called automatically by the constructor. Invoke again after
|
|
38
|
+
* {@link destroy} to re-initialise.
|
|
39
|
+
*/
|
|
40
|
+
init(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Tears down the widget: removes the injected DOM, detaches all event
|
|
43
|
+
* listeners, restores the original input's attributes, and moves it
|
|
44
|
+
* back to its original DOM position.
|
|
45
|
+
*
|
|
46
|
+
* Fires a `taga11y:destroy` event on the original input.
|
|
47
|
+
*/
|
|
48
|
+
destroy(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Adds a single tag by value.
|
|
51
|
+
*
|
|
52
|
+
* Resolves the display label from loaded suggestions (matching on
|
|
53
|
+
* `value`), falling back to `label === value` if no match exists.
|
|
54
|
+
*
|
|
55
|
+
* @param value - The tag value to add.
|
|
56
|
+
* @returns `true` if the tag was added; `false` if rejected
|
|
57
|
+
* (duplicate or max reached).
|
|
58
|
+
*
|
|
59
|
+
* Fires `taga11y:add` and `taga11y:change` on success.
|
|
60
|
+
* Fires no events on rejection (shows error chip + region instead).
|
|
61
|
+
*/
|
|
62
|
+
addTag(value: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Removes a single tag by value.
|
|
65
|
+
*
|
|
66
|
+
* @param value - The tag value to remove.
|
|
67
|
+
* @returns The removed `TagData`, or `null` if no tag with that
|
|
68
|
+
* value exists.
|
|
69
|
+
*
|
|
70
|
+
* Fires `taga11y:remove` and `taga11y:change`. Returns focus to
|
|
71
|
+
* the combobox input after removal.
|
|
72
|
+
*/
|
|
73
|
+
removeTag(value: string): TagData | null;
|
|
74
|
+
/**
|
|
75
|
+
* Removes all tags at once.
|
|
76
|
+
*
|
|
77
|
+
* Fires `taga11y:clear` (detail: `{ tags: TagData[] }`) and
|
|
78
|
+
* `taga11y:change` (detail: `{ tags: [] }`).
|
|
79
|
+
*/
|
|
80
|
+
clearTags(): void;
|
|
81
|
+
/**
|
|
82
|
+
* Returns a defensive copy of the current tag array.
|
|
83
|
+
*
|
|
84
|
+
* @returns Array of `TagData` objects representing selected tags.
|
|
85
|
+
*/
|
|
86
|
+
getTags(): TagData[];
|
|
87
|
+
/**
|
|
88
|
+
* Batch-adds multiple tags. Duplicates are skipped silently.
|
|
89
|
+
*
|
|
90
|
+
* Fires `taga11y:add` per successfully added tag and a single
|
|
91
|
+
* `taga11y:change` after all additions with the final tag set.
|
|
92
|
+
*
|
|
93
|
+
* @param items - Suggestion items to add.
|
|
94
|
+
*/
|
|
95
|
+
addTags(items: SuggestionItem[]): void;
|
|
96
|
+
/**
|
|
97
|
+
*Fully replaces all tags with the given items.
|
|
98
|
+
*
|
|
99
|
+
* Fires `taga11y:clear` with the previously selected tags, then
|
|
100
|
+
* `taga11y:add` per newly added tag, and finally a single
|
|
101
|
+
* `taga11y:change` with the final tag set.
|
|
102
|
+
*
|
|
103
|
+
* @param items - Suggestion items to set as the new tag set.
|
|
104
|
+
*/
|
|
105
|
+
setTags(items: SuggestionItem[]): void;
|
|
106
|
+
/**
|
|
107
|
+
* Checks whether a tag with the given value is currently selected.
|
|
108
|
+
*
|
|
109
|
+
* @param value - The tag value to check.
|
|
110
|
+
* @returns `true` if a tag with the matching value exists.
|
|
111
|
+
*/
|
|
112
|
+
isTagged(value: string): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Opens the suggestion dropdown. No-op if already open or disabled.
|
|
115
|
+
*/
|
|
116
|
+
open(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Closes the suggestion dropdown. No-op if already closed.
|
|
119
|
+
*/
|
|
120
|
+
close(): void;
|
|
121
|
+
/**
|
|
122
|
+
* Focuses the combobox input element.
|
|
123
|
+
*/
|
|
124
|
+
focus(): void;
|
|
125
|
+
/**
|
|
126
|
+
* Blurs the combobox input element.
|
|
127
|
+
*/
|
|
128
|
+
blur(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Updates one or more runtime options after initialisation.
|
|
131
|
+
*
|
|
132
|
+
* Only the provided keys are applied; unprovided keys retain their
|
|
133
|
+
* current values. Each option triggers specific side effects:
|
|
134
|
+
*
|
|
135
|
+
* - `disabled` — enables/disables the input, hidden input, and chip
|
|
136
|
+
* remove buttons; toggles `.taga11y--disabled` class.
|
|
137
|
+
* - `theme` — sets or removes `data-theme` on the wrapper.
|
|
138
|
+
* - `maxTags` — updates the selection manager's limit.
|
|
139
|
+
* - `maxSuggestions` — updates the dropdown display cap; takes effect on the
|
|
140
|
+
* next filter (does not re-render an already-open dropdown).
|
|
141
|
+
* - `delimiter` — updates delimiter characters.
|
|
142
|
+
* - `enforceSuggestions` — toggles whitelist mode.
|
|
143
|
+
* - `label` — creates, updates, or removes the visible label element.
|
|
144
|
+
* - `suggestions` — replaces the suggestion source.
|
|
145
|
+
* - `debounceMs` — updates the debounce delay for dynamic mode.
|
|
146
|
+
* - `serialize` — updates the hidden input serializer.
|
|
147
|
+
* - `deserialize` — updates the initial-value parser; takes effect on the
|
|
148
|
+
* next form reset (does not retroactively re-parse current tags).
|
|
149
|
+
* - `name` — updates the hidden input's name attribute.
|
|
150
|
+
*
|
|
151
|
+
* @param newOptions - Partial options object with keys to update.
|
|
152
|
+
*/
|
|
153
|
+
settings(newOptions: Partial<Taga11yOptions>): void;
|
|
154
|
+
/**
|
|
155
|
+
* Registers a listener for a taga11y custom event on the original
|
|
156
|
+
* input element.
|
|
157
|
+
*
|
|
158
|
+
* @param event - Event name. One of `"taga11y:add"`,
|
|
159
|
+
* `"taga11y:remove"`, `"taga11y:clear"`, `"taga11y:change"`,
|
|
160
|
+
* `"taga11y:paste"`, or `"taga11y:destroy"`. A known event name infers
|
|
161
|
+
* the handler's `CustomEvent` detail; any other string is also accepted.
|
|
162
|
+
* @param handler - Event listener callback.
|
|
163
|
+
*/
|
|
164
|
+
on<K extends keyof Taga11yEventMap>(event: K, handler: (event: CustomEvent<Taga11yEventMap[K]>) => void): void;
|
|
165
|
+
on(event: string, handler: EventListener): void;
|
|
166
|
+
/**
|
|
167
|
+
* Removes a previously registered event listener.
|
|
168
|
+
*
|
|
169
|
+
* @param event - Event name. Typed identically to {@link Taga11y.on}, so the
|
|
170
|
+
* same typed handler reference can be passed to both.
|
|
171
|
+
* @param handler - The handler to remove.
|
|
172
|
+
*/
|
|
173
|
+
off<K extends keyof Taga11yEventMap>(event: K, handler: (event: CustomEvent<Taga11yEventMap[K]>) => void): void;
|
|
174
|
+
off(event: string, handler: EventListener): void;
|
|
175
|
+
/**
|
|
176
|
+
* Dispatches a custom event on the original input element.
|
|
177
|
+
*
|
|
178
|
+
* All events bubble and are not cancelable.
|
|
179
|
+
*
|
|
180
|
+
* @param event - Event name.
|
|
181
|
+
* @param data - Event detail payload.
|
|
182
|
+
*/
|
|
183
|
+
emit(event: string, data: Record<string, unknown>): void;
|
|
184
|
+
/**
|
|
185
|
+
* Read-only property returning the current tag array (defensive copy).
|
|
186
|
+
* Equivalent to `getTags()`.
|
|
187
|
+
*/
|
|
188
|
+
get tags(): TagData[];
|
|
189
|
+
/**
|
|
190
|
+
* Read-only property indicating whether the suggestion dropdown
|
|
191
|
+
* is currently visible.
|
|
192
|
+
*/
|
|
193
|
+
get isOpen(): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Read-only property indicating whether the maximum tag count
|
|
196
|
+
* has been reached (when `maxTags` is configured).
|
|
197
|
+
*/
|
|
198
|
+
get maxTagsReached(): boolean;
|
|
199
|
+
private _parseOptions;
|
|
200
|
+
private _handleCommit;
|
|
201
|
+
private _handlePaste;
|
|
202
|
+
private _handleBlurCommit;
|
|
203
|
+
private _handleRemove;
|
|
204
|
+
private _handleRemoveLast;
|
|
205
|
+
private _handleFormReset;
|
|
206
|
+
private _showRejection;
|
|
207
|
+
private _syncChips;
|
|
208
|
+
private _announceTagsSummary;
|
|
209
|
+
private _syncHiddenInput;
|
|
210
|
+
private _resolveLabelFromAll;
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,eAAe,EAChB,MAAM,YAAY,CAAC;AAmBpB,YAAY,EACV,OAAO,EACP,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,WAAW,GACZ,CAAC;AACF,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAkEpB,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoB;IACpD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAmB;IAExD,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,gBAAgB,CAAwB;IAChD,OAAO,CAAC,iBAAiB,CAA6B;IAEtD;;;;;;OAMG;gBACS,KAAK,EAAE,gBAAgB,EAAE,OAAO,GAAE,cAAmB;IAgBjE;;;;;;;OAOG;IACH,IAAI,IAAI,IAAI;IA8GZ;;;;;;OAMG;IACH,OAAO,IAAI,IAAI;IAqCf;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAiB9B;;;;;;;;;OASG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAgBxC;;;;;OAKG;IACH,SAAS,IAAI,IAAI;IAWjB;;;;OAIG;IACH,OAAO,IAAI,OAAO,EAAE;IAMpB;;;;;;;OAOG;IACH,OAAO,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI;IAoBtC;;;;;;;;OAQG;IACH,OAAO,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI;IAmBtC;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAMhC;;OAEG;IACH,IAAI,IAAI,IAAI;IAKZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IAMZ;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI;IA8FnD;;;;;;;;;OASG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,eAAe,EAChC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GACxD,IAAI;IACP,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAK/C;;;;;;OAMG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,eAAe,EACjC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GACxD,IAAI;IACP,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAOhD;;;;;;;OAOG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAQxD;;;OAGG;IACH,IAAI,IAAI,IAAI,OAAO,EAAE,CAEpB;IAED;;;OAGG;IACH,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED;;;OAGG;IACH,IAAI,cAAc,IAAI,OAAO,CAG5B;IAID,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,YAAY;IAuCpB,OAAO,CAAC,iBAAiB;IAoCzB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,UAAU;IAmBlB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,oBAAoB;CAI7B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"a11y.tagAdded": "تمت إضافة وسم: {label}",
|
|
3
|
+
"a11y.tagRemoved": "تمت إزالة وسم: {label}",
|
|
4
|
+
"a11y.tagsCleared": "تم مسح الوسوم",
|
|
5
|
+
"a11y.noResults": "لا توجد نتائج",
|
|
6
|
+
"a11y.resultsCount": {
|
|
7
|
+
"zero": "لا توجد نتائج متاحة",
|
|
8
|
+
"one": "نتيجة واحدة متاحة",
|
|
9
|
+
"two": "نتيجتان متاحتان",
|
|
10
|
+
"few": "{n} نتائج متاحة",
|
|
11
|
+
"many": "{n} نتيجة متاحة",
|
|
12
|
+
"other": "{n} نتيجة متاحة"
|
|
13
|
+
},
|
|
14
|
+
"a11y.tagsSummary": {
|
|
15
|
+
"one": "وسم واحد محدد: {labels}",
|
|
16
|
+
"two": "وسمان محددان: {labels}",
|
|
17
|
+
"few": "{n} وسوم محددة: {labels}",
|
|
18
|
+
"many": "{n} وسمًا محددًا: {labels}",
|
|
19
|
+
"other": "{n} وسم محدد: {labels}"
|
|
20
|
+
},
|
|
21
|
+
"a11y.selectedTags": "الوسوم المحددة",
|
|
22
|
+
"a11y.removeTag": "إزالة {label}",
|
|
23
|
+
"ui.loading": "جارٍ تحميل الاقتراحات…",
|
|
24
|
+
"error.duplicate": "مضاف بالفعل: {label}",
|
|
25
|
+
"error.maxReached": "تم بلوغ الحد الأقصى للوسوم",
|
|
26
|
+
"error.notInList": "غير موجود في القائمة",
|
|
27
|
+
"error.loadError": "فشل تحميل الاقتراحات"
|
|
28
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"a11y.tagAdded": "Etiqueta adicionada: {label}",
|
|
3
|
+
"a11y.tagRemoved": "Etiqueta removida: {label}",
|
|
4
|
+
"a11y.tagsCleared": "Etiquetas removidas",
|
|
5
|
+
"a11y.noResults": "Sem resultados",
|
|
6
|
+
"a11y.resultsCount": {
|
|
7
|
+
"one": "{n} resultado disponível",
|
|
8
|
+
"other": "{n} resultados disponíveis"
|
|
9
|
+
},
|
|
10
|
+
"a11y.tagsSummary": {
|
|
11
|
+
"one": "{n} etiqueta selecionada: {labels}",
|
|
12
|
+
"other": "{n} etiquetas selecionadas: {labels}"
|
|
13
|
+
},
|
|
14
|
+
"a11y.selectedTags": "Etiquetas selecionadas",
|
|
15
|
+
"a11y.removeTag": "Remover {label}",
|
|
16
|
+
"ui.loading": "A carregar sugestões…",
|
|
17
|
+
"error.duplicate": "Já adicionada: {label}",
|
|
18
|
+
"error.maxReached": "Número máximo de etiquetas atingido",
|
|
19
|
+
"error.notInList": "Não está na lista",
|
|
20
|
+
"error.loadError": "Falha ao carregar sugestões"
|
|
21
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactElement, Ref, RefObject } from 'react';
|
|
2
|
+
import { Taga11y, type Taga11yOptions, type Taga11yAddDetail, type Taga11yRemoveDetail, type Taga11yClearDetail, type Taga11yChangeDetail, type Taga11yPasteDetail } from 'taga11y';
|
|
3
|
+
interface Taga11yHandlers {
|
|
4
|
+
/** Fired when a tag is successfully added. */
|
|
5
|
+
onAdd?: (event: CustomEvent<Taga11yAddDetail>) => void;
|
|
6
|
+
/** Fired when a tag is removed. */
|
|
7
|
+
onRemove?: (event: CustomEvent<Taga11yRemoveDetail>) => void;
|
|
8
|
+
/** Fired when all tags are cleared. */
|
|
9
|
+
onClear?: (event: CustomEvent<Taga11yClearDetail>) => void;
|
|
10
|
+
/** Fired after every mutation, with the current values and raw event. */
|
|
11
|
+
onChange?: (values: string[], event: CustomEvent<Taga11yChangeDetail>) => void;
|
|
12
|
+
/** Fired after a bulk-import paste gesture. */
|
|
13
|
+
onPaste?: (event: CustomEvent<Taga11yPasteDetail>) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Fired when the widget is destroyed (on unmount). The component's own
|
|
16
|
+
* unmount lifecycle is the idiomatic place for teardown; this exists for
|
|
17
|
+
* 1:1 parity with the core event surface.
|
|
18
|
+
*/
|
|
19
|
+
onDestroy?: (event: CustomEvent) => void;
|
|
20
|
+
}
|
|
21
|
+
type InputPassthrough = Omit<ComponentPropsWithoutRef<'input'>, keyof Taga11yOptions | keyof Taga11yHandlers | 'value' | 'defaultValue'>;
|
|
22
|
+
export interface Taga11yInputProps extends Taga11yOptions, Taga11yHandlers, InputPassthrough {
|
|
23
|
+
/** Controlled tag values. When provided, the consumer owns tag state. */
|
|
24
|
+
value?: string[];
|
|
25
|
+
/** Uncontrolled initial tag values. */
|
|
26
|
+
defaultValue?: string[];
|
|
27
|
+
/** Receives the live {@link Taga11y} instance after mount (escape hatch). */
|
|
28
|
+
instanceRef?: RefObject<Taga11y | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Standard React ref, resolving to the underlying `<input>` element (not the
|
|
31
|
+
* `Taga11y` instance — use {@link instanceRef} for that). Enables form
|
|
32
|
+
* libraries (e.g. react-hook-form's `{...field}`) to focus the field.
|
|
33
|
+
*/
|
|
34
|
+
ref?: Ref<HTMLInputElement>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Accessibility-first tagging input for React 19.
|
|
38
|
+
*
|
|
39
|
+
* Wraps the vanilla {@link Taga11y} class. Supports controlled (`value` +
|
|
40
|
+
* `onChange`) and uncontrolled (`defaultValue`) usage; forwards every core
|
|
41
|
+
* event as a callback; exposes the instance via `instanceRef`. Client-only
|
|
42
|
+
* mount keeps it SSR-safe.
|
|
43
|
+
*/
|
|
44
|
+
export declare function Taga11yInput(props: Taga11yInputProps): ReactElement;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACpF,OAAO,EACL,OAAO,EACP,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAExB,MAAM,SAAS,CAAC;AAqBjB,UAAU,eAAe;IACvB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACvD,mCAAmC;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC;IAC7D,uCAAuC;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC;IAC3D,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC;IAC/E,+CAA+C;IAC/C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC;IAC3D;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAC1C;AAED,KAAK,gBAAgB,GAAG,IAAI,CAC1B,wBAAwB,CAAC,OAAO,CAAC,EACjC,MAAM,cAAc,GAAG,MAAM,eAAe,GAAG,OAAO,GAAG,cAAc,CACxE,CAAC;AAEF,MAAM,WAAW,iBAAkB,SAAQ,cAAc,EAAE,eAAe,EAAE,gBAAgB;IAC1F,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACxC;;;;OAIG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAMD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CA2InE"}
|
package/dist/react.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`react`),t=require(`taga11y`),n=require(`react/jsx-runtime`);var r=typeof window<`u`?e.useLayoutEffect:e.useEffect,i=[`suggestions`,`maxTags`,`delimiter`,`enforceSuggestions`,`name`,`label`,`disabled`,`theme`,`serialize`,`deserialize`,`debounceMs`,`i18n`];function a(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}function o(o){let{value:s,defaultValue:c,instanceRef:l,ref:u,onAdd:d,onRemove:f,onClear:p,onChange:m,onPaste:h,onDestroy:g,..._}=o,v=(0,e.useRef)(null),y=(0,e.useRef)(null),b=(0,e.useCallback)(e=>{v.current=e,typeof u==`function`?u(e):u&&(u.current=e)},[u]),x={},S={},C=new Set(i);for(let e of Object.keys(_)){let t=_;C.has(e)?x[e]=t[e]:S[e]=t[e]}let w=(0,e.useRef)(x);w.current=x;let T=(0,e.useRef)(g);T.current=g,r(()=>{let e=v.current;if(!e)return;let n=new t.Taga11y(e,w.current);y.current=n,l&&(l.current=n);let r=s??c;r&&r.length>0&&n.setTags(r);let i=e=>{T.current?.(e)};return n.on(`taga11y:destroy`,i),()=>{n.destroy(),n.off(`taga11y:destroy`,i),y.current=null,l&&(l.current=null)}},[]);let E=(0,e.useRef)(x);return(0,e.useEffect)(()=>{let e=y.current;if(!e)return;let t={};for(let e of i)e!==`i18n`&&w.current[e]!==E.current[e]&&(t[e]=w.current[e]);Object.keys(t).length>0&&e.settings(t),E.current=w.current}),(0,e.useEffect)(()=>{if(s===void 0)return;let e=y.current;e&&(a(e.getTags().map(e=>e.value),s)||e.setTags(s))},[s]),(0,e.useEffect)(()=>{let e=y.current;if(!e||!m)return;let t=e=>{m(e.detail.tags.map(e=>e.value),e)};return e.on(`taga11y:change`,t),()=>e.off(`taga11y:change`,t)},[m]),(0,e.useEffect)(()=>{let e=y.current;if(!(!e||!d))return e.on(`taga11y:add`,d),()=>e.off(`taga11y:add`,d)},[d]),(0,e.useEffect)(()=>{let e=y.current;if(!(!e||!f))return e.on(`taga11y:remove`,f),()=>e.off(`taga11y:remove`,f)},[f]),(0,e.useEffect)(()=>{let e=y.current;if(!(!e||!p))return e.on(`taga11y:clear`,p),()=>e.off(`taga11y:clear`,p)},[p]),(0,e.useEffect)(()=>{let e=y.current;if(!(!e||!h))return e.on(`taga11y:paste`,h),()=>e.off(`taga11y:paste`,h)},[h]),(0,n.jsx)(`input`,{ref:b,...S})}exports.Taga11yInput=o;
|
package/dist/react.mjs
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { useCallback as e, useEffect as t, useLayoutEffect as n, useRef as r } from "react";
|
|
2
|
+
import { Taga11y as i } from "taga11y";
|
|
3
|
+
import { jsx as a } from "react/jsx-runtime";
|
|
4
|
+
//#region src/react/index.tsx
|
|
5
|
+
var o = typeof window < "u" ? n : t, s = [
|
|
6
|
+
"suggestions",
|
|
7
|
+
"maxTags",
|
|
8
|
+
"delimiter",
|
|
9
|
+
"enforceSuggestions",
|
|
10
|
+
"name",
|
|
11
|
+
"label",
|
|
12
|
+
"disabled",
|
|
13
|
+
"theme",
|
|
14
|
+
"serialize",
|
|
15
|
+
"deserialize",
|
|
16
|
+
"debounceMs",
|
|
17
|
+
"i18n"
|
|
18
|
+
];
|
|
19
|
+
function c(e, t) {
|
|
20
|
+
return e.length === t.length && e.every((e, n) => e === t[n]);
|
|
21
|
+
}
|
|
22
|
+
function l(n) {
|
|
23
|
+
let { value: l, defaultValue: u, instanceRef: d, ref: f, onAdd: p, onRemove: m, onClear: h, onChange: g, onPaste: _, onDestroy: v, ...y } = n, b = r(null), x = r(null), S = e((e) => {
|
|
24
|
+
b.current = e, typeof f == "function" ? f(e) : f && (f.current = e);
|
|
25
|
+
}, [f]), C = {}, w = {}, T = new Set(s);
|
|
26
|
+
for (let e of Object.keys(y)) {
|
|
27
|
+
let t = y;
|
|
28
|
+
T.has(e) ? C[e] = t[e] : w[e] = t[e];
|
|
29
|
+
}
|
|
30
|
+
let E = r(C);
|
|
31
|
+
E.current = C;
|
|
32
|
+
let D = r(v);
|
|
33
|
+
D.current = v, o(() => {
|
|
34
|
+
let e = b.current;
|
|
35
|
+
if (!e) return;
|
|
36
|
+
let t = new i(e, E.current);
|
|
37
|
+
x.current = t, d && (d.current = t);
|
|
38
|
+
let n = l ?? u;
|
|
39
|
+
n && n.length > 0 && t.setTags(n);
|
|
40
|
+
let r = (e) => {
|
|
41
|
+
D.current?.(e);
|
|
42
|
+
};
|
|
43
|
+
return t.on("taga11y:destroy", r), () => {
|
|
44
|
+
t.destroy(), t.off("taga11y:destroy", r), x.current = null, d && (d.current = null);
|
|
45
|
+
};
|
|
46
|
+
}, []);
|
|
47
|
+
let O = r(C);
|
|
48
|
+
return t(() => {
|
|
49
|
+
let e = x.current;
|
|
50
|
+
if (!e) return;
|
|
51
|
+
let t = {};
|
|
52
|
+
for (let e of s) e !== "i18n" && E.current[e] !== O.current[e] && (t[e] = E.current[e]);
|
|
53
|
+
Object.keys(t).length > 0 && e.settings(t), O.current = E.current;
|
|
54
|
+
}), t(() => {
|
|
55
|
+
if (l === void 0) return;
|
|
56
|
+
let e = x.current;
|
|
57
|
+
e && (c(e.getTags().map((e) => e.value), l) || e.setTags(l));
|
|
58
|
+
}, [l]), t(() => {
|
|
59
|
+
let e = x.current;
|
|
60
|
+
if (!e || !g) return;
|
|
61
|
+
let t = (e) => {
|
|
62
|
+
g(e.detail.tags.map((e) => e.value), e);
|
|
63
|
+
};
|
|
64
|
+
return e.on("taga11y:change", t), () => e.off("taga11y:change", t);
|
|
65
|
+
}, [g]), t(() => {
|
|
66
|
+
let e = x.current;
|
|
67
|
+
if (!(!e || !p)) return e.on("taga11y:add", p), () => e.off("taga11y:add", p);
|
|
68
|
+
}, [p]), t(() => {
|
|
69
|
+
let e = x.current;
|
|
70
|
+
if (!(!e || !m)) return e.on("taga11y:remove", m), () => e.off("taga11y:remove", m);
|
|
71
|
+
}, [m]), t(() => {
|
|
72
|
+
let e = x.current;
|
|
73
|
+
if (!(!e || !h)) return e.on("taga11y:clear", h), () => e.off("taga11y:clear", h);
|
|
74
|
+
}, [h]), t(() => {
|
|
75
|
+
let e = x.current;
|
|
76
|
+
if (!(!e || !_)) return e.on("taga11y:paste", _), () => e.off("taga11y:paste", _);
|
|
77
|
+
}, [_]), /* @__PURE__ */ a("input", {
|
|
78
|
+
ref: S,
|
|
79
|
+
...w
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { l as Taga11yInput };
|
package/dist/taga11y.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={"a11y.tagAdded":`Tag added: {label}`,"a11y.tagRemoved":`Tag removed: {label}`,"a11y.tagsCleared":`Tags cleared`,"a11y.noResults":`No results`,"a11y.resultsCount":{one:`{n} result available`,other:`{n} results available`},"a11y.tagsSummary":{one:`{n} tag selected: {labels}`,other:`{n} tags selected: {labels}`},"a11y.selectedTags":`Selected tags`,"a11y.removeTag":`Remove {label}`,"ui.loading":`Loading suggestions…`,"error.duplicate":`Already added: {label}`,"error.maxReached":`Maximum tags reached`,"error.notInList":`Not in the list`,"error.loadError":`Failed to load suggestions`},t=Object.keys(e);function n(n){if(!n)return{...e};let r={...e,...n},i=t.filter(e=>!(e in n));return i.length>0&&console.warn(`taga11y: i18n strings missing ${i.length} key(s), falling back to English: ${i.join(`, `)}`),r}function r(e){return typeof e==`object`&&!!e}function i(e,t){return t?e.replace(/\{(\w+)\}/g,(e,n)=>n in t?String(t[n]):e):e}function a(e,t,n,a){let o=e[n];return r(o)?a&&`n`in a?i(o[new Intl.PluralRules(t,{type:`cardinal`}).select(Number(a.n))]??o.other,a):i(o.other,a):i(o,a)}function o(e){return e.split(`-`)[0].toLowerCase()}function s(e,t,n){let r=document.documentElement.getAttribute(`lang`);(!r||o(r)!==o(t))&&e.setAttribute(`lang`,t),n&&e.setAttribute(`dir`,n)}function c(){let e=new Uint8Array(4);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function l(e){let t=e.id.trim();return t?`taga11y-${t}`:`taga11y-${c()}`}function u(e){return{base:e,label:`${e}-label`,listbox:`${e}-listbox`,option:t=>`${e}-option-${t}`,error:`${e}-error`,announcer:`${e}-announcer`}}function d(e){return typeof e==`string`?e:e.label}function f(e){return typeof e==`string`?e:e.value}function p(e,t){let n=t.toLowerCase();return e.filter(e=>d(e).toLowerCase().includes(n))}var m=class{constructor(e,t){this.tags=[],this.nextId=0,this.base=e,this.maxTags=t}addTag(e,t){if(this.maxTags!==void 0&&this.tags.length>=this.maxTags)return{ok:!1,reason:`max-reached`};if(this.tags.some(t=>t.value.toLowerCase()===e.toLowerCase()))return{ok:!1,reason:`duplicate`};let n=t??e,r={id:`${this.base}-tag-${this.nextId++}`,label:n,value:e};return this.tags.push(r),{ok:!0,tag:r}}removeTag(e){let t=this.tags.findIndex(t=>t.id===e);if(t===-1)return null;let[n]=this.tags.splice(t,1);return n??null}clearTags(){let e=[...this.tags];return this.tags=[],this.nextId=0,e}getTags(){return[...this.tags]}addTags(e){let t=[];for(let n of e){let e=this.addTag(f(n),d(n));e.ok&&t.push(e.tag)}return t}setTags(e){return this.clearTags(),this.addTags(e)}isTagged(e){return this.tags.some(t=>t.value.toLowerCase()===e.toLowerCase())}setMaxTags(e){this.maxTags=e}};function h(e,t){let n,r=(...r)=>{n!==void 0&&clearTimeout(n),n=setTimeout(()=>{n=void 0,e(...r)},t)};return r.cancel=()=>{n!==void 0&&(clearTimeout(n),n=void 0)},r}function g(e){let t=document.createElement(`ul`);return t.className=`taga11y__listbox`,t.setAttribute(`role`,`listbox`),t.id=e.listbox,t.hidden=!0,t}function _(e,t,n){e.innerHTML=``,t.forEach((t,r)=>{let i=document.createElement(`li`);i.className=`taga11y__option`,i.setAttribute(`role`,`option`),i.id=n.option(r),i.setAttribute(`aria-selected`,`false`),i.textContent=d(t),e.appendChild(i)})}function v(e,t,n,r,i,a){if(e.querySelectorAll(`.taga11y__option`).forEach(e=>e.remove()),n.removeAttribute(`aria-activedescendant`),i){t.hidden=!1;return}t.hidden=!0,_(e,r,a)}var y=class{constructor(e,t){if(this.isOpen=!1,this.activeIndex=-1,this.filteredSuggestions=[],this.isLoading=!1,this.cachedItems=null,this._isPrefetching=!1,this.abortController=null,this.debouncedQuery=null,this.listbox=e.listbox,this.input=e.input,this.loading=e.loading,this.wrapper=e.wrapper,this.ids=t.ids,this.strings=t.strings,this.locale=t.locale,this.maxSuggestions=t.maxSuggestions,this.source=t.suggestions,this.getSelectedValues=t.getSelectedValues,this.onAnnounce=t.onAnnounce??(()=>void 0),this.onLoadError=t.onLoadError??(()=>void 0),this.onOptionSelect=t.onOptionSelect,this.source&&`query`in this.source){let e=this.source;this.debouncedQuery=h(t=>{this.executeDynamicQuery(e,t)},t.debounceMs)}this.source&&`once`in this.source&&this.startPrefetch(this.source),this.resizeObserver=new ResizeObserver(()=>{}),this.resizeObserver.observe(this.wrapper),this.listbox.addEventListener(`mousedown`,e=>{let t=e.target.closest(`[role="option"]`);if(!t)return;e.preventDefault();let n=Array.from(this.listbox.querySelectorAll(`[role="option"]`)).indexOf(t);if(n===-1)return;let r=this.filteredSuggestions[n];r!==void 0&&this.onOptionSelect?.(r)})}async startPrefetch(e){this._isPrefetching=!0;try{this.cachedItems=await e.once(),this._isPrefetching=!1,this.isLoading&&(this.setLoading(!1),this.filter(this.input.value))}catch{this._isPrefetching=!1,this.isLoading&&this.setLoading(!1),this.onLoadError(a(this.strings,this.locale,`error.loadError`))}}async executeDynamicQuery(e,t){this.abortController?.abort(),this.abortController=new AbortController;let{signal:n}=this.abortController;this.setLoading(!0);try{let r=await e.query(t,n);if(n.aborted)return;let i=this.getSelectedValues(),o=p(r,t).filter(e=>!i.includes(f(e))).slice(0,this.maxSuggestions);this.filteredSuggestions=o,this.setLoading(!1),o.length===0?(this.close(),this.onAnnounce(a(this.strings,this.locale,`a11y.noResults`))):(v(this.listbox,this.loading,this.input,o,!1,this.ids),this.isOpen||this.open(),this.onAnnounce(a(this.strings,this.locale,`a11y.resultsCount`,{n:o.length})),this.highlightFirst())}catch(e){if(e instanceof Error&&e.name===`AbortError`)return;this.setLoading(!1),this.close(),this.onLoadError(a(this.strings,this.locale,`error.loadError`))}}open(){this.listbox.hidden=!1,this.input.setAttribute(`aria-expanded`,`true`),this.isOpen=!0}close(){this.debouncedQuery?.cancel(),this.abortController?.abort(),this.listbox.hidden=!0,this.input.setAttribute(`aria-expanded`,`false`),this.input.removeAttribute(`aria-activedescendant`),this.activeIndex=-1,this.loading.hidden=!0,this.isLoading=!1,this.isOpen=!1}toggle(){this.isOpen?this.close():this.open()}filter(e){if(!this.source)return;let t=e.trim();if(`query`in this.source){if(!t)return;this.debouncedQuery(t);return}if(`once`in this.source&&this.cachedItems===null&&this._isPrefetching){this.setLoading(!0);return}let n=`once`in this.source?this.cachedItems??[]:this.source,r=this.getSelectedValues(),i=p(n,t).filter(e=>!r.includes(f(e))).slice(0,this.maxSuggestions);this.filteredSuggestions=i,v(this.listbox,this.loading,this.input,i,!1,this.ids),i.length===0?(this.close(),this.onAnnounce(a(this.strings,this.locale,`a11y.noResults`))):(this.isOpen||this.open(),this.onAnnounce(a(this.strings,this.locale,`a11y.resultsCount`,{n:i.length})),this.highlightFirst())}setActiveIndex(e){let t=Array.from(this.listbox.querySelectorAll(`[role="option"]`));if(t.forEach(e=>e.setAttribute(`aria-selected`,`false`)),e<0||e>=t.length){this.activeIndex=-1,this.input.removeAttribute(`aria-activedescendant`);return}this.activeIndex=e;let n=t[e];n&&(n.setAttribute(`aria-selected`,`true`),this.input.setAttribute(`aria-activedescendant`,n.id))}highlightFirst(){this.setActiveIndex(0)}highlightPrev(){let e=this.filteredSuggestions.length;if(e===0)return;let t=this.activeIndex<=0?e-1:this.activeIndex-1;this.setActiveIndex(t)}highlightNext(){let e=this.filteredSuggestions.length;if(e===0)return;let t=this.activeIndex>=e-1?0:this.activeIndex+1;this.setActiveIndex(t)}highlightHome(){this.setActiveIndex(0)}highlightEnd(){this.setActiveIndex(this.filteredSuggestions.length-1)}selectActive(){return this.activeIndex<0?null:this.filteredSuggestions[this.activeIndex]??null}setLoading(e){this.isLoading=e,v(this.listbox,this.loading,this.input,this.filteredSuggestions,e,this.ids),e&&(this.isOpen||this.open(),this.onAnnounce(a(this.strings,this.locale,`ui.loading`)))}setSource(e,t){if(this.debouncedQuery?.cancel(),this.abortController?.abort(),this.abortController=null,this.cachedItems=null,this._isPrefetching=!1,this.source=e,e&&`query`in e){let n=e;this.debouncedQuery=h(e=>{this.executeDynamicQuery(n,e)},t)}else this.debouncedQuery=null;e&&`once`in e&&this.startPrefetch(e)}setDebounceMs(e){if(!this.source||!(`query`in this.source))return;let t=this.source;this.debouncedQuery?.cancel(),this.debouncedQuery=h(e=>{this.executeDynamicQuery(t,e)},e)}setMaxSuggestions(e){this.maxSuggestions=e}getAllSuggestions(){return this.source?Array.isArray(this.source)?this.source:`once`in this.source?this.cachedItems??[]:this.filteredSuggestions:[]}destroy(){this.debouncedQuery?.cancel(),this.abortController?.abort(),this.resizeObserver.disconnect()}},b=class{constructor(e,t){this.currentValue=``,this.input=e,this.onInput=t.onInput,this.onBlurCommit=t.onBlurCommit,this.onBlurClose=t.onBlurClose,this.onFocus=t.onFocus,this.getDelimiters=t.getDelimiters??(()=>[]),this.isEnforceSuggestions=t.isEnforceSuggestions??(()=>!1),this.getLoadedSuggestions=t.getLoadedSuggestions??(()=>[]),this.onCommit=t.onCommit??(()=>void 0),this.onCommitRejected=t.onCommitRejected??(()=>void 0),this.onPaste=t.onPaste??(()=>void 0),this.onCloseDropdown=t.onCloseDropdown??(()=>void 0),this.handleInput=()=>{this.currentValue=this.input.value;let e=this.getCharDelimiters();if(e.length>0&&this.containsAny(this.currentValue,e)){this.extractAndCommit(e);return}this.onInput(this.currentValue)},this.handleFocus=()=>{this.onFocus?.()},this.handleBlur=()=>{clearTimeout(this.blurTimer),this.blurTimer=setTimeout(()=>{this.currentValue&&this.onBlurCommit(this.currentValue),this.onBlurClose()},150)},this.handlePaste=e=>{let t=e.clipboardData?.getData(`text`)??``;if(!t)return;let n=this.getCharDelimiters();if(n.length===0||!this.containsAny(t,n))return;e.preventDefault();let r=RegExp(`[${x(n.join(``))}]`),i=t.split(r).map(e=>e.trim()).filter(e=>e!==``);this.input.value=``,this.currentValue=``,this.onPaste(i),this.onCloseDropdown()},this.input.addEventListener(`input`,this.handleInput),this.input.addEventListener(`focus`,this.handleFocus),this.input.addEventListener(`blur`,this.handleBlur),this.input.addEventListener(`paste`,this.handlePaste)}clearValue(){this.input.value=``,this.currentValue=``}getValue(){return this.currentValue}destroy(){clearTimeout(this.blurTimer),this.input.removeEventListener(`input`,this.handleInput),this.input.removeEventListener(`focus`,this.handleFocus),this.input.removeEventListener(`blur`,this.handleBlur),this.input.removeEventListener(`paste`,this.handlePaste)}getCharDelimiters(){return this.getDelimiters().filter(e=>e.length===1)}containsAny(e,t){for(let n of t)if(e.indexOf(n)!==-1)return!0;return!1}extractAndCommit(e){let t=this.currentValue,n=RegExp(`[${x(e.join(``))}]`),r=t.split(n).map(e=>e.trim()),i=r[r.length-1]??``,a=r.slice(0,-1).filter(e=>e!==``);for(let e of a)this.commitChunk(e);this.input.value=i,this.currentValue=i,i?this.onInput(i):this.onCloseDropdown()}commitChunk(e){if(this.isEnforceSuggestions()){let t=e.toLowerCase(),n=this.getLoadedSuggestions().find(e=>d(e).toLowerCase()===t);if(!n){this.onCommitRejected(e);return}this.onCommit(f(n))}else this.onCommit(e)}};function x(e){return e.replace(/[\\\]^-]/g,e=>`\\${e}`)}var S=class{constructor(e,t){this.input=e,this.onCommit=t.onCommit,this.onCommitRejected=t.onCommitRejected,this.onRemoveLast=t.onRemoveLast,this.clearInput=t.clearInput,this.hasChips=t.hasChips,this.getDropdown=t.getDropdown,this.getDelimiters=t.getDelimiters,this.isEnforceSuggestions=t.isEnforceSuggestions,this.getSuggestionSource=t.getSuggestionSource,this.getLoadedSuggestions=t.getLoadedSuggestions,this.handleKeydown=e=>this.routeKey(e),this.input.addEventListener(`keydown`,this.handleKeydown)}routeKey(e){let t=this.getDropdown(),n=this.getDelimiters();switch(e.key){case`ArrowDown`:e.preventDefault(),this.handleArrowDown(t);break;case`ArrowUp`:e.preventDefault(),this.handleArrowUp(t);break;case`Home`:t.isOpen&&(e.preventDefault(),t.highlightHome());break;case`End`:t.isOpen&&(e.preventDefault(),t.highlightEnd());break;case`Enter`:this.handleEnter(t,e);break;case`Escape`:t.isOpen&&(e.preventDefault(),t.close());break;case`Tab`:this.handleTab(t);break;case`Backspace`:this.handleBackspace(e);break;default:e.key!==`Enter`&&e.key!==`Tab`&&n.includes(e.key)&&this.input.value&&(e.preventDefault(),this.commit(this.input.value))}}handleArrowDown(e){if(e.isOpen){e.highlightNext();return}let t=this.getSuggestionSource(),n=!this.input.value;n&&t&&`query`in t||(n&&t&&e.filter(``),e.isOpen||e.open(),e.highlightFirst())}handleArrowUp(e){e.isOpen&&e.highlightPrev()}handleEnter(e,t){if(!e.isOpen){t.preventDefault(),this.input.value&&this.commit(this.input.value);return}t.preventDefault();let n=e.selectActive();n===null?(e.close(),this.input.value&&this.commit(this.input.value)):(e.close(),this.onCommit(f(n)),this.clearInput())}handleTab(e){this.getDelimiters().includes(`Tab`)&&this.input.value&&this.commit(this.input.value),e.close()}handleBackspace(e){this.input.value||this.hasChips()&&(e.preventDefault(),this.onRemoveLast())}commit(e){if(this.isEnforceSuggestions()){let t=e.toLowerCase(),n=this.getLoadedSuggestions().find(e=>d(e).toLowerCase()===t);if(!n){this.onCommitRejected(e);return}this.onCommit(f(n))}else this.onCommit(e);this.clearInput(),this.getDropdown().close()}destroy(){this.input.removeEventListener(`keydown`,this.handleKeydown)}};function C(){let e=document.createElement(`div`);return e.className=`taga11y__tags`,e}function w(e,t){let n=document.createElement(`ul`);return n.className=`taga11y__tag-list`,n.setAttribute(`aria-label`,a(e,t,`a11y.selectedTags`)),n}function T(e,t,n,r,i){let o=document.createElement(`li`);o.className=`taga11y__tag`,o.dataset.tagId=e.id;let s=document.createElement(`span`);s.className=`taga11y__tag-label`,s.textContent=e.label;let c=document.createElement(`button`);return c.className=`taga11y__tag-remove`,c.type=`button`,c.setAttribute(`aria-label`,a(n,r,`a11y.removeTag`,{label:e.label})),c.textContent=`×`,c.addEventListener(`click`,()=>{t(e.id),i?.()}),o.appendChild(s),o.appendChild(c),o}function E(e){let t=document.createElement(`li`);t.className=`taga11y__tag taga11y__tag--error`;let n=document.createElement(`span`);return n.className=`taga11y__tag-label`,n.textContent=e,t.appendChild(n),t}function D(e,t,n,r,i,a,o){Array.from(e.children).forEach(e=>e.remove());for(let a of t)e.appendChild(T(a,n,r,i,o));a&&e.appendChild(a)}function O(e,t){let n=document.createElement(`li`);n.className=`taga11y__loading`,n.setAttribute(`aria-hidden`,`true`),n.hidden=!0;let r=document.createElement(`span`);r.className=`taga11y__loading-spinner`;let i=document.createElement(`span`);return i.className=`taga11y__loading-text`,i.textContent=a(e,t,`ui.loading`),n.appendChild(r),n.appendChild(i),n}function k(e){let t=document.createElement(`div`);return t.className=`taga11y__error`,N()||t.setAttribute(`role`,`alert`),t.id=e.error,t.hidden=!0,t}function A(e){let t=document.createElement(`div`);return t.className=`taga11y__announcer`,t.setAttribute(`aria-live`,`polite`),t.setAttribute(`aria-atomic`,`true`),t.id=e.announcer,t}function j(e,t){e.id||=t.base,e.classList.add(`taga11y__input`),e.setAttribute(`role`,`combobox`),e.setAttribute(`aria-autocomplete`,`list`),e.setAttribute(`aria-haspopup`,`listbox`),e.setAttribute(`aria-expanded`,`false`),e.setAttribute(`aria-controls`,t.listbox),e.removeAttribute(`aria-activedescendant`),e.setAttribute(`autocomplete`,`off`),e.removeAttribute(`name`)}function M(e,t){let n=document.createElement(`input`);return n.type=`hidden`,n.className=`taga11y__hidden`,n.name=e,n.value=t,n}function N(){return typeof document.ariaNotify==`function`}function P(e,t,n=`normal`){if(N()){document.ariaNotify(t,{priority:n});return}e.textContent=``,setTimeout(()=>{e.textContent=t},0)}function F(e,t,n){let r=document.createElement(`div`);if(r.className=`taga11y`,n.label){let t=document.createElement(`label`);t.className=`taga11y__label`,t.htmlFor=e.id,t.textContent=n.label,r.appendChild(t)}let i=C(),a=w(n.strings,n.locale);i.appendChild(a),i.appendChild(e),r.appendChild(i);let o=g(t),s=O(n.strings,n.locale);o.appendChild(s),r.appendChild(o);let c=k(t);r.appendChild(c);let l=A(t);r.appendChild(l);let u=M(n.name,n.initialValue);return r.appendChild(u),{wrapper:r,tagsContainer:i,tagList:a,listbox:o,loading:s,error:c,announcer:l,hiddenInput:u}}function I(e,t,n){e.textContent=t,e.hidden=!1,N()&&P(e,t,`high`),setTimeout(()=>{L(e),n?.remove()},3e3)}function L(e){e.textContent=``,e.hidden=!0}function R(e,t,n,r){P(e,a(t,n,`a11y.tagAdded`,{label:r}))}function z(e,t,n,r){P(e,a(t,n,`a11y.tagRemoved`,{label:r}))}function B(e,t,n){P(e,a(t,n,`a11y.tagsCleared`))}function V(e,t,n,r){if(r.length===0)return;let i=new Intl.ListFormat(n,{type:`conjunction`,style:`long`}).format(r.map(e=>e.label));P(e,a(t,n,`a11y.tagsSummary`,{n:r.length,labels:i}))}function H(e,t,n,r,i,o){I(e,r===`duplicate`?a(t,n,`error.duplicate`,{label:i}):r===`max-reached`?a(t,n,`error.maxReached`):a(t,n,`error.notInList`),o)}function U(e){if(e==null)return null;if(e===`dark`||e===`light`)return e;throw TypeError(`taga11y: theme must be "dark", "light", or null — received "${e}"`)}var W=class{constructor(e,t={}){this._initialSnapshot=[],this._formResetHandler=null,this._input=e,this._originalName=e.name,this._originalId=e.id,this._originalValue=e.value,this._originalParent=e.parentNode,this._originalNextSibling=e.nextSibling,this._ids=u(l(e)),this._opts=this._parseOptions(t),this._strings=n(this._opts.i18n?.strings),this._locale=this._opts.i18n?.locale??`en`,this.init()}init(){this._initialSnapshot=this._opts.deserialize(this._input.value),this._input.value=``,this._input.defaultValue=``,j(this._input,this._ids),this._dom=F(this._input,this._ids,{...this._opts.label===void 0?{}:{label:this._opts.label},name:this._opts.name,initialValue:``,strings:this._strings,locale:this._locale}),this._opts.theme&&this._dom.wrapper.setAttribute(`data-theme`,this._opts.theme),this._opts.disabled&&(this._dom.wrapper.classList.add(`taga11y--disabled`),this._input.disabled=!0,this._dom.hiddenInput.disabled=!0),this._originalParent&&this._originalParent.insertBefore(this._dom.wrapper,this._originalNextSibling),this._opts.i18n&&s(this._dom.wrapper,this._opts.i18n.locale,this._opts.i18n.dir),this._selection=new m(this._ids.base,this._opts.maxTags),this._dropdown=new y({listbox:this._dom.listbox,input:this._input,loading:this._dom.loading,wrapper:this._dom.wrapper},{...this._opts.suggestions===void 0?{}:{suggestions:this._opts.suggestions},debounceMs:this._opts.debounceMs,maxSuggestions:this._opts.maxSuggestions,getSelectedValues:()=>this._selection.getTags().map(e=>e.value),ids:this._ids,strings:this._strings,locale:this._locale,onOptionSelect:e=>{this._dropdown.close(),this._handleCommit(f(e)),this._inputMgr.clearValue()},onAnnounce:e=>P(this._dom.announcer,e),onLoadError:e=>I(this._dom.error,e)}),this._inputMgr=new b(this._input,{onInput:e=>this._dropdown.filter(e),onBlurCommit:e=>this._handleBlurCommit(e),onBlurClose:()=>this._dropdown.close(),onFocus:()=>this._announceTagsSummary(),getDelimiters:()=>this._opts.delimiter,isEnforceSuggestions:()=>this._opts.enforceSuggestions,getLoadedSuggestions:()=>this._dropdown.getAllSuggestions(),onCommit:e=>this._handleCommit(e),onCommitRejected:e=>this._showRejection(e,`not-in-list`),onPaste:e=>this._handlePaste(e),onCloseDropdown:()=>this._dropdown.close()}),this._keyboard=new S(this._input,{onCommit:e=>this._handleCommit(e),onCommitRejected:e=>this._showRejection(e,`not-in-list`),onRemoveLast:()=>this._handleRemoveLast(),clearInput:()=>this._inputMgr.clearValue(),hasChips:()=>this._selection.getTags().length>0,getDropdown:()=>this._dropdown,getDelimiters:()=>this._opts.delimiter,isEnforceSuggestions:()=>this._opts.enforceSuggestions,getSuggestionSource:()=>this._opts.suggestions,getLoadedSuggestions:()=>this._dropdown.getAllSuggestions()});for(let e of this._initialSnapshot){let t=f(e),n=typeof e==`string`?this._resolveLabelFromAll(t):d(e);this._selection.addTag(t,n)}this._syncChips(),this._syncHiddenInput();let e=this._input.closest(`form`);e&&(this._formResetHandler=()=>this._handleFormReset(),e.addEventListener(`reset`,this._formResetHandler))}destroy(){this._keyboard.destroy(),this._inputMgr.destroy(),this._dropdown.destroy();let e=this._input.closest(`form`);e&&this._formResetHandler&&(e.removeEventListener(`reset`,this._formResetHandler),this._formResetHandler=null),this._originalParent&&this._originalParent.insertBefore(this._input,this._originalNextSibling),this._originalName&&this._input.setAttribute(`name`,this._originalName),this._originalId||this._input.removeAttribute(`id`),this._input.value=this._originalValue,this._input.defaultValue=this._originalValue,this._input.removeAttribute(`role`),this._input.removeAttribute(`aria-autocomplete`),this._input.removeAttribute(`aria-haspopup`),this._input.removeAttribute(`aria-expanded`),this._input.removeAttribute(`aria-controls`),this._input.removeAttribute(`aria-activedescendant`),this._input.disabled=!1,this._dom.wrapper.remove(),this.emit(`taga11y:destroy`,{})}addTag(e){let t=this._resolveLabelFromAll(e),n=this._selection.addTag(e,t);return n.ok?(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:add`,{tag:n.tag}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),R(this._dom.announcer,this._strings,this._locale,n.tag.label),!0):(this._showRejection(e,n.reason),!1)}removeTag(e){let t=this._selection.getTags().find(t=>t.value===e);if(!t)return null;let n=this._selection.removeTag(t.id);return n?(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:remove`,{tag:n}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),z(this._dom.announcer,this._strings,this._locale,n.label),this._input.focus(),n):null}clearTags(){let e=this._selection.clearTags();this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:clear`,{tags:e}),this.emit(`taga11y:change`,{tags:[]}),B(this._dom.announcer,this._strings,this._locale)}getTags(){return this._selection.getTags()}addTags(e){let t=!1;for(let n of e){let e=f(n),r=this._resolveLabelFromAll(e)||d(n),i=this._selection.addTag(e,r);i.ok&&(t=!0,this.emit(`taga11y:add`,{tag:i.tag}))}t&&(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:change`,{tags:this._selection.getTags()}))}setTags(e){let t=this._selection.clearTags();this.emit(`taga11y:clear`,{tags:t});for(let t of e){let e=f(t),n=this._resolveLabelFromAll(e)||d(t),r=this._selection.addTag(e,n);r.ok&&this.emit(`taga11y:add`,{tag:r.tag})}this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:change`,{tags:this._selection.getTags()})}isTagged(e){return this._selection.isTagged(e)}open(){this._opts.disabled||this._dropdown.isOpen||this._dropdown.open()}close(){this._dropdown.isOpen&&this._dropdown.close()}focus(){this._input.focus()}blur(){this._input.blur()}settings(e){if(`i18n`in e&&console.warn(`taga11y: i18n is init-only and cannot be changed via settings(); use destroy() + new Taga11y() to switch locale. Ignoring i18n; other provided keys are still applied.`),`disabled`in e){let t=e.disabled??!1;this._opts.disabled=t,this._input.disabled=t,this._dom.hiddenInput.disabled=t,this._dom.tagList.querySelectorAll(`.taga11y__tag-remove`).forEach(e=>{e.hidden=t}),this._dom.wrapper.classList.toggle(`taga11y--disabled`,t)}if(`theme`in e){let t=U(e.theme);this._opts.theme=t,t?this._dom.wrapper.setAttribute(`data-theme`,t):this._dom.wrapper.removeAttribute(`data-theme`)}if(`maxTags`in e&&(this._opts.maxTags=e.maxTags,this._selection.setMaxTags(e.maxTags)),`maxSuggestions`in e&&(this._opts.maxSuggestions=Math.max(0,e.maxSuggestions??10),this._dropdown.setMaxSuggestions(this._opts.maxSuggestions)),`delimiter`in e){let t=e.delimiter;this._opts.delimiter=Array.isArray(t)?t:t?[t]:[`,`,`Enter`]}if(`enforceSuggestions`in e&&(this._opts.enforceSuggestions=e.enforceSuggestions??!1),`label`in e){let t=e.label??null,n=this._dom.wrapper.querySelector(`.taga11y__label`);t==null?n?.remove():(n||(n=document.createElement(`label`),n.className=`taga11y__label`,n.htmlFor=this._input.id,this._dom.wrapper.insertBefore(n,this._dom.wrapper.firstChild)),n.textContent=t),this._opts.label=t??void 0}if(`suggestions`in e&&(this._opts.suggestions=e.suggestions,this._dropdown.setSource(e.suggestions,this._opts.debounceMs)),`debounceMs`in e&&(this._opts.debounceMs=Math.max(0,e.debounceMs??200),this._dropdown.setDebounceMs(this._opts.debounceMs)),`serialize`in e&&e.serialize&&(this._opts.serialize=e.serialize,this._syncHiddenInput()),`deserialize`in e&&e.deserialize&&(this._opts.deserialize=e.deserialize),`name`in e){let t=e.name??``;this._opts.name=t,this._dom.hiddenInput.name=t}}on(e,t){this._input.addEventListener(e,t)}off(e,t){this._input.removeEventListener(e,t)}emit(e,t){this._input.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!1}))}get tags(){return this._selection.getTags()}get isOpen(){return this._dropdown.isOpen}get maxTagsReached(){return this._opts.maxTags===void 0?!1:this._selection.getTags().length>=this._opts.maxTags}_parseOptions(e){if(e.suggestions&&!Array.isArray(e.suggestions)){let t=e.suggestions;if(`once`in t&&`query`in t)throw Error(`suggestions source cannot define both 'once' and 'query'`)}let t=e.delimiter;return{suggestions:e.suggestions,maxTags:e.maxTags,maxSuggestions:Math.max(0,e.maxSuggestions??10),delimiter:Array.isArray(t)?t:t?[t]:[`,`,`Enter`],enforceSuggestions:e.enforceSuggestions??!1,name:e.name??this._originalName,label:e.label,disabled:e.disabled??!1,theme:U(e.theme),serialize:e.serialize??(e=>e.map(e=>e.value).join(`,`)),deserialize:e.deserialize??(e=>e?e.split(`,`).map(e=>e.trim()).filter(Boolean):[]),debounceMs:Math.max(0,e.debounceMs??200),i18n:e.i18n}}_handleCommit(e){let t=this._resolveLabelFromAll(e),n=this._selection.addTag(e,t);n.ok?(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:add`,{tag:n.tag}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),R(this._dom.announcer,this._strings,this._locale,n.tag.label)):this._showRejection(e,n.reason)}_handlePaste(e){let t=[],n=[];for(let r of e){let e,i;if(this._opts.enforceSuggestions){let t=r.toLowerCase(),a=this._dropdown.getAllSuggestions().find(e=>d(e).toLowerCase()===t);if(!a){n.push(r);continue}e=f(a),i=d(a)}else e=r,i=r;let a=this._selection.addTag(e,i);a.ok?(t.push(a.tag),this.emit(`taga11y:add`,{tag:a.tag})):n.push(r)}t.length>0&&(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:change`,{tags:this._selection.getTags()})),this.emit(`taga11y:paste`,{added:t,skipped:n})}_handleBlurCommit(e){if(this._opts.enforceSuggestions){let t=e.toLowerCase(),n=this._dropdown.getAllSuggestions().find(e=>d(e).toLowerCase()===t);if(!n){this._showRejection(e,`not-in-list`),this._inputMgr.clearValue();return}let r=this._selection.addTag(f(n),d(n));r.ok?(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:add`,{tag:r.tag}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),R(this._dom.announcer,this._strings,this._locale,r.tag.label)):this._showRejection(e,r.reason)}else{let t=this._selection.addTag(e,e);t.ok?(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:add`,{tag:t.tag}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),R(this._dom.announcer,this._strings,this._locale,t.tag.label)):this._showRejection(e,t.reason)}this._inputMgr.clearValue()}_handleRemove(e){let t=this._selection.removeTag(e);t&&(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:remove`,{tag:t}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),z(this._dom.announcer,this._strings,this._locale,t.label))}_handleRemoveLast(){let e=this._selection.getTags();e.length!==0&&this._handleRemove(e[e.length-1].id)}_handleFormReset(){let e=this._selection.clearTags();this.emit(`taga11y:clear`,{tags:e});for(let e of this._initialSnapshot){let t=f(e),n=typeof e==`string`?this._resolveLabelFromAll(t):d(e),r=this._selection.addTag(t,n);r.ok&&this.emit(`taga11y:add`,{tag:r.tag})}this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:change`,{tags:this._selection.getTags()})}_showRejection(e,t){this._dom.tagList.querySelector(`.taga11y__tag--error`)?.remove();let n=E(e);this._dom.tagList.appendChild(n),H(this._dom.error,this._strings,this._locale,t,e,n)}_syncChips(){let e=this._dom.tagList.querySelector(`.taga11y__tag--error`)??void 0;D(this._dom.tagList,this._selection.getTags(),e=>this._handleRemove(e),this._strings,this._locale,e,()=>this._input.focus()),this._opts.disabled&&this._dom.tagList.querySelectorAll(`.taga11y__tag-remove`).forEach(e=>{e.hidden=!0})}_announceTagsSummary(){V(this._dom.announcer,this._strings,this._locale,this._selection.getTags())}_syncHiddenInput(){this._dom.hiddenInput.value=this._opts.serialize(this._selection.getTags())}_resolveLabelFromAll(e){let t=this._dropdown.getAllSuggestions().find(t=>f(t)===e);return t?d(t):e}};exports.Taga11y=W;
|
package/dist/taga11y.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
.taga11y,.taga11y *,.taga11y :before,.taga11y :after{box-sizing:border-box}.taga11y{--taga11y-color-bg:#fff;--taga11y-color-text:#000;--taga11y-color-border:#767676;--taga11y-color-border-focus:#0060df;--taga11y-color-tag-bg:#efefef;--taga11y-color-error-border:#c62828;--taga11y-color-tag-text:var(--taga11y-color-text,#000);--taga11y-color-tag-border:var(--taga11y-color-tag-text,#000);--taga11y-color-tag-remove-hover:var(--taga11y-color-border-focus,#0060df);--taga11y-color-suggestion-bg:var(--taga11y-color-bg,#fff);--taga11y-color-suggestion-active-bg:var(--taga11y-color-border-focus,#0060df);--taga11y-color-suggestion-active-text:var(--taga11y-color-bg,#fff);--taga11y-color-suggestion-border:var(--taga11y-color-border-focus,#0060df);--taga11y-color-error-bg:var(--taga11y-color-bg,#fff);--taga11y-color-error-text:var(--taga11y-color-text,#000);--taga11y-color-spinner:var(--taga11y-color-border-focus,#0060df);--taga11y-radius:2px;--taga11y-border-width:1px;--taga11y-outline-width:2px;--taga11y-shadow:none;--taga11y-font-family:inherit;--taga11y-font-size:1em;--taga11y-spacing:1px 2px;--taga11y-tag-padding-block:1px;--taga11y-tag-padding-inline:4px;--taga11y-tag-label-gap:2px;font-family:var(--taga11y-font-family);font-size:var(--taga11y-font-size);display:block;position:relative}@media (prefers-color-scheme:dark){.taga11y{--taga11y-color-bg:#000;--taga11y-color-text:#fff;--taga11y-color-border:#898989;--taga11y-color-border-focus:#5fb3f5;--taga11y-color-tag-bg:#101010;--taga11y-color-error-border:#ef9a9a}}.taga11y[data-theme=dark]{--taga11y-color-bg:#000;--taga11y-color-text:#fff;--taga11y-color-border:#898989;--taga11y-color-border-focus:#5fb3f5;--taga11y-color-tag-bg:#101010;--taga11y-color-error-border:#ef9a9a}.taga11y[data-theme=light]{--taga11y-color-bg:#fff;--taga11y-color-text:#000;--taga11y-color-border:#767676;--taga11y-color-border-focus:#0060df;--taga11y-color-tag-bg:#efefef;--taga11y-color-error-border:#c62828}.taga11y__label{color:var(--taga11y-color-text);font-size:var(--taga11y-font-size);font-family:var(--taga11y-font-family);margin-bottom:4px;display:block}.taga11y__tags{anchor-name:--taga11y-anchor;padding:var(--taga11y-spacing);background:var(--taga11y-color-bg);border:var(--taga11y-border-width) solid var(--taga11y-color-border);border-radius:var(--taga11y-radius);box-shadow:var(--taga11y-shadow);cursor:text;flex-wrap:wrap;align-items:center;gap:4px;display:flex}.taga11y__tags:focus-within{outline:var(--taga11y-outline-width) solid var(--taga11y-color-border-focus);outline-offset:calc(-1 * var(--taga11y-border-width))}.taga11y__tags:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){flex-direction:row-reverse}.taga11y__tag-list{margin:0;padding:0;list-style:none;display:contents}.taga11y__input{min-width:4ch;color:var(--taga11y-color-text);font-family:var(--taga11y-font-family);font-size:var(--taga11y-font-size);padding-block:var(--taga11y-tag-padding-block);background:0 0;border:none;outline:none;flex:4ch;padding-inline:0}.taga11y__listbox{z-index:100;background:var(--taga11y-color-suggestion-bg);border-width:var(--taga11y-outline-width);border-style:solid;border-color:var(--taga11y-color-suggestion-border);border-radius:var(--taga11y-radius);width:100%;max-height:240px;margin:0;padding:0;list-style:none;position:absolute;top:100%;left:0;overflow-y:auto;box-shadow:0 4px 8px #0000001f}@supports (anchor-name:--a) and (anchor-scope:--a){.taga11y{anchor-scope:--taga11y-anchor}.taga11y__listbox{position-anchor:--taga11y-anchor;top:anchor(bottom);left:anchor(left);width:anchor-size(width);position-try-fallbacks:flip-block;position:fixed}}.taga11y__option{padding:var(--taga11y-spacing);color:var(--taga11y-color-text);cursor:pointer;-webkit-user-select:none;user-select:none}@media (hover:hover){.taga11y__option:hover{background:var(--taga11y-color-suggestion-active-bg);color:var(--taga11y-color-suggestion-active-text)}}.taga11y__option:active,.taga11y__option[aria-selected=true]{background:var(--taga11y-color-suggestion-active-bg);color:var(--taga11y-color-suggestion-active-text)}.taga11y__tag{align-items:center;gap:var(--taga11y-tag-label-gap);padding:var(--taga11y-tag-padding-block) var(--taga11y-tag-padding-inline);background:var(--taga11y-color-tag-bg);color:var(--taga11y-color-tag-text);border-radius:var(--taga11y-radius);box-shadow:inset 0 0 0 1px var(--taga11y-color-tag-border);font-size:var(--taga11y-font-size);max-width:100%;display:inline-flex}.taga11y__tag:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){flex-direction:row-reverse}.taga11y__tag-label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.taga11y__tag-remove{cursor:pointer;color:inherit;font-size:var(--taga11y-font-size);border-radius:var(--taga11y-radius);background:0 0;border:none;justify-content:center;align-items:center;padding:0 2px;line-height:1;display:inline-flex;position:relative}.taga11y__tag-remove:before{content:"";min-width:24px;min-height:24px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.taga11y__tag-remove:hover{color:var(--taga11y-color-tag-remove-hover)}.taga11y__tag-remove:focus{outline:2px solid var(--taga11y-color-border-focus);outline-offset:1px}.taga11y__tag--error{background:var(--taga11y-color-error-bg);color:var(--taga11y-color-error-text);box-shadow:inset 0 0 0 1px var(--taga11y-color-error-border)}.taga11y__loading{padding:var(--taga11y-spacing);color:var(--taga11y-color-text);align-items:center;gap:6px;display:flex}.taga11y__loading[hidden]{display:none}.taga11y__loading-spinner{border:2px solid #0000;border-top-color:var(--taga11y-color-spinner);border-radius:50%;flex-shrink:0;width:1em;height:1em;animation:.7s linear infinite taga11y-spin;display:inline-block}@keyframes taga11y-spin{to{transform:rotate(360deg)}}.taga11y__loading-text{font-size:var(--taga11y-font-size)}.taga11y__error{color:var(--taga11y-color-error-text);border:var(--taga11y-border-width) solid var(--taga11y-color-error-border);border-radius:var(--taga11y-radius);background:var(--taga11y-color-error-bg);margin-top:2px;padding:2px 4px;font-size:.875em}.taga11y__announcer{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.taga11y__hidden{display:none}.taga11y--disabled{opacity:.5;cursor:not-allowed}.taga11y--disabled .taga11y__tags,.taga11y--disabled .taga11y__input{cursor:not-allowed;pointer-events:none}@media (prefers-reduced-motion:reduce){.taga11y__loading-spinner{border-top-color:#0000;border-color:var(--taga11y-color-spinner);animation:none}.taga11y__tag,.taga11y__error,.taga11y__listbox,.taga11y__option{transition:none;animation:none}}
|
|
2
|
+
/*$vite$:1*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var Taga11y=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t={"a11y.tagAdded":`Tag added: {label}`,"a11y.tagRemoved":`Tag removed: {label}`,"a11y.tagsCleared":`Tags cleared`,"a11y.noResults":`No results`,"a11y.resultsCount":{one:`{n} result available`,other:`{n} results available`},"a11y.tagsSummary":{one:`{n} tag selected: {labels}`,other:`{n} tags selected: {labels}`},"a11y.selectedTags":`Selected tags`,"a11y.removeTag":`Remove {label}`,"ui.loading":`Loading suggestions…`,"error.duplicate":`Already added: {label}`,"error.maxReached":`Maximum tags reached`,"error.notInList":`Not in the list`,"error.loadError":`Failed to load suggestions`},n=Object.keys(t);function r(e){if(!e)return{...t};let r={...t,...e},i=n.filter(t=>!(t in e));return i.length>0&&console.warn(`taga11y: i18n strings missing ${i.length} key(s), falling back to English: ${i.join(`, `)}`),r}function i(e){return typeof e==`object`&&!!e}function a(e,t){return t?e.replace(/\{(\w+)\}/g,(e,n)=>n in t?String(t[n]):e):e}function o(e,t,n,r){let o=e[n];return i(o)?r&&`n`in r?a(o[new Intl.PluralRules(t,{type:`cardinal`}).select(Number(r.n))]??o.other,r):a(o.other,r):a(o,r)}function s(e){return e.split(`-`)[0].toLowerCase()}function c(e,t,n){let r=document.documentElement.getAttribute(`lang`);(!r||s(r)!==s(t))&&e.setAttribute(`lang`,t),n&&e.setAttribute(`dir`,n)}function l(){let e=new Uint8Array(4);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function u(e){let t=e.id.trim();return t?`taga11y-${t}`:`taga11y-${l()}`}function d(e){return{base:e,label:`${e}-label`,listbox:`${e}-listbox`,option:t=>`${e}-option-${t}`,error:`${e}-error`,announcer:`${e}-announcer`}}function f(e){return typeof e==`string`?e:e.label}function p(e){return typeof e==`string`?e:e.value}function m(e,t){let n=t.toLowerCase();return e.filter(e=>f(e).toLowerCase().includes(n))}var h=class{constructor(e,t){this.tags=[],this.nextId=0,this.base=e,this.maxTags=t}addTag(e,t){if(this.maxTags!==void 0&&this.tags.length>=this.maxTags)return{ok:!1,reason:`max-reached`};if(this.tags.some(t=>t.value.toLowerCase()===e.toLowerCase()))return{ok:!1,reason:`duplicate`};let n=t??e,r={id:`${this.base}-tag-${this.nextId++}`,label:n,value:e};return this.tags.push(r),{ok:!0,tag:r}}removeTag(e){let t=this.tags.findIndex(t=>t.id===e);if(t===-1)return null;let[n]=this.tags.splice(t,1);return n??null}clearTags(){let e=[...this.tags];return this.tags=[],this.nextId=0,e}getTags(){return[...this.tags]}addTags(e){let t=[];for(let n of e){let e=this.addTag(p(n),f(n));e.ok&&t.push(e.tag)}return t}setTags(e){return this.clearTags(),this.addTags(e)}isTagged(e){return this.tags.some(t=>t.value.toLowerCase()===e.toLowerCase())}setMaxTags(e){this.maxTags=e}};function g(e,t){let n,r=(...r)=>{n!==void 0&&clearTimeout(n),n=setTimeout(()=>{n=void 0,e(...r)},t)};return r.cancel=()=>{n!==void 0&&(clearTimeout(n),n=void 0)},r}function _(e){let t=document.createElement(`ul`);return t.className=`taga11y__listbox`,t.setAttribute(`role`,`listbox`),t.id=e.listbox,t.hidden=!0,t}function v(e,t,n){e.innerHTML=``,t.forEach((t,r)=>{let i=document.createElement(`li`);i.className=`taga11y__option`,i.setAttribute(`role`,`option`),i.id=n.option(r),i.setAttribute(`aria-selected`,`false`),i.textContent=f(t),e.appendChild(i)})}function y(e,t,n,r,i,a){if(e.querySelectorAll(`.taga11y__option`).forEach(e=>e.remove()),n.removeAttribute(`aria-activedescendant`),i){t.hidden=!1;return}t.hidden=!0,v(e,r,a)}var b=class{constructor(e,t){if(this.isOpen=!1,this.activeIndex=-1,this.filteredSuggestions=[],this.isLoading=!1,this.cachedItems=null,this._isPrefetching=!1,this.abortController=null,this.debouncedQuery=null,this.listbox=e.listbox,this.input=e.input,this.loading=e.loading,this.wrapper=e.wrapper,this.ids=t.ids,this.strings=t.strings,this.locale=t.locale,this.maxSuggestions=t.maxSuggestions,this.source=t.suggestions,this.getSelectedValues=t.getSelectedValues,this.onAnnounce=t.onAnnounce??(()=>void 0),this.onLoadError=t.onLoadError??(()=>void 0),this.onOptionSelect=t.onOptionSelect,this.source&&`query`in this.source){let e=this.source;this.debouncedQuery=g(t=>{this.executeDynamicQuery(e,t)},t.debounceMs)}this.source&&`once`in this.source&&this.startPrefetch(this.source),this.resizeObserver=new ResizeObserver(()=>{}),this.resizeObserver.observe(this.wrapper),this.listbox.addEventListener(`mousedown`,e=>{let t=e.target.closest(`[role="option"]`);if(!t)return;e.preventDefault();let n=Array.from(this.listbox.querySelectorAll(`[role="option"]`)).indexOf(t);if(n===-1)return;let r=this.filteredSuggestions[n];r!==void 0&&this.onOptionSelect?.(r)})}async startPrefetch(e){this._isPrefetching=!0;try{this.cachedItems=await e.once(),this._isPrefetching=!1,this.isLoading&&(this.setLoading(!1),this.filter(this.input.value))}catch{this._isPrefetching=!1,this.isLoading&&this.setLoading(!1),this.onLoadError(o(this.strings,this.locale,`error.loadError`))}}async executeDynamicQuery(e,t){this.abortController?.abort(),this.abortController=new AbortController;let{signal:n}=this.abortController;this.setLoading(!0);try{let r=await e.query(t,n);if(n.aborted)return;let i=this.getSelectedValues(),a=m(r,t).filter(e=>!i.includes(p(e))).slice(0,this.maxSuggestions);this.filteredSuggestions=a,this.setLoading(!1),a.length===0?(this.close(),this.onAnnounce(o(this.strings,this.locale,`a11y.noResults`))):(y(this.listbox,this.loading,this.input,a,!1,this.ids),this.isOpen||this.open(),this.onAnnounce(o(this.strings,this.locale,`a11y.resultsCount`,{n:a.length})),this.highlightFirst())}catch(e){if(e instanceof Error&&e.name===`AbortError`)return;this.setLoading(!1),this.close(),this.onLoadError(o(this.strings,this.locale,`error.loadError`))}}open(){this.listbox.hidden=!1,this.input.setAttribute(`aria-expanded`,`true`),this.isOpen=!0}close(){this.debouncedQuery?.cancel(),this.abortController?.abort(),this.listbox.hidden=!0,this.input.setAttribute(`aria-expanded`,`false`),this.input.removeAttribute(`aria-activedescendant`),this.activeIndex=-1,this.loading.hidden=!0,this.isLoading=!1,this.isOpen=!1}toggle(){this.isOpen?this.close():this.open()}filter(e){if(!this.source)return;let t=e.trim();if(`query`in this.source){if(!t)return;this.debouncedQuery(t);return}if(`once`in this.source&&this.cachedItems===null&&this._isPrefetching){this.setLoading(!0);return}let n=`once`in this.source?this.cachedItems??[]:this.source,r=this.getSelectedValues(),i=m(n,t).filter(e=>!r.includes(p(e))).slice(0,this.maxSuggestions);this.filteredSuggestions=i,y(this.listbox,this.loading,this.input,i,!1,this.ids),i.length===0?(this.close(),this.onAnnounce(o(this.strings,this.locale,`a11y.noResults`))):(this.isOpen||this.open(),this.onAnnounce(o(this.strings,this.locale,`a11y.resultsCount`,{n:i.length})),this.highlightFirst())}setActiveIndex(e){let t=Array.from(this.listbox.querySelectorAll(`[role="option"]`));if(t.forEach(e=>e.setAttribute(`aria-selected`,`false`)),e<0||e>=t.length){this.activeIndex=-1,this.input.removeAttribute(`aria-activedescendant`);return}this.activeIndex=e;let n=t[e];n&&(n.setAttribute(`aria-selected`,`true`),this.input.setAttribute(`aria-activedescendant`,n.id))}highlightFirst(){this.setActiveIndex(0)}highlightPrev(){let e=this.filteredSuggestions.length;if(e===0)return;let t=this.activeIndex<=0?e-1:this.activeIndex-1;this.setActiveIndex(t)}highlightNext(){let e=this.filteredSuggestions.length;if(e===0)return;let t=this.activeIndex>=e-1?0:this.activeIndex+1;this.setActiveIndex(t)}highlightHome(){this.setActiveIndex(0)}highlightEnd(){this.setActiveIndex(this.filteredSuggestions.length-1)}selectActive(){return this.activeIndex<0?null:this.filteredSuggestions[this.activeIndex]??null}setLoading(e){this.isLoading=e,y(this.listbox,this.loading,this.input,this.filteredSuggestions,e,this.ids),e&&(this.isOpen||this.open(),this.onAnnounce(o(this.strings,this.locale,`ui.loading`)))}setSource(e,t){if(this.debouncedQuery?.cancel(),this.abortController?.abort(),this.abortController=null,this.cachedItems=null,this._isPrefetching=!1,this.source=e,e&&`query`in e){let n=e;this.debouncedQuery=g(e=>{this.executeDynamicQuery(n,e)},t)}else this.debouncedQuery=null;e&&`once`in e&&this.startPrefetch(e)}setDebounceMs(e){if(!this.source||!(`query`in this.source))return;let t=this.source;this.debouncedQuery?.cancel(),this.debouncedQuery=g(e=>{this.executeDynamicQuery(t,e)},e)}setMaxSuggestions(e){this.maxSuggestions=e}getAllSuggestions(){return this.source?Array.isArray(this.source)?this.source:`once`in this.source?this.cachedItems??[]:this.filteredSuggestions:[]}destroy(){this.debouncedQuery?.cancel(),this.abortController?.abort(),this.resizeObserver.disconnect()}},x=class{constructor(e,t){this.currentValue=``,this.input=e,this.onInput=t.onInput,this.onBlurCommit=t.onBlurCommit,this.onBlurClose=t.onBlurClose,this.onFocus=t.onFocus,this.getDelimiters=t.getDelimiters??(()=>[]),this.isEnforceSuggestions=t.isEnforceSuggestions??(()=>!1),this.getLoadedSuggestions=t.getLoadedSuggestions??(()=>[]),this.onCommit=t.onCommit??(()=>void 0),this.onCommitRejected=t.onCommitRejected??(()=>void 0),this.onPaste=t.onPaste??(()=>void 0),this.onCloseDropdown=t.onCloseDropdown??(()=>void 0),this.handleInput=()=>{this.currentValue=this.input.value;let e=this.getCharDelimiters();if(e.length>0&&this.containsAny(this.currentValue,e)){this.extractAndCommit(e);return}this.onInput(this.currentValue)},this.handleFocus=()=>{this.onFocus?.()},this.handleBlur=()=>{clearTimeout(this.blurTimer),this.blurTimer=setTimeout(()=>{this.currentValue&&this.onBlurCommit(this.currentValue),this.onBlurClose()},150)},this.handlePaste=e=>{let t=e.clipboardData?.getData(`text`)??``;if(!t)return;let n=this.getCharDelimiters();if(n.length===0||!this.containsAny(t,n))return;e.preventDefault();let r=RegExp(`[${S(n.join(``))}]`),i=t.split(r).map(e=>e.trim()).filter(e=>e!==``);this.input.value=``,this.currentValue=``,this.onPaste(i),this.onCloseDropdown()},this.input.addEventListener(`input`,this.handleInput),this.input.addEventListener(`focus`,this.handleFocus),this.input.addEventListener(`blur`,this.handleBlur),this.input.addEventListener(`paste`,this.handlePaste)}clearValue(){this.input.value=``,this.currentValue=``}getValue(){return this.currentValue}destroy(){clearTimeout(this.blurTimer),this.input.removeEventListener(`input`,this.handleInput),this.input.removeEventListener(`focus`,this.handleFocus),this.input.removeEventListener(`blur`,this.handleBlur),this.input.removeEventListener(`paste`,this.handlePaste)}getCharDelimiters(){return this.getDelimiters().filter(e=>e.length===1)}containsAny(e,t){for(let n of t)if(e.indexOf(n)!==-1)return!0;return!1}extractAndCommit(e){let t=this.currentValue,n=RegExp(`[${S(e.join(``))}]`),r=t.split(n).map(e=>e.trim()),i=r[r.length-1]??``,a=r.slice(0,-1).filter(e=>e!==``);for(let e of a)this.commitChunk(e);this.input.value=i,this.currentValue=i,i?this.onInput(i):this.onCloseDropdown()}commitChunk(e){if(this.isEnforceSuggestions()){let t=e.toLowerCase(),n=this.getLoadedSuggestions().find(e=>f(e).toLowerCase()===t);if(!n){this.onCommitRejected(e);return}this.onCommit(p(n))}else this.onCommit(e)}};function S(e){return e.replace(/[\\\]^-]/g,e=>`\\${e}`)}var C=class{constructor(e,t){this.input=e,this.onCommit=t.onCommit,this.onCommitRejected=t.onCommitRejected,this.onRemoveLast=t.onRemoveLast,this.clearInput=t.clearInput,this.hasChips=t.hasChips,this.getDropdown=t.getDropdown,this.getDelimiters=t.getDelimiters,this.isEnforceSuggestions=t.isEnforceSuggestions,this.getSuggestionSource=t.getSuggestionSource,this.getLoadedSuggestions=t.getLoadedSuggestions,this.handleKeydown=e=>this.routeKey(e),this.input.addEventListener(`keydown`,this.handleKeydown)}routeKey(e){let t=this.getDropdown(),n=this.getDelimiters();switch(e.key){case`ArrowDown`:e.preventDefault(),this.handleArrowDown(t);break;case`ArrowUp`:e.preventDefault(),this.handleArrowUp(t);break;case`Home`:t.isOpen&&(e.preventDefault(),t.highlightHome());break;case`End`:t.isOpen&&(e.preventDefault(),t.highlightEnd());break;case`Enter`:this.handleEnter(t,e);break;case`Escape`:t.isOpen&&(e.preventDefault(),t.close());break;case`Tab`:this.handleTab(t);break;case`Backspace`:this.handleBackspace(e);break;default:e.key!==`Enter`&&e.key!==`Tab`&&n.includes(e.key)&&this.input.value&&(e.preventDefault(),this.commit(this.input.value))}}handleArrowDown(e){if(e.isOpen){e.highlightNext();return}let t=this.getSuggestionSource(),n=!this.input.value;n&&t&&`query`in t||(n&&t&&e.filter(``),e.isOpen||e.open(),e.highlightFirst())}handleArrowUp(e){e.isOpen&&e.highlightPrev()}handleEnter(e,t){if(!e.isOpen){t.preventDefault(),this.input.value&&this.commit(this.input.value);return}t.preventDefault();let n=e.selectActive();n===null?(e.close(),this.input.value&&this.commit(this.input.value)):(e.close(),this.onCommit(p(n)),this.clearInput())}handleTab(e){this.getDelimiters().includes(`Tab`)&&this.input.value&&this.commit(this.input.value),e.close()}handleBackspace(e){this.input.value||this.hasChips()&&(e.preventDefault(),this.onRemoveLast())}commit(e){if(this.isEnforceSuggestions()){let t=e.toLowerCase(),n=this.getLoadedSuggestions().find(e=>f(e).toLowerCase()===t);if(!n){this.onCommitRejected(e);return}this.onCommit(p(n))}else this.onCommit(e);this.clearInput(),this.getDropdown().close()}destroy(){this.input.removeEventListener(`keydown`,this.handleKeydown)}};function w(){let e=document.createElement(`div`);return e.className=`taga11y__tags`,e}function T(e,t){let n=document.createElement(`ul`);return n.className=`taga11y__tag-list`,n.setAttribute(`aria-label`,o(e,t,`a11y.selectedTags`)),n}function E(e,t,n,r,i){let a=document.createElement(`li`);a.className=`taga11y__tag`,a.dataset.tagId=e.id;let s=document.createElement(`span`);s.className=`taga11y__tag-label`,s.textContent=e.label;let c=document.createElement(`button`);return c.className=`taga11y__tag-remove`,c.type=`button`,c.setAttribute(`aria-label`,o(n,r,`a11y.removeTag`,{label:e.label})),c.textContent=`×`,c.addEventListener(`click`,()=>{t(e.id),i?.()}),a.appendChild(s),a.appendChild(c),a}function D(e){let t=document.createElement(`li`);t.className=`taga11y__tag taga11y__tag--error`;let n=document.createElement(`span`);return n.className=`taga11y__tag-label`,n.textContent=e,t.appendChild(n),t}function O(e,t,n,r,i,a,o){Array.from(e.children).forEach(e=>e.remove());for(let a of t)e.appendChild(E(a,n,r,i,o));a&&e.appendChild(a)}function k(e,t){let n=document.createElement(`li`);n.className=`taga11y__loading`,n.setAttribute(`aria-hidden`,`true`),n.hidden=!0;let r=document.createElement(`span`);r.className=`taga11y__loading-spinner`;let i=document.createElement(`span`);return i.className=`taga11y__loading-text`,i.textContent=o(e,t,`ui.loading`),n.appendChild(r),n.appendChild(i),n}function A(e){let t=document.createElement(`div`);return t.className=`taga11y__error`,P()||t.setAttribute(`role`,`alert`),t.id=e.error,t.hidden=!0,t}function j(e){let t=document.createElement(`div`);return t.className=`taga11y__announcer`,t.setAttribute(`aria-live`,`polite`),t.setAttribute(`aria-atomic`,`true`),t.id=e.announcer,t}function M(e,t){e.id||=t.base,e.classList.add(`taga11y__input`),e.setAttribute(`role`,`combobox`),e.setAttribute(`aria-autocomplete`,`list`),e.setAttribute(`aria-haspopup`,`listbox`),e.setAttribute(`aria-expanded`,`false`),e.setAttribute(`aria-controls`,t.listbox),e.removeAttribute(`aria-activedescendant`),e.setAttribute(`autocomplete`,`off`),e.removeAttribute(`name`)}function N(e,t){let n=document.createElement(`input`);return n.type=`hidden`,n.className=`taga11y__hidden`,n.name=e,n.value=t,n}function P(){return typeof document.ariaNotify==`function`}function F(e,t,n=`normal`){if(P()){document.ariaNotify(t,{priority:n});return}e.textContent=``,setTimeout(()=>{e.textContent=t},0)}function I(e,t,n){let r=document.createElement(`div`);if(r.className=`taga11y`,n.label){let t=document.createElement(`label`);t.className=`taga11y__label`,t.htmlFor=e.id,t.textContent=n.label,r.appendChild(t)}let i=w(),a=T(n.strings,n.locale);i.appendChild(a),i.appendChild(e),r.appendChild(i);let o=_(t),s=k(n.strings,n.locale);o.appendChild(s),r.appendChild(o);let c=A(t);r.appendChild(c);let l=j(t);r.appendChild(l);let u=N(n.name,n.initialValue);return r.appendChild(u),{wrapper:r,tagsContainer:i,tagList:a,listbox:o,loading:s,error:c,announcer:l,hiddenInput:u}}function L(e,t,n){e.textContent=t,e.hidden=!1,P()&&F(e,t,`high`),setTimeout(()=>{R(e),n?.remove()},3e3)}function R(e){e.textContent=``,e.hidden=!0}function z(e,t,n,r){F(e,o(t,n,`a11y.tagAdded`,{label:r}))}function B(e,t,n,r){F(e,o(t,n,`a11y.tagRemoved`,{label:r}))}function V(e,t,n){F(e,o(t,n,`a11y.tagsCleared`))}function H(e,t,n,r){if(r.length===0)return;let i=new Intl.ListFormat(n,{type:`conjunction`,style:`long`}).format(r.map(e=>e.label));F(e,o(t,n,`a11y.tagsSummary`,{n:r.length,labels:i}))}function U(e,t,n,r,i,a){L(e,r===`duplicate`?o(t,n,`error.duplicate`,{label:i}):r===`max-reached`?o(t,n,`error.maxReached`):o(t,n,`error.notInList`),a)}function W(e){if(e==null)return null;if(e===`dark`||e===`light`)return e;throw TypeError(`taga11y: theme must be "dark", "light", or null — received "${e}"`)}return e.Taga11y=class{constructor(e,t={}){this._initialSnapshot=[],this._formResetHandler=null,this._input=e,this._originalName=e.name,this._originalId=e.id,this._originalValue=e.value,this._originalParent=e.parentNode,this._originalNextSibling=e.nextSibling,this._ids=d(u(e)),this._opts=this._parseOptions(t),this._strings=r(this._opts.i18n?.strings),this._locale=this._opts.i18n?.locale??`en`,this.init()}init(){this._initialSnapshot=this._opts.deserialize(this._input.value),this._input.value=``,this._input.defaultValue=``,M(this._input,this._ids),this._dom=I(this._input,this._ids,{...this._opts.label===void 0?{}:{label:this._opts.label},name:this._opts.name,initialValue:``,strings:this._strings,locale:this._locale}),this._opts.theme&&this._dom.wrapper.setAttribute(`data-theme`,this._opts.theme),this._opts.disabled&&(this._dom.wrapper.classList.add(`taga11y--disabled`),this._input.disabled=!0,this._dom.hiddenInput.disabled=!0),this._originalParent&&this._originalParent.insertBefore(this._dom.wrapper,this._originalNextSibling),this._opts.i18n&&c(this._dom.wrapper,this._opts.i18n.locale,this._opts.i18n.dir),this._selection=new h(this._ids.base,this._opts.maxTags),this._dropdown=new b({listbox:this._dom.listbox,input:this._input,loading:this._dom.loading,wrapper:this._dom.wrapper},{...this._opts.suggestions===void 0?{}:{suggestions:this._opts.suggestions},debounceMs:this._opts.debounceMs,maxSuggestions:this._opts.maxSuggestions,getSelectedValues:()=>this._selection.getTags().map(e=>e.value),ids:this._ids,strings:this._strings,locale:this._locale,onOptionSelect:e=>{this._dropdown.close(),this._handleCommit(p(e)),this._inputMgr.clearValue()},onAnnounce:e=>F(this._dom.announcer,e),onLoadError:e=>L(this._dom.error,e)}),this._inputMgr=new x(this._input,{onInput:e=>this._dropdown.filter(e),onBlurCommit:e=>this._handleBlurCommit(e),onBlurClose:()=>this._dropdown.close(),onFocus:()=>this._announceTagsSummary(),getDelimiters:()=>this._opts.delimiter,isEnforceSuggestions:()=>this._opts.enforceSuggestions,getLoadedSuggestions:()=>this._dropdown.getAllSuggestions(),onCommit:e=>this._handleCommit(e),onCommitRejected:e=>this._showRejection(e,`not-in-list`),onPaste:e=>this._handlePaste(e),onCloseDropdown:()=>this._dropdown.close()}),this._keyboard=new C(this._input,{onCommit:e=>this._handleCommit(e),onCommitRejected:e=>this._showRejection(e,`not-in-list`),onRemoveLast:()=>this._handleRemoveLast(),clearInput:()=>this._inputMgr.clearValue(),hasChips:()=>this._selection.getTags().length>0,getDropdown:()=>this._dropdown,getDelimiters:()=>this._opts.delimiter,isEnforceSuggestions:()=>this._opts.enforceSuggestions,getSuggestionSource:()=>this._opts.suggestions,getLoadedSuggestions:()=>this._dropdown.getAllSuggestions()});for(let e of this._initialSnapshot){let t=p(e),n=typeof e==`string`?this._resolveLabelFromAll(t):f(e);this._selection.addTag(t,n)}this._syncChips(),this._syncHiddenInput();let e=this._input.closest(`form`);e&&(this._formResetHandler=()=>this._handleFormReset(),e.addEventListener(`reset`,this._formResetHandler))}destroy(){this._keyboard.destroy(),this._inputMgr.destroy(),this._dropdown.destroy();let e=this._input.closest(`form`);e&&this._formResetHandler&&(e.removeEventListener(`reset`,this._formResetHandler),this._formResetHandler=null),this._originalParent&&this._originalParent.insertBefore(this._input,this._originalNextSibling),this._originalName&&this._input.setAttribute(`name`,this._originalName),this._originalId||this._input.removeAttribute(`id`),this._input.value=this._originalValue,this._input.defaultValue=this._originalValue,this._input.removeAttribute(`role`),this._input.removeAttribute(`aria-autocomplete`),this._input.removeAttribute(`aria-haspopup`),this._input.removeAttribute(`aria-expanded`),this._input.removeAttribute(`aria-controls`),this._input.removeAttribute(`aria-activedescendant`),this._input.disabled=!1,this._dom.wrapper.remove(),this.emit(`taga11y:destroy`,{})}addTag(e){let t=this._resolveLabelFromAll(e),n=this._selection.addTag(e,t);return n.ok?(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:add`,{tag:n.tag}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),z(this._dom.announcer,this._strings,this._locale,n.tag.label),!0):(this._showRejection(e,n.reason),!1)}removeTag(e){let t=this._selection.getTags().find(t=>t.value===e);if(!t)return null;let n=this._selection.removeTag(t.id);return n?(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:remove`,{tag:n}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),B(this._dom.announcer,this._strings,this._locale,n.label),this._input.focus(),n):null}clearTags(){let e=this._selection.clearTags();this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:clear`,{tags:e}),this.emit(`taga11y:change`,{tags:[]}),V(this._dom.announcer,this._strings,this._locale)}getTags(){return this._selection.getTags()}addTags(e){let t=!1;for(let n of e){let e=p(n),r=this._resolveLabelFromAll(e)||f(n),i=this._selection.addTag(e,r);i.ok&&(t=!0,this.emit(`taga11y:add`,{tag:i.tag}))}t&&(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:change`,{tags:this._selection.getTags()}))}setTags(e){let t=this._selection.clearTags();this.emit(`taga11y:clear`,{tags:t});for(let t of e){let e=p(t),n=this._resolveLabelFromAll(e)||f(t),r=this._selection.addTag(e,n);r.ok&&this.emit(`taga11y:add`,{tag:r.tag})}this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:change`,{tags:this._selection.getTags()})}isTagged(e){return this._selection.isTagged(e)}open(){this._opts.disabled||this._dropdown.isOpen||this._dropdown.open()}close(){this._dropdown.isOpen&&this._dropdown.close()}focus(){this._input.focus()}blur(){this._input.blur()}settings(e){if(`i18n`in e&&console.warn(`taga11y: i18n is init-only and cannot be changed via settings(); use destroy() + new Taga11y() to switch locale. Ignoring i18n; other provided keys are still applied.`),`disabled`in e){let t=e.disabled??!1;this._opts.disabled=t,this._input.disabled=t,this._dom.hiddenInput.disabled=t,this._dom.tagList.querySelectorAll(`.taga11y__tag-remove`).forEach(e=>{e.hidden=t}),this._dom.wrapper.classList.toggle(`taga11y--disabled`,t)}if(`theme`in e){let t=W(e.theme);this._opts.theme=t,t?this._dom.wrapper.setAttribute(`data-theme`,t):this._dom.wrapper.removeAttribute(`data-theme`)}if(`maxTags`in e&&(this._opts.maxTags=e.maxTags,this._selection.setMaxTags(e.maxTags)),`maxSuggestions`in e&&(this._opts.maxSuggestions=Math.max(0,e.maxSuggestions??10),this._dropdown.setMaxSuggestions(this._opts.maxSuggestions)),`delimiter`in e){let t=e.delimiter;this._opts.delimiter=Array.isArray(t)?t:t?[t]:[`,`,`Enter`]}if(`enforceSuggestions`in e&&(this._opts.enforceSuggestions=e.enforceSuggestions??!1),`label`in e){let t=e.label??null,n=this._dom.wrapper.querySelector(`.taga11y__label`);t==null?n?.remove():(n||(n=document.createElement(`label`),n.className=`taga11y__label`,n.htmlFor=this._input.id,this._dom.wrapper.insertBefore(n,this._dom.wrapper.firstChild)),n.textContent=t),this._opts.label=t??void 0}if(`suggestions`in e&&(this._opts.suggestions=e.suggestions,this._dropdown.setSource(e.suggestions,this._opts.debounceMs)),`debounceMs`in e&&(this._opts.debounceMs=Math.max(0,e.debounceMs??200),this._dropdown.setDebounceMs(this._opts.debounceMs)),`serialize`in e&&e.serialize&&(this._opts.serialize=e.serialize,this._syncHiddenInput()),`deserialize`in e&&e.deserialize&&(this._opts.deserialize=e.deserialize),`name`in e){let t=e.name??``;this._opts.name=t,this._dom.hiddenInput.name=t}}on(e,t){this._input.addEventListener(e,t)}off(e,t){this._input.removeEventListener(e,t)}emit(e,t){this._input.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!1}))}get tags(){return this._selection.getTags()}get isOpen(){return this._dropdown.isOpen}get maxTagsReached(){return this._opts.maxTags===void 0?!1:this._selection.getTags().length>=this._opts.maxTags}_parseOptions(e){if(e.suggestions&&!Array.isArray(e.suggestions)){let t=e.suggestions;if(`once`in t&&`query`in t)throw Error(`suggestions source cannot define both 'once' and 'query'`)}let t=e.delimiter;return{suggestions:e.suggestions,maxTags:e.maxTags,maxSuggestions:Math.max(0,e.maxSuggestions??10),delimiter:Array.isArray(t)?t:t?[t]:[`,`,`Enter`],enforceSuggestions:e.enforceSuggestions??!1,name:e.name??this._originalName,label:e.label,disabled:e.disabled??!1,theme:W(e.theme),serialize:e.serialize??(e=>e.map(e=>e.value).join(`,`)),deserialize:e.deserialize??(e=>e?e.split(`,`).map(e=>e.trim()).filter(Boolean):[]),debounceMs:Math.max(0,e.debounceMs??200),i18n:e.i18n}}_handleCommit(e){let t=this._resolveLabelFromAll(e),n=this._selection.addTag(e,t);n.ok?(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:add`,{tag:n.tag}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),z(this._dom.announcer,this._strings,this._locale,n.tag.label)):this._showRejection(e,n.reason)}_handlePaste(e){let t=[],n=[];for(let r of e){let e,i;if(this._opts.enforceSuggestions){let t=r.toLowerCase(),a=this._dropdown.getAllSuggestions().find(e=>f(e).toLowerCase()===t);if(!a){n.push(r);continue}e=p(a),i=f(a)}else e=r,i=r;let a=this._selection.addTag(e,i);a.ok?(t.push(a.tag),this.emit(`taga11y:add`,{tag:a.tag})):n.push(r)}t.length>0&&(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:change`,{tags:this._selection.getTags()})),this.emit(`taga11y:paste`,{added:t,skipped:n})}_handleBlurCommit(e){if(this._opts.enforceSuggestions){let t=e.toLowerCase(),n=this._dropdown.getAllSuggestions().find(e=>f(e).toLowerCase()===t);if(!n){this._showRejection(e,`not-in-list`),this._inputMgr.clearValue();return}let r=this._selection.addTag(p(n),f(n));r.ok?(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:add`,{tag:r.tag}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),z(this._dom.announcer,this._strings,this._locale,r.tag.label)):this._showRejection(e,r.reason)}else{let t=this._selection.addTag(e,e);t.ok?(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:add`,{tag:t.tag}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),z(this._dom.announcer,this._strings,this._locale,t.tag.label)):this._showRejection(e,t.reason)}this._inputMgr.clearValue()}_handleRemove(e){let t=this._selection.removeTag(e);t&&(this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:remove`,{tag:t}),this.emit(`taga11y:change`,{tags:this._selection.getTags()}),B(this._dom.announcer,this._strings,this._locale,t.label))}_handleRemoveLast(){let e=this._selection.getTags();e.length!==0&&this._handleRemove(e[e.length-1].id)}_handleFormReset(){let e=this._selection.clearTags();this.emit(`taga11y:clear`,{tags:e});for(let e of this._initialSnapshot){let t=p(e),n=typeof e==`string`?this._resolveLabelFromAll(t):f(e),r=this._selection.addTag(t,n);r.ok&&this.emit(`taga11y:add`,{tag:r.tag})}this._syncChips(),this._syncHiddenInput(),this.emit(`taga11y:change`,{tags:this._selection.getTags()})}_showRejection(e,t){this._dom.tagList.querySelector(`.taga11y__tag--error`)?.remove();let n=D(e);this._dom.tagList.appendChild(n),U(this._dom.error,this._strings,this._locale,t,e,n)}_syncChips(){let e=this._dom.tagList.querySelector(`.taga11y__tag--error`)??void 0;O(this._dom.tagList,this._selection.getTags(),e=>this._handleRemove(e),this._strings,this._locale,e,()=>this._input.focus()),this._opts.disabled&&this._dom.tagList.querySelectorAll(`.taga11y__tag-remove`).forEach(e=>{e.hidden=!0})}_announceTagsSummary(){H(this._dom.announcer,this._strings,this._locale,this._selection.getTags())}_syncHiddenInput(){this._dom.hiddenInput.value=this._opts.serialize(this._selection.getTags())}_resolveLabelFromAll(e){let t=this._dropdown.getAllSuggestions().find(t=>p(t)===e);return t?f(t):e}},e})({});
|