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
@@ -0,0 +1,201 @@
1
+ /**
2
+ * A single suggestion item. Can be a plain string (label equals value)
3
+ * or an object with a display `label` and a form `value`.
4
+ */
5
+ export type SuggestionItem = string | {
6
+ label: string;
7
+ value: string;
8
+ };
9
+ /**
10
+ * Static suggestion source — a plain array of suggestions evaluated once
11
+ * at initialisation and filtered in memory thereafter.
12
+ */
13
+ export type StaticSource = SuggestionItem[];
14
+ /**
15
+ * Pre-fetched suggestion source — a single async call that returns all
16
+ * suggestions upfront. Results are cached and filtered in memory for
17
+ * every subsequent filter cycle.
18
+ */
19
+ export type PrefetchSource = {
20
+ once: () => Promise<SuggestionItem[]>;
21
+ };
22
+ /**
23
+ * Dynamic suggestion source — an async callback invoked on every keystroke
24
+ * (debounced). Receives the current input text and an `AbortSignal` that
25
+ * fires when a newer request supersedes this one.
26
+ */
27
+ export type DynamicSource = {
28
+ query: (input: string, signal: AbortSignal) => Promise<SuggestionItem[]>;
29
+ };
30
+ /**
31
+ * The shape accepted by the `suggestions` option. One of:
32
+ * - `StaticSource` — plain array
33
+ * - `PrefetchSource` — `{ once }` object
34
+ * - `DynamicSource` — `{ query }` object
35
+ *
36
+ * Defining both `once` and `query` on the same object throws.
37
+ */
38
+ export type SuggestionsSource = StaticSource | PrefetchSource | DynamicSource;
39
+ /**
40
+ * A single selected tag as stored internally and emitted in event payloads.
41
+ */
42
+ export interface TagData {
43
+ /** Unique internal identifier (e.g. `"taga11y-tags-tag-0"`). */
44
+ id: string;
45
+ /** Human-readable label displayed in the chip. */
46
+ label: string;
47
+ /** Form value committed to the hidden input. */
48
+ value: string;
49
+ }
50
+ /**
51
+ * CLDR plural-forms value. `other` is always required (every locale has an
52
+ * `other` category; it is the universal fallback). The remaining categories
53
+ * are optional and fall back to `other` at resolution time.
54
+ */
55
+ export type PluralForms = {
56
+ other: string;
57
+ } & Partial<Record<'zero' | 'one' | 'two' | 'few' | 'many', string>>;
58
+ /**
59
+ * Typed map of every user-facing string slot. Eleven slots are plain
60
+ * strings; `a11y.resultsCount` and `a11y.tagsSummary` are
61
+ * {@link PluralForms} objects resolved per-locale via `Intl.PluralRules`.
62
+ * All values are plain JSON.
63
+ */
64
+ export interface I18nStrings {
65
+ 'a11y.tagAdded': string;
66
+ 'a11y.tagRemoved': string;
67
+ 'a11y.tagsCleared': string;
68
+ 'a11y.noResults': string;
69
+ 'a11y.resultsCount': PluralForms;
70
+ 'a11y.tagsSummary': PluralForms;
71
+ 'a11y.selectedTags': string;
72
+ 'a11y.removeTag': string;
73
+ 'ui.loading': string;
74
+ 'error.duplicate': string;
75
+ 'error.maxReached': string;
76
+ 'error.notInList': string;
77
+ 'error.loadError': string;
78
+ }
79
+ /** Dot-key identifying a single {@link I18nStrings} slot. */
80
+ export type I18nKey = keyof I18nStrings;
81
+ /**
82
+ * Internationalisation option. Init-only — not accepted by `settings()`.
83
+ * Runtime locale change requires `destroy()` + `new Taga11y()`.
84
+ */
85
+ export interface I18nOptions {
86
+ /** BCP 47 locale tag, e.g. `"pt"`, `"ar"`, `"pt-BR"`. */
87
+ locale: string;
88
+ /**
89
+ * Explicit text direction stamped on the wrapper. Omit to inherit
90
+ * direction from the parent cascade (the common case).
91
+ */
92
+ dir?: 'ltr' | 'rtl';
93
+ /**
94
+ * Partial override of the built-in English strings. Missing keys fall
95
+ * back to English; a supplied `a11y.resultsCount` wholly replaces the
96
+ * English default for that slot and must include `other`.
97
+ */
98
+ strings?: Partial<I18nStrings>;
99
+ }
100
+ export interface Taga11yOptions {
101
+ /**
102
+ * Suggestion source: static array, pre-fetched async, or dynamic callback.
103
+ * Omit for free-text mode with no suggestions.
104
+ */
105
+ suggestions?: SuggestionsSource;
106
+ /** Maximum number of tags the user can select. Undefined means no limit. */
107
+ maxTags?: number;
108
+ /**
109
+ * Maximum number of suggestions rendered in the dropdown at once.
110
+ * Defaults to 10. `0` shows no suggestions; to show all matches pass a
111
+ * large number (e.g. `9999999`). Negative values are clamped to 0.
112
+ * Live-updatable via `settings()`; a new value takes effect on the next
113
+ * filter and does not re-render an already-open dropdown.
114
+ */
115
+ maxSuggestions?: number;
116
+ /**
117
+ * Characters that trigger tag commit when typed. Defaults to `[, Enter]`.
118
+ * Accepts a single character/string or an array.
119
+ */
120
+ delimiter?: string | string[];
121
+ /**
122
+ * When true, only suggestions from the source can be committed.
123
+ * Free-text entry is rejected with an error.
124
+ */
125
+ enforceSuggestions?: boolean;
126
+ /**
127
+ * Name attribute for the hidden form input. Defaults to the original
128
+ * input's `name` attribute.
129
+ */
130
+ name?: string;
131
+ /** Optional visible label rendered above the component. */
132
+ label?: string;
133
+ /** When true, the component is rendered in a disabled state. */
134
+ disabled?: boolean;
135
+ /**
136
+ * Forced theme override. `null` (default) follows the OS preference.
137
+ * Use `"dark"` or `"light"` to override regardless of OS setting.
138
+ */
139
+ theme?: 'dark' | 'light' | null;
140
+ /**
141
+ * Custom serializer for the hidden input value. Receives the current
142
+ * tag array and returns a string. Defaults to comma-joining values.
143
+ */
144
+ serialize?: (tags: TagData[]) => string;
145
+ /**
146
+ * Custom deserializer for the original input's `value` on init and on
147
+ * form reset. Pairs with `serialize` to enable round-tripping a custom
148
+ * format. Returns the same `SuggestionItem` shape `suggestions` accepts:
149
+ * plain strings resolve labels from loaded suggestions (falling back to
150
+ * label === value); `{ label, value }` objects are used as-is. Defaults
151
+ * to splitting on `","`, trimming, and dropping empties.
152
+ */
153
+ deserialize?: (raw: string) => SuggestionItem[];
154
+ /**
155
+ * Debounce delay in milliseconds for dynamic suggestion requests.
156
+ * Default: 200. Only applies to dynamic (`{ query }`) mode.
157
+ */
158
+ debounceMs?: number;
159
+ /**
160
+ * Internationalisation: locale, optional direction, and partial string
161
+ * overrides. Init-only — ignored by `settings()`. Omit for built-in
162
+ * English with no `lang`/`dir` on the wrapper.
163
+ */
164
+ i18n?: I18nOptions;
165
+ }
166
+ /** Detail payload for the `taga11y:add` event. */
167
+ export interface Taga11yAddDetail {
168
+ tag: TagData;
169
+ }
170
+ /** Detail payload for the `taga11y:remove` event. */
171
+ export interface Taga11yRemoveDetail {
172
+ tag: TagData;
173
+ }
174
+ /** Detail payload for the `taga11y:clear` event — the tags that were cleared. */
175
+ export interface Taga11yClearDetail {
176
+ tags: TagData[];
177
+ }
178
+ /** Detail payload for the `taga11y:change` event — the current tag set. */
179
+ export interface Taga11yChangeDetail {
180
+ tags: TagData[];
181
+ }
182
+ /**
183
+ * Detail payload for the `taga11y:paste` event. `added` lists committed tags
184
+ * in commit order; `skipped` lists trimmed chunk strings that were rejected.
185
+ */
186
+ export interface Taga11yPasteDetail {
187
+ added: TagData[];
188
+ skipped: string[];
189
+ }
190
+ /** Detail payload for the `taga11y:destroy` event (no fields). */
191
+ export type Taga11yDestroyDetail = Record<string, never>;
192
+ /** Maps each taga11y custom event name to its `CustomEvent` detail type. */
193
+ export interface Taga11yEventMap {
194
+ 'taga11y:add': Taga11yAddDetail;
195
+ 'taga11y:remove': Taga11yRemoveDetail;
196
+ 'taga11y:clear': Taga11yClearDetail;
197
+ 'taga11y:change': Taga11yChangeDetail;
198
+ 'taga11y:paste': Taga11yPasteDetail;
199
+ 'taga11y:destroy': Taga11yDestroyDetail;
200
+ }
201
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export type DebouncedFn<T extends unknown[]> = ((...args: T) => void) & {
2
+ cancel: () => void;
3
+ };
4
+ export declare function debounce<T extends unknown[]>(fn: (...args: T) => void, ms: number): DebouncedFn<T>;
5
+ //# sourceMappingURL=debounce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../src/utils/debounce.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,OAAO,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG;IACtE,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,CAAC,SAAS,OAAO,EAAE,EAC1C,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,EACxB,EAAE,EAAE,MAAM,GACT,WAAW,CAAC,CAAC,CAAC,CAmBhB"}
@@ -0,0 +1,5 @@
1
+ import type { SuggestionItem } from '../types.js';
2
+ export declare function getLabel(item: SuggestionItem): string;
3
+ export declare function getValue(item: SuggestionItem): string;
4
+ export declare function filter(items: SuggestionItem[], query: string): SuggestionItem[];
5
+ //# sourceMappingURL=filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/utils/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAErD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAErD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAG/E"}
@@ -0,0 +1,11 @@
1
+ export declare function deriveBaseId(input: HTMLInputElement): string;
2
+ export interface DerivedIds {
3
+ base: string;
4
+ label: string;
5
+ listbox: string;
6
+ option: (n: number) => string;
7
+ error: string;
8
+ announcer: string;
9
+ }
10
+ export declare function buildIds(base: string): DerivedIds;
11
+ //# sourceMappingURL=id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAMA,wBAAgB,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAG5D;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CASjD"}
@@ -0,0 +1,155 @@
1
+ import { type PropType } from 'vue';
2
+ import { type Taga11yOptions, type SuggestionsSource, type SuggestionItem, type TagData } from 'taga11y';
3
+ /**
4
+ * Accessibility-first tagging input for Vue 3.
5
+ *
6
+ * A render-function component (no SFC) wrapping the vanilla {@link Taga11y}
7
+ * class. Supports `v-model` (controlled) and `defaultValue` (uncontrolled);
8
+ * emits every core event; exposes the instance via `expose()`. Mounts
9
+ * client-only so the document-touching constructor is SSR-safe.
10
+ */
11
+ export declare const Taga11yInput: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
12
+ /** Controlled tag values (v-model). When provided, the parent owns state. */
13
+ modelValue: {
14
+ type: PropType<string[]>;
15
+ default: undefined;
16
+ };
17
+ /** Uncontrolled initial tag values. */
18
+ defaultValue: {
19
+ type: PropType<string[]>;
20
+ default: undefined;
21
+ };
22
+ suggestions: {
23
+ type: PropType<SuggestionsSource>;
24
+ default: undefined;
25
+ };
26
+ maxTags: {
27
+ type: NumberConstructor;
28
+ default: undefined;
29
+ };
30
+ delimiter: {
31
+ type: PropType<string | string[]>;
32
+ default: undefined;
33
+ };
34
+ enforceSuggestions: {
35
+ type: BooleanConstructor;
36
+ default: undefined;
37
+ };
38
+ name: {
39
+ type: StringConstructor;
40
+ default: undefined;
41
+ };
42
+ label: {
43
+ type: StringConstructor;
44
+ default: undefined;
45
+ };
46
+ disabled: {
47
+ type: BooleanConstructor;
48
+ default: undefined;
49
+ };
50
+ theme: {
51
+ type: PropType<"dark" | "light" | null>;
52
+ default: undefined;
53
+ };
54
+ serialize: {
55
+ type: PropType<(tags: TagData[]) => string>;
56
+ default: undefined;
57
+ };
58
+ deserialize: {
59
+ type: PropType<(raw: string) => SuggestionItem[]>;
60
+ default: undefined;
61
+ };
62
+ debounceMs: {
63
+ type: NumberConstructor;
64
+ default: undefined;
65
+ };
66
+ i18n: {
67
+ type: PropType<Taga11yOptions["i18n"]>;
68
+ default: undefined;
69
+ };
70
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
71
+ [key: string]: any;
72
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("change" | "paste" | "remove" | "update:modelValue" | "add" | "clear" | "destroy")[], "change" | "paste" | "remove" | "update:modelValue" | "add" | "clear" | "destroy", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
73
+ /** Controlled tag values (v-model). When provided, the parent owns state. */
74
+ modelValue: {
75
+ type: PropType<string[]>;
76
+ default: undefined;
77
+ };
78
+ /** Uncontrolled initial tag values. */
79
+ defaultValue: {
80
+ type: PropType<string[]>;
81
+ default: undefined;
82
+ };
83
+ suggestions: {
84
+ type: PropType<SuggestionsSource>;
85
+ default: undefined;
86
+ };
87
+ maxTags: {
88
+ type: NumberConstructor;
89
+ default: undefined;
90
+ };
91
+ delimiter: {
92
+ type: PropType<string | string[]>;
93
+ default: undefined;
94
+ };
95
+ enforceSuggestions: {
96
+ type: BooleanConstructor;
97
+ default: undefined;
98
+ };
99
+ name: {
100
+ type: StringConstructor;
101
+ default: undefined;
102
+ };
103
+ label: {
104
+ type: StringConstructor;
105
+ default: undefined;
106
+ };
107
+ disabled: {
108
+ type: BooleanConstructor;
109
+ default: undefined;
110
+ };
111
+ theme: {
112
+ type: PropType<"dark" | "light" | null>;
113
+ default: undefined;
114
+ };
115
+ serialize: {
116
+ type: PropType<(tags: TagData[]) => string>;
117
+ default: undefined;
118
+ };
119
+ deserialize: {
120
+ type: PropType<(raw: string) => SuggestionItem[]>;
121
+ default: undefined;
122
+ };
123
+ debounceMs: {
124
+ type: NumberConstructor;
125
+ default: undefined;
126
+ };
127
+ i18n: {
128
+ type: PropType<Taga11yOptions["i18n"]>;
129
+ default: undefined;
130
+ };
131
+ }>> & Readonly<{
132
+ onChange?: (...args: any[]) => any;
133
+ onPaste?: (...args: any[]) => any;
134
+ onAdd?: (...args: any[]) => any;
135
+ onRemove?: (...args: any[]) => any;
136
+ onClear?: (...args: any[]) => any;
137
+ onDestroy?: (...args: any[]) => any;
138
+ "onUpdate:modelValue"?: (...args: any[]) => any;
139
+ }>, {
140
+ label: string;
141
+ name: string;
142
+ suggestions: SuggestionsSource;
143
+ i18n: import("taga11y").I18nOptions | undefined;
144
+ disabled: boolean;
145
+ maxTags: number;
146
+ delimiter: string | string[];
147
+ enforceSuggestions: boolean;
148
+ theme: "dark" | "light" | null;
149
+ serialize: (tags: TagData[]) => string;
150
+ deserialize: (raw: string) => SuggestionItem[];
151
+ debounceMs: number;
152
+ defaultValue: string[];
153
+ modelValue: string[];
154
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
155
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vue/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,QAAQ,EACd,MAAM,KAAK,CAAC;AACb,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,OAAO,EACb,MAAM,SAAS,CAAC;AAqBjB;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY;IAGrB,6EAA6E;;cAChD,QAAQ,CAAC,MAAM,EAAE,CAAC;;;IAC/C,uCAAuC;;cACR,QAAQ,CAAC,MAAM,EAAE,CAAC;;;;cACT,QAAQ,CAAC,iBAAiB,CAAC;;;;;;;;cAE7B,QAAQ,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;cAKxC,QAAQ,CAAC,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;;;;cAC3B,QAAQ,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC;;;;cAEhD,QAAQ,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,cAAc,EAAE,CAAC;;;;;;;;cAIvC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;;;;;;IAlBxD,6EAA6E;;cAChD,QAAQ,CAAC,MAAM,EAAE,CAAC;;;IAC/C,uCAAuC;;cACR,QAAQ,CAAC,MAAM,EAAE,CAAC;;;;cACT,QAAQ,CAAC,iBAAiB,CAAC;;;;;;;;cAE7B,QAAQ,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;cAKxC,QAAQ,CAAC,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;;;;cAC3B,QAAQ,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC;;;;cAEhD,QAAQ,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,cAAc,EAAE,CAAC;;;;;;;;cAIvC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;sBANT,OAAO,EAAE,KAAK,MAAM;uBAEhC,MAAM,KAAK,cAAc,EAAE;;;;4EAkFhE,CAAC"}
package/dist/vue.cjs ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`taga11y`),t=require(`vue`);var n=[`suggestions`,`maxTags`,`delimiter`,`enforceSuggestions`,`name`,`label`,`disabled`,`theme`,`serialize`,`deserialize`,`debounceMs`,`i18n`];function r(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}var i=(0,t.defineComponent)({name:`Taga11yInput`,props:{modelValue:{type:Array,default:void 0},defaultValue:{type:Array,default:void 0},suggestions:{type:[Array,Object],default:void 0},maxTags:{type:Number,default:void 0},delimiter:{type:[String,Array],default:void 0},enforceSuggestions:{type:Boolean,default:void 0},name:{type:String,default:void 0},label:{type:String,default:void 0},disabled:{type:Boolean,default:void 0},theme:{type:String,default:void 0},serialize:{type:Function,default:void 0},deserialize:{type:Function,default:void 0},debounceMs:{type:Number,default:void 0},i18n:{type:Object,default:void 0}},emits:[`update:modelValue`,`add`,`remove`,`clear`,`change`,`paste`,`destroy`],setup(i,{emit:a,expose:o}){let s=(0,t.ref)(null),c=(0,t.shallowRef)(null);function l(){let e={};for(let t of n){let n=i[t];n!==void 0&&(e[t]=n)}return e}(0,t.onMounted)(()=>{let t=s.value;if(!t)return;let n=new e.Taga11y(t,l());c.value=n;let r=i.modelValue??i.defaultValue;r&&r.length>0&&n.setTags(r),n.on(`taga11y:change`,e=>{a(`change`,e.detail),a(`update:modelValue`,e.detail.tags.map(e=>e.value))}),n.on(`taga11y:add`,e=>a(`add`,e.detail)),n.on(`taga11y:remove`,e=>a(`remove`,e.detail)),n.on(`taga11y:clear`,e=>a(`clear`,e.detail)),n.on(`taga11y:paste`,e=>a(`paste`,e.detail)),n.on(`taga11y:destroy`,e=>a(`destroy`,e.detail))}),(0,t.onBeforeUnmount)(()=>{c.value?.destroy(),c.value=null}),(0,t.watch)(()=>i.modelValue,e=>{let t=c.value;e===void 0||!t||r(t.getTags().map(e=>e.value),e)||t.setTags(e)});let u={};for(let e of n)u[e]=i[e];return(0,t.watch)(()=>n.map(e=>i[e]),()=>{let e=c.value;if(!e)return;let t={};for(let e of n)e!==`i18n`&&(i[e]!==u[e]&&(t[e]=i[e]),u[e]=i[e]);Object.keys(t).length>0&&e.settings(t)}),o({instance:c}),()=>(0,t.h)(`input`,{ref:s})}});exports.Taga11yInput=i;
package/dist/vue.mjs ADDED
@@ -0,0 +1,127 @@
1
+ import { Taga11y as e } from "taga11y";
2
+ import { defineComponent as t, h as n, onBeforeUnmount as r, onMounted as i, ref as a, shallowRef as o, watch as s } from "vue";
3
+ //#region src/vue/index.ts
4
+ var c = [
5
+ "suggestions",
6
+ "maxTags",
7
+ "delimiter",
8
+ "enforceSuggestions",
9
+ "name",
10
+ "label",
11
+ "disabled",
12
+ "theme",
13
+ "serialize",
14
+ "deserialize",
15
+ "debounceMs",
16
+ "i18n"
17
+ ];
18
+ function l(e, t) {
19
+ return e.length === t.length && e.every((e, n) => e === t[n]);
20
+ }
21
+ var u = t({
22
+ name: "Taga11yInput",
23
+ props: {
24
+ modelValue: {
25
+ type: Array,
26
+ default: void 0
27
+ },
28
+ defaultValue: {
29
+ type: Array,
30
+ default: void 0
31
+ },
32
+ suggestions: {
33
+ type: [Array, Object],
34
+ default: void 0
35
+ },
36
+ maxTags: {
37
+ type: Number,
38
+ default: void 0
39
+ },
40
+ delimiter: {
41
+ type: [String, Array],
42
+ default: void 0
43
+ },
44
+ enforceSuggestions: {
45
+ type: Boolean,
46
+ default: void 0
47
+ },
48
+ name: {
49
+ type: String,
50
+ default: void 0
51
+ },
52
+ label: {
53
+ type: String,
54
+ default: void 0
55
+ },
56
+ disabled: {
57
+ type: Boolean,
58
+ default: void 0
59
+ },
60
+ theme: {
61
+ type: String,
62
+ default: void 0
63
+ },
64
+ serialize: {
65
+ type: Function,
66
+ default: void 0
67
+ },
68
+ deserialize: {
69
+ type: Function,
70
+ default: void 0
71
+ },
72
+ debounceMs: {
73
+ type: Number,
74
+ default: void 0
75
+ },
76
+ i18n: {
77
+ type: Object,
78
+ default: void 0
79
+ }
80
+ },
81
+ emits: [
82
+ "update:modelValue",
83
+ "add",
84
+ "remove",
85
+ "clear",
86
+ "change",
87
+ "paste",
88
+ "destroy"
89
+ ],
90
+ setup(t, { emit: u, expose: d }) {
91
+ let f = a(null), p = o(null);
92
+ function m() {
93
+ let e = {};
94
+ for (let n of c) {
95
+ let r = t[n];
96
+ r !== void 0 && (e[n] = r);
97
+ }
98
+ return e;
99
+ }
100
+ i(() => {
101
+ let n = f.value;
102
+ if (!n) return;
103
+ let r = new e(n, m());
104
+ p.value = r;
105
+ let i = t.modelValue ?? t.defaultValue;
106
+ i && i.length > 0 && r.setTags(i), r.on("taga11y:change", (e) => {
107
+ u("change", e.detail), u("update:modelValue", e.detail.tags.map((e) => e.value));
108
+ }), r.on("taga11y:add", (e) => u("add", e.detail)), r.on("taga11y:remove", (e) => u("remove", e.detail)), r.on("taga11y:clear", (e) => u("clear", e.detail)), r.on("taga11y:paste", (e) => u("paste", e.detail)), r.on("taga11y:destroy", (e) => u("destroy", e.detail));
109
+ }), r(() => {
110
+ p.value?.destroy(), p.value = null;
111
+ }), s(() => t.modelValue, (e) => {
112
+ let t = p.value;
113
+ e === void 0 || !t || l(t.getTags().map((e) => e.value), e) || t.setTags(e);
114
+ });
115
+ let h = {};
116
+ for (let e of c) h[e] = t[e];
117
+ return s(() => c.map((e) => t[e]), () => {
118
+ let e = p.value;
119
+ if (!e) return;
120
+ let n = {};
121
+ for (let e of c) e !== "i18n" && (t[e] !== h[e] && (n[e] = t[e]), h[e] = t[e]);
122
+ Object.keys(n).length > 0 && e.settings(n);
123
+ }), d({ instance: p }), () => n("input", { ref: f });
124
+ }
125
+ });
126
+ //#endregion
127
+ export { u as Taga11yInput };
package/package.json ADDED
@@ -0,0 +1,111 @@
1
+ {
2
+ "name": "taga11y",
3
+ "version": "1.0.0",
4
+ "description": "Accessibility-first tagging library",
5
+ "type": "module",
6
+ "sideEffects": [
7
+ "**/*.css"
8
+ ],
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/taga11y.mjs",
12
+ "require": "./dist/taga11y.cjs",
13
+ "types": "./dist/index.d.ts"
14
+ },
15
+ "./react": {
16
+ "types": "./dist/react/index.d.ts",
17
+ "import": "./dist/react.mjs",
18
+ "require": "./dist/react.cjs"
19
+ },
20
+ "./vue": {
21
+ "types": "./dist/vue/index.d.ts",
22
+ "import": "./dist/vue.mjs",
23
+ "require": "./dist/vue.cjs"
24
+ },
25
+ "./dist/taga11y.css": "./dist/taga11y.css",
26
+ "./locales/*.json": "./dist/locales/*.json"
27
+ },
28
+ "main": "./dist/taga11y.cjs",
29
+ "module": "./dist/taga11y.mjs",
30
+ "types": "./dist/index.d.ts",
31
+ "files": [
32
+ "dist",
33
+ "src"
34
+ ],
35
+ "peerDependencies": {
36
+ "react": "^19",
37
+ "react-dom": "^19",
38
+ "vue": "^3"
39
+ },
40
+ "peerDependenciesMeta": {
41
+ "react": {
42
+ "optional": true
43
+ },
44
+ "react-dom": {
45
+ "optional": true
46
+ },
47
+ "vue": {
48
+ "optional": true
49
+ }
50
+ },
51
+ "scripts": {
52
+ "build": "vite build && vite build -c vite.config.wrappers.ts && tsc -p tsconfig.build.json",
53
+ "postbuild": "typedoc",
54
+ "build:examples": "vite build -c vite.config.examples.ts",
55
+ "dev": "npm run build:examples && (vite build --watch & vite serve examples)",
56
+ "test": "vitest",
57
+ "test:e2e": "playwright test",
58
+ "lint": "eslint src",
59
+ "docs": "typedoc"
60
+ },
61
+ "keywords": [
62
+ "accessibility",
63
+ "a11y",
64
+ "tags",
65
+ "tagging",
66
+ "combobox",
67
+ "aria",
68
+ "multiselect",
69
+ "wcag",
70
+ "screen-reader",
71
+ "chip",
72
+ "chip-input",
73
+ "tag-input",
74
+ "autocomplete"
75
+ ],
76
+ "author": "BinaryUnit",
77
+ "license": "MIT",
78
+ "homepage": "https://binaryunit.codeberg.page/taga11y/",
79
+ "repository": {
80
+ "type": "git",
81
+ "url": "https://codeberg.org/BinaryUnit/taga11y.git"
82
+ },
83
+ "bugs": {
84
+ "url": "https://codeberg.org/BinaryUnit/taga11y/issues"
85
+ },
86
+ "devDependencies": {
87
+ "@axe-core/playwright": "^4.11.3",
88
+ "@eslint/js": "^10.0.1",
89
+ "@playwright/test": "^1.60.0",
90
+ "@testing-library/react": "^16.3.2",
91
+ "@testing-library/vue": "^8.1.0",
92
+ "@types/react": "^19.2.17",
93
+ "@types/react-dom": "^19.2.3",
94
+ "@vitejs/plugin-react": "^6.0.3",
95
+ "@vitejs/plugin-vue": "^6.0.7",
96
+ "@vitest/coverage-v8": "^4.1.5",
97
+ "eslint": "^10.3.0",
98
+ "happy-dom": "^20.9.0",
99
+ "react": "^19.2.7",
100
+ "react-dom": "^19.2.7",
101
+ "react-hook-form": "^7.80.0",
102
+ "typedoc": "^0.28.19",
103
+ "typescript": "^6.0.3",
104
+ "typescript-eslint": "^8.59.2",
105
+ "vite": "^8.0.11",
106
+ "vite-plugin-dts": "^5.0.0",
107
+ "vitest": "^4.1.5",
108
+ "vitest-axe": "^0.1.0",
109
+ "vue": "^3.5.39"
110
+ }
111
+ }