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.
Files changed (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +309 -0
  3. package/dist/a11y.d.ts +8 -0
  4. package/dist/a11y.d.ts.map +1 -0
  5. package/dist/core/dropdown.d.ts +63 -0
  6. package/dist/core/dropdown.d.ts.map +1 -0
  7. package/dist/core/input.d.ts +42 -0
  8. package/dist/core/input.d.ts.map +1 -0
  9. package/dist/core/keyboard.d.ts +37 -0
  10. package/dist/core/keyboard.d.ts.map +1 -0
  11. package/dist/core/selection.d.ts +24 -0
  12. package/dist/core/selection.d.ts.map +1 -0
  13. package/dist/dom/chips.d.ts +6 -0
  14. package/dist/dom/chips.d.ts.map +1 -0
  15. package/dist/dom/listbox.d.ts +5 -0
  16. package/dist/dom/listbox.d.ts.map +1 -0
  17. package/dist/dom/render.d.ts +24 -0
  18. package/dist/dom/render.d.ts.map +1 -0
  19. package/dist/i18n.d.ts +44 -0
  20. package/dist/i18n.d.ts.map +1 -0
  21. package/dist/index.d.ts +212 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/locales/ar.json +28 -0
  24. package/dist/locales/pt.json +21 -0
  25. package/dist/react/index.d.ts +46 -0
  26. package/dist/react/index.d.ts.map +1 -0
  27. package/dist/react.cjs +1 -0
  28. package/dist/react.mjs +83 -0
  29. package/dist/taga11y.cjs +1 -0
  30. package/dist/taga11y.css +2 -0
  31. package/dist/taga11y.iife.js +1 -0
  32. package/dist/taga11y.mjs +829 -0
  33. package/dist/types.d.ts +201 -0
  34. package/dist/types.d.ts.map +1 -0
  35. package/dist/utils/debounce.d.ts +5 -0
  36. package/dist/utils/debounce.d.ts.map +1 -0
  37. package/dist/utils/filter.d.ts +5 -0
  38. package/dist/utils/filter.d.ts.map +1 -0
  39. package/dist/utils/id.d.ts +11 -0
  40. package/dist/utils/id.d.ts.map +1 -0
  41. package/dist/vue/index.d.ts +155 -0
  42. package/dist/vue/index.d.ts.map +1 -0
  43. package/dist/vue.cjs +1 -0
  44. package/dist/vue.mjs +127 -0
  45. package/package.json +111 -0
  46. package/src/a11y.ts +85 -0
  47. package/src/aria-notify.d.ts +9 -0
  48. package/src/core/dropdown.ts +331 -0
  49. package/src/core/input.ts +172 -0
  50. package/src/core/keyboard.ts +200 -0
  51. package/src/core/selection.ts +78 -0
  52. package/src/dom/chips.ts +80 -0
  53. package/src/dom/listbox.ts +49 -0
  54. package/src/dom/render.ts +154 -0
  55. package/src/i18n.ts +131 -0
  56. package/src/index.ts +900 -0
  57. package/src/react/index.tsx +223 -0
  58. package/src/styles/index.css +367 -0
  59. package/src/types.ts +224 -0
  60. package/src/utils/debounce.ts +27 -0
  61. package/src/utils/filter.ts +14 -0
  62. package/src/utils/id.ts +30 -0
  63. package/src/vite-env.d.ts +1 -0
  64. package/src/vue/index.ts +145 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BinaryUnit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,309 @@
1
+ <div align="center">
2
+
3
+ # taga11y
4
+
5
+ [![npm version](https://img.shields.io/npm/v/taga11y.svg)](https://www.npmjs.com/package/taga11y)
6
+ [![minzipped size](https://img.shields.io/bundlephobia/minzip/taga11y)](https://bundlephobia.com/package/taga11y)
7
+ [![zero dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)](https://www.npmjs.com/package/taga11y)
8
+ [![license: MIT](https://img.shields.io/npm/l/taga11y)](./LICENSE)
9
+
10
+ ### Accessible tagging, built in — not bolted on.
11
+
12
+ A zero-dependency multi-select / tag input with inline chips, built to the
13
+ **WAI-ARIA APG combobox pattern** exactly — `aria-activedescendant` keeps focus
14
+ on the input throughout dropdown navigation. Keyboard, switch-device, and
15
+ screen-reader support aren't features here; they're the product.
16
+
17
+ Out of the box it renders as close to a **native form control** as it gets,
18
+ blending into any page untouched, yet it's fully customizable.
19
+
20
+ **~8 KB gzipped** &nbsp;·&nbsp; **zero dependencies** &nbsp;·&nbsp; **vanilla JS · React · Vue**
21
+
22
+ <sub><b>WAI-ARIA APG combobox</b> · SR matrix: NVDA · JAWS · VoiceOver · TalkBack · axe-core + Chromium/Firefox/WebKit e2e</sub>
23
+
24
+ ### **[➡️ Try the live demos & read the docs ⬅️](https://binaryunit.codeberg.page/taga11y/)**
25
+
26
+ </div>
27
+
28
+ ---
29
+
30
+ ## Features
31
+
32
+ - **Accessible by default** — full WAI-ARIA APG combobox pattern, screen reader announcements, keyboard and switch device support
33
+ - **Progressive enhancement** — the original `<input>` is enhanced in place and works as a form control without JavaScript
34
+ - **Three suggestion modes** — static arrays, pre-fetched async, and dynamic per-keystroke callbacks
35
+ - **Whitelist mode** — restrict to predefined suggestions with `enforceSuggestions: true`
36
+ - **Configurable** — delimiters, max tags, debounce, theming, custom serializers
37
+ - **Dark mode** — automatic (`prefers-color-scheme`) or forced (`data-theme`)
38
+ - **CSS custom properties** — retheme from ~6 base tokens; 9 derived tokens cascade automatically (per-token opt-out preserved)
39
+ - **Native form integration** — hidden input with serialised values, form reset support
40
+ - **Zero dependencies** — bundles to a single ESM/CJS/IIFE file via Vite
41
+
42
+ ## Installation
43
+
44
+ ### npm
45
+
46
+ ```sh
47
+ npm install taga11y
48
+ ```
49
+
50
+ Import the core class and the stylesheet:
51
+
52
+ ```js
53
+ import Taga11y from 'taga11y';
54
+ import 'taga11y/dist/taga11y.css';
55
+ ```
56
+
57
+ ### CDN / IIFE
58
+
59
+ ```html
60
+ <script src="https://unpkg.com/taga11y/dist/taga11y.iife.js"></script>
61
+ <link rel="stylesheet" href="https://unpkg.com/taga11y/dist/taga11y.css">
62
+
63
+ <script>
64
+ const widget = new Taga11y(inputEl, {
65
+ suggestions: ['JavaScript', 'TypeScript'],
66
+ });
67
+ </script>
68
+ ```
69
+
70
+ Also available on [jsDelivr](https://www.jsdelivr.com/), often faster in
71
+ Europe and Asia:
72
+
73
+ ```html
74
+ <script src="https://cdn.jsdelivr.net/npm/taga11y/dist/taga11y.iife.js"></script>
75
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/taga11y/dist/taga11y.css">
76
+ ```
77
+
78
+ ## Quick start
79
+
80
+ ```html
81
+ <label for="tags">Select tags:</label>
82
+ <input id="tags" type="text">
83
+ ```
84
+
85
+ ```js
86
+ const input = document.querySelector('#tags');
87
+ const widget = new Taga11y(input, {
88
+ suggestions: ['JavaScript', 'TypeScript', 'Rust', 'Go', 'Python'],
89
+ maxTags: 10,
90
+ delimiter: [',', 'Enter'],
91
+ });
92
+ ```
93
+
94
+ ## Framework wrappers
95
+
96
+ First-party React and Vue components are shipped from subpath exports. Both
97
+ wrap the same vanilla `Taga11y` class, support controlled and uncontrolled
98
+ binding, forward every event, expose the underlying instance, and mount
99
+ client-only (SSR-safe). Import the stylesheet once, as with the core.
100
+
101
+ > Peer dependencies: React 19 (`taga11y/react`) or Vue 3 (`taga11y/vue`).
102
+
103
+ ### React
104
+
105
+ ```tsx
106
+ import { useState } from 'react';
107
+ import { Taga11yInput } from 'taga11y/react';
108
+ import 'taga11y/dist/taga11y.css';
109
+
110
+ function Example() {
111
+ const [tags, setTags] = useState(['JavaScript']);
112
+ return (
113
+ <Taga11yInput
114
+ value={tags} // controlled; omit and use defaultValue for uncontrolled
115
+ onChange={(values) => setTags(values)}
116
+ suggestions={['JavaScript', 'TypeScript', 'Rust']}
117
+ maxTags={5}
118
+ />
119
+ );
120
+ }
121
+ ```
122
+
123
+ Props: every `Taga11yOptions` key, plus `value`/`defaultValue` (string arrays),
124
+ the event callbacks `onAdd`/`onRemove`/`onClear`/`onChange`/`onPaste`/`onDestroy`,
125
+ and `instanceRef` to receive the live `Taga11y` instance. A standard `ref`
126
+ resolves to the underlying `<input>` element (use `instanceRef` for the
127
+ instance). Unknown props pass through to the underlying `<input>`.
128
+
129
+ #### With react-hook-form
130
+
131
+ Because `onChange` is value-first and `ref` resolves to the `<input>`, the
132
+ component drops into a `<Controller>` via `{...field}`:
133
+
134
+ ```tsx
135
+ import { useForm, Controller } from 'react-hook-form';
136
+ import { Taga11yInput } from 'taga11y/react';
137
+
138
+ function TagsField() {
139
+ const { control } = useForm({ defaultValues: { tags: [] } });
140
+ return (
141
+ <Controller
142
+ name="tags"
143
+ control={control}
144
+ render={({ field }) => (
145
+ <Taga11yInput {...field} suggestions={['JavaScript', 'TypeScript', 'Rust']} />
146
+ )}
147
+ />
148
+ );
149
+ }
150
+ ```
151
+
152
+ `field.onChange` receives the tag array on every mutation, and `field.ref` gets
153
+ the input node so focus-on-validation-error works.
154
+
155
+ ### Vue
156
+
157
+ ```vue
158
+ <script setup>
159
+ import { ref } from 'vue';
160
+ import { Taga11yInput } from 'taga11y/vue';
161
+ import 'taga11y/dist/taga11y.css';
162
+
163
+ const tags = ref(['JavaScript']);
164
+ </script>
165
+
166
+ <template>
167
+ <Taga11yInput
168
+ v-model="tags"
169
+ :suggestions="['JavaScript', 'TypeScript', 'Rust']"
170
+ :max-tags="5"
171
+ />
172
+ </template>
173
+ ```
174
+
175
+ Use `v-model` (controlled) or `defaultValue` (uncontrolled). Emits `add`,
176
+ `remove`, `clear`, `change`, `paste`, `destroy`; the instance is available via a
177
+ template ref (`expose()`).
178
+
179
+ > **Notes** — `onDestroy`/`destroy` fire during unmount; your framework's own
180
+ > unmount hook is usually the better place for teardown. The `i18n` option is
181
+ > init-only: change it by remounting, not by updating the prop.
182
+
183
+ ## Configuration
184
+
185
+ All options are optional.
186
+
187
+ | Option | Type | Default | Description |
188
+ |---|---|---|---|
189
+ | `suggestions` | `SuggestionItem[] \| { once } \| { query }` | — | Suggestion source: static array, pre-fetched async (`{ once: () => Promise<SuggestionItem[]> }`), or dynamic per-keystroke (`{ query: (input, signal) => Promise<SuggestionItem[]> }`). Omit for free-text mode. |
190
+ | `maxTags` | `number` | — | Maximum number of tags. No limit when omitted. |
191
+ | `maxSuggestions` | `number` | `10` | Maximum suggestions rendered in the dropdown at once. `0` shows none; to show all matches pass a large number (e.g. `9999999`). Negative values are clamped to `0`. |
192
+ | `delimiter` | `string \| string[]` | `[',', 'Enter']` | Character(s) that commit the current input as a tag. `'Tab'` is a valid value. |
193
+ | `enforceSuggestions` | `boolean` | `false` | When `true`, only suggestions from the source can be committed. Free-text is rejected. |
194
+ | `name` | `string` | inherited from `input.name` | `name` on the hidden form input. The original input's `name` is removed on init (prevents double submission) and restored on `destroy()`. Override only when you need a different name. |
195
+ | `label` | `string` | — | Injects a `<label>` inside the widget wrapper. Only use when no page-level `<label for="…">` exists — existing page labels work automatically via the preserved `id`. Do not combine both. |
196
+ | `disabled` | `boolean` | `false` | Renders the component in a disabled state. |
197
+ | `theme` | `'dark' \| 'light' \| null` | `null` | Forces a colour scheme. `null` follows `prefers-color-scheme`. |
198
+ | `serialize` | `(tags: TagData[]) => string` | comma-join values | Custom serializer for the hidden input value. |
199
+ | `deserialize` | `(raw: string) => SuggestionItem[]` | split on `,`, trim, drop empties | Custom parser for the original input's `value` on init and on form reset. Pair with `serialize` to round-trip a non-comma format (e.g. JSON). String items resolve labels from loaded suggestions; `{ label, value }` items are used as-is. |
200
+ | `debounceMs` | `number` | `200` | Debounce delay (ms) for dynamic suggestion requests. Negative values are clamped to `0`. |
201
+ | `i18n` | `{ locale: string; dir?: 'ltr' \| 'rtl'; strings?: Partial<I18nStrings> }` | — | Internationalisation. `locale` is a BCP 47 tag; `dir` (optional) stamps direction on the wrapper, otherwise it cascades; `strings` partially overrides the built-in English map (missing keys fall back to English with a dev `console.warn`). **Init-only** — ignored by `settings()`; switch locale via `destroy()` + `new Taga11y()`. See the [i18n guide](docs/guides/i18n.md). |
202
+
203
+ ## Events
204
+
205
+ The widget dispatches custom events on the original `<input>` element. All events bubble, are non-cancelable, and carry a `detail` payload. Use `widget.on(name, handler)` or `inputEl.addEventListener(name, handler)`.
206
+
207
+ | Event | Detail | When fired |
208
+ |---|---|---|
209
+ | `taga11y:add` | `{ tag: TagData }` | After a single tag is added (typing, suggestion select, `addTag`, `addTags`, or each chunk of a delimited paste). |
210
+ | `taga11y:remove` | `{ tag: TagData }` | After a tag is removed (chip button, Backspace on empty input, or `removeTag`). |
211
+ | `taga11y:clear` | `{ tags: TagData[] }` | After all tags are cleared via `clearTags` or `setTags` (fired before the new tags are added). |
212
+ | `taga11y:change` | `{ tags: TagData[] }` | After any mutation, with the final tag set. Fired once per `addTags` / `setTags` / delimited paste, after all per-chunk `taga11y:add` events. |
213
+ | `taga11y:paste` | `{ added: TagData[], skipped: string[] }` | Once after a paste gesture that contained a configured single-character delimiter. `skipped` lists chunks rejected (not in suggestion list in whitelist mode, already selected, or `maxTags` reached). Not fired for paste without a delimiter. |
214
+ | `taga11y:destroy` | `{}` | After `destroy()` tears down the widget. |
215
+
216
+ See [docs/guides/events.md](docs/guides/events.md) for full per-event reference and examples.
217
+
218
+ ## API Docs
219
+
220
+ Full API documentation with all classes, methods, types, and options is generated by TypeDoc and available at [the API reference](https://binaryunit.codeberg.page/taga11y/api/).
221
+
222
+ - [Taga11y class](https://binaryunit.codeberg.page/taga11y/api/classes/Taga11y.html) — constructor, methods, computed getters
223
+ - [Types & interfaces](https://binaryunit.codeberg.page/taga11y/api/modules.html) — `TagData`, `Taga11yOptions`, `SuggestionsSource`, `SuggestionItem`
224
+
225
+ ## Bundle size
226
+
227
+ Tiny, zero-dependency, and tree-shakeable. Gzipped:
228
+
229
+ | Artifact | Gzipped |
230
+ |---|---|
231
+ | Core (`taga11y.mjs`) | ~8.0 KB |
232
+ | Stylesheet (`taga11y.css`) | ~1.6 KB |
233
+ | React wrapper (`taga11y/react`) | ~1.0 KB + core |
234
+ | Vue wrapper (`taga11y/vue`) | ~1.0 KB + core |
235
+
236
+ The framework wrappers import the core rather than duplicating it, so a React or
237
+ Vue app pays the wrapper cost once on top of the shared core.
238
+
239
+ ## Browser support
240
+
241
+ Modern evergreen browsers — the 2023+ baseline of **Chrome/Edge 120+,
242
+ Firefox 120+, and Safari 17+**. No Internet Explorer.
243
+
244
+ The baseline is set by the CSS `:dir()` pseudo-class (used for RTL layout);
245
+ below it, RTL layout falls back to LTR and every other feature still works.
246
+ taga11y also relies on `ResizeObserver`, `AbortController`/`AbortSignal`,
247
+ `Intl.PluralRules`, `crypto.getRandomValues`, and the CSS `inset` property —
248
+ all available across this baseline.
249
+
250
+ The dropdown's viewport-flip (opening upward when clipped below the fold) is a
251
+ **progressive enhancement** built on CSS Anchor Positioning (`anchor-name`,
252
+ `position-try-fallbacks`), currently Chromium 125+. It's gated behind
253
+ `@supports`, so browsers without anchor positioning simply keep the standard
254
+ absolute-positioned dropdown — no functionality is lost.
255
+
256
+ ## Guides
257
+
258
+ - [Theming](docs/guides/theming.md) — CSS custom properties, dark mode, custom themes
259
+ - [Accessibility](docs/guides/accessibility.md) — ARIA pattern, keyboard navigation, AT compatibility
260
+ - [Migration from Tagify / Choices.js](docs/guides/migration.md) — API mapping, DOM differences
261
+ - [Custom Events](docs/guides/events.md) — `taga11y:add`, `taga11y:remove`, `taga11y:clear`, `taga11y:change`, `taga11y:paste`, `taga11y:destroy`
262
+ - [Limitations](docs/guides/limitations.md) — Known limitations and design trade-offs
263
+
264
+ ## Contributing
265
+
266
+ Guides for contributors verifying and extending taga11y:
267
+
268
+ - [Testing](docs/guides/testing.md) — four-layer test strategy (unit, integration, screen reader, modality)
269
+ - [Screen Reader Verification](docs/guides/sr-verification.md) — AT pairing matrix and manual steps
270
+ - [Modality Checklist](docs/guides/modality-checklist.md) — keyboard, touch, voice, switch-device checklists
271
+ - [PR Accessibility Checklist](docs/guides/pr-a11y-checklist.md) — a11y review checklist for pull requests
272
+
273
+ ## Examples
274
+
275
+ See the `examples/` directory for runnable demos:
276
+
277
+ Run the examples locally:
278
+
279
+ ```sh
280
+ npm run dev
281
+ ```
282
+
283
+ - [Basic ESM](examples/basic-esm.html) — ES Module inclusion
284
+ - [Basic CJS](examples/basic-cjs.html) — CommonJS inclusion
285
+ - [Basic IIFE](examples/basic-iife.html) — Script tag inclusion
286
+ - [Whitelist mode](examples/whitelist.html)
287
+ - [Custom delimiter](examples/delimiter.html)
288
+ - [Dynamic suggestions (mock API)](examples/dynamic.html)
289
+ - [Fetch error demo](examples/error-fetch.html)
290
+ - [Pre-fetched suggestions](examples/prefetch.html)
291
+ - [Dropdown viewport flip](examples/viewport-flip.html)
292
+ - [Dark mode](examples/dark-mode.html)
293
+ - [Multiple themes on one page](examples/multi-theme.html)
294
+ - [Custom theme](examples/custom-theme.html)
295
+ - [Internationalisation — Portuguese + Arabic RTL](examples/i18n.html)
296
+ - [Disabled state](examples/disabled.html)
297
+ - [Form integration](examples/form.html)
298
+ - [Custom serializer & deserializer](examples/serialize.html)
299
+ - [Programmatic API](examples/programmatic.html)
300
+ - [Accessibility / keyboard demo](examples/a11y-demo.html)
301
+ - [All custom events demo](examples/events.html) — live event log for `taga11y:add`, `taga11y:remove`, `taga11y:clear`, `taga11y:change`, `taga11y:paste`, `taga11y:destroy`
302
+ - [Debug — keyboard & input event trace](examples/debug-events.html)
303
+ - [React — controlled (value / onChange)](examples/react.html)
304
+ - [react-hook-form — Controller integration](examples/react-hook-form.html)
305
+ - [Vue — controlled (v-model)](examples/vue.html)
306
+
307
+ ## License
308
+
309
+ [MIT](./LICENSE)
package/dist/a11y.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { I18nStrings, TagData } from './types.js';
2
+ export declare function showError(error: HTMLDivElement, message: string, errorChip?: HTMLElement): void;
3
+ export declare function announceTagAdded(announcer: HTMLDivElement, strings: I18nStrings, locale: string, label: string): void;
4
+ export declare function announceTagRemoved(announcer: HTMLDivElement, strings: I18nStrings, locale: string, label: string): void;
5
+ export declare function announceTagsCleared(announcer: HTMLDivElement, strings: I18nStrings, locale: string): void;
6
+ export declare function announceTagsSummary(announcer: HTMLDivElement, strings: I18nStrings, locale: string, tags: TagData[]): void;
7
+ export declare function announceRejection(error: HTMLDivElement, strings: I18nStrings, locale: string, reason: 'duplicate' | 'max-reached' | 'not-in-list', label: string, errorChip?: HTMLElement): void;
8
+ //# sourceMappingURL=a11y.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y.d.ts","sourceRoot":"","sources":["../src/a11y.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEvD,wBAAgB,SAAS,CACvB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,WAAW,GACtB,IAAI,CAWN;AAOD,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,IAAI,CAEN;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,IAAI,CAEN;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,GACb,IAAI,CAEN;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EAAE,GACd,IAAI,CAUN;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,aAAa,EACnD,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,WAAW,GACtB,IAAI,CAQN"}
@@ -0,0 +1,63 @@
1
+ import type { SuggestionItem, SuggestionsSource, I18nStrings } from '../types.js';
2
+ import type { DerivedIds } from '../utils/id.js';
3
+ export declare class DropdownManager {
4
+ private readonly listbox;
5
+ private readonly input;
6
+ private readonly loading;
7
+ private readonly wrapper;
8
+ private readonly ids;
9
+ private readonly strings;
10
+ private readonly locale;
11
+ private maxSuggestions;
12
+ private source;
13
+ private readonly getSelectedValues;
14
+ private readonly onAnnounce;
15
+ private readonly onLoadError;
16
+ private readonly onOptionSelect;
17
+ isOpen: boolean;
18
+ private activeIndex;
19
+ filteredSuggestions: SuggestionItem[];
20
+ private isLoading;
21
+ private cachedItems;
22
+ private _isPrefetching;
23
+ private abortController;
24
+ private debouncedQuery;
25
+ private readonly resizeObserver;
26
+ constructor(elements: {
27
+ listbox: HTMLUListElement;
28
+ input: HTMLInputElement;
29
+ loading: HTMLLIElement;
30
+ wrapper: HTMLElement;
31
+ }, options: {
32
+ suggestions?: SuggestionsSource;
33
+ debounceMs: number;
34
+ maxSuggestions: number;
35
+ getSelectedValues: () => string[];
36
+ ids: DerivedIds;
37
+ strings: I18nStrings;
38
+ locale: string;
39
+ onAnnounce?: (message: string) => void;
40
+ onLoadError?: (message: string) => void;
41
+ onOptionSelect?: (item: SuggestionItem) => void;
42
+ });
43
+ private startPrefetch;
44
+ private executeDynamicQuery;
45
+ open(): void;
46
+ close(): void;
47
+ toggle(): void;
48
+ filter(query: string): void;
49
+ setActiveIndex(index: number): void;
50
+ highlightFirst(): void;
51
+ highlightPrev(): void;
52
+ highlightNext(): void;
53
+ highlightHome(): void;
54
+ highlightEnd(): void;
55
+ selectActive(): SuggestionItem | null;
56
+ setLoading(value: boolean): void;
57
+ setSource(source: SuggestionsSource | undefined, debounceMs: number): void;
58
+ setDebounceMs(debounceMs: number): void;
59
+ setMaxSuggestions(maxSuggestions: number): void;
60
+ getAllSuggestions(): SuggestionItem[];
61
+ destroy(): void;
62
+ }
63
+ //# sourceMappingURL=dropdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dropdown.d.ts","sourceRoot":"","sources":["../../src/core/dropdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAMjD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAiB;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4B;IACxD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA+C;IAE9E,MAAM,UAAS;IACf,OAAO,CAAC,WAAW,CAAM;IACzB,mBAAmB,EAAE,cAAc,EAAE,CAAM;IAC3C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;gBAG9C,QAAQ,EAAE;QACR,OAAO,EAAE,gBAAgB,CAAC;QAC1B,KAAK,EAAE,gBAAgB,CAAC;QACxB,OAAO,EAAE,aAAa,CAAC;QACvB,OAAO,EAAE,WAAW,CAAC;KACtB,EACD,OAAO,EAAE;QACP,WAAW,CAAC,EAAE,iBAAiB,CAAC;QAChC,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,MAAM,EAAE,CAAC;QAClC,GAAG,EAAE,UAAU,CAAC;QAChB,OAAO,EAAE,WAAW,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;QACvC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;QACxC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;KACjD;YA6CW,aAAa;YAiBb,mBAAmB;IAyCjC,IAAI,IAAI,IAAI;IAMZ,KAAK,IAAI,IAAI;IAcb,MAAM,IAAI,IAAI;IAQd,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IA0C3B,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAmBnC,cAAc,IAAI,IAAI;IAItB,aAAa,IAAI,IAAI;IAOrB,aAAa,IAAI,IAAI;IAOrB,aAAa,IAAI,IAAI;IAIrB,YAAY,IAAI,IAAI;IAIpB,YAAY,IAAI,cAAc,GAAG,IAAI;IAKrC,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAShC,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAsB1E,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IASvC,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAK/C,iBAAiB,IAAI,cAAc,EAAE;IAOrC,OAAO,IAAI,IAAI;CAKhB"}
@@ -0,0 +1,42 @@
1
+ import type { SuggestionItem } from '../types.js';
2
+ export declare class InputManager {
3
+ private readonly input;
4
+ private readonly onInput;
5
+ private readonly onBlurCommit;
6
+ private readonly onBlurClose;
7
+ private readonly onFocus;
8
+ private readonly getDelimiters;
9
+ private readonly isEnforceSuggestions;
10
+ private readonly getLoadedSuggestions;
11
+ private readonly onCommit;
12
+ private readonly onCommitRejected;
13
+ private readonly onPaste;
14
+ private readonly onCloseDropdown;
15
+ private currentValue;
16
+ private blurTimer;
17
+ private readonly handleInput;
18
+ private readonly handleFocus;
19
+ private readonly handleBlur;
20
+ private readonly handlePaste;
21
+ constructor(input: HTMLInputElement, callbacks: {
22
+ onInput: (value: string) => void;
23
+ onBlurCommit: (value: string) => void;
24
+ onBlurClose: () => void;
25
+ onFocus?: () => void;
26
+ getDelimiters?: () => string[];
27
+ isEnforceSuggestions?: () => boolean;
28
+ getLoadedSuggestions?: () => SuggestionItem[];
29
+ onCommit?: (value: string) => void;
30
+ onCommitRejected?: (value: string) => void;
31
+ onPaste?: (chunks: string[]) => void;
32
+ onCloseDropdown?: () => void;
33
+ });
34
+ clearValue(): void;
35
+ getValue(): string;
36
+ destroy(): void;
37
+ private getCharDelimiters;
38
+ private containsAny;
39
+ private extractAndCommit;
40
+ private commitChunk;
41
+ }
42
+ //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/core/input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAgB;IACrD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAyB;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA0B;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAa;IAE7C,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,SAAS,CAA4C;IAE7D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;gBAGxD,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE;QACT,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QACjC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QACtC,WAAW,EAAE,MAAM,IAAI,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;QAC/B,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC;QACrC,oBAAoB,CAAC,EAAE,MAAM,cAAc,EAAE,CAAC;QAC9C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QACnC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QAC3C,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;QACrC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;KAC9B;IA2DH,UAAU,IAAI,IAAI;IAKlB,QAAQ,IAAI,MAAM;IAIlB,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,gBAAgB;IA0BxB,OAAO,CAAC,WAAW;CAepB"}
@@ -0,0 +1,37 @@
1
+ import type { SuggestionsSource, SuggestionItem } from '../types.js';
2
+ import type { DropdownManager } from './dropdown.js';
3
+ export declare class KeyboardManager {
4
+ private readonly input;
5
+ private readonly onCommit;
6
+ private readonly onCommitRejected;
7
+ private readonly onRemoveLast;
8
+ private readonly clearInput;
9
+ private readonly hasChips;
10
+ private readonly getDropdown;
11
+ private readonly getDelimiters;
12
+ private readonly isEnforceSuggestions;
13
+ private readonly getSuggestionSource;
14
+ private readonly getLoadedSuggestions;
15
+ private readonly handleKeydown;
16
+ constructor(input: HTMLInputElement, callbacks: {
17
+ onCommit: (value: string) => void;
18
+ onCommitRejected: (value: string) => void;
19
+ onRemoveLast: () => void;
20
+ clearInput: () => void;
21
+ hasChips: () => boolean;
22
+ getDropdown: () => DropdownManager;
23
+ getDelimiters: () => string[];
24
+ isEnforceSuggestions: () => boolean;
25
+ getSuggestionSource: () => SuggestionsSource | undefined;
26
+ getLoadedSuggestions: () => SuggestionItem[];
27
+ });
28
+ private routeKey;
29
+ private handleArrowDown;
30
+ private handleArrowUp;
31
+ private handleEnter;
32
+ private handleTab;
33
+ private handleBackspace;
34
+ private commit;
35
+ destroy(): void;
36
+ }
37
+ //# sourceMappingURL=keyboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../src/core/keyboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA0B;IAC3D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAgB;IACrD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsC;IAC1E,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAyB;IAE9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;gBAGzD,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE;QACT,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QAClC,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QAC1C,YAAY,EAAE,MAAM,IAAI,CAAC;QACzB,UAAU,EAAE,MAAM,IAAI,CAAC;QACvB,QAAQ,EAAE,MAAM,OAAO,CAAC;QACxB,WAAW,EAAE,MAAM,eAAe,CAAC;QACnC,aAAa,EAAE,MAAM,MAAM,EAAE,CAAC;QAC9B,oBAAoB,EAAE,MAAM,OAAO,CAAC;QACpC,mBAAmB,EAAE,MAAM,iBAAiB,GAAG,SAAS,CAAC;QACzD,oBAAoB,EAAE,MAAM,cAAc,EAAE,CAAC;KAC9C;IAkBH,OAAO,CAAC,QAAQ;IA4DhB,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,WAAW;IAuBnB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,MAAM;IAkBd,OAAO,IAAI,IAAI;CAGhB"}
@@ -0,0 +1,24 @@
1
+ import type { TagData, SuggestionItem } from '../types.js';
2
+ export type AddTagResult = {
3
+ ok: true;
4
+ tag: TagData;
5
+ } | {
6
+ ok: false;
7
+ reason: 'duplicate' | 'max-reached';
8
+ };
9
+ export declare class SelectionManager {
10
+ private tags;
11
+ private nextId;
12
+ private readonly base;
13
+ private maxTags;
14
+ constructor(base: string, maxTags?: number);
15
+ addTag(value: string, label?: string): AddTagResult;
16
+ removeTag(id: string): TagData | null;
17
+ clearTags(): TagData[];
18
+ getTags(): TagData[];
19
+ addTags(items: SuggestionItem[]): TagData[];
20
+ setTags(items: SuggestionItem[]): TagData[];
21
+ isTagged(value: string): boolean;
22
+ setMaxTags(maxTags: number | undefined): void;
23
+ }
24
+ //# sourceMappingURL=selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../src/core/selection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG3D,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,aAAa,CAAA;CAAE,CAAC;AAEvD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,OAAO,CAAqB;gBAExB,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAK1C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,YAAY;IAoBnD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAOrC,SAAS,IAAI,OAAO,EAAE;IAOtB,OAAO,IAAI,OAAO,EAAE;IAIpB,OAAO,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,OAAO,EAAE;IAS3C,OAAO,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,OAAO,EAAE;IAK3C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIhC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;CAG9C"}
@@ -0,0 +1,6 @@
1
+ import type { TagData, I18nStrings } from '../types.js';
2
+ export declare function createTagsContainer(): HTMLDivElement;
3
+ export declare function createTagList(strings: I18nStrings, locale: string): HTMLUListElement;
4
+ export declare function createErrorChip(text: string): HTMLLIElement;
5
+ export declare function updateChips(tagList: HTMLUListElement, tags: TagData[], onRemove: (id: string) => void, strings: I18nStrings, locale: string, errorChip?: HTMLLIElement, afterRemove?: () => void): void;
6
+ //# sourceMappingURL=chips.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chips.d.ts","sourceRoot":"","sources":["../../src/dom/chips.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGxD,wBAAgB,mBAAmB,IAAI,cAAc,CAIpD;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,GACb,gBAAgB,CAKlB;AAgCD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAU3D;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,OAAO,EAAE,EACf,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,EAC9B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,aAAa,EACzB,WAAW,CAAC,EAAE,MAAM,IAAI,GACvB,IAAI,CAUN"}
@@ -0,0 +1,5 @@
1
+ import type { SuggestionItem } from '../types.js';
2
+ import type { DerivedIds } from '../utils/id.js';
3
+ export declare function createListbox(ids: DerivedIds): HTMLUListElement;
4
+ export declare function updateListbox(listbox: HTMLUListElement, loading: HTMLLIElement, input: HTMLInputElement, items: SuggestionItem[], isLoading: boolean, ids: DerivedIds): void;
5
+ //# sourceMappingURL=listbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listbox.d.ts","sourceRoot":"","sources":["../../src/dom/listbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAO/D;AAmBD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,cAAc,EAAE,EACvB,SAAS,EAAE,OAAO,EAClB,GAAG,EAAE,UAAU,GACd,IAAI,CAWN"}
@@ -0,0 +1,24 @@
1
+ import type { DerivedIds } from '../utils/id.js';
2
+ import type { I18nStrings } from '../types.js';
3
+ export interface DomElements {
4
+ wrapper: HTMLDivElement;
5
+ tagsContainer: HTMLDivElement;
6
+ tagList: HTMLUListElement;
7
+ listbox: HTMLUListElement;
8
+ loading: HTMLLIElement;
9
+ error: HTMLDivElement;
10
+ announcer: HTMLDivElement;
11
+ hiddenInput: HTMLInputElement;
12
+ }
13
+ export declare function setupCombobox(input: HTMLInputElement, ids: DerivedIds): void;
14
+ export declare function createHiddenInput(name: string, initialValue: string): HTMLInputElement;
15
+ export declare function ariaNotifySupported(): boolean;
16
+ export declare function announce(region: HTMLDivElement, message: string, priority?: 'normal' | 'high'): void;
17
+ export declare function render(input: HTMLInputElement, ids: DerivedIds, opts: {
18
+ label?: string;
19
+ name: string;
20
+ initialValue: string;
21
+ strings: I18nStrings;
22
+ locale: string;
23
+ }): DomElements;
24
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/dom/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,CAAC;IACxB,aAAa,EAAE,cAAc,CAAC;IAC9B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,EAAE,cAAc,CAAC;IAC1B,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AA2CD,wBAAgB,aAAa,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAa5E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,gBAAgB,CAOtF;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED,wBAAgB,QAAQ,CACtB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,QAAQ,GAAG,MAAiB,GACrC,IAAI,CASN;AAED,wBAAgB,MAAM,CACpB,KAAK,EAAE,gBAAgB,EACvB,GAAG,EAAE,UAAU,EACf,IAAI,EAAE;IACJ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB,GACA,WAAW,CA0Cb"}
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ import type { I18nStrings, I18nKey } from './types.js';
2
+ /**
3
+ * Built-in English defaults. Eleven plain strings plus the plural-shaped
4
+ * `a11y.resultsCount`. These are the fallback for any key not supplied
5
+ * via the `i18n.strings` option.
6
+ */
7
+ export declare const EN: I18nStrings;
8
+ /**
9
+ * Merges a partial string map over the English defaults at the slot level
10
+ * (a supplied `a11y.resultsCount` wholly replaces the English default for
11
+ * that slot — there is no per-category merge). When `provided` is given,
12
+ * emits a single `console.warn` listing every key that fell back to
13
+ * English. The plural slot counts as satisfied when present (it must
14
+ * carry `other`); absent optional CLDR categories are not warned.
15
+ *
16
+ * @param provided - Partial overrides, or `undefined` for pure English.
17
+ */
18
+ export declare function resolveStrings(provided?: Partial<I18nStrings>): I18nStrings;
19
+ /**
20
+ * Resolves a string slot for the given locale and interpolation vars.
21
+ *
22
+ * For the plural-shaped slot, when `vars.n` is present the CLDR category
23
+ * is selected via `Intl.PluralRules(locale).select(Number(vars.n))`,
24
+ * falling back to the required `other` form if that category is absent.
25
+ * Plain-string slots ignore `locale` and resolve placeholders directly.
26
+ *
27
+ * @param strings - Resolved string map (post `resolveStrings`).
28
+ * @param locale - Active widget locale (BCP 47).
29
+ * @param key - Dot-key slot to resolve.
30
+ * @param vars - Optional `{placeholder}` substitutions.
31
+ */
32
+ export declare function t(strings: I18nStrings, locale: string, key: I18nKey, vars?: Record<string, string | number>): string;
33
+ /**
34
+ * Stamps `lang` on the wrapper when the widget locale differs from the
35
+ * document's primary language subtag (or the document has no `lang`).
36
+ * Stamps `dir` only when explicitly provided — direction otherwise
37
+ * cascades from the parent hierarchy.
38
+ *
39
+ * @param wrapper - The widget wrapper element (already in the DOM).
40
+ * @param locale - Active widget locale.
41
+ * @param dir - Explicit direction, or `undefined` to inherit.
42
+ */
43
+ export declare function applyLocale(wrapper: HTMLElement, locale: string, dir?: 'ltr' | 'rtl'): void;
44
+ //# sourceMappingURL=i18n.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAe,MAAM,YAAY,CAAC;AAEpE;;;;GAIG;AACH,eAAO,MAAM,EAAE,EAAE,WAoBhB,CAAC;AAIF;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAc3E;AAaD;;;;;;;;;;;;GAYG;AACH,wBAAgB,CAAC,CACf,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,OAAO,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACrC,MAAM,CAeR;AAOD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,GAClB,IAAI,CAQN"}