praxis-kit 1.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.
- package/LICENSE +21 -0
- package/dist/chunk-KDUNVQK2.js +2059 -0
- package/dist/codemod/index.d.ts +21 -0
- package/dist/codemod/index.js +241955 -0
- package/dist/eslint/index.d.ts +84 -0
- package/dist/eslint/index.js +1068 -0
- package/dist/lit/index.d.ts +304 -0
- package/dist/lit/index.js +1887 -0
- package/dist/merge-refs-CfBqh1UO.d.ts +374 -0
- package/dist/preact/index.d.ts +292 -0
- package/dist/preact/index.js +2062 -0
- package/dist/react/index.d.ts +27 -0
- package/dist/react/index.js +197 -0
- package/dist/react/legacy.d.ts +21 -0
- package/dist/react/legacy.js +209 -0
- package/dist/solid/index.d.ts +287 -0
- package/dist/solid/index.js +1837 -0
- package/dist/svelte/index.d.ts +343 -0
- package/dist/svelte/index.js +1723 -0
- package/dist/tailwind/index.d.ts +138 -0
- package/dist/tailwind/index.js +508 -0
- package/dist/ts-plugin/index.cjs +191 -0
- package/dist/ts-plugin/index.d.cts +10 -0
- package/dist/vite-plugin/index.d.ts +395 -0
- package/dist/vite-plugin/index.js +1329 -0
- package/dist/vue/index.d.ts +309 -0
- package/dist/vue/index.js +1922 -0
- package/dist/web/index.d.ts +302 -0
- package/dist/web/index.js +1858 -0
- package/package.json +176 -0
|
@@ -0,0 +1,2062 @@
|
|
|
1
|
+
// ../../adapters/preact/src/create-contract-component.ts
|
|
2
|
+
import { forwardRef as forwardRef2 } from "preact/compat";
|
|
3
|
+
|
|
4
|
+
// ../../adapters/preact/src/normalize-children.ts
|
|
5
|
+
import { isValidElement } from "preact";
|
|
6
|
+
function normalizeChildren(children) {
|
|
7
|
+
if (isValidElement(children)) return [children];
|
|
8
|
+
if (Array.isArray(children)) return children.filter(isValidElement);
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// ../shared/src/guards/children/component-id.ts
|
|
13
|
+
var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol("praxis.component-default-tag");
|
|
14
|
+
|
|
15
|
+
// ../../lib/primitive/src/utils/is-object.ts
|
|
16
|
+
function isNull(value) {
|
|
17
|
+
return value === null;
|
|
18
|
+
}
|
|
19
|
+
function isObject(value) {
|
|
20
|
+
return !isNull(value) && typeof value === "object";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// ../../lib/primitive/src/merge/constants.ts
|
|
24
|
+
var EVENT_HANDLER_RE = /^on[A-Z]/;
|
|
25
|
+
|
|
26
|
+
// ../../lib/primitive/src/merge/predicates.ts
|
|
27
|
+
function isFunction(value) {
|
|
28
|
+
return typeof value === "function";
|
|
29
|
+
}
|
|
30
|
+
function isPlainObject(value) {
|
|
31
|
+
if (!isObject(value)) return false;
|
|
32
|
+
const proto = Object.getPrototypeOf(value);
|
|
33
|
+
return proto === Object.prototype || proto === null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ../../adapters/preact/src/apply-display-name.ts
|
|
37
|
+
function applyDisplayName(component, name) {
|
|
38
|
+
Object.assign(component, { displayName: name ?? "PolymorphicComponent" });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ../../lib/adapter-utils/src/apply-filter.ts
|
|
42
|
+
function applyFilter(props, filterProps, variantKeys) {
|
|
43
|
+
const out = {};
|
|
44
|
+
for (const k in props) {
|
|
45
|
+
if (!Object.hasOwn(props, k)) continue;
|
|
46
|
+
if (filterProps(k, variantKeys)) continue;
|
|
47
|
+
out[k] = props[k];
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ../core/dist/chunk-US6MPMDF.js
|
|
53
|
+
function makeResolveTag(defaultTag) {
|
|
54
|
+
return function tag(as) {
|
|
55
|
+
return as ?? defaultTag;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function assertNever(value) {
|
|
59
|
+
throw new Error(`Unexpected value: ${String(value)}`);
|
|
60
|
+
}
|
|
61
|
+
function r(e) {
|
|
62
|
+
var t, f, n = "";
|
|
63
|
+
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
64
|
+
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
65
|
+
var o = e.length;
|
|
66
|
+
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
67
|
+
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
68
|
+
return n;
|
|
69
|
+
}
|
|
70
|
+
function clsx() {
|
|
71
|
+
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
72
|
+
return n;
|
|
73
|
+
}
|
|
74
|
+
function cn(...inputs) {
|
|
75
|
+
return clsx(...inputs);
|
|
76
|
+
}
|
|
77
|
+
function mergeProps(defaultProps, props) {
|
|
78
|
+
return {
|
|
79
|
+
...defaultProps ?? {},
|
|
80
|
+
...props
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function isNull2(value) {
|
|
84
|
+
return value === null;
|
|
85
|
+
}
|
|
86
|
+
function isObject2(value) {
|
|
87
|
+
return !isNull2(value) && typeof value === "object";
|
|
88
|
+
}
|
|
89
|
+
function isString(value) {
|
|
90
|
+
return typeof value === "string";
|
|
91
|
+
}
|
|
92
|
+
function isNumber(value) {
|
|
93
|
+
return typeof value === "number";
|
|
94
|
+
}
|
|
95
|
+
var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
|
|
96
|
+
function composeNormalizers(normalizers, fn) {
|
|
97
|
+
if (!normalizers?.length) return fn;
|
|
98
|
+
return ((props) => {
|
|
99
|
+
const patched = normalizers.reduce(
|
|
100
|
+
(acc, normalizer) => ({ ...acc, ...normalizer(acc) }),
|
|
101
|
+
props
|
|
102
|
+
);
|
|
103
|
+
return fn ? fn(patched) : patched;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function whenDefined(key, value) {
|
|
107
|
+
return value === void 0 ? {} : { [key]: value };
|
|
108
|
+
}
|
|
109
|
+
function resolveFactoryOptions(options = {}) {
|
|
110
|
+
const { styling, enforcement } = options;
|
|
111
|
+
const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
|
|
112
|
+
const variantKeys = styling?.variants === void 0 ? EMPTY_VARIANT_KEYS : new Set(Object.keys(styling.variants));
|
|
113
|
+
return Object.freeze({
|
|
114
|
+
defaultTag: options.tag ?? "div",
|
|
115
|
+
strict: enforcement?.strict ?? false,
|
|
116
|
+
variantKeys,
|
|
117
|
+
...whenDefined("displayName", options.name),
|
|
118
|
+
...whenDefined("defaultProps", options.defaults),
|
|
119
|
+
...whenDefined("baseClassName", styling?.base),
|
|
120
|
+
...whenDefined("tagMap", styling?.tags),
|
|
121
|
+
...whenDefined("presetMap", styling?.presets),
|
|
122
|
+
...whenDefined("variants", styling?.variants),
|
|
123
|
+
...whenDefined("defaultVariants", styling?.defaults),
|
|
124
|
+
...whenDefined("compoundVariants", styling?.compounds),
|
|
125
|
+
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
126
|
+
...whenDefined("ariaRules", enforcement?.aria),
|
|
127
|
+
...whenDefined("childRules", enforcement?.children),
|
|
128
|
+
...whenDefined("allowedAs", enforcement?.allowedAs),
|
|
129
|
+
...whenDefined("precomputedClasses", styling?.precomputedClasses)
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function report(strict, message) {
|
|
133
|
+
if (strict === false) return;
|
|
134
|
+
const mode = strict === true ? "throw" : strict;
|
|
135
|
+
if (mode === "throw") throw new Error(message);
|
|
136
|
+
console.warn(message);
|
|
137
|
+
}
|
|
138
|
+
function validateFactoryOptions(resolved) {
|
|
139
|
+
const { strict } = resolved;
|
|
140
|
+
if (strict === false) return;
|
|
141
|
+
const name = resolved.displayName ?? "Component";
|
|
142
|
+
const { variants } = resolved;
|
|
143
|
+
const checkSelection = (label2, selection) => {
|
|
144
|
+
const record = selection;
|
|
145
|
+
for (const dim in record) {
|
|
146
|
+
const value = record[dim];
|
|
147
|
+
if (value === void 0 || value === null) continue;
|
|
148
|
+
if (!variants || !Object.hasOwn(variants, dim)) {
|
|
149
|
+
report(strict, `${name}: ${label2} references unknown variant "${dim}".`);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const states = variants[dim];
|
|
153
|
+
const stateKey = String(value);
|
|
154
|
+
if (!Object.hasOwn(states, stateKey)) {
|
|
155
|
+
report(
|
|
156
|
+
strict,
|
|
157
|
+
`${name}: ${label2} sets "${dim}" to unknown value "${stateKey}" (valid: ${Object.keys(states).join(", ")}).`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const { presetMap } = resolved;
|
|
163
|
+
if (presetMap) {
|
|
164
|
+
for (const presetKey in presetMap) {
|
|
165
|
+
checkSelection(`preset "${presetKey}"`, presetMap[presetKey]);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (resolved.defaultVariants) checkSelection("defaults", resolved.defaultVariants);
|
|
169
|
+
}
|
|
170
|
+
var warned = /* @__PURE__ */ new Set();
|
|
171
|
+
var pendingAsyncWarns = /* @__PURE__ */ new Set();
|
|
172
|
+
var asyncWarnScheduled = false;
|
|
173
|
+
function flushAsyncWarns() {
|
|
174
|
+
asyncWarnScheduled = false;
|
|
175
|
+
const messages = [...pendingAsyncWarns];
|
|
176
|
+
pendingAsyncWarns.clear();
|
|
177
|
+
for (const msg of messages) {
|
|
178
|
+
console.warn(msg);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function report2(strict, message) {
|
|
182
|
+
if (!strict) return;
|
|
183
|
+
const mode = strict === true ? "throw" : strict;
|
|
184
|
+
if (mode === "throw") throw new Error(message);
|
|
185
|
+
if (mode === "async-warn") {
|
|
186
|
+
if (pendingAsyncWarns.has(message)) return;
|
|
187
|
+
pendingAsyncWarns.add(message);
|
|
188
|
+
if (!asyncWarnScheduled) {
|
|
189
|
+
asyncWarnScheduled = true;
|
|
190
|
+
queueMicrotask(flushAsyncWarns);
|
|
191
|
+
}
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (warned.has(message)) return;
|
|
195
|
+
warned.add(message);
|
|
196
|
+
console.warn(message);
|
|
197
|
+
}
|
|
198
|
+
function label(name) {
|
|
199
|
+
return name ? `[${name}]` : "[createContractComponent]";
|
|
200
|
+
}
|
|
201
|
+
function validateRenderProps(options, props, presetKey) {
|
|
202
|
+
const { strict, presetMap, variants, displayName } = options;
|
|
203
|
+
if (!strict) return;
|
|
204
|
+
const tag = label(displayName);
|
|
205
|
+
if (presetKey !== void 0 && (!presetMap || !Object.hasOwn(presetMap, presetKey))) {
|
|
206
|
+
report2(strict, `${tag} Unknown presetKey "${presetKey}" \u2014 no preset with that name exists.`);
|
|
207
|
+
}
|
|
208
|
+
if (variants) {
|
|
209
|
+
for (const key in variants) {
|
|
210
|
+
if (!Object.hasOwn(props, key)) continue;
|
|
211
|
+
const value = props[key];
|
|
212
|
+
if (value === void 0 || value === null) continue;
|
|
213
|
+
const dim = variants[key];
|
|
214
|
+
if (dim && !Object.hasOwn(dim, String(value))) {
|
|
215
|
+
report2(
|
|
216
|
+
strict,
|
|
217
|
+
`${tag} Variant "${key}=${String(value)}" is not a defined value for the "${key}" dimension.`
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function panic(message) {
|
|
224
|
+
throw new Error(message);
|
|
225
|
+
}
|
|
226
|
+
function describe(value) {
|
|
227
|
+
if (value === null) return "null";
|
|
228
|
+
if (Array.isArray(value)) return "array";
|
|
229
|
+
return typeof value;
|
|
230
|
+
}
|
|
231
|
+
function assertPluginShape(result) {
|
|
232
|
+
if (result === null || typeof result !== "object")
|
|
233
|
+
panic(
|
|
234
|
+
`[praxis-kit] Plugin factory must return an object with a 'pipeline' function. Got: ${result === null ? "null" : typeof result}.`
|
|
235
|
+
);
|
|
236
|
+
const plugin = result;
|
|
237
|
+
if (typeof plugin.pipeline !== "function")
|
|
238
|
+
panic(
|
|
239
|
+
`[praxis-kit] Plugin factory return value is missing a 'pipeline' function. Got pipeline: ${typeof plugin.pipeline}.`
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
function guardPipeline(pipeline) {
|
|
243
|
+
if (process.env.NODE_ENV === "production") return pipeline;
|
|
244
|
+
return function guardedPipeline(tag, props, className, variantKey) {
|
|
245
|
+
const result = pipeline(tag, props, className, variantKey);
|
|
246
|
+
if (typeof result !== "string")
|
|
247
|
+
panic(`[praxis-kit] Plugin pipeline must return a string. Got: ${describe(result)}.`);
|
|
248
|
+
return result;
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
var NOOP_CLASS_PIPELINE = (_tag, _props, className) => Array.isArray(className) ? className.join(" ") : className ?? "";
|
|
252
|
+
function resolveClassPipeline(options, resolved, strict, capabilities) {
|
|
253
|
+
const factory = options.styling?.plugin;
|
|
254
|
+
if (!factory) {
|
|
255
|
+
const createClassPipeline2 = capabilities?.createClassPipeline;
|
|
256
|
+
const classPipeline2 = createClassPipeline2 ? createClassPipeline2(resolved) : NOOP_CLASS_PIPELINE;
|
|
257
|
+
return { pluginResult: void 0, classPipeline: classPipeline2 };
|
|
258
|
+
}
|
|
259
|
+
const pluginResult = factory(resolved, strict);
|
|
260
|
+
assertPluginShape(pluginResult);
|
|
261
|
+
const classPipeline = guardPipeline(pluginResult.pipeline);
|
|
262
|
+
return { pluginResult, classPipeline };
|
|
263
|
+
}
|
|
264
|
+
function createRuntimeMethods(resolved, classPipeline, engine) {
|
|
265
|
+
return {
|
|
266
|
+
resolveTag: makeResolveTag(resolved.defaultTag),
|
|
267
|
+
resolveProps(props) {
|
|
268
|
+
return mergeProps(resolved.defaultProps, props);
|
|
269
|
+
},
|
|
270
|
+
resolveClasses(tag, props, className, variantKey) {
|
|
271
|
+
if (process.env.NODE_ENV !== "production") {
|
|
272
|
+
validateRenderProps(resolved, props, variantKey);
|
|
273
|
+
}
|
|
274
|
+
return classPipeline(tag, props, className, variantKey);
|
|
275
|
+
},
|
|
276
|
+
resolveAria(tag, props) {
|
|
277
|
+
if (!engine) return { props };
|
|
278
|
+
const result = engine.validate(tag, props);
|
|
279
|
+
return { props: result.props };
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function createRuntimeObject(methods, resolved, pluginResult) {
|
|
284
|
+
return pluginResult ? { ...methods, options: resolved, hasStyling: true, classPlugin: pluginResult } : { ...methods, options: resolved };
|
|
285
|
+
}
|
|
286
|
+
function createPolymorphic(options = {}, capabilities) {
|
|
287
|
+
const resolved = resolveFactoryOptions(options);
|
|
288
|
+
if (process.env.NODE_ENV !== "production") validateFactoryOptions(resolved);
|
|
289
|
+
const { pluginResult, classPipeline } = resolveClassPipeline(
|
|
290
|
+
options,
|
|
291
|
+
resolved,
|
|
292
|
+
resolved.strict,
|
|
293
|
+
capabilities
|
|
294
|
+
);
|
|
295
|
+
const engine = options.enforcement !== void 0 && capabilities?.AriaEngine ? new capabilities.AriaEngine(
|
|
296
|
+
resolved.strict,
|
|
297
|
+
resolved.ariaRules?.length ? { rules: resolved.ariaRules } : void 0
|
|
298
|
+
) : null;
|
|
299
|
+
const methods = createRuntimeMethods(resolved, classPipeline, engine);
|
|
300
|
+
return createRuntimeObject(
|
|
301
|
+
methods,
|
|
302
|
+
resolved,
|
|
303
|
+
pluginResult
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
var KNOWN_ARIA_ROLES = [
|
|
307
|
+
"alert",
|
|
308
|
+
"alertdialog",
|
|
309
|
+
"application",
|
|
310
|
+
"article",
|
|
311
|
+
"banner",
|
|
312
|
+
"blockquote",
|
|
313
|
+
"button",
|
|
314
|
+
"caption",
|
|
315
|
+
"cell",
|
|
316
|
+
"checkbox",
|
|
317
|
+
"code",
|
|
318
|
+
"columnheader",
|
|
319
|
+
"combobox",
|
|
320
|
+
"complementary",
|
|
321
|
+
"contentinfo",
|
|
322
|
+
"definition",
|
|
323
|
+
"deletion",
|
|
324
|
+
"dialog",
|
|
325
|
+
"document",
|
|
326
|
+
"emphasis",
|
|
327
|
+
"feed",
|
|
328
|
+
"figure",
|
|
329
|
+
"form",
|
|
330
|
+
"generic",
|
|
331
|
+
"grid",
|
|
332
|
+
"gridcell",
|
|
333
|
+
"group",
|
|
334
|
+
"heading",
|
|
335
|
+
"img",
|
|
336
|
+
"insertion",
|
|
337
|
+
"link",
|
|
338
|
+
"list",
|
|
339
|
+
"listbox",
|
|
340
|
+
"listitem",
|
|
341
|
+
"log",
|
|
342
|
+
"main",
|
|
343
|
+
"marquee",
|
|
344
|
+
"math",
|
|
345
|
+
"menu",
|
|
346
|
+
"menubar",
|
|
347
|
+
"menuitem",
|
|
348
|
+
"menuitemcheckbox",
|
|
349
|
+
"menuitemradio",
|
|
350
|
+
"meter",
|
|
351
|
+
"navigation",
|
|
352
|
+
"none",
|
|
353
|
+
"note",
|
|
354
|
+
"option",
|
|
355
|
+
"paragraph",
|
|
356
|
+
"presentation",
|
|
357
|
+
"progressbar",
|
|
358
|
+
"radio",
|
|
359
|
+
"radiogroup",
|
|
360
|
+
"region",
|
|
361
|
+
"row",
|
|
362
|
+
"rowgroup",
|
|
363
|
+
"rowheader",
|
|
364
|
+
"scrollbar",
|
|
365
|
+
"search",
|
|
366
|
+
"searchbox",
|
|
367
|
+
"separator",
|
|
368
|
+
"slider",
|
|
369
|
+
"spinbutton",
|
|
370
|
+
"status",
|
|
371
|
+
"strong",
|
|
372
|
+
"subscript",
|
|
373
|
+
"superscript",
|
|
374
|
+
"switch",
|
|
375
|
+
"tab",
|
|
376
|
+
"table",
|
|
377
|
+
"tablist",
|
|
378
|
+
"tabpanel",
|
|
379
|
+
"term",
|
|
380
|
+
"textbox",
|
|
381
|
+
"time",
|
|
382
|
+
"timer",
|
|
383
|
+
"toolbar",
|
|
384
|
+
"tooltip",
|
|
385
|
+
"tree",
|
|
386
|
+
"treegrid",
|
|
387
|
+
"treeitem"
|
|
388
|
+
];
|
|
389
|
+
var KNOWN_ARIA_ROLES_SET = new Set(KNOWN_ARIA_ROLES);
|
|
390
|
+
var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
391
|
+
"aria-atomic",
|
|
392
|
+
"aria-busy",
|
|
393
|
+
"aria-controls",
|
|
394
|
+
"aria-current",
|
|
395
|
+
"aria-describedby",
|
|
396
|
+
"aria-details",
|
|
397
|
+
"aria-disabled",
|
|
398
|
+
"aria-errormessage",
|
|
399
|
+
"aria-flowto",
|
|
400
|
+
"aria-hidden",
|
|
401
|
+
"aria-keyshortcuts",
|
|
402
|
+
"aria-label",
|
|
403
|
+
"aria-labelledby",
|
|
404
|
+
"aria-live",
|
|
405
|
+
"aria-owns",
|
|
406
|
+
"aria-relevant",
|
|
407
|
+
"aria-roledescription"
|
|
408
|
+
]);
|
|
409
|
+
var IMPLICIT_ROLE_RECORD = {
|
|
410
|
+
article: "article",
|
|
411
|
+
aside: "complementary",
|
|
412
|
+
footer: "contentinfo",
|
|
413
|
+
header: "banner",
|
|
414
|
+
main: "main",
|
|
415
|
+
nav: "navigation",
|
|
416
|
+
button: "button",
|
|
417
|
+
a: "link",
|
|
418
|
+
select: "listbox",
|
|
419
|
+
h1: "heading",
|
|
420
|
+
h2: "heading",
|
|
421
|
+
h3: "heading",
|
|
422
|
+
h4: "heading",
|
|
423
|
+
h5: "heading",
|
|
424
|
+
h6: "heading",
|
|
425
|
+
ul: "list",
|
|
426
|
+
ol: "list",
|
|
427
|
+
li: "listitem",
|
|
428
|
+
table: "table",
|
|
429
|
+
tr: "row",
|
|
430
|
+
td: "cell",
|
|
431
|
+
th: "columnheader"
|
|
432
|
+
};
|
|
433
|
+
var STRONG_ROLES = [
|
|
434
|
+
"main",
|
|
435
|
+
"navigation",
|
|
436
|
+
"complementary",
|
|
437
|
+
"contentinfo",
|
|
438
|
+
"banner"
|
|
439
|
+
];
|
|
440
|
+
var STANDALONE_ROLES = ["article"];
|
|
441
|
+
var STRONG_ROLES_SET = new Set(STRONG_ROLES);
|
|
442
|
+
var STANDALONE_ROLES_SET = new Set(STANDALONE_ROLES);
|
|
443
|
+
var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
|
|
444
|
+
[
|
|
445
|
+
"aria-activedescendant",
|
|
446
|
+
/* @__PURE__ */ new Set([
|
|
447
|
+
"application",
|
|
448
|
+
"combobox",
|
|
449
|
+
"grid",
|
|
450
|
+
"group",
|
|
451
|
+
"listbox",
|
|
452
|
+
"menu",
|
|
453
|
+
"menubar",
|
|
454
|
+
"radiogroup",
|
|
455
|
+
"spinbutton",
|
|
456
|
+
"tablist",
|
|
457
|
+
"toolbar",
|
|
458
|
+
"textbox",
|
|
459
|
+
"tree",
|
|
460
|
+
"treegrid"
|
|
461
|
+
])
|
|
462
|
+
],
|
|
463
|
+
["aria-autocomplete", /* @__PURE__ */ new Set(["combobox", "searchbox", "textbox"])],
|
|
464
|
+
[
|
|
465
|
+
"aria-checked",
|
|
466
|
+
/* @__PURE__ */ new Set(["checkbox", "menuitemcheckbox", "option", "radio", "switch", "treeitem"])
|
|
467
|
+
],
|
|
468
|
+
["aria-colcount", /* @__PURE__ */ new Set(["grid", "table", "treegrid"])],
|
|
469
|
+
["aria-colindex", /* @__PURE__ */ new Set(["cell", "columnheader", "gridcell", "row", "rowheader"])],
|
|
470
|
+
["aria-colspan", /* @__PURE__ */ new Set(["cell", "columnheader", "gridcell", "rowheader"])],
|
|
471
|
+
[
|
|
472
|
+
"aria-expanded",
|
|
473
|
+
/* @__PURE__ */ new Set([
|
|
474
|
+
"button",
|
|
475
|
+
"combobox",
|
|
476
|
+
"gridcell",
|
|
477
|
+
"listbox",
|
|
478
|
+
"menuitem",
|
|
479
|
+
"menuitemcheckbox",
|
|
480
|
+
"menuitemradio",
|
|
481
|
+
"row",
|
|
482
|
+
"rowheader",
|
|
483
|
+
"tab",
|
|
484
|
+
"treeitem"
|
|
485
|
+
])
|
|
486
|
+
],
|
|
487
|
+
[
|
|
488
|
+
"aria-haspopup",
|
|
489
|
+
/* @__PURE__ */ new Set([
|
|
490
|
+
"button",
|
|
491
|
+
"combobox",
|
|
492
|
+
"gridcell",
|
|
493
|
+
"listbox",
|
|
494
|
+
"menuitem",
|
|
495
|
+
"menuitemcheckbox",
|
|
496
|
+
"menuitemradio",
|
|
497
|
+
"tab",
|
|
498
|
+
"treeitem"
|
|
499
|
+
])
|
|
500
|
+
],
|
|
501
|
+
["aria-level", /* @__PURE__ */ new Set(["heading", "listitem", "row", "treeitem"])],
|
|
502
|
+
["aria-modal", /* @__PURE__ */ new Set(["alertdialog", "dialog"])],
|
|
503
|
+
["aria-multiline", /* @__PURE__ */ new Set(["textbox"])],
|
|
504
|
+
["aria-multiselectable", /* @__PURE__ */ new Set(["grid", "listbox", "tablist", "tree", "treegrid"])],
|
|
505
|
+
[
|
|
506
|
+
"aria-orientation",
|
|
507
|
+
/* @__PURE__ */ new Set(["scrollbar", "select", "separator", "slider", "tablist", "toolbar", "tree"])
|
|
508
|
+
],
|
|
509
|
+
["aria-placeholder", /* @__PURE__ */ new Set(["searchbox", "textbox"])],
|
|
510
|
+
[
|
|
511
|
+
"aria-posinset",
|
|
512
|
+
/* @__PURE__ */ new Set([
|
|
513
|
+
"article",
|
|
514
|
+
"listitem",
|
|
515
|
+
"menuitem",
|
|
516
|
+
"menuitemcheckbox",
|
|
517
|
+
"menuitemradio",
|
|
518
|
+
"option",
|
|
519
|
+
"radio",
|
|
520
|
+
"row",
|
|
521
|
+
"tab"
|
|
522
|
+
])
|
|
523
|
+
],
|
|
524
|
+
["aria-pressed", /* @__PURE__ */ new Set(["button"])],
|
|
525
|
+
[
|
|
526
|
+
"aria-readonly",
|
|
527
|
+
/* @__PURE__ */ new Set([
|
|
528
|
+
"combobox",
|
|
529
|
+
"grid",
|
|
530
|
+
"gridcell",
|
|
531
|
+
"listbox",
|
|
532
|
+
"radiogroup",
|
|
533
|
+
"slider",
|
|
534
|
+
"spinbutton",
|
|
535
|
+
"textbox",
|
|
536
|
+
"tree",
|
|
537
|
+
"treegrid"
|
|
538
|
+
])
|
|
539
|
+
],
|
|
540
|
+
[
|
|
541
|
+
"aria-required",
|
|
542
|
+
/* @__PURE__ */ new Set([
|
|
543
|
+
"combobox",
|
|
544
|
+
"gridcell",
|
|
545
|
+
"listbox",
|
|
546
|
+
"radiogroup",
|
|
547
|
+
"spinbutton",
|
|
548
|
+
"textbox",
|
|
549
|
+
"tree",
|
|
550
|
+
"treegrid"
|
|
551
|
+
])
|
|
552
|
+
],
|
|
553
|
+
["aria-rowcount", /* @__PURE__ */ new Set(["grid", "table", "treegrid"])],
|
|
554
|
+
["aria-rowindex", /* @__PURE__ */ new Set(["cell", "columnheader", "gridcell", "row", "rowheader"])],
|
|
555
|
+
["aria-rowspan", /* @__PURE__ */ new Set(["cell", "columnheader", "gridcell", "rowheader"])],
|
|
556
|
+
[
|
|
557
|
+
"aria-selected",
|
|
558
|
+
/* @__PURE__ */ new Set(["columnheader", "gridcell", "option", "row", "rowheader", "tab", "treeitem"])
|
|
559
|
+
],
|
|
560
|
+
[
|
|
561
|
+
"aria-setsize",
|
|
562
|
+
/* @__PURE__ */ new Set([
|
|
563
|
+
"article",
|
|
564
|
+
"listitem",
|
|
565
|
+
"menuitem",
|
|
566
|
+
"menuitemcheckbox",
|
|
567
|
+
"menuitemradio",
|
|
568
|
+
"option",
|
|
569
|
+
"radio",
|
|
570
|
+
"row",
|
|
571
|
+
"tab"
|
|
572
|
+
])
|
|
573
|
+
],
|
|
574
|
+
["aria-sort", /* @__PURE__ */ new Set(["columnheader", "rowheader"])],
|
|
575
|
+
[
|
|
576
|
+
"aria-valuemax",
|
|
577
|
+
/* @__PURE__ */ new Set(["meter", "progressbar", "scrollbar", "separator", "slider", "spinbutton"])
|
|
578
|
+
],
|
|
579
|
+
[
|
|
580
|
+
"aria-valuemin",
|
|
581
|
+
/* @__PURE__ */ new Set(["meter", "progressbar", "scrollbar", "separator", "slider", "spinbutton"])
|
|
582
|
+
],
|
|
583
|
+
[
|
|
584
|
+
"aria-valuenow",
|
|
585
|
+
/* @__PURE__ */ new Set(["meter", "progressbar", "scrollbar", "separator", "slider", "spinbutton"])
|
|
586
|
+
],
|
|
587
|
+
[
|
|
588
|
+
"aria-valuetext",
|
|
589
|
+
/* @__PURE__ */ new Set(["meter", "progressbar", "scrollbar", "separator", "slider", "spinbutton"])
|
|
590
|
+
]
|
|
591
|
+
]);
|
|
592
|
+
function isUndefined(value) {
|
|
593
|
+
return value === void 0;
|
|
594
|
+
}
|
|
595
|
+
function isGlobalAriaAttribute(attr) {
|
|
596
|
+
return GLOBAL_ARIA_ATTRIBUTES.has(attr);
|
|
597
|
+
}
|
|
598
|
+
function isAriaAttributeValidForRole(attr, role) {
|
|
599
|
+
const allowedRoles = ROLE_RESTRICTED_ATTRIBUTES.get(attr);
|
|
600
|
+
if (isUndefined(allowedRoles)) return true;
|
|
601
|
+
if (isUndefined(role)) return false;
|
|
602
|
+
return allowedRoles.has(role);
|
|
603
|
+
}
|
|
604
|
+
function isStrongImplicitRole(tag) {
|
|
605
|
+
if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
|
|
606
|
+
return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
|
|
607
|
+
}
|
|
608
|
+
function isStandaloneTag(tag) {
|
|
609
|
+
if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
|
|
610
|
+
return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
|
|
611
|
+
}
|
|
612
|
+
function isKnownAriaRole(value) {
|
|
613
|
+
return isString(value) && KNOWN_ARIA_ROLES_SET.has(value);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// ../core/dist/chunk-7YNORQXK.js
|
|
617
|
+
var COMPONENT_DEFAULT_TAG2 = /* @__PURE__ */ Symbol("praxis.component-default-tag");
|
|
618
|
+
function resolveChildTag(child) {
|
|
619
|
+
if (!isObject2(child) || !("type" in child)) return void 0;
|
|
620
|
+
const t = child.type;
|
|
621
|
+
if (isString(t)) return t;
|
|
622
|
+
if (isObject2(t) && COMPONENT_DEFAULT_TAG2 in t) {
|
|
623
|
+
const defaultTag = t[COMPONENT_DEFAULT_TAG2];
|
|
624
|
+
if (!isString(defaultTag)) return void 0;
|
|
625
|
+
const props = child.props;
|
|
626
|
+
const as = isObject2(props) && "as" in props ? props.as : void 0;
|
|
627
|
+
return isString(as) ? as : defaultTag;
|
|
628
|
+
}
|
|
629
|
+
return void 0;
|
|
630
|
+
}
|
|
631
|
+
function isTag(...tags) {
|
|
632
|
+
const set = new Set(tags);
|
|
633
|
+
return (child) => {
|
|
634
|
+
const tag = resolveChildTag(child);
|
|
635
|
+
return tag !== void 0 && set.has(tag);
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
function isOpenContent(...blockedTags) {
|
|
639
|
+
const set = new Set(blockedTags);
|
|
640
|
+
return (child) => isObject2(child) && "type" in child && (!isString(child.type) || !set.has(child.type));
|
|
641
|
+
}
|
|
642
|
+
var METADATA_TAGS = ["script", "template"];
|
|
643
|
+
var metadataMatch = isTag(...METADATA_TAGS);
|
|
644
|
+
function metadata(name = "metadata") {
|
|
645
|
+
return { name, match: metadataMatch };
|
|
646
|
+
}
|
|
647
|
+
function firstOptional(name, tag) {
|
|
648
|
+
return { name, match: isTag(tag), cardinality: { max: 1 }, position: "first" };
|
|
649
|
+
}
|
|
650
|
+
function contract(children) {
|
|
651
|
+
return { strict: "warn", children };
|
|
652
|
+
}
|
|
653
|
+
function ariaContract(aria) {
|
|
654
|
+
return { strict: "warn", aria };
|
|
655
|
+
}
|
|
656
|
+
function firstChildContract(name, tag) {
|
|
657
|
+
return contract([firstOptional(name, tag), { name: "content", match: isOpenContent(tag) }]);
|
|
658
|
+
}
|
|
659
|
+
var VOID_TAGS = [
|
|
660
|
+
"area",
|
|
661
|
+
"base",
|
|
662
|
+
"br",
|
|
663
|
+
"col",
|
|
664
|
+
"embed",
|
|
665
|
+
"hr",
|
|
666
|
+
"img",
|
|
667
|
+
"input",
|
|
668
|
+
"link",
|
|
669
|
+
"meta",
|
|
670
|
+
"param",
|
|
671
|
+
"source",
|
|
672
|
+
"track",
|
|
673
|
+
"wbr"
|
|
674
|
+
];
|
|
675
|
+
var TEXT_ONLY_TAGS = ["option", "script", "style", "textarea", "title"];
|
|
676
|
+
var LANDMARK_TAGS = ["article", "aside", "footer", "header", "main", "nav"];
|
|
677
|
+
var listContract = contract([{ name: "list-item", match: isTag("li", ...METADATA_TAGS) }]);
|
|
678
|
+
var tableContract = contract([
|
|
679
|
+
firstOptional("caption", "caption"),
|
|
680
|
+
{ name: "colgroup", match: isTag("colgroup") },
|
|
681
|
+
{ name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
|
|
682
|
+
{ name: "tbody", match: isTag("tbody") },
|
|
683
|
+
{ name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
|
|
684
|
+
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
685
|
+
]);
|
|
686
|
+
var tableBodyContract = contract([
|
|
687
|
+
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
688
|
+
]);
|
|
689
|
+
var tableRowContract = contract([
|
|
690
|
+
{ name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
|
|
691
|
+
]);
|
|
692
|
+
var colgroupContract = contract([{ name: "column", match: isTag("col", "template") }]);
|
|
693
|
+
var dlContract = contract([
|
|
694
|
+
{ name: "term", match: isTag("dt") },
|
|
695
|
+
{ name: "description", match: isTag("dd") },
|
|
696
|
+
{ name: "group", match: isTag("div") },
|
|
697
|
+
metadata()
|
|
698
|
+
]);
|
|
699
|
+
var selectContract = contract([
|
|
700
|
+
{ name: "option", match: isTag("option", "optgroup", "hr", ...METADATA_TAGS) }
|
|
701
|
+
]);
|
|
702
|
+
var optgroupContract = contract([
|
|
703
|
+
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
704
|
+
]);
|
|
705
|
+
var datalistContract = contract([
|
|
706
|
+
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
707
|
+
]);
|
|
708
|
+
var pictureContract = contract([
|
|
709
|
+
{ name: "source", match: isTag("source", ...METADATA_TAGS) },
|
|
710
|
+
{ name: "image", match: isTag("img"), cardinality: { min: 1, max: 1 }, position: "last" }
|
|
711
|
+
]);
|
|
712
|
+
var figureContract = contract([
|
|
713
|
+
{ name: "caption", match: isTag("figcaption"), cardinality: { max: 1 } },
|
|
714
|
+
{ name: "content", match: isOpenContent("figcaption") }
|
|
715
|
+
]);
|
|
716
|
+
var detailsContract = firstChildContract("summary", "summary");
|
|
717
|
+
var fieldsetContract = firstChildContract("legend", "legend");
|
|
718
|
+
var mediaContract = contract([
|
|
719
|
+
{ name: "source", match: isTag("source") },
|
|
720
|
+
{ name: "track", match: isTag("track") },
|
|
721
|
+
metadata(),
|
|
722
|
+
{ name: "content", match: isOpenContent("source", "track", ...METADATA_TAGS) }
|
|
723
|
+
]);
|
|
724
|
+
var headContract = contract([
|
|
725
|
+
{
|
|
726
|
+
name: "metadata",
|
|
727
|
+
match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
|
|
728
|
+
}
|
|
729
|
+
]);
|
|
730
|
+
var htmlContract = contract([
|
|
731
|
+
{ name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
|
|
732
|
+
{ name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
|
|
733
|
+
]);
|
|
734
|
+
var voidContract = contract([]);
|
|
735
|
+
var textOnlyContract = contract([
|
|
736
|
+
{
|
|
737
|
+
name: "text",
|
|
738
|
+
match: (child) => isString(child) || isNumber(child)
|
|
739
|
+
}
|
|
740
|
+
]);
|
|
741
|
+
var LANDMARK_TAG_SET = new Set(LANDMARK_TAGS);
|
|
742
|
+
var removeLandmarkRoleOverride = {
|
|
743
|
+
kind: "removeRole",
|
|
744
|
+
apply: ({ props }) => {
|
|
745
|
+
if (!("role" in props)) return { applied: false, next: props };
|
|
746
|
+
const { role: _r, ...rest } = props;
|
|
747
|
+
return { applied: true, next: rest, previous: props };
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
function landmarkRoleRule({ tag, props, implicitRole }) {
|
|
751
|
+
if (!LANDMARK_TAG_SET.has(tag) || !implicitRole) return [];
|
|
752
|
+
const role = props.role;
|
|
753
|
+
if (!role || role === implicitRole) return [];
|
|
754
|
+
return [
|
|
755
|
+
{
|
|
756
|
+
valid: false,
|
|
757
|
+
fixable: true,
|
|
758
|
+
severity: "error",
|
|
759
|
+
fix: removeLandmarkRoleOverride,
|
|
760
|
+
message: `<${tag}> has a fixed landmark role="${implicitRole}". role="${role}" overrides it and confuses assistive technology. The override has been removed.`
|
|
761
|
+
}
|
|
762
|
+
];
|
|
763
|
+
}
|
|
764
|
+
var landmarkContract = ariaContract([landmarkRoleRule]);
|
|
765
|
+
var CONTRACT_GROUPS = [
|
|
766
|
+
[VOID_TAGS, voidContract],
|
|
767
|
+
[TEXT_ONLY_TAGS, textOnlyContract],
|
|
768
|
+
[LANDMARK_TAGS, landmarkContract],
|
|
769
|
+
[["ul", "ol", "menu"], listContract],
|
|
770
|
+
[["audio", "video"], mediaContract],
|
|
771
|
+
[["thead", "tbody", "tfoot"], tableBodyContract]
|
|
772
|
+
];
|
|
773
|
+
function contractMap(groups) {
|
|
774
|
+
return Object.fromEntries(
|
|
775
|
+
groups.flatMap(([tags, enforcement]) => tags.map((tag) => [tag, enforcement]))
|
|
776
|
+
);
|
|
777
|
+
}
|
|
778
|
+
var htmlContracts = {
|
|
779
|
+
...contractMap(CONTRACT_GROUPS),
|
|
780
|
+
table: tableContract,
|
|
781
|
+
tr: tableRowContract,
|
|
782
|
+
colgroup: colgroupContract,
|
|
783
|
+
dl: dlContract,
|
|
784
|
+
select: selectContract,
|
|
785
|
+
optgroup: optgroupContract,
|
|
786
|
+
datalist: datalistContract,
|
|
787
|
+
picture: pictureContract,
|
|
788
|
+
figure: figureContract,
|
|
789
|
+
details: detailsContract,
|
|
790
|
+
fieldset: fieldsetContract,
|
|
791
|
+
head: headContract,
|
|
792
|
+
html: htmlContract
|
|
793
|
+
};
|
|
794
|
+
var IMPLICIT_ROLE_RECORD2 = {
|
|
795
|
+
article: "article",
|
|
796
|
+
aside: "complementary",
|
|
797
|
+
footer: "contentinfo",
|
|
798
|
+
header: "banner",
|
|
799
|
+
main: "main",
|
|
800
|
+
nav: "navigation",
|
|
801
|
+
button: "button",
|
|
802
|
+
a: "link",
|
|
803
|
+
select: "listbox",
|
|
804
|
+
h1: "heading",
|
|
805
|
+
h2: "heading",
|
|
806
|
+
h3: "heading",
|
|
807
|
+
h4: "heading",
|
|
808
|
+
h5: "heading",
|
|
809
|
+
h6: "heading",
|
|
810
|
+
ul: "list",
|
|
811
|
+
ol: "list",
|
|
812
|
+
li: "listitem",
|
|
813
|
+
table: "table",
|
|
814
|
+
tr: "row",
|
|
815
|
+
td: "cell",
|
|
816
|
+
th: "columnheader"
|
|
817
|
+
};
|
|
818
|
+
function getImplicitRole(tag) {
|
|
819
|
+
if (tag in IMPLICIT_ROLE_RECORD2) return IMPLICIT_ROLE_RECORD2[tag];
|
|
820
|
+
return void 0;
|
|
821
|
+
}
|
|
822
|
+
var pendingAsyncWarns2 = /* @__PURE__ */ new Set();
|
|
823
|
+
var asyncWarnScheduled2 = false;
|
|
824
|
+
function flushAsyncWarns2() {
|
|
825
|
+
asyncWarnScheduled2 = false;
|
|
826
|
+
const messages = [...pendingAsyncWarns2];
|
|
827
|
+
pendingAsyncWarns2.clear();
|
|
828
|
+
for (const msg of messages) {
|
|
829
|
+
console.warn(msg);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
function scheduleAsyncWarn(message) {
|
|
833
|
+
if (pendingAsyncWarns2.has(message)) return;
|
|
834
|
+
pendingAsyncWarns2.add(message);
|
|
835
|
+
if (!asyncWarnScheduled2) {
|
|
836
|
+
asyncWarnScheduled2 = true;
|
|
837
|
+
queueMicrotask(flushAsyncWarns2);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
var StrictBase = class {
|
|
841
|
+
strict;
|
|
842
|
+
constructor(strict) {
|
|
843
|
+
this.strict = strict;
|
|
844
|
+
}
|
|
845
|
+
violate(message) {
|
|
846
|
+
if (this.strict === true || this.strict === "throw") {
|
|
847
|
+
throw new Error(message);
|
|
848
|
+
}
|
|
849
|
+
this.warn(message);
|
|
850
|
+
}
|
|
851
|
+
// Always caps at console.warn — never throws. ARIA 'warning' violations route here
|
|
852
|
+
// so they surface even in strict='throw' mode without aborting a render.
|
|
853
|
+
warn(message) {
|
|
854
|
+
if (!this.strict) return;
|
|
855
|
+
if (this.strict === "async-warn") {
|
|
856
|
+
scheduleAsyncWarn(message);
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
console.warn(message);
|
|
860
|
+
}
|
|
861
|
+
invariant(condition, message) {
|
|
862
|
+
if (!condition) {
|
|
863
|
+
this.violate(message);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
};
|
|
867
|
+
function isNull3(value) {
|
|
868
|
+
return value === null;
|
|
869
|
+
}
|
|
870
|
+
var VALID = [{ valid: true }];
|
|
871
|
+
function isIntrinsicTag(tag) {
|
|
872
|
+
return isString(tag);
|
|
873
|
+
}
|
|
874
|
+
function omitProp(obj, key) {
|
|
875
|
+
const { [key]: _, ...rest } = obj;
|
|
876
|
+
return rest;
|
|
877
|
+
}
|
|
878
|
+
var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
879
|
+
#extraRules;
|
|
880
|
+
#planCache = /* @__PURE__ */ new Map();
|
|
881
|
+
static #MAX_CACHE = 100;
|
|
882
|
+
// Memoized AriaFix objects keyed by attribute name — the ARIA attribute set is
|
|
883
|
+
// finite so this Map is bounded and avoids recreating closures on every cache miss.
|
|
884
|
+
static #removeAttributeFixCache = /* @__PURE__ */ new Map();
|
|
885
|
+
constructor(strict = "warn", options) {
|
|
886
|
+
super(strict);
|
|
887
|
+
this.#extraRules = options?.rules ?? [];
|
|
888
|
+
}
|
|
889
|
+
static #normalizeEmptyRole(tag, props) {
|
|
890
|
+
if (props.role !== "") return { normalized: false };
|
|
891
|
+
return {
|
|
892
|
+
normalized: true,
|
|
893
|
+
result: {
|
|
894
|
+
props: omitProp(props, "role"),
|
|
895
|
+
violations: [
|
|
896
|
+
{
|
|
897
|
+
message: `<${tag}> has an explicit empty role="". Omit the attribute instead.`,
|
|
898
|
+
tag,
|
|
899
|
+
role: "",
|
|
900
|
+
attribute: void 0,
|
|
901
|
+
severity: "warning",
|
|
902
|
+
phase: "evaluate"
|
|
903
|
+
}
|
|
904
|
+
]
|
|
905
|
+
}
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
static #deriveContext(tag, props) {
|
|
909
|
+
if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
|
|
910
|
+
const implicitRole = getImplicitRole(tag);
|
|
911
|
+
const hasExplicitLiveRole = !implicitRole && _AriaPolicyEngine.#LIVE_REGION_ROLES.has(props.role ?? "");
|
|
912
|
+
if (!implicitRole && !hasExplicitLiveRole)
|
|
913
|
+
return { proceed: false, result: { props, violations: [] } };
|
|
914
|
+
const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
|
|
915
|
+
if (normalized.normalized) return { proceed: false, result: normalized.result };
|
|
916
|
+
const effectiveRole = props.role ?? implicitRole;
|
|
917
|
+
return {
|
|
918
|
+
proceed: true,
|
|
919
|
+
tag,
|
|
920
|
+
implicitRole,
|
|
921
|
+
effectiveRole,
|
|
922
|
+
context: { tag, props, implicitRole, effectiveRole }
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
static #runRules(rules, context) {
|
|
926
|
+
const violations = [];
|
|
927
|
+
const fixes = [];
|
|
928
|
+
for (const rule of rules) {
|
|
929
|
+
for (const result of rule(context)) {
|
|
930
|
+
if (!result.valid) {
|
|
931
|
+
violations.push({
|
|
932
|
+
message: result.message ?? `Invalid role "${context.props.role}" on <${context.tag}>`,
|
|
933
|
+
tag: context.tag,
|
|
934
|
+
role: context.props.role,
|
|
935
|
+
attribute: result.attribute,
|
|
936
|
+
severity: result.severity,
|
|
937
|
+
phase: "evaluate"
|
|
938
|
+
});
|
|
939
|
+
if (result.fixable) fixes.push(result.fix);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
return { violations, fixes };
|
|
944
|
+
}
|
|
945
|
+
static #getRules(context) {
|
|
946
|
+
return _AriaPolicyEngine.#hasRole(context.props) ? _AriaPolicyEngine.#pipeline : [_AriaPolicyEngine.#checkInvalidAriaAttributes];
|
|
947
|
+
}
|
|
948
|
+
static evaluate(tag, props) {
|
|
949
|
+
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
950
|
+
if (!derived.proceed) return derived.result;
|
|
951
|
+
const { tag: narrowedTag, implicitRole, context } = derived;
|
|
952
|
+
const { violations, fixes } = _AriaPolicyEngine.#runRules(
|
|
953
|
+
_AriaPolicyEngine.#getRules(context),
|
|
954
|
+
context
|
|
955
|
+
);
|
|
956
|
+
const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, props, fixes);
|
|
957
|
+
return { props: next, violations };
|
|
958
|
+
}
|
|
959
|
+
static #evaluateWithRules(tag, props, extraRules) {
|
|
960
|
+
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
961
|
+
if (!derived.proceed) return derived.result;
|
|
962
|
+
const { tag: narrowedTag, implicitRole, context } = derived;
|
|
963
|
+
const { violations, fixes } = _AriaPolicyEngine.#runRules(
|
|
964
|
+
[..._AriaPolicyEngine.#getRules(context), ...extraRules],
|
|
965
|
+
context
|
|
966
|
+
);
|
|
967
|
+
const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, props, fixes);
|
|
968
|
+
return { props: next, violations };
|
|
969
|
+
}
|
|
970
|
+
report(violations) {
|
|
971
|
+
for (const v of violations) {
|
|
972
|
+
if (v.severity === "error") this.violate(v.message);
|
|
973
|
+
else this.warn(v.message);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
// Cache key covers only the aria-relevant subset of props (tag + role + aria-* attrs).
|
|
977
|
+
// Non-aria props (className, onClick, etc.) do not affect ARIA decisions and are excluded
|
|
978
|
+
// so cache hits survive re-renders that only change non-aria props.
|
|
979
|
+
// Note: #extraRules are NOT included in the key — each engine instance has its own Map,
|
|
980
|
+
// so two engines with different rules never share cache entries. If caching ever becomes
|
|
981
|
+
// static/shared, rule identity would need to be folded into the key.
|
|
982
|
+
static #createPlanKey(tag, props) {
|
|
983
|
+
if (!isIntrinsicTag(tag)) return null;
|
|
984
|
+
const parts = [tag];
|
|
985
|
+
if (typeof props.role === "string") parts.push(`role:${props.role}`);
|
|
986
|
+
const ariaEntries = [];
|
|
987
|
+
for (const k in props) {
|
|
988
|
+
if (!Object.hasOwn(props, k) || !k.startsWith("aria-")) continue;
|
|
989
|
+
const v = props[k];
|
|
990
|
+
if (!isString(v) && !isNumber(v) && typeof v !== "boolean") continue;
|
|
991
|
+
ariaEntries.push(`${k}:${String(v)}`);
|
|
992
|
+
}
|
|
993
|
+
if (ariaEntries.length > 0) parts.push(...ariaEntries.sort());
|
|
994
|
+
return parts.join("|");
|
|
995
|
+
}
|
|
996
|
+
static #computePlan(inputProps, resultProps) {
|
|
997
|
+
const removals = /* @__PURE__ */ new Set();
|
|
998
|
+
const updates = {};
|
|
999
|
+
for (const key in inputProps) {
|
|
1000
|
+
if (Object.hasOwn(inputProps, key) && !(key in resultProps)) removals.add(key);
|
|
1001
|
+
}
|
|
1002
|
+
for (const key in resultProps) {
|
|
1003
|
+
if (!Object.hasOwn(resultProps, key)) continue;
|
|
1004
|
+
const resultVal = resultProps[key];
|
|
1005
|
+
if (inputProps[key] !== resultVal) updates[key] = resultVal;
|
|
1006
|
+
}
|
|
1007
|
+
return { removals, updates };
|
|
1008
|
+
}
|
|
1009
|
+
static #applyPlan(props, removals, updates) {
|
|
1010
|
+
const hasRemovals = removals.size > 0;
|
|
1011
|
+
const hasUpdates = Object.keys(updates).length > 0;
|
|
1012
|
+
if (!hasRemovals && !hasUpdates) return props;
|
|
1013
|
+
const next = {};
|
|
1014
|
+
for (const k in props) {
|
|
1015
|
+
if (Object.hasOwn(props, k) && !removals.has(k)) next[k] = props[k];
|
|
1016
|
+
}
|
|
1017
|
+
Object.assign(next, updates);
|
|
1018
|
+
return next;
|
|
1019
|
+
}
|
|
1020
|
+
validate(tag, props) {
|
|
1021
|
+
const key = _AriaPolicyEngine.#createPlanKey(tag, props);
|
|
1022
|
+
if (!isNull3(key)) {
|
|
1023
|
+
const cached = this.#planCache.get(key);
|
|
1024
|
+
if (cached !== void 0) {
|
|
1025
|
+
this.#planCache.delete(key);
|
|
1026
|
+
this.#planCache.set(key, cached);
|
|
1027
|
+
if (cached.violations.length > 0) this.report(cached.violations);
|
|
1028
|
+
return {
|
|
1029
|
+
props: _AriaPolicyEngine.#applyPlan(props, cached.removals, cached.updates),
|
|
1030
|
+
violations: cached.violations
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
const result = this.#extraRules.length ? _AriaPolicyEngine.#evaluateWithRules(tag, props, this.#extraRules) : _AriaPolicyEngine.evaluate(tag, props);
|
|
1035
|
+
if (result.violations.length > 0) this.report(result.violations);
|
|
1036
|
+
if (!isNull3(key)) {
|
|
1037
|
+
const { removals, updates } = _AriaPolicyEngine.#computePlan(
|
|
1038
|
+
props,
|
|
1039
|
+
result.props
|
|
1040
|
+
);
|
|
1041
|
+
const plan = { removals, updates, violations: result.violations };
|
|
1042
|
+
this.#planCache.set(key, plan);
|
|
1043
|
+
if (this.#planCache.size > _AriaPolicyEngine.#MAX_CACHE) {
|
|
1044
|
+
const lru = this.#planCache.keys().next().value;
|
|
1045
|
+
if (lru !== void 0) this.#planCache.delete(lru);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
return result;
|
|
1049
|
+
}
|
|
1050
|
+
static #hasRole(props) {
|
|
1051
|
+
return isString(props.role) && props.role.length > 0;
|
|
1052
|
+
}
|
|
1053
|
+
static #applyFixes(tag, implicitRole, props, fixes) {
|
|
1054
|
+
if (fixes.length === 0) return props;
|
|
1055
|
+
const sorted = [...fixes].sort((a, b) => (a.priority ?? Infinity) - (b.priority ?? Infinity));
|
|
1056
|
+
let next = props;
|
|
1057
|
+
for (const { apply } of sorted) {
|
|
1058
|
+
const effectiveRole = next.role ?? implicitRole;
|
|
1059
|
+
const fixContext = { tag, implicitRole, effectiveRole, props: next };
|
|
1060
|
+
const fixResult = apply(fixContext);
|
|
1061
|
+
if (fixResult.applied) next = fixResult.next;
|
|
1062
|
+
}
|
|
1063
|
+
return next;
|
|
1064
|
+
}
|
|
1065
|
+
static #removeRole = {
|
|
1066
|
+
kind: "removeRole",
|
|
1067
|
+
apply: ({ props }) => {
|
|
1068
|
+
if (!("role" in props)) return { applied: false, next: props };
|
|
1069
|
+
return { applied: true, next: omitProp(props, "role"), previous: props };
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
static #makeRemoveAttributeFix(attr) {
|
|
1073
|
+
const cached = _AriaPolicyEngine.#removeAttributeFixCache.get(attr);
|
|
1074
|
+
if (cached) return cached;
|
|
1075
|
+
const fix = {
|
|
1076
|
+
kind: `removeAttribute:${attr}`,
|
|
1077
|
+
apply: ({ props }) => {
|
|
1078
|
+
if (!(attr in props)) return { applied: false, next: props };
|
|
1079
|
+
return { applied: true, next: omitProp(props, attr), previous: props };
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
_AriaPolicyEngine.#removeAttributeFixCache.set(attr, fix);
|
|
1083
|
+
return fix;
|
|
1084
|
+
}
|
|
1085
|
+
// Snapshot diagnostic model: all rules evaluate against the same (tag, props, implicitRole) snapshot.
|
|
1086
|
+
static #pipeline = [
|
|
1087
|
+
_AriaPolicyEngine.#checkInvalidRoleOverride,
|
|
1088
|
+
_AriaPolicyEngine.#checkRedundantRole,
|
|
1089
|
+
_AriaPolicyEngine.#checkStandaloneRegion,
|
|
1090
|
+
_AriaPolicyEngine.#checkInvalidAriaAttributes,
|
|
1091
|
+
_AriaPolicyEngine.#checkMissingLiveRegion,
|
|
1092
|
+
_AriaPolicyEngine.#checkMissingAtomic,
|
|
1093
|
+
_AriaPolicyEngine.#checkInvalidAriaRelevant
|
|
1094
|
+
];
|
|
1095
|
+
static #checkInvalidRoleOverride({
|
|
1096
|
+
tag,
|
|
1097
|
+
props,
|
|
1098
|
+
implicitRole
|
|
1099
|
+
}) {
|
|
1100
|
+
const role = props.role;
|
|
1101
|
+
if (!implicitRole || !role || role === implicitRole) return VALID;
|
|
1102
|
+
if (isStrongImplicitRole(tag) && role === "region") {
|
|
1103
|
+
return [
|
|
1104
|
+
{
|
|
1105
|
+
valid: false,
|
|
1106
|
+
fixable: true,
|
|
1107
|
+
severity: "error",
|
|
1108
|
+
fix: _AriaPolicyEngine.#removeRole,
|
|
1109
|
+
message: `<${tag}> should not override its implicit role="${implicitRole}" with role="${role}".`
|
|
1110
|
+
}
|
|
1111
|
+
];
|
|
1112
|
+
}
|
|
1113
|
+
return VALID;
|
|
1114
|
+
}
|
|
1115
|
+
static #checkRedundantRole({ tag, props, implicitRole }) {
|
|
1116
|
+
const role = props.role;
|
|
1117
|
+
if (!implicitRole || !role || role !== implicitRole) return VALID;
|
|
1118
|
+
return [
|
|
1119
|
+
{
|
|
1120
|
+
valid: false,
|
|
1121
|
+
fixable: true,
|
|
1122
|
+
severity: "warning",
|
|
1123
|
+
fix: _AriaPolicyEngine.#removeRole,
|
|
1124
|
+
message: `<${tag}> already has implicit role="${implicitRole}". Avoid redundant role assignment.`
|
|
1125
|
+
}
|
|
1126
|
+
];
|
|
1127
|
+
}
|
|
1128
|
+
static #checkStandaloneRegion({ tag, props, implicitRole }) {
|
|
1129
|
+
const role = props.role;
|
|
1130
|
+
if (role !== "region") return VALID;
|
|
1131
|
+
if (!isStandaloneTag(tag)) return VALID;
|
|
1132
|
+
return [
|
|
1133
|
+
{
|
|
1134
|
+
valid: false,
|
|
1135
|
+
fixable: true,
|
|
1136
|
+
severity: "error",
|
|
1137
|
+
fix: _AriaPolicyEngine.#removeRole,
|
|
1138
|
+
message: `<${tag}> is a self-contained element with implicit role="${implicitRole}". Assigning role="region" has been removed.`
|
|
1139
|
+
}
|
|
1140
|
+
];
|
|
1141
|
+
}
|
|
1142
|
+
static #checkInvalidAriaAttributes({
|
|
1143
|
+
tag,
|
|
1144
|
+
props,
|
|
1145
|
+
effectiveRole
|
|
1146
|
+
}) {
|
|
1147
|
+
const results = [];
|
|
1148
|
+
for (const key in props) {
|
|
1149
|
+
if (!Object.hasOwn(props, key)) continue;
|
|
1150
|
+
if (!key.startsWith("aria-")) continue;
|
|
1151
|
+
if (isGlobalAriaAttribute(key)) continue;
|
|
1152
|
+
if (isAriaAttributeValidForRole(key, effectiveRole)) continue;
|
|
1153
|
+
results.push({
|
|
1154
|
+
valid: false,
|
|
1155
|
+
severity: "warning",
|
|
1156
|
+
fixable: true,
|
|
1157
|
+
attribute: key,
|
|
1158
|
+
message: `"${key}" is not valid on role="${effectiveRole ?? tag}". It will be removed.`,
|
|
1159
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix(key)
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
return results;
|
|
1163
|
+
}
|
|
1164
|
+
// WAI-ARIA live region roles and their implied aria-live politeness values.
|
|
1165
|
+
static #LIVE_REGION_ROLES = /* @__PURE__ */ new Map([
|
|
1166
|
+
["alert", "assertive"],
|
|
1167
|
+
["status", "polite"],
|
|
1168
|
+
["log", "polite"],
|
|
1169
|
+
["timer", "off"]
|
|
1170
|
+
]);
|
|
1171
|
+
static #checkMissingLiveRegion({ effectiveRole, props }) {
|
|
1172
|
+
if (!effectiveRole) return VALID;
|
|
1173
|
+
const impliedLive = _AriaPolicyEngine.#LIVE_REGION_ROLES.get(effectiveRole);
|
|
1174
|
+
if (!impliedLive) return VALID;
|
|
1175
|
+
if ("aria-live" in props) return VALID;
|
|
1176
|
+
const injectLive = {
|
|
1177
|
+
kind: `injectLive:${effectiveRole}`,
|
|
1178
|
+
apply: (ctx) => ({
|
|
1179
|
+
applied: true,
|
|
1180
|
+
next: { ...ctx.props, "aria-live": impliedLive },
|
|
1181
|
+
previous: ctx.props
|
|
1182
|
+
})
|
|
1183
|
+
};
|
|
1184
|
+
return [
|
|
1185
|
+
{
|
|
1186
|
+
valid: false,
|
|
1187
|
+
fixable: true,
|
|
1188
|
+
severity: "warning",
|
|
1189
|
+
fix: injectLive,
|
|
1190
|
+
message: `role="${effectiveRole}" implies aria-live="${impliedLive}" but it is missing. It has been injected.`
|
|
1191
|
+
}
|
|
1192
|
+
];
|
|
1193
|
+
}
|
|
1194
|
+
static #checkMissingAtomic({ effectiveRole, props }) {
|
|
1195
|
+
if (!effectiveRole || !_AriaPolicyEngine.#LIVE_REGION_ROLES.has(effectiveRole)) return VALID;
|
|
1196
|
+
if ("aria-atomic" in props) return VALID;
|
|
1197
|
+
return [
|
|
1198
|
+
{
|
|
1199
|
+
valid: false,
|
|
1200
|
+
fixable: false,
|
|
1201
|
+
severity: "warning",
|
|
1202
|
+
message: `role="${effectiveRole}" is a live region. Consider setting aria-atomic="true" if the full region should be announced as a unit, or aria-atomic="false" if only changed nodes should be read.`
|
|
1203
|
+
}
|
|
1204
|
+
];
|
|
1205
|
+
}
|
|
1206
|
+
static #VALID_RELEVANT_TOKENS = /* @__PURE__ */ new Set(["additions", "removals", "text", "all"]);
|
|
1207
|
+
// Custom fix rules passed via `options.rules` must be pure functions of (tag, props) — the cache
|
|
1208
|
+
// replays stored fixes against new prop objects, so fixes that close over external state will
|
|
1209
|
+
// produce inconsistent results on cache hits.
|
|
1210
|
+
static #normalizeRelevantAllFix = {
|
|
1211
|
+
kind: "normalizeRelevantAll",
|
|
1212
|
+
apply: ({ props: p }) => ({
|
|
1213
|
+
applied: true,
|
|
1214
|
+
next: { ...p, "aria-relevant": "all" },
|
|
1215
|
+
previous: p
|
|
1216
|
+
})
|
|
1217
|
+
};
|
|
1218
|
+
static #checkInvalidAriaRelevant({ props }) {
|
|
1219
|
+
const relevant = props["aria-relevant"];
|
|
1220
|
+
if (relevant === void 0) return VALID;
|
|
1221
|
+
if (typeof relevant !== "string") return VALID;
|
|
1222
|
+
const tokens = relevant.trim().split(/\s+/);
|
|
1223
|
+
const invalid = tokens.filter((t) => !_AriaPolicyEngine.#VALID_RELEVANT_TOKENS.has(t));
|
|
1224
|
+
if (invalid.length > 0) {
|
|
1225
|
+
return [
|
|
1226
|
+
{
|
|
1227
|
+
valid: false,
|
|
1228
|
+
fixable: true,
|
|
1229
|
+
severity: "warning",
|
|
1230
|
+
attribute: "aria-relevant",
|
|
1231
|
+
message: `aria-relevant contains invalid token(s): ${invalid.map((t) => `"${t}"`).join(", ")}. Valid tokens are: additions, removals, text, all.`,
|
|
1232
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix("aria-relevant")
|
|
1233
|
+
}
|
|
1234
|
+
];
|
|
1235
|
+
}
|
|
1236
|
+
if (tokens.includes("all") && tokens.length > 1) {
|
|
1237
|
+
return [
|
|
1238
|
+
{
|
|
1239
|
+
valid: false,
|
|
1240
|
+
fixable: true,
|
|
1241
|
+
severity: "warning",
|
|
1242
|
+
attribute: "aria-relevant",
|
|
1243
|
+
message: `aria-relevant includes "all" alongside other tokens. "all" supersedes additions, removals, and text \u2014 use aria-relevant="all" alone.`,
|
|
1244
|
+
fix: _AriaPolicyEngine.#normalizeRelevantAllFix
|
|
1245
|
+
}
|
|
1246
|
+
];
|
|
1247
|
+
}
|
|
1248
|
+
return VALID;
|
|
1249
|
+
}
|
|
1250
|
+
};
|
|
1251
|
+
function getTypeName(value) {
|
|
1252
|
+
if (value === null) return "null";
|
|
1253
|
+
if (value === void 0) return "undefined";
|
|
1254
|
+
const primitive = typeof value;
|
|
1255
|
+
if (primitive !== "object") {
|
|
1256
|
+
return primitive;
|
|
1257
|
+
}
|
|
1258
|
+
const name = value.constructor?.name;
|
|
1259
|
+
return typeof name === "string" && name !== "Object" ? name : "object";
|
|
1260
|
+
}
|
|
1261
|
+
var MatchValidationErrorBuilder = class {
|
|
1262
|
+
#prefix;
|
|
1263
|
+
constructor(ctx = "") {
|
|
1264
|
+
this.#prefix = ctx ? `${ctx}:
|
|
1265
|
+
` : "";
|
|
1266
|
+
}
|
|
1267
|
+
#template(typeName, index, prefix = "", suffix = "") {
|
|
1268
|
+
const leadingStr = prefix ? `${prefix} ` : "";
|
|
1269
|
+
const followingStr = suffix ? ` ${suffix}` : "";
|
|
1270
|
+
return `${leadingStr}child "${typeName}" at index ${index}${followingStr}.`;
|
|
1271
|
+
}
|
|
1272
|
+
unexpectedChild(typeName, index) {
|
|
1273
|
+
return this.#template(typeName, index, "unexpected");
|
|
1274
|
+
}
|
|
1275
|
+
multipleMatches(typeName, index, ruleNames) {
|
|
1276
|
+
const quoted = ruleNames.map((n) => `"${n}"`);
|
|
1277
|
+
return this.#template(
|
|
1278
|
+
typeName,
|
|
1279
|
+
index,
|
|
1280
|
+
"",
|
|
1281
|
+
`matches multiple child rules: ${quoted.join(" and ")}`
|
|
1282
|
+
);
|
|
1283
|
+
}
|
|
1284
|
+
#format(errors) {
|
|
1285
|
+
return this.#prefix + errors.join("\n");
|
|
1286
|
+
}
|
|
1287
|
+
toError(errors) {
|
|
1288
|
+
if (errors.length === 0) {
|
|
1289
|
+
return new Error(this.#prefix + "Unknown validation error.");
|
|
1290
|
+
}
|
|
1291
|
+
return new Error(this.#format(errors));
|
|
1292
|
+
}
|
|
1293
|
+
};
|
|
1294
|
+
function normalizeCardinality(input, impliesSingleton) {
|
|
1295
|
+
const min = input?.min ?? 0;
|
|
1296
|
+
const max = input?.max ?? (impliesSingleton ? 1 : Infinity);
|
|
1297
|
+
if (min === 0 && max === Infinity) {
|
|
1298
|
+
return { kind: "unbounded" };
|
|
1299
|
+
}
|
|
1300
|
+
if (min > max) {
|
|
1301
|
+
throw new RangeError(`normalizeChildRule: min (${min}) cannot exceed max (${max})`);
|
|
1302
|
+
}
|
|
1303
|
+
return {
|
|
1304
|
+
kind: "bounded",
|
|
1305
|
+
min,
|
|
1306
|
+
max
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
function normalizeChildRule(rule) {
|
|
1310
|
+
const position = rule.position ?? "any";
|
|
1311
|
+
const impliesSingleton = position === "first" || position === "last";
|
|
1312
|
+
return {
|
|
1313
|
+
...rule,
|
|
1314
|
+
position,
|
|
1315
|
+
cardinality: normalizeCardinality(rule.cardinality, impliesSingleton)
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
function getChildType(child) {
|
|
1319
|
+
if (!isObject2(child) || !("type" in child)) return void 0;
|
|
1320
|
+
return child.type;
|
|
1321
|
+
}
|
|
1322
|
+
function buildPartialIndex(rules) {
|
|
1323
|
+
const typeIndex = /* @__PURE__ */ new Map();
|
|
1324
|
+
const duplicateTypes = /* @__PURE__ */ new Set();
|
|
1325
|
+
const untypedIndices = [];
|
|
1326
|
+
for (let ri = 0; ri < rules.length; ri++) {
|
|
1327
|
+
const t = rules[ri].type;
|
|
1328
|
+
if (t === void 0) {
|
|
1329
|
+
untypedIndices.push(ri);
|
|
1330
|
+
} else if (typeIndex.has(t)) {
|
|
1331
|
+
duplicateTypes.add(t);
|
|
1332
|
+
} else {
|
|
1333
|
+
typeIndex.set(t, ri);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
if (duplicateTypes.size > 0) {
|
|
1337
|
+
for (const t of duplicateTypes) typeIndex.delete(t);
|
|
1338
|
+
for (let ri = 0; ri < rules.length; ri++) {
|
|
1339
|
+
if (duplicateTypes.has(rules[ri].type)) untypedIndices.push(ri);
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
return { typeIndex, untypedIndices };
|
|
1343
|
+
}
|
|
1344
|
+
var RuleMatcher = class {
|
|
1345
|
+
#rules;
|
|
1346
|
+
#typeIndex;
|
|
1347
|
+
#untypedIndices;
|
|
1348
|
+
constructor(rules) {
|
|
1349
|
+
this.#rules = rules;
|
|
1350
|
+
const { typeIndex, untypedIndices } = buildPartialIndex(rules);
|
|
1351
|
+
this.#typeIndex = typeIndex;
|
|
1352
|
+
this.#untypedIndices = untypedIndices;
|
|
1353
|
+
}
|
|
1354
|
+
match(children) {
|
|
1355
|
+
const forward = /* @__PURE__ */ new Map();
|
|
1356
|
+
const reverse = /* @__PURE__ */ new Map();
|
|
1357
|
+
const unexpectedIndices = /* @__PURE__ */ new Set();
|
|
1358
|
+
const ambiguousIndices = /* @__PURE__ */ new Set();
|
|
1359
|
+
for (let ri = 0; ri < this.#rules.length; ri++) {
|
|
1360
|
+
reverse.set(ri, /* @__PURE__ */ new Set());
|
|
1361
|
+
}
|
|
1362
|
+
for (const [ci, child] of children.entries()) {
|
|
1363
|
+
const t = getChildType(child);
|
|
1364
|
+
if (t !== void 0) {
|
|
1365
|
+
const ri = this.#typeIndex.get(t);
|
|
1366
|
+
if (ri !== void 0) {
|
|
1367
|
+
let childEntry = forward.get(ci);
|
|
1368
|
+
if (!childEntry) {
|
|
1369
|
+
childEntry = /* @__PURE__ */ new Set();
|
|
1370
|
+
forward.set(ci, childEntry);
|
|
1371
|
+
}
|
|
1372
|
+
childEntry.add(ri);
|
|
1373
|
+
reverse.get(ri).add(ci);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
for (const ri of this.#untypedIndices) {
|
|
1377
|
+
if (!this.#rules[ri].match(child)) continue;
|
|
1378
|
+
let childEntry = forward.get(ci);
|
|
1379
|
+
if (!childEntry) {
|
|
1380
|
+
childEntry = /* @__PURE__ */ new Set();
|
|
1381
|
+
forward.set(ci, childEntry);
|
|
1382
|
+
}
|
|
1383
|
+
childEntry.add(ri);
|
|
1384
|
+
reverse.get(ri).add(ci);
|
|
1385
|
+
}
|
|
1386
|
+
const entry = forward.get(ci);
|
|
1387
|
+
if (!entry) {
|
|
1388
|
+
unexpectedIndices.add(ci);
|
|
1389
|
+
} else if (entry.size > 1) {
|
|
1390
|
+
ambiguousIndices.add(ci);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
return { matrix: { childToRules: { forward, reverse } }, unexpectedIndices, ambiguousIndices };
|
|
1394
|
+
}
|
|
1395
|
+
};
|
|
1396
|
+
var RuleValidator = class _RuleValidator extends StrictBase {
|
|
1397
|
+
#context;
|
|
1398
|
+
constructor(context, strict) {
|
|
1399
|
+
super(strict);
|
|
1400
|
+
this.#context = context;
|
|
1401
|
+
}
|
|
1402
|
+
validate(rules, matrix, childCount) {
|
|
1403
|
+
const firstIndex = 0;
|
|
1404
|
+
const lastIndex = childCount - 1;
|
|
1405
|
+
for (const [ri, rule] of rules.entries()) {
|
|
1406
|
+
const matches = matrix.childToRules.reverse.get(ri);
|
|
1407
|
+
const matchCount = matches.size;
|
|
1408
|
+
this.#validateCardinality(rule, matchCount);
|
|
1409
|
+
if (matchCount === 0) continue;
|
|
1410
|
+
this.#validatePositions(rule, matches, firstIndex, lastIndex);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
#validateCardinality(rule, matchCount) {
|
|
1414
|
+
const { cardinality, name } = rule;
|
|
1415
|
+
if (cardinality.kind !== "bounded") {
|
|
1416
|
+
return;
|
|
1417
|
+
}
|
|
1418
|
+
const { min, max } = cardinality;
|
|
1419
|
+
if (matchCount < min) {
|
|
1420
|
+
this.violate(`${this.#context}: "${name}" requires at least ${min}.`);
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
if (matchCount > max) {
|
|
1424
|
+
this.violate(`${this.#context}: "${name}" allows at most ${max}.`);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
#validatePositions(rule, matches, firstIndex, lastIndex) {
|
|
1428
|
+
const { name, position } = rule;
|
|
1429
|
+
for (const index of matches) {
|
|
1430
|
+
if (_RuleValidator.#isValidPosition(index, position, firstIndex, lastIndex)) {
|
|
1431
|
+
continue;
|
|
1432
|
+
}
|
|
1433
|
+
this.violate(`${this.#context}: "${name}" must be ${position}, got index ${index}`);
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
static #isValidPosition(matchIndex, position, firstIndex, lastIndex) {
|
|
1437
|
+
switch (position) {
|
|
1438
|
+
case "first":
|
|
1439
|
+
return matchIndex === firstIndex;
|
|
1440
|
+
case "last":
|
|
1441
|
+
return matchIndex === lastIndex;
|
|
1442
|
+
case "any":
|
|
1443
|
+
return true;
|
|
1444
|
+
default:
|
|
1445
|
+
return assertNever(position);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
};
|
|
1449
|
+
var ChildrenEvaluator = class extends StrictBase {
|
|
1450
|
+
#rules;
|
|
1451
|
+
#ruleNames;
|
|
1452
|
+
#matcher;
|
|
1453
|
+
#ruleValidator;
|
|
1454
|
+
#matchBuilder;
|
|
1455
|
+
constructor(rules, strict = "warn", context = "Component") {
|
|
1456
|
+
super(strict);
|
|
1457
|
+
this.#rules = rules.map((r2) => normalizeChildRule(r2));
|
|
1458
|
+
this.#ruleNames = this.#rules.map((r2) => r2.name);
|
|
1459
|
+
for (const rule of this.#rules) {
|
|
1460
|
+
const { name, position, cardinality } = rule;
|
|
1461
|
+
if ((position === "first" || position === "last") && (cardinality.kind === "unbounded" || cardinality.max > 1)) {
|
|
1462
|
+
throw new RangeError(
|
|
1463
|
+
`ChildrenEvaluator [${context}]: rule "${name}" sets position="${position}" with an unbound or >1 max. position="first|last" implies max=1.`
|
|
1464
|
+
);
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
this.#matcher = new RuleMatcher(this.#rules);
|
|
1468
|
+
this.#ruleValidator = new RuleValidator(context, strict);
|
|
1469
|
+
this.#matchBuilder = new MatchValidationErrorBuilder(context);
|
|
1470
|
+
}
|
|
1471
|
+
evaluate(children) {
|
|
1472
|
+
if (!this.strict) return;
|
|
1473
|
+
const { matrix, unexpectedIndices, ambiguousIndices } = this.#matcher.match(children);
|
|
1474
|
+
this.#ruleValidator.validate(this.#rules, matrix, children.length);
|
|
1475
|
+
if (unexpectedIndices.size === 0 && ambiguousIndices.size === 0) return;
|
|
1476
|
+
const errors = [];
|
|
1477
|
+
const violating = [...unexpectedIndices, ...ambiguousIndices].sort((a, b) => a - b);
|
|
1478
|
+
for (const ci of violating) {
|
|
1479
|
+
const typeName = getTypeName(children[ci]);
|
|
1480
|
+
if (unexpectedIndices.has(ci)) {
|
|
1481
|
+
errors.push(this.#matchBuilder.unexpectedChild(typeName, ci));
|
|
1482
|
+
} else {
|
|
1483
|
+
const matches = matrix.childToRules.forward.get(ci);
|
|
1484
|
+
const names = [...matches].map((ri) => this.#ruleNames[ri] ?? `#${ri}`);
|
|
1485
|
+
errors.push(this.#matchBuilder.multipleMatches(typeName, ci, names));
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
this.invariant(errors.length === 0, this.#matchBuilder.toError(errors).message);
|
|
1489
|
+
}
|
|
1490
|
+
};
|
|
1491
|
+
var disabledProps = ({
|
|
1492
|
+
disabled,
|
|
1493
|
+
"aria-disabled": ariaDisabled,
|
|
1494
|
+
"data-disabled": dataDisabled
|
|
1495
|
+
}) => {
|
|
1496
|
+
if (!disabled) return {};
|
|
1497
|
+
return {
|
|
1498
|
+
...ariaDisabled === void 0 && { "aria-disabled": "true" },
|
|
1499
|
+
...dataDisabled === void 0 && { "data-disabled": "" }
|
|
1500
|
+
};
|
|
1501
|
+
};
|
|
1502
|
+
var invalidProps = ({
|
|
1503
|
+
invalid,
|
|
1504
|
+
"aria-invalid": ariaInvalid,
|
|
1505
|
+
"data-invalid": dataInvalid
|
|
1506
|
+
}) => {
|
|
1507
|
+
if (!invalid) return {};
|
|
1508
|
+
return {
|
|
1509
|
+
...ariaInvalid === void 0 && { "aria-invalid": "true" },
|
|
1510
|
+
...dataInvalid === void 0 && { "data-invalid": "" }
|
|
1511
|
+
};
|
|
1512
|
+
};
|
|
1513
|
+
|
|
1514
|
+
// ../core/dist/chunk-RHOMAG5Q.js
|
|
1515
|
+
var falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
|
|
1516
|
+
var cx = clsx;
|
|
1517
|
+
var cva = (base, config) => (props) => {
|
|
1518
|
+
var _config_compoundVariants;
|
|
1519
|
+
if ((config === null || config === void 0 ? void 0 : config.variants) == null) return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
|
|
1520
|
+
const { variants, defaultVariants } = config;
|
|
1521
|
+
const getVariantClassNames = Object.keys(variants).map((variant) => {
|
|
1522
|
+
const variantProp = props === null || props === void 0 ? void 0 : props[variant];
|
|
1523
|
+
const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
|
|
1524
|
+
if (variantProp === null) return null;
|
|
1525
|
+
const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
|
|
1526
|
+
return variants[variant][variantKey];
|
|
1527
|
+
});
|
|
1528
|
+
const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
|
|
1529
|
+
let [key, value] = param;
|
|
1530
|
+
if (value === void 0) {
|
|
1531
|
+
return acc;
|
|
1532
|
+
}
|
|
1533
|
+
acc[key] = value;
|
|
1534
|
+
return acc;
|
|
1535
|
+
}, {});
|
|
1536
|
+
const getCompoundVariantClassNames = config === null || config === void 0 ? void 0 : (_config_compoundVariants = config.compoundVariants) === null || _config_compoundVariants === void 0 ? void 0 : _config_compoundVariants.reduce((acc, param) => {
|
|
1537
|
+
let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param;
|
|
1538
|
+
return Object.entries(compoundVariantOptions).every((param2) => {
|
|
1539
|
+
let [key, value] = param2;
|
|
1540
|
+
return Array.isArray(value) ? value.includes({
|
|
1541
|
+
...defaultVariants,
|
|
1542
|
+
...propsWithoutUndefined
|
|
1543
|
+
}[key]) : {
|
|
1544
|
+
...defaultVariants,
|
|
1545
|
+
...propsWithoutUndefined
|
|
1546
|
+
}[key] === value;
|
|
1547
|
+
}) ? [
|
|
1548
|
+
...acc,
|
|
1549
|
+
cvClass,
|
|
1550
|
+
cvClassName
|
|
1551
|
+
] : acc;
|
|
1552
|
+
}, []);
|
|
1553
|
+
return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
|
|
1554
|
+
};
|
|
1555
|
+
function cva2(base, config) {
|
|
1556
|
+
const fn = cva(base, config);
|
|
1557
|
+
return (props) => cn(fn(props));
|
|
1558
|
+
}
|
|
1559
|
+
var StaticClassResolver = class {
|
|
1560
|
+
#baseClass;
|
|
1561
|
+
#cache = /* @__PURE__ */ new Map();
|
|
1562
|
+
#resolveTag;
|
|
1563
|
+
constructor(baseClass, tagMap) {
|
|
1564
|
+
this.#baseClass = Array.isArray(baseClass) ? baseClass.join(" ") : baseClass;
|
|
1565
|
+
this.#resolveTag = tagMap ? (tag) => {
|
|
1566
|
+
const extra = tagMap[tag];
|
|
1567
|
+
if (!extra) return this.#baseClass;
|
|
1568
|
+
const extraStr = Array.isArray(extra) ? extra.join(" ") : extra;
|
|
1569
|
+
return `${this.#baseClass} ${extraStr}`;
|
|
1570
|
+
} : () => this.#baseClass;
|
|
1571
|
+
}
|
|
1572
|
+
resolve(tag, skipTagMap = false) {
|
|
1573
|
+
if (typeof tag !== "string" || skipTagMap) return this.#baseClass;
|
|
1574
|
+
const cached = this.#cache.get(tag);
|
|
1575
|
+
if (cached !== void 0) {
|
|
1576
|
+
this.#cache.delete(tag);
|
|
1577
|
+
this.#cache.set(tag, cached);
|
|
1578
|
+
return cached;
|
|
1579
|
+
}
|
|
1580
|
+
const result = this.#resolveTag(tag);
|
|
1581
|
+
this.#cache.set(tag, result);
|
|
1582
|
+
if (this.#cache.size > 200) {
|
|
1583
|
+
const lru = this.#cache.keys().next().value;
|
|
1584
|
+
if (lru !== void 0) this.#cache.delete(lru);
|
|
1585
|
+
}
|
|
1586
|
+
return result;
|
|
1587
|
+
}
|
|
1588
|
+
};
|
|
1589
|
+
var VariantClassResolver = class _VariantClassResolver {
|
|
1590
|
+
#cvaFn;
|
|
1591
|
+
#presetMap;
|
|
1592
|
+
#variantKeys;
|
|
1593
|
+
#precomputedClasses;
|
|
1594
|
+
#cache = /* @__PURE__ */ new Map();
|
|
1595
|
+
constructor(cvaFn, presetMap, variantKeys, precomputedClasses) {
|
|
1596
|
+
this.#cvaFn = cvaFn ?? null;
|
|
1597
|
+
this.#presetMap = Object.freeze(presetMap ?? {});
|
|
1598
|
+
this.#variantKeys = variantKeys ?? null;
|
|
1599
|
+
this.#precomputedClasses = precomputedClasses ?? null;
|
|
1600
|
+
}
|
|
1601
|
+
resolve({ props, variantKey }) {
|
|
1602
|
+
const normalizedKey = variantKey ?? "__none__";
|
|
1603
|
+
const cacheKey = this.#createCacheKey(props, normalizedKey);
|
|
1604
|
+
if (this.#precomputedClasses !== null) {
|
|
1605
|
+
const precomputed = this.#precomputedClasses[cacheKey];
|
|
1606
|
+
if (precomputed !== void 0) return precomputed;
|
|
1607
|
+
}
|
|
1608
|
+
const cached = this.#cache.get(cacheKey);
|
|
1609
|
+
if (cached !== void 0) {
|
|
1610
|
+
this.#cache.delete(cacheKey);
|
|
1611
|
+
this.#cache.set(cacheKey, cached);
|
|
1612
|
+
return cached;
|
|
1613
|
+
}
|
|
1614
|
+
const result = this.#compute(props, variantKey);
|
|
1615
|
+
this.#cache.set(cacheKey, result);
|
|
1616
|
+
if (this.#cache.size > 1e3) {
|
|
1617
|
+
const lru = this.#cache.keys().next().value;
|
|
1618
|
+
if (lru !== void 0) this.#cache.delete(lru);
|
|
1619
|
+
}
|
|
1620
|
+
return result;
|
|
1621
|
+
}
|
|
1622
|
+
#compute(props, variantKey) {
|
|
1623
|
+
if (!this.#cvaFn) return "";
|
|
1624
|
+
if (!variantKey) return this.#cvaFn(props);
|
|
1625
|
+
const preset = this.#presetMap[variantKey];
|
|
1626
|
+
if (!preset) return this.#cvaFn(props);
|
|
1627
|
+
return this.#cvaFn({ ...preset, ...props });
|
|
1628
|
+
}
|
|
1629
|
+
// When variantKeys is provided, only those keys are included in the cache key — non-variant
|
|
1630
|
+
// props (className, id, etc.) produce identical CVA output and must not fragment the cache.
|
|
1631
|
+
// Iterating #variantKeys directly (fixed Set insertion order) avoids Object.keys + filter + sort.
|
|
1632
|
+
// String is built incrementally to avoid a parts[] array allocation on every render.
|
|
1633
|
+
#createCacheKey(props, variantKey) {
|
|
1634
|
+
if (this.#variantKeys !== null) {
|
|
1635
|
+
let key2 = variantKey;
|
|
1636
|
+
for (const k of this.#variantKeys) {
|
|
1637
|
+
if (k in props) key2 += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
1638
|
+
}
|
|
1639
|
+
return key2;
|
|
1640
|
+
}
|
|
1641
|
+
let key = variantKey;
|
|
1642
|
+
for (const k of Object.keys(props).sort()) {
|
|
1643
|
+
key += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
1644
|
+
}
|
|
1645
|
+
return key;
|
|
1646
|
+
}
|
|
1647
|
+
static #serializeValue(value) {
|
|
1648
|
+
if (value === void 0) return "u";
|
|
1649
|
+
if (value === null) return "n";
|
|
1650
|
+
if (typeof value === "boolean") return `b:${value}`;
|
|
1651
|
+
if (typeof value === "string") return `s:${value}`;
|
|
1652
|
+
return `x:${String(value)}`;
|
|
1653
|
+
}
|
|
1654
|
+
};
|
|
1655
|
+
function createClassPipeline(resolved) {
|
|
1656
|
+
const baseClass = resolved.baseClassName ?? "";
|
|
1657
|
+
const cvaFn = resolved.variants ? cva2("", {
|
|
1658
|
+
variants: resolved.variants,
|
|
1659
|
+
defaultVariants: resolved.defaultVariants,
|
|
1660
|
+
compoundVariants: resolved.compoundVariants
|
|
1661
|
+
}) : null;
|
|
1662
|
+
const variantKeys = resolved.variants ? new Set(Object.keys(resolved.variants)) : void 0;
|
|
1663
|
+
const staticResolver = new StaticClassResolver(baseClass, resolved.tagMap);
|
|
1664
|
+
const variantResolver = new VariantClassResolver(
|
|
1665
|
+
cvaFn,
|
|
1666
|
+
resolved.presetMap,
|
|
1667
|
+
variantKeys,
|
|
1668
|
+
resolved.precomputedClasses
|
|
1669
|
+
);
|
|
1670
|
+
return function resolveClasses(tag, props, className, variantKey) {
|
|
1671
|
+
const staticClasses = staticResolver.resolve(tag, variantKey !== void 0);
|
|
1672
|
+
const variantClasses = variantResolver.resolve({ props, variantKey });
|
|
1673
|
+
if (!className)
|
|
1674
|
+
return staticClasses && variantClasses ? `${staticClasses} ${variantClasses}` : staticClasses || variantClasses;
|
|
1675
|
+
return cn(staticClasses, variantClasses, className);
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
// ../core/dist/index.js
|
|
1680
|
+
var FULL_CAPABILITIES = { createClassPipeline, AriaEngine: AriaPolicyEngine };
|
|
1681
|
+
function createPolymorphic2(options = {}) {
|
|
1682
|
+
return createPolymorphic(options, FULL_CAPABILITIES);
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
// ../../lib/adapter-utils/src/build-core-runtime.ts
|
|
1686
|
+
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
1687
|
+
function buildCoreRuntime(normalized) {
|
|
1688
|
+
const runtime = createPolymorphic2(normalized);
|
|
1689
|
+
const ownedKeys = "classPlugin" in runtime ? runtime.classPlugin.ownedKeys ?? EMPTY_SET : EMPTY_SET;
|
|
1690
|
+
return { runtime, ownedKeys };
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
// ../../lib/adapter-utils/src/build-engines.ts
|
|
1694
|
+
function buildEngines(strict, childRules, context) {
|
|
1695
|
+
return childRules?.length ? { childrenEvaluator: new ChildrenEvaluator(childRules, strict, context) } : {};
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
// ../../lib/adapter-utils/src/compose-filter.ts
|
|
1699
|
+
function composeFilter(ownedKeys, filterProps) {
|
|
1700
|
+
const defaultFilter = (key, variantKeys) => variantKeys.has(key) || ownedKeys.has(key);
|
|
1701
|
+
if (!filterProps) {
|
|
1702
|
+
return defaultFilter;
|
|
1703
|
+
}
|
|
1704
|
+
return (key, variantKeys) => defaultFilter(key, variantKeys) || filterProps(key, variantKeys);
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
// ../../lib/adapter-utils/src/resolve-adapter-common-options.ts
|
|
1708
|
+
function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultStrict = "throw") {
|
|
1709
|
+
return {
|
|
1710
|
+
name: options.name ?? defaultName,
|
|
1711
|
+
strict: options.enforcement?.strict ?? defaultStrict
|
|
1712
|
+
};
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
// ../../lib/adapter-utils/src/slot-validator.ts
|
|
1716
|
+
var SlotValidator = class extends StrictBase {
|
|
1717
|
+
#name;
|
|
1718
|
+
#elementTerm;
|
|
1719
|
+
constructor(name, strict, elementTerm) {
|
|
1720
|
+
super(strict);
|
|
1721
|
+
this.#name = name;
|
|
1722
|
+
this.#elementTerm = elementTerm;
|
|
1723
|
+
}
|
|
1724
|
+
assertExclusive() {
|
|
1725
|
+
this.violate(`${this.#name}: "as" and "asChild" are mutually exclusive`);
|
|
1726
|
+
}
|
|
1727
|
+
warnDiscardedChildren(count) {
|
|
1728
|
+
const suffix = count === 1 ? "" : "ren";
|
|
1729
|
+
this.warn(
|
|
1730
|
+
`${this.#name}: asChild discarded ${count} non-element child${suffix} \u2014 only ${this.#elementTerm}s are valid asChild children.`
|
|
1731
|
+
);
|
|
1732
|
+
}
|
|
1733
|
+
assertSingleChild(count) {
|
|
1734
|
+
const msg = count === 0 ? `${this.#name}: asChild requires a ${this.#elementTerm} child` : `${this.#name}: asChild requires exactly one ${this.#elementTerm} child, got ${count}`;
|
|
1735
|
+
this.violate(msg);
|
|
1736
|
+
}
|
|
1737
|
+
};
|
|
1738
|
+
|
|
1739
|
+
// ../shared/src/constants/primitive/slot-name.ts
|
|
1740
|
+
var SLOT_NAME = "Slot";
|
|
1741
|
+
|
|
1742
|
+
// ../../lib/adapter-utils/src/slot/policies.ts
|
|
1743
|
+
import { clsx as clsx2 } from "clsx";
|
|
1744
|
+
function chainHandlers(childHandler, slotHandler) {
|
|
1745
|
+
return (...args) => {
|
|
1746
|
+
childHandler(...args);
|
|
1747
|
+
const event = args[0];
|
|
1748
|
+
if (!(typeof event === "object" && event !== null && "defaultPrevented" in event && event.defaultPrevented)) {
|
|
1749
|
+
slotHandler(...args);
|
|
1750
|
+
}
|
|
1751
|
+
};
|
|
1752
|
+
}
|
|
1753
|
+
function mergeClassNames(slot, child) {
|
|
1754
|
+
return clsx2(slot, child);
|
|
1755
|
+
}
|
|
1756
|
+
function mergeStyles(slot, child) {
|
|
1757
|
+
if (!isPlainObject(slot) || !isPlainObject(child)) return child;
|
|
1758
|
+
return { ...slot, ...child };
|
|
1759
|
+
}
|
|
1760
|
+
var policyHandlers = {
|
|
1761
|
+
chain: (slotVal, childVal) => chainHandlers(childVal, slotVal),
|
|
1762
|
+
concat: (slotVal, childVal) => mergeClassNames(slotVal, childVal),
|
|
1763
|
+
"shallow-merge": (slotVal, childVal) => mergeStyles(slotVal, childVal),
|
|
1764
|
+
"child-wins": (_slotVal, childVal) => childVal
|
|
1765
|
+
};
|
|
1766
|
+
|
|
1767
|
+
// ../../lib/adapter-utils/src/slot/merge-slot-props.ts
|
|
1768
|
+
function mergeSlotProps(slotProps, childProps) {
|
|
1769
|
+
const merged = { ...slotProps };
|
|
1770
|
+
for (const key in childProps) {
|
|
1771
|
+
if (!Object.hasOwn(childProps, key)) continue;
|
|
1772
|
+
merged[key] = applyMergePolicy(key, slotProps[key], childProps[key]);
|
|
1773
|
+
}
|
|
1774
|
+
return merged;
|
|
1775
|
+
}
|
|
1776
|
+
function classifyProp(key, slotVal, childVal) {
|
|
1777
|
+
if (EVENT_HANDLER_RE.test(key) && isFunction(slotVal) && isFunction(childVal)) return "chain";
|
|
1778
|
+
if (key === "className") return "concat";
|
|
1779
|
+
if (key === "style") return "shallow-merge";
|
|
1780
|
+
return "child-wins";
|
|
1781
|
+
}
|
|
1782
|
+
function applyMergePolicy(key, slotVal, childVal) {
|
|
1783
|
+
return policyHandlers[classifyProp(key, slotVal, childVal)](slotVal, childVal);
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
// ../../adapters/preact/src/slot/Slot.tsx
|
|
1787
|
+
import { forwardRef } from "preact/compat";
|
|
1788
|
+
|
|
1789
|
+
// ../../adapters/preact/src/slot/applySlot.ts
|
|
1790
|
+
import { isValidElement as isValidElement4 } from "preact";
|
|
1791
|
+
|
|
1792
|
+
// ../../adapters/preact/src/slot/invariant.ts
|
|
1793
|
+
function panic2(message) {
|
|
1794
|
+
throw new Error(message);
|
|
1795
|
+
}
|
|
1796
|
+
function invariant(condition, message) {
|
|
1797
|
+
if (!condition) panic2(message);
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
// ../../adapters/preact/src/slot/extractSlottable.ts
|
|
1801
|
+
import { h, Fragment as Fragment2, isValidElement as isValidElement3 } from "preact";
|
|
1802
|
+
|
|
1803
|
+
// ../../adapters/preact/src/slot/predicates.ts
|
|
1804
|
+
import { isValidElement as isValidElement2 } from "preact";
|
|
1805
|
+
|
|
1806
|
+
// ../../adapters/preact/src/slot/Slottable.tsx
|
|
1807
|
+
import { Fragment } from "preact";
|
|
1808
|
+
import { jsx } from "preact/jsx-runtime";
|
|
1809
|
+
function Slottable({ children }) {
|
|
1810
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
// ../../adapters/preact/src/slot/predicates.ts
|
|
1814
|
+
function isSlottableElement(value) {
|
|
1815
|
+
return isValidElement2(value) && value.type === Slottable;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
// ../../adapters/preact/src/slot/extractSlottable.ts
|
|
1819
|
+
function extractSlottable(children) {
|
|
1820
|
+
const childrenArray = Array.isArray(children) ? children : [children];
|
|
1821
|
+
const slottables = childrenArray.filter(isSlottableElement);
|
|
1822
|
+
invariant(slottables.length <= 1, "Slot: multiple Slottable children are not allowed");
|
|
1823
|
+
if (slottables.length === 0) return null;
|
|
1824
|
+
const [slottable] = slottables;
|
|
1825
|
+
invariant(slottable, "Missing Slottable element");
|
|
1826
|
+
const child = slottable.props.children;
|
|
1827
|
+
invariant(
|
|
1828
|
+
child !== null && child !== void 0,
|
|
1829
|
+
"Slottable expects exactly one Preact element child, received null"
|
|
1830
|
+
);
|
|
1831
|
+
invariant(
|
|
1832
|
+
typeof child !== "string" && typeof child !== "number",
|
|
1833
|
+
"Slottable expects exactly one Preact element child, received text content"
|
|
1834
|
+
);
|
|
1835
|
+
invariant(isValidElement3(child), "Slottable expects exactly one Preact element child");
|
|
1836
|
+
invariant(child.type !== Fragment2, "Slottable child cannot be a Fragment");
|
|
1837
|
+
const index = childrenArray.indexOf(slottable);
|
|
1838
|
+
return {
|
|
1839
|
+
child,
|
|
1840
|
+
rebuild(merged) {
|
|
1841
|
+
const out = childrenArray.map((node, i) => i === index ? merged : node);
|
|
1842
|
+
return h(Fragment2, null, ...out);
|
|
1843
|
+
}
|
|
1844
|
+
};
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
// ../../adapters/preact/src/slot/applySlot.ts
|
|
1848
|
+
function applySlot(children, slotProps, ref, cloneSlotChild2) {
|
|
1849
|
+
const extraction = extractSlottable(children);
|
|
1850
|
+
if (extraction) {
|
|
1851
|
+
const merged = cloneSlotChild2({ child: extraction.child, slotProps, ref });
|
|
1852
|
+
return extraction.rebuild(merged);
|
|
1853
|
+
}
|
|
1854
|
+
invariant(isValidElement4(children), "Slot: child must be a valid Preact element");
|
|
1855
|
+
return cloneSlotChild2({ child: children, slotProps, ref });
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
// ../../adapters/preact/src/slot/cloneSlotChild.ts
|
|
1859
|
+
import { cloneElement, Fragment as Fragment3 } from "preact";
|
|
1860
|
+
|
|
1861
|
+
// ../../adapters/preact/src/slot/composeRefs.ts
|
|
1862
|
+
function mergeRefs(...refs) {
|
|
1863
|
+
const active = refs.filter((r2) => r2 != null);
|
|
1864
|
+
if (active.length === 0) return null;
|
|
1865
|
+
if (active.length === 1) return active[0];
|
|
1866
|
+
return (value) => {
|
|
1867
|
+
for (const ref of active) {
|
|
1868
|
+
if (typeof ref === "function") {
|
|
1869
|
+
ref(value);
|
|
1870
|
+
} else {
|
|
1871
|
+
ref.current = value;
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
};
|
|
1875
|
+
}
|
|
1876
|
+
function getChildRef(child) {
|
|
1877
|
+
const ref = child.ref;
|
|
1878
|
+
return ref ?? null;
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
// ../../adapters/preact/src/slot/cloneSlotChild.ts
|
|
1882
|
+
function cloneSlotChild({ child, slotProps, ref }) {
|
|
1883
|
+
const childProps = child.props;
|
|
1884
|
+
const isFragment = child.type === Fragment3;
|
|
1885
|
+
const childRef = isFragment ? null : getChildRef(child);
|
|
1886
|
+
const mergedRef = isFragment ? null : mergeRefs(ref, childRef);
|
|
1887
|
+
const merged = mergeSlotProps(slotProps, childProps);
|
|
1888
|
+
return cloneElement(child, mergedRef !== null ? { ...merged, ref: mergedRef } : merged);
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
// ../../adapters/preact/src/slot/Slot.tsx
|
|
1892
|
+
var Slot = forwardRef(function Slot2({ children, ...slotProps }, ref) {
|
|
1893
|
+
return applySlot(children, slotProps, ref ?? null, cloneSlotChild);
|
|
1894
|
+
});
|
|
1895
|
+
Object.assign(Slot, { displayName: SLOT_NAME });
|
|
1896
|
+
|
|
1897
|
+
// ../../adapters/preact/src/slot/slot-validator.ts
|
|
1898
|
+
var SlotValidator2 = class extends SlotValidator {
|
|
1899
|
+
constructor(name, strict) {
|
|
1900
|
+
super(name, strict, "Preact element");
|
|
1901
|
+
}
|
|
1902
|
+
};
|
|
1903
|
+
|
|
1904
|
+
// ../../adapters/preact/src/build-runtime.ts
|
|
1905
|
+
function normalizeOptions(options) {
|
|
1906
|
+
return {
|
|
1907
|
+
...options,
|
|
1908
|
+
slotComponent: options.slotComponent ?? Slot,
|
|
1909
|
+
...resolveAdapterCommonOptions(options)
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
function buildRuntime(options) {
|
|
1913
|
+
const normalized = normalizeOptions(options);
|
|
1914
|
+
const { runtime, ownedKeys } = buildCoreRuntime(normalized);
|
|
1915
|
+
const slotValidator = new SlotValidator2(normalized.name, normalized.strict);
|
|
1916
|
+
const { childrenEvaluator } = buildEngines(
|
|
1917
|
+
normalized.strict,
|
|
1918
|
+
normalized.enforcement?.children,
|
|
1919
|
+
normalized.name
|
|
1920
|
+
);
|
|
1921
|
+
const filterProps = composeFilter(ownedKeys, normalized.filterProps);
|
|
1922
|
+
return {
|
|
1923
|
+
runtime,
|
|
1924
|
+
slotComponent: normalized.slotComponent,
|
|
1925
|
+
normalizeChildren,
|
|
1926
|
+
slotValidator,
|
|
1927
|
+
filterProps,
|
|
1928
|
+
...childrenEvaluator !== void 0 && { childrenEvaluator }
|
|
1929
|
+
};
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
// ../../adapters/preact/src/render.ts
|
|
1933
|
+
import { h as h2 } from "preact";
|
|
1934
|
+
function buildDirectives(as, asChild) {
|
|
1935
|
+
return {
|
|
1936
|
+
...as !== void 0 && { as },
|
|
1937
|
+
...asChild !== void 0 && { asChild }
|
|
1938
|
+
};
|
|
1939
|
+
}
|
|
1940
|
+
function buildRenderState(tag, directives, props, className, children) {
|
|
1941
|
+
const state = { tag, directives, props, className };
|
|
1942
|
+
if (children !== void 0) state.children = children;
|
|
1943
|
+
return state;
|
|
1944
|
+
}
|
|
1945
|
+
function resolveRenderState(runtime, props, filterProps) {
|
|
1946
|
+
const { as, asChild, children, className, variantKey, ...rest } = props;
|
|
1947
|
+
const tag = runtime.resolveTag(as);
|
|
1948
|
+
const mergedProps = runtime.resolveProps(rest);
|
|
1949
|
+
const normalizedProps = runtime.options.normalizeFn ? runtime.options.normalizeFn(mergedProps) : mergedProps;
|
|
1950
|
+
const resolvedClass = runtime.resolveClasses(tag, normalizedProps, className, variantKey);
|
|
1951
|
+
const filteredProps = applyFilter(normalizedProps, filterProps, runtime.options.variantKeys);
|
|
1952
|
+
return buildRenderState(tag, buildDirectives(as, asChild), filteredProps, resolvedClass, children);
|
|
1953
|
+
}
|
|
1954
|
+
function warnDiscardedChildren(originalChildren, normalizedChildren, validator) {
|
|
1955
|
+
if (!Array.isArray(originalChildren)) return;
|
|
1956
|
+
const discarded = originalChildren.length - normalizedChildren.length;
|
|
1957
|
+
if (discarded > 0) validator.warnDiscardedChildren(discarded);
|
|
1958
|
+
}
|
|
1959
|
+
function isSingleElementArray(arr) {
|
|
1960
|
+
return arr.length === 1;
|
|
1961
|
+
}
|
|
1962
|
+
function resolveSlotChildren(children, normalized, validator) {
|
|
1963
|
+
warnDiscardedChildren(children, normalized, validator);
|
|
1964
|
+
if (isSingleElementArray(normalized)) {
|
|
1965
|
+
return normalized[0];
|
|
1966
|
+
}
|
|
1967
|
+
if (normalized.length > 1 && normalized.some(isSlottableElement)) {
|
|
1968
|
+
return normalized;
|
|
1969
|
+
}
|
|
1970
|
+
validator.assertSingleChild(normalized.length);
|
|
1971
|
+
return null;
|
|
1972
|
+
}
|
|
1973
|
+
function validateSlotDirectives(directives, validator) {
|
|
1974
|
+
const { as, asChild } = directives;
|
|
1975
|
+
if (!asChild) return false;
|
|
1976
|
+
if (as !== void 0) {
|
|
1977
|
+
validator.assertExclusive();
|
|
1978
|
+
return false;
|
|
1979
|
+
}
|
|
1980
|
+
return true;
|
|
1981
|
+
}
|
|
1982
|
+
function resolveSlotRender(state, getNormalized, validator) {
|
|
1983
|
+
if (!validateSlotDirectives(state.directives, validator)) return null;
|
|
1984
|
+
const child = resolveSlotChildren(state.children, getNormalized(), validator);
|
|
1985
|
+
if (child === null) return null;
|
|
1986
|
+
return { child };
|
|
1987
|
+
}
|
|
1988
|
+
function renderResolvedSlot(slotComponent, state, resolved, ref) {
|
|
1989
|
+
return h2(slotComponent, {
|
|
1990
|
+
...state.props,
|
|
1991
|
+
className: state.className,
|
|
1992
|
+
ref,
|
|
1993
|
+
children: resolved.child
|
|
1994
|
+
});
|
|
1995
|
+
}
|
|
1996
|
+
function tryRenderAsChild(state, ref, slotComponent, getNormalized, validator) {
|
|
1997
|
+
const resolved = resolveSlotRender(state, getNormalized, validator);
|
|
1998
|
+
if (resolved === null) return null;
|
|
1999
|
+
return renderResolvedSlot(slotComponent, state, resolved, ref);
|
|
2000
|
+
}
|
|
2001
|
+
function buildElementProps(props, className, ref, children) {
|
|
2002
|
+
const { role, ...rest } = props;
|
|
2003
|
+
return {
|
|
2004
|
+
...rest,
|
|
2005
|
+
className,
|
|
2006
|
+
ref,
|
|
2007
|
+
...children !== void 0 && { children },
|
|
2008
|
+
...isKnownAriaRole(role) && { role }
|
|
2009
|
+
};
|
|
2010
|
+
}
|
|
2011
|
+
function renderIntrinsic(state, ref, runtime) {
|
|
2012
|
+
const elementProps = buildElementProps(state.props, state.className, ref, state.children);
|
|
2013
|
+
const domProps = typeof state.tag === "string" ? runtime.resolveAria(state.tag, elementProps).props : elementProps;
|
|
2014
|
+
return h2(state.tag, domProps);
|
|
2015
|
+
}
|
|
2016
|
+
function render({
|
|
2017
|
+
runtime,
|
|
2018
|
+
props,
|
|
2019
|
+
ref,
|
|
2020
|
+
slotComponent,
|
|
2021
|
+
normalizeChildren: normalizeChildren2,
|
|
2022
|
+
filterProps,
|
|
2023
|
+
slotValidator,
|
|
2024
|
+
childrenEvaluator
|
|
2025
|
+
}) {
|
|
2026
|
+
const state = resolveRenderState(runtime, props, filterProps);
|
|
2027
|
+
let cached;
|
|
2028
|
+
const once = () => cached ??= normalizeChildren2(state.children);
|
|
2029
|
+
if (process.env.NODE_ENV !== "production") childrenEvaluator?.evaluate(once());
|
|
2030
|
+
const slotResult = tryRenderAsChild(state, ref, slotComponent, once, slotValidator);
|
|
2031
|
+
return slotResult ?? renderIntrinsic(state, ref, runtime);
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
// ../../adapters/preact/src/create-contract-component.ts
|
|
2035
|
+
function createContractComponent(options) {
|
|
2036
|
+
const bundle = buildRuntime(options);
|
|
2037
|
+
const Component = forwardRef2(function Component2(props, ref) {
|
|
2038
|
+
return render({
|
|
2039
|
+
...bundle,
|
|
2040
|
+
normalizeChildren,
|
|
2041
|
+
props,
|
|
2042
|
+
ref: ref ?? null
|
|
2043
|
+
});
|
|
2044
|
+
});
|
|
2045
|
+
applyDisplayName(Component, options.name);
|
|
2046
|
+
if (typeof bundle.runtime.options.defaultTag === "string") {
|
|
2047
|
+
Object.assign(Component, { [COMPONENT_DEFAULT_TAG]: bundle.runtime.options.defaultTag });
|
|
2048
|
+
}
|
|
2049
|
+
return Component;
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
// ../../adapters/preact/src/define-contract-component.ts
|
|
2053
|
+
function defineContractComponent(options) {
|
|
2054
|
+
return (factory) => factory(options);
|
|
2055
|
+
}
|
|
2056
|
+
export {
|
|
2057
|
+
Slottable,
|
|
2058
|
+
createContractComponent,
|
|
2059
|
+
defineContractComponent,
|
|
2060
|
+
disabledProps,
|
|
2061
|
+
invalidProps
|
|
2062
|
+
};
|