@lekoala/combobox 0.1.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 (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +566 -0
  3. package/custom-elements.json +247 -0
  4. package/dist/combobox.css +447 -0
  5. package/dist/combobox.js +2220 -0
  6. package/dist/combobox.min.css +1 -0
  7. package/dist/combobox.min.js +2 -0
  8. package/dist/types/combo-box.d.ts +112 -0
  9. package/dist/types/combo-box.d.ts.map +1 -0
  10. package/dist/types/combobox.d.ts +530 -0
  11. package/dist/types/combobox.d.ts.map +1 -0
  12. package/dist/types/define.d.ts +2 -0
  13. package/dist/types/define.d.ts.map +1 -0
  14. package/dist/types/helpers.d.ts +251 -0
  15. package/dist/types/helpers.d.ts.map +1 -0
  16. package/dist/types/index.d.ts +24 -0
  17. package/dist/types/index.d.ts.map +1 -0
  18. package/dist/types/locales/de.d.ts +7 -0
  19. package/dist/types/locales/de.d.ts.map +1 -0
  20. package/dist/types/locales/en.d.ts +8 -0
  21. package/dist/types/locales/en.d.ts.map +1 -0
  22. package/dist/types/locales/es.d.ts +7 -0
  23. package/dist/types/locales/es.d.ts.map +1 -0
  24. package/dist/types/locales/fr.d.ts +7 -0
  25. package/dist/types/locales/fr.d.ts.map +1 -0
  26. package/dist/types/locales/it.d.ts +7 -0
  27. package/dist/types/locales/it.d.ts.map +1 -0
  28. package/dist/types/locales/nl.d.ts +7 -0
  29. package/dist/types/locales/nl.d.ts.map +1 -0
  30. package/dist/types/locales/pt.d.ts +7 -0
  31. package/dist/types/locales/pt.d.ts.map +1 -0
  32. package/dist/types/locales/ru.d.ts +7 -0
  33. package/dist/types/locales/ru.d.ts.map +1 -0
  34. package/dist/types/locales/zh-CN.d.ts +7 -0
  35. package/dist/types/locales/zh-CN.d.ts.map +1 -0
  36. package/dist/types/messages.d.ts +48 -0
  37. package/dist/types/messages.d.ts.map +1 -0
  38. package/package.json +92 -0
  39. package/src/combo-box.js +316 -0
  40. package/src/combobox.css +447 -0
  41. package/src/combobox.js +2975 -0
  42. package/src/define.js +20 -0
  43. package/src/helpers.js +377 -0
  44. package/src/index.js +35 -0
  45. package/src/locales/de.js +17 -0
  46. package/src/locales/en.js +18 -0
  47. package/src/locales/es.js +17 -0
  48. package/src/locales/fr.js +17 -0
  49. package/src/locales/it.js +17 -0
  50. package/src/locales/nl.js +17 -0
  51. package/src/locales/pt.js +17 -0
  52. package/src/locales/ru.js +17 -0
  53. package/src/locales/zh-CN.js +17 -0
  54. package/src/messages.js +55 -0
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Pure helpers shared by the Combobox engine.
3
+ *
4
+ * Free of DOM/engine state and unit-tested directly as ESM. The global build
5
+ * (dist/combobox.js) inlines them through its single side-effect entry,
6
+ * src/define.js; nothing in src/ ever touches window/globalThis.
7
+ *
8
+ * Separator contract:
9
+ * - separator values are full strings, not a character class (`",|;"` means
10
+ * comma, pipe and semicolon are all independent separators);
11
+ * - the `|`-delimited form is the `<combo-box separators="…">` attribute
12
+ * encoding, so a literal `|` cannot be expressed as an attribute separator;
13
+ * - matching prefers the longest separator at any position.
14
+ */
15
+ export type ComboboxItem = Record<string, any> & {
16
+ value: string;
17
+ label: string;
18
+ disabled?: boolean;
19
+ selected?: boolean;
20
+ group?: string;
21
+ option?: HTMLOptionElement | null;
22
+ data?: Record<string, string | undefined>;
23
+ title?: string;
24
+ };
25
+ export type ItemFields = {
26
+ labelField?: string;
27
+ valueField?: string;
28
+ };
29
+ export type Token = {
30
+ text: string;
31
+ /**
32
+ * The separator that terminated the token
33
+ */
34
+ sep: string;
35
+ };
36
+ export type SplitResult = {
37
+ /**
38
+ * Completed tokens
39
+ */
40
+ done: Token[];
41
+ /**
42
+ * Trailing unterminated text that must stay in the input
43
+ */
44
+ rest: string;
45
+ };
46
+ /**
47
+ * Canonical combobox item. `value`/`label` are the serialized payload; the
48
+ * remaining keys mirror source metadata the engine reads back. Applications
49
+ * may hang their own payload on items (label/value fields are honored by the
50
+ * engine, a `data-*` mapping is not).
51
+ * @typedef {Record<string, any> & {
52
+ * value: string,
53
+ * label: string,
54
+ * disabled?: boolean,
55
+ * selected?: boolean,
56
+ * group?: string,
57
+ * option?: HTMLOptionElement | null,
58
+ * data?: Record<string, string | undefined>,
59
+ * title?: string,
60
+ * }} ComboboxItem
61
+ */
62
+ /**
63
+ * Field mapping used to convert plain data objects into canonical items.
64
+ * @typedef {Object} ItemFields
65
+ * @property {string} [labelField]
66
+ * @property {string} [valueField]
67
+ */
68
+ /**
69
+ * A completed separator-delimited token.
70
+ * @typedef {Object} Token
71
+ * @property {string} text
72
+ * @property {string} sep The separator that terminated the token
73
+ */
74
+ /**
75
+ * Result of a tokenization pass.
76
+ * @typedef {Object} SplitResult
77
+ * @property {Token[]} done Completed tokens
78
+ * @property {string} rest Trailing unterminated text that must stay in the input
79
+ */
80
+ /**
81
+ * @param {object} object
82
+ * @param {string} key
83
+ * @returns {boolean}
84
+ */
85
+ export declare function hasOwn(object: object, key: string): boolean;
86
+ /**
87
+ * Strip combining diacritics only (NFD + remove the U+0300–U+036F block).
88
+ * Case is preserved — use `normalize()` when case-insensitivity is also
89
+ * wanted. Everything in the engine that is "accent-insensitive" funnels
90
+ * through here, so there is exactly one definition of accent folding.
91
+ *
92
+ * @param {*} value
93
+ * @returns {string}
94
+ */
95
+ export declare function stripDiacritics(value: any): string;
96
+ /**
97
+ * @param {*} value
98
+ * @returns {string}
99
+ */
100
+ export declare function normalize(value: any): string;
101
+ /**
102
+ * Match a single `value` against `query` under a `match` strategy map
103
+ * ("includes" | "startswith" | "fuzzy" | "pattern").
104
+ *
105
+ * Contract: this helper decides **how a field matches** — it never receives
106
+ * more than one field value, so a match can never cross `searchFields`
107
+ * boundaries. The engine calls it as `values.some((value) => matchesField(value, query, mode))`.
108
+ *
109
+ * `pattern` is a string transformed into a `RegExp` with the `i` flag only
110
+ * (never a caller-supplied `RegExp`, so a stateful `g`/`y` matcher cannot
111
+ * leak between items). It first tests the raw value with the authored regex,
112
+ * then falls back to an accent-insensitive pass over `stripDiacritics()`
113
+ * text with a diacritics-folded spelling of the query — so `liège`, `Liège`,
114
+ * `LIEGE` and `liege` all match each other while `[A-Z]`-style regexes keep
115
+ * their original semantics (case is handled by `/i`, not by lowercasing).
116
+ * An invalid regex still yields `false` for every value.
117
+ *
118
+ * @param {*} value
119
+ * @param {*} query
120
+ * @param {*} mode
121
+ * @returns {boolean}
122
+ */
123
+ export declare function matchesField(value: any, query: any, mode: any): boolean;
124
+ /**
125
+ * Case- and accent-insensitive regex matching for a single value.
126
+ * See `matchesField` for the contract around the `i`-only flag and the
127
+ * additive accent-fold fallback; an invalid query returns `false`.
128
+ *
129
+ * @param {*} value
130
+ * @param {*} query
131
+ * @returns {boolean}
132
+ */
133
+ export declare function patternMatch(value: any, query: any): boolean;
134
+ /**
135
+ * Convert any input to a canonical `{ value, label }`.
136
+ *
137
+ * @param {*} raw
138
+ * @param {ItemFields | null} [fields]
139
+ * @returns {ComboboxItem | null}
140
+ */
141
+ export declare function toItem(raw: any, fields?: ItemFields | null): ComboboxItem | null;
142
+ /**
143
+ * Parse the pipe-delimited separator attribute into an array of full
144
+ * separator strings. `null`/empty values yield no separators.
145
+ *
146
+ * @param {string | string[] | null | undefined} raw
147
+ * @returns {string[]}
148
+ */
149
+ export declare function parseSeparators(raw: string | string[] | null | undefined): string[];
150
+ /**
151
+ * Split `input` by the longest matching separators.
152
+ * Returns `{ done: [{ text, sep }], rest }`: `done` holds complete tokens
153
+ * (each terminated by a separator); `rest` is the trailing unterminated
154
+ * text (the incomplete token that must stay in the input).
155
+ *
156
+ * @param {string | null | undefined} input
157
+ * @param {string | string[] | null | undefined} separators
158
+ * @returns {SplitResult}
159
+ */
160
+ export declare function splitTokens(input: string | null | undefined, separators: string | string[] | null | undefined): SplitResult;
161
+ /**
162
+ * Rank items by a score function with a stable tiebreak on the original
163
+ * relative order. `score(item, index) => number | false | null`:
164
+ * - `false` and `null` exclude the item (no confidence / explicit exclusion);
165
+ * - `0` is a valid score and keeps the item, ranked last for its tie group.
166
+ *
167
+ * The `index` argument is the position in the input list at scoring time,
168
+ * mirroring how the engine feeds filtered items to the user's scorer.
169
+ *
170
+ * @template T
171
+ * @param {T[]} items
172
+ * @param {(item: T, index: number) => number | false | null} score
173
+ * @returns {T[]}
174
+ */
175
+ export declare function rankByScore<T>(items: T[], score: (item: T, index: number) => number | false | null): T[];
176
+ /**
177
+ * Reconcile the remembered selection order against the currently selected
178
+ * values. Outcome: every selected value that appears in `order` first in the
179
+ * remembered sequence, then any selected value unknown to `order` appended in
180
+ * native `values` order. A remembered value that is no longer selected is
181
+ * never kept. `values` is treated as the source of truth for membership.
182
+ *
183
+ * @template T
184
+ * @param {T[]} values
185
+ * @param {T[]} order
186
+ * @returns {T[]}
187
+ */
188
+ export declare function reconcileSelected<T>(values: T[], order: T[]): T[];
189
+ /**
190
+ * Move `identity` within `list` to `index` (clamped to valid bounds). Returns
191
+ * `{ order, from, to }` when a real move happens (a fresh array, the input is
192
+ * never mutated), or `null` when the identity is unknown or already at the
193
+ * target position. `from`/`to` are the pre-move positions.
194
+ *
195
+ * Match is strict identity (SameValueZero), so the list may hold strings or
196
+ * option-element references alike — callers never need string coercion.
197
+ *
198
+ * @template T
199
+ * @param {T[]} list
200
+ * @param {T} identity
201
+ * @param {number} index
202
+ * @returns {{ order: T[], from: number, to: number } | null}
203
+ */
204
+ export declare function moveValueInOrder<T>(list: T[], identity: T, index: number): {
205
+ order: T[];
206
+ from: number;
207
+ to: number;
208
+ } | null;
209
+ /**
210
+ * Split a comma-delimited attribute value into a trimmed, non-empty list.
211
+ * `"label, email, "` → `["label", "email"]`; empty input → `[]`.
212
+ *
213
+ * @param {string | null | undefined} raw
214
+ * @returns {string[]}
215
+ */
216
+ export declare function parseList(raw: string | null | undefined): string[];
217
+ /**
218
+ * Boolean `<combo-box>` attribute semantics: absent → `undefined` (so the
219
+ * caller can omit the option and keep the DEFAULTS value), present → `true`
220
+ * unless the authored value is exactly the string `"false"`.
221
+ *
222
+ * @param {Element} element
223
+ * @param {string} name
224
+ * @returns {boolean | undefined}
225
+ */
226
+ export declare function booleanAttribute(element: Element, name: string): boolean | undefined;
227
+ /**
228
+ * Parse a count-like `<combo-box>` attribute. `null` and non-integer values
229
+ * (e.g. `"banana"` or `"2.5"`) yield `undefined` so the caller can omit the
230
+ * option and let the DEFAULTS value apply instead of spreading `NaN`.
231
+ *
232
+ * @param {string | null | undefined} raw
233
+ * @returns {number | undefined}
234
+ */
235
+ export declare function parseInteger(raw: string | null | undefined): number | undefined;
236
+ /**
237
+ * Very light subsequence fuzzy match, used by `match: "fuzzy"`.
238
+ *
239
+ * Contract: both `str` and `lookup` must already be normalized (case/accent
240
+ * folding happens in the caller, in `normalize()`) — fuzzyMatch does no
241
+ * normalization of its own. A whitespace-only lookup matches everything; a
242
+ * plain substring still wins via the fast `includes` path; otherwise every
243
+ * non-space character of the lookup must appear in order. The scan advances by
244
+ * `char.length` (not `1`) so a surrogate-pair character is consumed whole.
245
+ *
246
+ * @param {string} str
247
+ * @param {*} lookup
248
+ * @returns {boolean}
249
+ */
250
+ export declare function fuzzyMatch(str: string, lookup: any): boolean;
251
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export { ComboBoxElement, defineCombobox } from "./combo-box.js";
2
+ export { Combobox, default } from "./combobox.js";
3
+ export { booleanAttribute, fuzzyMatch, moveValueInOrder, normalize, parseInteger, parseList, parseSeparators, rankByScore, reconcileSelected, splitTokens, toItem, } from "./helpers.js";
4
+ export type ComboboxOptions = import("./combobox.js").ComboboxOptions;
5
+ export type ComboboxItem = import("./helpers.js").ComboboxItem;
6
+ export type ComboboxSource = HTMLInputElement | HTMLSelectElement;
7
+ export type LoadContext = import("./combobox.js").LoadContext;
8
+ /**
9
+ * Public configuration for a Combobox instance.
10
+ * @typedef {import("./combobox.js").ComboboxOptions} ComboboxOptions
11
+ */
12
+ /**
13
+ * Canonical combobox item (value/label payload plus optional metadata).
14
+ * @typedef {import("./helpers.js").ComboboxItem} ComboboxItem
15
+ */
16
+ /**
17
+ * A selectable source for a combobox: a free-form input+datalist or a select.
18
+ * @typedef {HTMLInputElement | HTMLSelectElement} ComboboxSource
19
+ */
20
+ /**
21
+ * Context passed to the async load callback.
22
+ * @typedef {import("./combobox.js").LoadContext} LoadContext
23
+ */
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,SAAS,EACT,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,MAAM,GACP,MAAM,cAAc,CAAC;AAInB,YAAmD,eAAe,GAAxD,OAAO,eAAe,EAAE,eAAe,CAAiB;AAKlE,YAA+C,YAAY,GAAjD,OAAO,cAAc,EAAE,YAAY,CAAc;AAK3D,YAAgD,cAAc,GAApD,gBAAgB,GAAG,iBAAiB,CAAgB;AAK9D,YAA+C,WAAW,GAAhD,OAAO,eAAe,EAAE,WAAW,CAAa;AAjB7D;;;GAGG;AAEH;;;GAGG;AAEH;;;GAGG;AAEH;;;GAGG"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * German UI messages.
3
+ * @type {import("../messages.js").Messages}
4
+ */
5
+ declare const messages: import("../messages.js").Messages;
6
+ export default messages;
7
+ //# sourceMappingURL=de.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"de.d.ts","sourceRoot":"","sources":["../../../src/locales/de.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,QAAA,MAAM,QAAQ,EAFJ,OAAO,gBAAgB,EAAE,QAQlC,CAAC;eAIa,QAAQ"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * English UI messages — canonical catalog: keys and default values match the
3
+ * engine defaults, so `en` is the reference every other locale mirrors.
4
+ * @type {import("../messages.js").Messages}
5
+ */
6
+ declare const messages: import("../messages.js").Messages;
7
+ export default messages;
8
+ //# sourceMappingURL=en.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../src/locales/en.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,QAAA,MAAM,QAAQ,EAFJ,OAAO,gBAAgB,EAAE,QAQlC,CAAC;eAIa,QAAQ"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Spanish UI messages.
3
+ * @type {import("../messages.js").Messages}
4
+ */
5
+ declare const messages: import("../messages.js").Messages;
6
+ export default messages;
7
+ //# sourceMappingURL=es.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"es.d.ts","sourceRoot":"","sources":["../../../src/locales/es.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,QAAA,MAAM,QAAQ,EAFJ,OAAO,gBAAgB,EAAE,QAQlC,CAAC;eAIa,QAAQ"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * French UI messages.
3
+ * @type {import("../messages.js").Messages}
4
+ */
5
+ declare const messages: import("../messages.js").Messages;
6
+ export default messages;
7
+ //# sourceMappingURL=fr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fr.d.ts","sourceRoot":"","sources":["../../../src/locales/fr.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,QAAA,MAAM,QAAQ,EAFJ,OAAO,gBAAgB,EAAE,QAQlC,CAAC;eAIa,QAAQ"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Italian UI messages.
3
+ * @type {import("../messages.js").Messages}
4
+ */
5
+ declare const messages: import("../messages.js").Messages;
6
+ export default messages;
7
+ //# sourceMappingURL=it.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"it.d.ts","sourceRoot":"","sources":["../../../src/locales/it.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,QAAA,MAAM,QAAQ,EAFJ,OAAO,gBAAgB,EAAE,QAQlC,CAAC;eAIa,QAAQ"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Dutch UI messages.
3
+ * @type {import("../messages.js").Messages}
4
+ */
5
+ declare const messages: import("../messages.js").Messages;
6
+ export default messages;
7
+ //# sourceMappingURL=nl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nl.d.ts","sourceRoot":"","sources":["../../../src/locales/nl.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,QAAA,MAAM,QAAQ,EAFJ,OAAO,gBAAgB,EAAE,QAQlC,CAAC;eAIa,QAAQ"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Portuguese (European) UI messages.
3
+ * @type {import("../messages.js").Messages}
4
+ */
5
+ declare const messages: import("../messages.js").Messages;
6
+ export default messages;
7
+ //# sourceMappingURL=pt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pt.d.ts","sourceRoot":"","sources":["../../../src/locales/pt.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,QAAA,MAAM,QAAQ,EAFJ,OAAO,gBAAgB,EAAE,QAQlC,CAAC;eAIa,QAAQ"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Russian UI messages.
3
+ * @type {import("../messages.js").Messages}
4
+ */
5
+ declare const messages: import("../messages.js").Messages;
6
+ export default messages;
7
+ //# sourceMappingURL=ru.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ru.d.ts","sourceRoot":"","sources":["../../../src/locales/ru.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,QAAA,MAAM,QAAQ,EAFJ,OAAO,gBAAgB,EAAE,QAQlC,CAAC;eAIa,QAAQ"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Simplified Chinese UI messages.
3
+ * @type {import("../messages.js").Messages}
4
+ */
5
+ declare const messages: import("../messages.js").Messages;
6
+ export default messages;
7
+ //# sourceMappingURL=zh-CN.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zh-CN.d.ts","sourceRoot":"","sources":["../../../src/locales/zh-CN.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,QAAA,MAAM,QAAQ,EAFJ,OAAO,gBAAgB,EAAE,QAQlC,CAAC;eAIa,QAAQ"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Generated UI text, centralized for i18n. This module is DOM-free so the
3
+ * catalog can be imported and unit-tested without a browser; the engine's
4
+ * `Combobox.getDefaultMessages()` / `setDefaultMessages()` statics delegate to
5
+ * it, and the shipped `src/locales/*` modules apply their translations through
6
+ * `setDefaultMessages` on import.
7
+ */
8
+ export type Messages = {
9
+ noResults?: string;
10
+ loading?: string;
11
+ loadError?: string;
12
+ create?: (query: string, context?: import("./combobox.js").ComboboxContext) => string;
13
+ position?: (label: string, position: number, total: number, context?: import("./combobox.js").ComboboxContext) => string;
14
+ };
15
+ /**
16
+ * Screen-reader / UI status messages. Defaults are merged so the label
17
+ * producers (`create`, `position`) are always functions; the plain status
18
+ * strings (`noResults`, `loading`, `loadError`) are literal text rendered by
19
+ * `setContent` (rich DOM rows use the `render.*` hooks instead).
20
+ * @typedef {Object} Messages
21
+ * @property {string} [noResults]
22
+ * @property {string} [loading]
23
+ * @property {string} [loadError]
24
+ * @property {(query: string, context?: import("./combobox.js").ComboboxContext) => string} [create]
25
+ * @property {(label: string, position: number, total: number, context?: import("./combobox.js").ComboboxContext) => string} [position]
26
+ */
27
+ /** @type {Messages} */
28
+ declare const DEFAULT_MESSAGES: Messages;
29
+ /**
30
+ * Read the current default UI messages. Returns a shallow copy; mutating
31
+ * the result does not affect the engine.
32
+ * @returns {Messages}
33
+ */
34
+ export declare function getDefaultMessages(): Messages;
35
+ /**
36
+ * Merge application or locale-provided UI text into the default messages.
37
+ * Called by the shipped `locales/*` modules on import. Only comboboxes
38
+ * created *after* this call see the new text: instances resolve their
39
+ * messages as a snapshot at construction time. Per-instance `messages`
40
+ * options always take precedence over these defaults. Missing keys keep
41
+ * their current translation, and producer keys (`create`, `position`) stay
42
+ * functions.
43
+ * @param {Partial<Messages>} messages
44
+ * @returns {void}
45
+ */
46
+ export declare function setDefaultMessages(messages: Partial<Messages>): void;
47
+ export { DEFAULT_MESSAGES };
48
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/messages.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOA,YAAkB,QAAQ,GAC1B;IAAoB,SAAS,AAA7B,CACA,EADW,MAAM,CACjB;IAAoB,OAAO,AAA3B,CACA,EADW,MAAM,CACjB;IAAoB,SAAS,AAA7B,CACA,EADW,MAAM,CACjB;IAA0F,MAAM,AAAhG,CACA,EADW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,eAAe,EAAE,eAAe,KAAK,MAAM,CACvF;IAA2H,QAAQ,AAAnI,CAAoI,EAAzH,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,eAAe,EAAE,eAAe,KAAK,MAAM,CAAY;CAAA,CAAA;AAVvI;;;;;;;;;;;GAWG;AAEH,uBAAuB;AACvB,QAAA,MAAM,gBAAgB,EADX,QAOV,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,IAFrB,QAAQ,CAIpB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAHhC,OAAO,CAAC,QAAQ,CAGgB,GAF9B,IAAI,CAIhB;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "@lekoala/combobox",
3
+ "version": "0.1.0",
4
+ "description": "Native-first <combo-box> combobox/filterable-select",
5
+ "type": "module",
6
+ "sideEffects": [
7
+ "./dist/combobox.js",
8
+ "./dist/combobox.min.js",
9
+ "./dist/combobox.css",
10
+ "./dist/combobox.min.css",
11
+ "./src/combobox.css",
12
+ "./src/define.js"
13
+ ],
14
+ "license": "MIT",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/lekoala/combobox.git"
18
+ },
19
+ "homepage": "https://github.com/lekoala/combobox",
20
+ "bugs": "https://github.com/lekoala/combobox/issues",
21
+ "packageManager": "bun@1.4.0",
22
+ "customElements": "custom-elements.json",
23
+ "keywords": [
24
+ "combobox",
25
+ "select",
26
+ "filterable-select",
27
+ "datalist",
28
+ "custom-select",
29
+ "popover",
30
+ "web-component"
31
+ ],
32
+ "files": [
33
+ "dist",
34
+ "src",
35
+ "custom-elements.json",
36
+ "LICENSE",
37
+ "README.md"
38
+ ],
39
+ "exports": {
40
+ ".": {
41
+ "types": "./dist/types/index.d.ts",
42
+ "import": "./src/index.js"
43
+ },
44
+ "./define": {
45
+ "types": "./dist/types/define.d.ts",
46
+ "import": "./src/define.js"
47
+ },
48
+ "./combobox.css": "./src/combobox.css",
49
+ "./locales/*": {
50
+ "types": "./dist/types/locales/*.d.ts",
51
+ "import": "./src/locales/*"
52
+ },
53
+ "./dist/combobox.js": "./dist/combobox.js",
54
+ "./dist/combobox.min.js": "./dist/combobox.min.js",
55
+ "./dist/combobox.css": "./dist/combobox.css",
56
+ "./dist/combobox.min.css": "./dist/combobox.min.css"
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ },
61
+ "scripts": {
62
+ "dev": "bun run sync && node test/server.js",
63
+ "build:bundle": "bun scripts/build.js",
64
+ "build:types": "bun run types",
65
+ "build:manifest": "bun scripts/custom-elements.js",
66
+ "build": "bun run build:bundle && bun run build:types && bun run build:manifest",
67
+ "lint": "biome check .",
68
+ "format": "biome format --write .",
69
+ "typecheck": "tsc -p jsconfig.json",
70
+ "types": "tsc -p tsconfig.types.json",
71
+ "test": "bun test test/unit",
72
+ "test:syntax": "node --check src/combobox.js && node --check src/combo-box.js && node --check src/helpers.js && node --check src/index.js && node --check src/define.js",
73
+ "test:types": "tsc -p test/types/tsconfig.json",
74
+ "test:browser": "playwright test test/browser --project chromium",
75
+ "test:browser:headed": "playwright test test/browser --project chromium --headed",
76
+ "test:browser:all": "playwright test test/browser",
77
+ "test:dist": "playwright test test/dist --project chromium",
78
+ "sync": "bun run build",
79
+ "check": "bun run test:syntax && bun run lint && bun run typecheck && bun run test",
80
+ "check:package": "bun scripts/check-package.js",
81
+ "check:generated": "bun scripts/check-generated.js",
82
+ "verify": "bun run check && bun run sync && bun run test:types && bun run check:generated && bun run check:package",
83
+ "check:all": "bun run verify && bun run test:browser:all && bun run test:dist",
84
+ "prepack": "bun run sync",
85
+ "prepublishOnly": "bun run verify"
86
+ },
87
+ "devDependencies": {
88
+ "@biomejs/biome": "2.5.11",
89
+ "@playwright/test": "1.62.1",
90
+ "typescript": "7.0.2"
91
+ }
92
+ }