praxis-kit 3.1.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -126
- package/dist/chunk-TJRHF6MS.js +2777 -0
- package/dist/codemod/index.js +20 -20
- package/dist/contract/index.d.ts +2 -258
- package/dist/contract/index.js +158 -1190
- package/dist/eslint/index.js +403 -178
- package/dist/lit/index.d.ts +9 -238
- package/dist/lit/index.js +1392 -745
- package/dist/merge-refs-DUuHyTRO.d.ts +144 -0
- package/dist/preact/index.d.ts +11 -255
- package/dist/preact/index.js +1686 -1025
- package/dist/react/index.d.ts +24 -12
- package/dist/react/index.js +115 -116
- package/dist/react/legacy.d.ts +8 -12
- package/dist/react/legacy.js +116 -136
- package/dist/solid/index.d.ts +7 -251
- package/dist/solid/index.js +1476 -706
- package/dist/svelte/index.d.ts +7 -325
- package/dist/svelte/index.js +1407 -725
- package/dist/tailwind/index.d.ts +5 -4
- package/dist/tailwind/index.js +366 -90
- package/dist/ts-plugin/index.cjs +5 -5
- package/dist/vite-plugin/index.d.ts +91 -120
- package/dist/vite-plugin/index.js +568 -347
- package/dist/vue/index.d.ts +14 -258
- package/dist/vue/index.js +1701 -926
- package/dist/web/index.d.ts +13 -241
- package/dist/web/index.js +1371 -733
- package/package.json +4 -3
- package/dist/chunk-6RJN5B6L.js +0 -2221
- package/dist/merge-refs-CfAbwCKz.d.ts +0 -380
package/dist/preact/index.js
CHANGED
|
@@ -1,23 +1,18 @@
|
|
|
1
|
-
// ../../
|
|
2
|
-
|
|
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 [];
|
|
1
|
+
// ../../lib/adapter-utils/src/apply-display-name.ts
|
|
2
|
+
function applyDisplayName(component, name) {
|
|
3
|
+
Object.assign(component, { displayName: name ?? "PolymorphicComponent" });
|
|
10
4
|
}
|
|
11
5
|
|
|
12
|
-
// ../shared/src/guards/children/component-id.ts
|
|
13
|
-
var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol.for("praxis.component-default-tag");
|
|
14
|
-
|
|
15
6
|
// ../../lib/primitive/src/utils/is-object.ts
|
|
16
|
-
function
|
|
17
|
-
|
|
7
|
+
function isObject(value, excludeArrays = false) {
|
|
8
|
+
if (value === null || typeof value !== "object") return false;
|
|
9
|
+
return excludeArrays ? !Array.isArray(value) : true;
|
|
18
10
|
}
|
|
19
|
-
function
|
|
20
|
-
return
|
|
11
|
+
function isString(value) {
|
|
12
|
+
return typeof value === "string";
|
|
13
|
+
}
|
|
14
|
+
function isNumber(value) {
|
|
15
|
+
return typeof value === "number";
|
|
21
16
|
}
|
|
22
17
|
|
|
23
18
|
// ../../lib/primitive/src/merge/constants.ts
|
|
@@ -33,372 +28,198 @@ function isPlainObject(value) {
|
|
|
33
28
|
return proto === Object.prototype || proto === null;
|
|
34
29
|
}
|
|
35
30
|
|
|
36
|
-
// ../../
|
|
37
|
-
function
|
|
38
|
-
|
|
31
|
+
// ../../lib/primitive/src/utils/assert-never.ts
|
|
32
|
+
function assertNever(value) {
|
|
33
|
+
throw new Error(`Unexpected value: ${String(value)}`);
|
|
39
34
|
}
|
|
40
35
|
|
|
41
|
-
// ../../lib/
|
|
42
|
-
function
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
// ../../lib/primitive/src/utils/iterate.ts
|
|
37
|
+
function find(iterable, callback) {
|
|
38
|
+
for (const value of iterable) {
|
|
39
|
+
const result = callback(value);
|
|
40
|
+
if (result != null) {
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
48
43
|
}
|
|
49
|
-
return
|
|
44
|
+
return null;
|
|
50
45
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
function some(iterable, predicate) {
|
|
47
|
+
for (const value of iterable) {
|
|
48
|
+
if (predicate(value)) return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
55
51
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
function every(iterable, predicate) {
|
|
53
|
+
let index = 0;
|
|
54
|
+
for (const value of iterable) {
|
|
55
|
+
if (!predicate(value, index++)) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
62
60
|
}
|
|
63
|
-
function
|
|
64
|
-
|
|
61
|
+
function* filter(iterable, predicate) {
|
|
62
|
+
let index = 0;
|
|
63
|
+
for (const value of iterable) {
|
|
64
|
+
if (predicate(value, index++)) {
|
|
65
|
+
yield value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
65
68
|
}
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
72
|
-
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
73
|
-
return n;
|
|
69
|
+
function* map(iterable, callback) {
|
|
70
|
+
let index = 0;
|
|
71
|
+
for (const value of iterable) {
|
|
72
|
+
yield callback(value, index++);
|
|
73
|
+
}
|
|
74
74
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
function forEach(iterable, callback) {
|
|
76
|
+
let index = 0;
|
|
77
|
+
for (const value of iterable) {
|
|
78
|
+
callback(value, index++);
|
|
79
|
+
}
|
|
78
80
|
}
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
+
function reduce(iterable, initial, callback) {
|
|
82
|
+
let accumulator = initial;
|
|
83
|
+
let index = 0;
|
|
84
|
+
for (const value of iterable) {
|
|
85
|
+
accumulator = callback(accumulator, value, index++);
|
|
86
|
+
}
|
|
87
|
+
return accumulator;
|
|
81
88
|
}
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
function collect(iterable, callback) {
|
|
90
|
+
const result = {};
|
|
91
|
+
let index = 0;
|
|
92
|
+
for (const value of iterable) {
|
|
93
|
+
const entry = callback(value, index++);
|
|
94
|
+
if (entry === null) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
result[entry[0]] = entry[1];
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
87
100
|
}
|
|
88
|
-
function
|
|
89
|
-
|
|
101
|
+
function findLast(value, callback) {
|
|
102
|
+
for (let index = value.length - 1; index >= 0; index--) {
|
|
103
|
+
const result = callback(value[index], index);
|
|
104
|
+
if (result != null) {
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
function* items(collection) {
|
|
111
|
+
for (let i = 0; i < collection.length; i++) {
|
|
112
|
+
const item = collection.item(i);
|
|
113
|
+
if (item !== null) {
|
|
114
|
+
yield item;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
90
117
|
}
|
|
91
|
-
function
|
|
92
|
-
return
|
|
118
|
+
function nodeList(list) {
|
|
119
|
+
return {
|
|
120
|
+
*[Symbol.iterator]() {
|
|
121
|
+
for (let i = 0; i < list.length; i++) {
|
|
122
|
+
const node = list.item(i);
|
|
123
|
+
if (node !== null) {
|
|
124
|
+
yield node;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
93
129
|
}
|
|
94
|
-
function
|
|
95
|
-
return
|
|
130
|
+
function mapEntries(m) {
|
|
131
|
+
return m.entries();
|
|
96
132
|
}
|
|
97
|
-
function
|
|
98
|
-
return
|
|
133
|
+
function set(s) {
|
|
134
|
+
return s.values();
|
|
99
135
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (!normalizers?.length) return fn;
|
|
103
|
-
return ((props) => {
|
|
104
|
-
const patched = normalizers.reduce(
|
|
105
|
-
(acc, normalizer) => ({ ...acc, ...normalizer(acc) }),
|
|
106
|
-
props
|
|
107
|
-
);
|
|
108
|
-
return fn ? fn(patched) : patched;
|
|
109
|
-
});
|
|
136
|
+
function hasOwn(object, key) {
|
|
137
|
+
return Object.hasOwn(object, key);
|
|
110
138
|
}
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
|
|
117
|
-
const variantKeys = styling?.variants === void 0 ? EMPTY_VARIANT_KEYS : new Set(Object.keys(styling.variants));
|
|
118
|
-
return Object.freeze({
|
|
119
|
-
defaultTag: options.tag ?? "div",
|
|
120
|
-
strict: enforcement?.strict ?? false,
|
|
121
|
-
variantKeys,
|
|
122
|
-
...whenDefined("displayName", options.name),
|
|
123
|
-
...whenDefined("defaultProps", options.defaults),
|
|
124
|
-
...whenDefined("baseClassName", styling?.base),
|
|
125
|
-
...whenDefined("tagMap", styling?.tags),
|
|
126
|
-
...whenDefined("recipeMap", styling?.presets),
|
|
127
|
-
...whenDefined("variants", styling?.variants),
|
|
128
|
-
...whenDefined("defaultVariants", styling?.defaults),
|
|
129
|
-
...whenDefined("compoundVariants", styling?.compounds),
|
|
130
|
-
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
131
|
-
...whenDefined("ariaRules", enforcement?.aria),
|
|
132
|
-
...whenDefined("childRules", enforcement?.children),
|
|
133
|
-
...whenDefined("allowedAs", enforcement?.allowedAs),
|
|
134
|
-
...whenDefined("precomputedClasses", styling?.precomputedClasses)
|
|
135
|
-
});
|
|
139
|
+
function* entries(object) {
|
|
140
|
+
for (const key in object) {
|
|
141
|
+
if (!hasOwn(object, key)) continue;
|
|
142
|
+
yield [key, object[key]];
|
|
143
|
+
}
|
|
136
144
|
}
|
|
137
|
-
function
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (mode === "throw") throw new Error(message);
|
|
141
|
-
console.warn(message);
|
|
142
|
-
}
|
|
143
|
-
function validateFactoryOptions(resolved) {
|
|
144
|
-
const { strict } = resolved;
|
|
145
|
-
if (strict === false) return;
|
|
146
|
-
const name = resolved.displayName ?? "Component";
|
|
147
|
-
const { variants } = resolved;
|
|
148
|
-
const checkSelection = (label2, selection) => {
|
|
149
|
-
const record = selection;
|
|
150
|
-
for (const dim in record) {
|
|
151
|
-
const value = record[dim];
|
|
152
|
-
if (value === void 0 || value === null) continue;
|
|
153
|
-
if (!variants || !Object.hasOwn(variants, dim)) {
|
|
154
|
-
report(strict, `${name}: ${label2} references unknown variant "${dim}".`);
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
const states = variants[dim];
|
|
158
|
-
const stateKey = String(value);
|
|
159
|
-
if (!Object.hasOwn(states, stateKey)) {
|
|
160
|
-
report(
|
|
161
|
-
strict,
|
|
162
|
-
`${name}: ${label2} sets "${dim}" to unknown value "${stateKey}" (valid: ${Object.keys(states).join(", ")}).`
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
const { recipeMap } = resolved;
|
|
168
|
-
if (recipeMap) {
|
|
169
|
-
for (const recipeKey in recipeMap) {
|
|
170
|
-
checkSelection(`preset "${recipeKey}"`, recipeMap[recipeKey]);
|
|
171
|
-
}
|
|
145
|
+
function* keys(object) {
|
|
146
|
+
for (const [key] of entries(object)) {
|
|
147
|
+
yield key;
|
|
172
148
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
var asyncWarnScheduled = false;
|
|
178
|
-
function flushAsyncWarns() {
|
|
179
|
-
asyncWarnScheduled = false;
|
|
180
|
-
const messages = [...pendingAsyncWarns];
|
|
181
|
-
pendingAsyncWarns.clear();
|
|
182
|
-
for (const msg of messages) {
|
|
183
|
-
console.warn(msg);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function report2(strict, message) {
|
|
187
|
-
if (!strict) return;
|
|
188
|
-
const mode = strict === true ? "throw" : strict;
|
|
189
|
-
if (mode === "throw") throw new Error(message);
|
|
190
|
-
if (mode === "async-warn") {
|
|
191
|
-
if (pendingAsyncWarns.has(message)) return;
|
|
192
|
-
pendingAsyncWarns.add(message);
|
|
193
|
-
if (!asyncWarnScheduled) {
|
|
194
|
-
asyncWarnScheduled = true;
|
|
195
|
-
queueMicrotask(flushAsyncWarns);
|
|
196
|
-
}
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
if (warned.has(message)) return;
|
|
200
|
-
warned.add(message);
|
|
201
|
-
console.warn(message);
|
|
202
|
-
}
|
|
203
|
-
function label(name) {
|
|
204
|
-
return name ? `[${name}]` : "[createContractComponent]";
|
|
205
|
-
}
|
|
206
|
-
function validateRenderProps(options, props, recipeKey) {
|
|
207
|
-
const { strict, recipeMap, variants, displayName } = options;
|
|
208
|
-
if (!strict) return;
|
|
209
|
-
const tag = label(displayName);
|
|
210
|
-
if (recipeKey !== void 0 && (!recipeMap || !Object.hasOwn(recipeMap, recipeKey))) {
|
|
211
|
-
report2(strict, `${tag} Unknown recipeKey "${recipeKey}" \u2014 no preset with that name exists.`);
|
|
212
|
-
}
|
|
213
|
-
if (variants) {
|
|
214
|
-
for (const key in variants) {
|
|
215
|
-
if (!Object.hasOwn(props, key)) continue;
|
|
216
|
-
const value = props[key];
|
|
217
|
-
if (value === void 0 || value === null) continue;
|
|
218
|
-
const dim = variants[key];
|
|
219
|
-
if (dim && !Object.hasOwn(dim, String(value))) {
|
|
220
|
-
report2(
|
|
221
|
-
strict,
|
|
222
|
-
`${tag} Variant "${key}=${String(value)}" is not a defined value for the "${key}" dimension.`
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
149
|
+
}
|
|
150
|
+
function* values(object) {
|
|
151
|
+
for (const [, value] of entries(object)) {
|
|
152
|
+
yield value;
|
|
226
153
|
}
|
|
227
154
|
}
|
|
228
|
-
function
|
|
229
|
-
|
|
155
|
+
function mapValues(object, callback) {
|
|
156
|
+
const result = {};
|
|
157
|
+
for (const [key, value] of entries(object)) {
|
|
158
|
+
result[key] = callback(value, key);
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
230
161
|
}
|
|
231
|
-
function
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
162
|
+
function forEachEntry(object, callback) {
|
|
163
|
+
for (const [key, value] of entries(object)) {
|
|
164
|
+
callback(key, value);
|
|
165
|
+
}
|
|
235
166
|
}
|
|
236
|
-
function
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
);
|
|
241
|
-
const plugin = result;
|
|
242
|
-
if (typeof plugin.pipeline !== "function")
|
|
243
|
-
panic(
|
|
244
|
-
`[praxis-kit] Plugin factory return value is missing a 'pipeline' function. Got pipeline: ${typeof plugin.pipeline}.`
|
|
245
|
-
);
|
|
167
|
+
function forEachKey(object, callback) {
|
|
168
|
+
for (const key of keys(object)) {
|
|
169
|
+
callback(key);
|
|
170
|
+
}
|
|
246
171
|
}
|
|
247
|
-
function
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if (typeof result !== "string")
|
|
252
|
-
panic(`[praxis-kit] Plugin pipeline must return a string. Got: ${describe(result)}.`);
|
|
253
|
-
return result;
|
|
254
|
-
};
|
|
172
|
+
function forEachValue(object, callback) {
|
|
173
|
+
for (const value of values(object)) {
|
|
174
|
+
callback(value);
|
|
175
|
+
}
|
|
255
176
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
if (!factory) {
|
|
260
|
-
const createClassPipeline2 = capabilities?.createClassPipeline;
|
|
261
|
-
const classPipeline2 = createClassPipeline2 ? createClassPipeline2(resolved) : NOOP_CLASS_PIPELINE;
|
|
262
|
-
return { pluginResult: void 0, classPipeline: classPipeline2 };
|
|
177
|
+
function forEachSet(s, callback) {
|
|
178
|
+
for (const value of s) {
|
|
179
|
+
callback(value);
|
|
263
180
|
}
|
|
264
|
-
const pluginResult = factory(resolved, strict);
|
|
265
|
-
assertPluginShape(pluginResult);
|
|
266
|
-
const classPipeline = guardPipeline(pluginResult.pipeline);
|
|
267
|
-
return { pluginResult, classPipeline };
|
|
268
181
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
182
|
+
var iterate = Object.freeze({
|
|
183
|
+
entries,
|
|
184
|
+
filter,
|
|
185
|
+
find,
|
|
186
|
+
findLast,
|
|
187
|
+
forEach,
|
|
188
|
+
forEachEntry,
|
|
189
|
+
forEachKey,
|
|
190
|
+
forEachSet,
|
|
191
|
+
forEachValue,
|
|
192
|
+
items,
|
|
193
|
+
keys,
|
|
194
|
+
map,
|
|
195
|
+
mapEntries,
|
|
196
|
+
mapValues,
|
|
197
|
+
nodeList,
|
|
198
|
+
reduce,
|
|
199
|
+
collect,
|
|
200
|
+
set,
|
|
201
|
+
some,
|
|
202
|
+
every,
|
|
203
|
+
values
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// ../../lib/primitive/src/utils/merge-refs.ts
|
|
207
|
+
function mergeRefsCore(...refs) {
|
|
208
|
+
const active = refs.filter((r) => r != null);
|
|
209
|
+
if (active.length === 0) return null;
|
|
210
|
+
if (active.length === 1) return active[0];
|
|
211
|
+
return (value) => {
|
|
212
|
+
iterate.forEach(active, (ref) => {
|
|
213
|
+
if (typeof ref === "function") {
|
|
214
|
+
ref(value);
|
|
215
|
+
} else {
|
|
216
|
+
ref.current = value;
|
|
278
217
|
}
|
|
279
|
-
|
|
280
|
-
},
|
|
281
|
-
resolveAria(tag, props) {
|
|
282
|
-
if (!engine) return { props };
|
|
283
|
-
const result = engine.validate(tag, props);
|
|
284
|
-
return { props: result.props };
|
|
285
|
-
}
|
|
218
|
+
});
|
|
286
219
|
};
|
|
287
220
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
function createPolymorphic(options = {}, capabilities) {
|
|
292
|
-
const baseResolved = resolveFactoryOptions(options);
|
|
293
|
-
const resolved = capabilities?.htmlPropNormalizersFn !== void 0 ? Object.freeze({
|
|
294
|
-
...baseResolved,
|
|
295
|
-
htmlPropNormalizersFn: capabilities.htmlPropNormalizersFn
|
|
296
|
-
}) : baseResolved;
|
|
297
|
-
if (process.env.NODE_ENV !== "production") validateFactoryOptions(resolved);
|
|
298
|
-
const { pluginResult, classPipeline } = resolveClassPipeline(
|
|
299
|
-
options,
|
|
300
|
-
resolved,
|
|
301
|
-
resolved.strict,
|
|
302
|
-
capabilities
|
|
303
|
-
);
|
|
304
|
-
const allAriaRules = [
|
|
305
|
-
.../* @__PURE__ */ new Set([...capabilities?.htmlAriaRules ?? [], ...resolved.ariaRules ?? []])
|
|
306
|
-
];
|
|
307
|
-
const engine = options.enforcement !== void 0 && capabilities?.AriaEngine ? new capabilities.AriaEngine(
|
|
308
|
-
resolved.strict,
|
|
309
|
-
allAriaRules.length ? { rules: allAriaRules } : void 0
|
|
310
|
-
) : null;
|
|
311
|
-
const methods = createRuntimeMethods(resolved, classPipeline, engine);
|
|
312
|
-
return createRuntimeObject(
|
|
313
|
-
methods,
|
|
314
|
-
resolved,
|
|
315
|
-
pluginResult
|
|
316
|
-
);
|
|
317
|
-
}
|
|
318
|
-
var KNOWN_ARIA_ROLES = [
|
|
319
|
-
"alert",
|
|
320
|
-
"alertdialog",
|
|
321
|
-
"application",
|
|
322
|
-
"article",
|
|
323
|
-
"banner",
|
|
324
|
-
"blockquote",
|
|
325
|
-
"button",
|
|
326
|
-
"caption",
|
|
327
|
-
"cell",
|
|
328
|
-
"checkbox",
|
|
329
|
-
"code",
|
|
330
|
-
"columnheader",
|
|
331
|
-
"combobox",
|
|
332
|
-
"complementary",
|
|
333
|
-
"contentinfo",
|
|
334
|
-
"definition",
|
|
335
|
-
"deletion",
|
|
336
|
-
"dialog",
|
|
337
|
-
"document",
|
|
338
|
-
"emphasis",
|
|
339
|
-
"feed",
|
|
340
|
-
"figure",
|
|
341
|
-
"form",
|
|
342
|
-
"generic",
|
|
343
|
-
"grid",
|
|
344
|
-
"gridcell",
|
|
345
|
-
"group",
|
|
346
|
-
"heading",
|
|
347
|
-
"img",
|
|
348
|
-
"insertion",
|
|
349
|
-
"link",
|
|
350
|
-
"list",
|
|
351
|
-
"listbox",
|
|
352
|
-
"listitem",
|
|
353
|
-
"log",
|
|
354
|
-
"main",
|
|
355
|
-
"marquee",
|
|
356
|
-
"math",
|
|
357
|
-
"menu",
|
|
358
|
-
"menubar",
|
|
359
|
-
"menuitem",
|
|
360
|
-
"menuitemcheckbox",
|
|
361
|
-
"menuitemradio",
|
|
362
|
-
"meter",
|
|
363
|
-
"navigation",
|
|
364
|
-
"none",
|
|
365
|
-
"note",
|
|
366
|
-
"option",
|
|
367
|
-
"paragraph",
|
|
368
|
-
"presentation",
|
|
369
|
-
"progressbar",
|
|
370
|
-
"radio",
|
|
371
|
-
"radiogroup",
|
|
372
|
-
"region",
|
|
373
|
-
"row",
|
|
374
|
-
"rowgroup",
|
|
375
|
-
"rowheader",
|
|
376
|
-
"scrollbar",
|
|
377
|
-
"search",
|
|
378
|
-
"searchbox",
|
|
379
|
-
"separator",
|
|
380
|
-
"slider",
|
|
381
|
-
"spinbutton",
|
|
382
|
-
"status",
|
|
383
|
-
"strong",
|
|
384
|
-
"subscript",
|
|
385
|
-
"superscript",
|
|
386
|
-
"switch",
|
|
387
|
-
"tab",
|
|
388
|
-
"table",
|
|
389
|
-
"tablist",
|
|
390
|
-
"tabpanel",
|
|
391
|
-
"term",
|
|
392
|
-
"textbox",
|
|
393
|
-
"time",
|
|
394
|
-
"timer",
|
|
395
|
-
"toolbar",
|
|
396
|
-
"tooltip",
|
|
397
|
-
"tree",
|
|
398
|
-
"treegrid",
|
|
399
|
-
"treeitem"
|
|
400
|
-
];
|
|
401
|
-
var KNOWN_ARIA_ROLES_SET = new Set(KNOWN_ARIA_ROLES);
|
|
221
|
+
|
|
222
|
+
// ../../lib/primitive/src/constants/aria/global-aria-attributes.ts
|
|
402
223
|
var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
403
224
|
"aria-atomic",
|
|
404
225
|
"aria-busy",
|
|
@@ -418,29 +239,59 @@ var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
418
239
|
"aria-relevant",
|
|
419
240
|
"aria-roledescription"
|
|
420
241
|
]);
|
|
242
|
+
|
|
243
|
+
// ../../lib/primitive/src/constants/aria/implicit-role-record.ts
|
|
421
244
|
var IMPLICIT_ROLE_RECORD = {
|
|
245
|
+
// Landmarks
|
|
422
246
|
article: "article",
|
|
423
247
|
aside: "complementary",
|
|
424
248
|
footer: "contentinfo",
|
|
425
249
|
header: "banner",
|
|
426
250
|
main: "main",
|
|
427
251
|
nav: "navigation",
|
|
428
|
-
|
|
252
|
+
// Interactive
|
|
429
253
|
a: "link",
|
|
254
|
+
button: "button",
|
|
430
255
|
select: "listbox",
|
|
256
|
+
textarea: "textbox",
|
|
257
|
+
// Headings
|
|
431
258
|
h1: "heading",
|
|
432
259
|
h2: "heading",
|
|
433
260
|
h3: "heading",
|
|
434
261
|
h4: "heading",
|
|
435
262
|
h5: "heading",
|
|
436
263
|
h6: "heading",
|
|
264
|
+
// Lists
|
|
437
265
|
ul: "list",
|
|
438
266
|
ol: "list",
|
|
439
267
|
li: "listitem",
|
|
268
|
+
// Tables
|
|
440
269
|
table: "table",
|
|
441
270
|
tr: "row",
|
|
442
271
|
td: "cell",
|
|
443
|
-
th: "columnheader"
|
|
272
|
+
th: "columnheader",
|
|
273
|
+
// Structural / semantic
|
|
274
|
+
dialog: "dialog",
|
|
275
|
+
fieldset: "group",
|
|
276
|
+
figure: "figure",
|
|
277
|
+
meter: "meter",
|
|
278
|
+
output: "status",
|
|
279
|
+
progress: "progressbar"
|
|
280
|
+
};
|
|
281
|
+
var INPUT_TYPE_ROLE_MAP = {
|
|
282
|
+
checkbox: "checkbox",
|
|
283
|
+
radio: "radio",
|
|
284
|
+
range: "slider",
|
|
285
|
+
number: "spinbutton",
|
|
286
|
+
search: "searchbox",
|
|
287
|
+
text: "textbox",
|
|
288
|
+
email: "textbox",
|
|
289
|
+
tel: "textbox",
|
|
290
|
+
url: "textbox",
|
|
291
|
+
button: "button",
|
|
292
|
+
submit: "button",
|
|
293
|
+
reset: "button",
|
|
294
|
+
image: "button"
|
|
444
295
|
};
|
|
445
296
|
var STRONG_ROLES = [
|
|
446
297
|
"main",
|
|
@@ -452,6 +303,8 @@ var STRONG_ROLES = [
|
|
|
452
303
|
var STANDALONE_ROLES = ["article"];
|
|
453
304
|
var STRONG_ROLES_SET = new Set(STRONG_ROLES);
|
|
454
305
|
var STANDALONE_ROLES_SET = new Set(STANDALONE_ROLES);
|
|
306
|
+
|
|
307
|
+
// ../../lib/primitive/src/constants/aria/role-restricted-attributes.ts
|
|
455
308
|
var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
|
|
456
309
|
[
|
|
457
310
|
"aria-activedescendant",
|
|
@@ -601,9 +454,18 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
|
|
|
601
454
|
/* @__PURE__ */ new Set(["meter", "progressbar", "scrollbar", "separator", "slider", "spinbutton"])
|
|
602
455
|
]
|
|
603
456
|
]);
|
|
457
|
+
|
|
458
|
+
// ../../lib/primitive/src/guards/foundational/is-defined.ts
|
|
604
459
|
function isUndefined(value) {
|
|
605
460
|
return value === void 0;
|
|
606
461
|
}
|
|
462
|
+
|
|
463
|
+
// ../../lib/primitive/src/guards/foundational/is-null.ts
|
|
464
|
+
function isNull(value) {
|
|
465
|
+
return value === null;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// ../../lib/primitive/src/guards/aria/is-aria-attribute.ts
|
|
607
469
|
function isGlobalAriaAttribute(attr) {
|
|
608
470
|
return GLOBAL_ARIA_ATTRIBUTES.has(attr);
|
|
609
471
|
}
|
|
@@ -613,6 +475,8 @@ function isAriaAttributeValidForRole(attr, role) {
|
|
|
613
475
|
if (isUndefined(role)) return false;
|
|
614
476
|
return allowedRoles.has(role);
|
|
615
477
|
}
|
|
478
|
+
|
|
479
|
+
// ../../lib/primitive/src/guards/aria/is-aria-role.ts
|
|
616
480
|
function isStrongImplicitRole(tag) {
|
|
617
481
|
if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
|
|
618
482
|
return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
|
|
@@ -621,53 +485,35 @@ function isStandaloneTag(tag) {
|
|
|
621
485
|
if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
|
|
622
486
|
return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
|
|
623
487
|
}
|
|
624
|
-
function
|
|
625
|
-
|
|
488
|
+
function getInputImplicitRole(type) {
|
|
489
|
+
if (type == null || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
|
|
490
|
+
return INPUT_TYPE_ROLE_MAP[type];
|
|
626
491
|
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
footer: "contentinfo",
|
|
633
|
-
header: "banner",
|
|
634
|
-
main: "main",
|
|
635
|
-
nav: "navigation",
|
|
636
|
-
button: "button",
|
|
637
|
-
a: "link",
|
|
638
|
-
select: "listbox",
|
|
639
|
-
h1: "heading",
|
|
640
|
-
h2: "heading",
|
|
641
|
-
h3: "heading",
|
|
642
|
-
h4: "heading",
|
|
643
|
-
h5: "heading",
|
|
644
|
-
h6: "heading",
|
|
645
|
-
ul: "list",
|
|
646
|
-
ol: "list",
|
|
647
|
-
li: "listitem",
|
|
648
|
-
table: "table",
|
|
649
|
-
tr: "row",
|
|
650
|
-
td: "cell",
|
|
651
|
-
th: "columnheader"
|
|
652
|
-
};
|
|
653
|
-
function getImplicitRole(tag) {
|
|
654
|
-
if (tag in IMPLICIT_ROLE_RECORD2) return IMPLICIT_ROLE_RECORD2[tag];
|
|
492
|
+
function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
|
|
493
|
+
const isNamed = typeof ariaLabel === "string" || typeof ariaLabelledBy === "string";
|
|
494
|
+
if (!isNamed) return void 0;
|
|
495
|
+
if (tag === "section") return "region";
|
|
496
|
+
if (tag === "form") return "form";
|
|
655
497
|
return void 0;
|
|
656
498
|
}
|
|
657
|
-
|
|
499
|
+
|
|
500
|
+
// ../../lib/primitive/src/guards/children/component-id.ts
|
|
501
|
+
var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol.for("praxis.component-default-tag");
|
|
502
|
+
|
|
503
|
+
// ../../lib/primitive/src/guards/children/is-tag.ts
|
|
658
504
|
function getAsProp(child) {
|
|
659
|
-
if (!
|
|
505
|
+
if (!isObject(child) || !("props" in child)) return void 0;
|
|
660
506
|
const props = child.props;
|
|
661
|
-
if (!
|
|
507
|
+
if (!isObject(props)) return void 0;
|
|
662
508
|
const as = props.as;
|
|
663
509
|
return isString(as) && as !== "" ? as : void 0;
|
|
664
510
|
}
|
|
665
511
|
function getTag(child) {
|
|
666
|
-
if (!
|
|
512
|
+
if (!isObject(child) || !("type" in child)) return void 0;
|
|
667
513
|
const t = child.type;
|
|
668
514
|
if (isString(t)) return t;
|
|
669
|
-
if (typeof t === "function" ||
|
|
670
|
-
const defaultTag = t[
|
|
515
|
+
if (typeof t === "function" || isObject(t)) {
|
|
516
|
+
const defaultTag = t[COMPONENT_DEFAULT_TAG];
|
|
671
517
|
if (!isString(defaultTag)) return void 0;
|
|
672
518
|
return getAsProp(child) ?? defaultTag;
|
|
673
519
|
}
|
|
@@ -675,65 +521,543 @@ function getTag(child) {
|
|
|
675
521
|
}
|
|
676
522
|
function isTag(...args) {
|
|
677
523
|
if (isString(args[0])) {
|
|
678
|
-
const
|
|
524
|
+
const set3 = new Set(args);
|
|
679
525
|
return (child2) => {
|
|
680
526
|
const tag2 = getTag(child2);
|
|
681
|
-
return tag2 !== void 0 &&
|
|
527
|
+
return tag2 !== void 0 && set3.has(tag2);
|
|
682
528
|
};
|
|
683
529
|
}
|
|
684
530
|
const [child, ...tags] = args;
|
|
685
|
-
const
|
|
531
|
+
const set2 = new Set(tags);
|
|
686
532
|
const tag = getTag(child);
|
|
687
|
-
return tag !== void 0 &&
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
function
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
}
|
|
707
|
-
var StrictBase = class {
|
|
708
|
-
strict;
|
|
709
|
-
constructor(strict) {
|
|
710
|
-
this.strict = strict;
|
|
711
|
-
}
|
|
712
|
-
violate(message) {
|
|
713
|
-
if (this.strict === true || this.strict === "throw") {
|
|
714
|
-
throw new Error(message);
|
|
715
|
-
}
|
|
716
|
-
this.warn(message);
|
|
533
|
+
return tag !== void 0 && set2.has(tag);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// ../../lib/contract/src/aria/aria-role-policy.ts
|
|
537
|
+
function getImplicitRole(tag, props) {
|
|
538
|
+
if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
|
|
539
|
+
if (tag === "input") return getInputImplicitRole(props?.type);
|
|
540
|
+
if (tag === "img") return props?.alt === "" ? "none" : "img";
|
|
541
|
+
if (tag === "section" || tag === "form") {
|
|
542
|
+
return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
|
|
543
|
+
}
|
|
544
|
+
return void 0;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// ../../lib/contract/src/strict/invariant-base.ts
|
|
548
|
+
var InvariantBase = class {
|
|
549
|
+
diagnostics;
|
|
550
|
+
constructor(diagnostics) {
|
|
551
|
+
this.diagnostics = diagnostics;
|
|
717
552
|
}
|
|
718
|
-
|
|
553
|
+
get active() {
|
|
554
|
+
return this.diagnostics.active;
|
|
555
|
+
}
|
|
556
|
+
violate(input) {
|
|
557
|
+
this.diagnostics.error(input);
|
|
558
|
+
}
|
|
559
|
+
// Always caps at warn — never throws. ARIA 'warning' violations route here
|
|
719
560
|
// so they surface even in strict='throw' mode without aborting a render.
|
|
720
|
-
warn(
|
|
721
|
-
|
|
722
|
-
if (this.strict === "async-warn") {
|
|
723
|
-
scheduleAsyncWarn(message);
|
|
724
|
-
return;
|
|
725
|
-
}
|
|
726
|
-
console.warn(message);
|
|
561
|
+
warn(input) {
|
|
562
|
+
this.diagnostics.warn(input);
|
|
727
563
|
}
|
|
728
|
-
invariant(condition,
|
|
729
|
-
if (!condition)
|
|
730
|
-
this.violate(message);
|
|
731
|
-
}
|
|
564
|
+
invariant(condition, input) {
|
|
565
|
+
if (!condition) this.violate(input);
|
|
732
566
|
}
|
|
733
567
|
};
|
|
734
|
-
|
|
735
|
-
|
|
568
|
+
|
|
569
|
+
// ../../lib/diagnostics/src/category.ts
|
|
570
|
+
var DiagnosticCategory = /* @__PURE__ */ ((DiagnosticCategory2) => {
|
|
571
|
+
DiagnosticCategory2[DiagnosticCategory2["Contract"] = 0] = "Contract";
|
|
572
|
+
DiagnosticCategory2[DiagnosticCategory2["HTML"] = 1] = "HTML";
|
|
573
|
+
DiagnosticCategory2[DiagnosticCategory2["ARIA"] = 2] = "ARIA";
|
|
574
|
+
DiagnosticCategory2[DiagnosticCategory2["Composition"] = 3] = "Composition";
|
|
575
|
+
DiagnosticCategory2[DiagnosticCategory2["Rendering"] = 4] = "Rendering";
|
|
576
|
+
DiagnosticCategory2[DiagnosticCategory2["Accessibility"] = 5] = "Accessibility";
|
|
577
|
+
DiagnosticCategory2[DiagnosticCategory2["Performance"] = 6] = "Performance";
|
|
578
|
+
DiagnosticCategory2[DiagnosticCategory2["Internal"] = 7] = "Internal";
|
|
579
|
+
DiagnosticCategory2[DiagnosticCategory2["Deprecation"] = 8] = "Deprecation";
|
|
580
|
+
DiagnosticCategory2[DiagnosticCategory2["Lint"] = 9] = "Lint";
|
|
581
|
+
return DiagnosticCategory2;
|
|
582
|
+
})(DiagnosticCategory || {});
|
|
583
|
+
|
|
584
|
+
// ../../lib/diagnostics/src/error.ts
|
|
585
|
+
var PraxisError = class extends Error {
|
|
586
|
+
diagnostic;
|
|
587
|
+
constructor(diagnostic) {
|
|
588
|
+
super(diagnostic.message);
|
|
589
|
+
this.name = "PraxisError";
|
|
590
|
+
this.diagnostic = diagnostic;
|
|
591
|
+
}
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
// ../../lib/diagnostics/src/severity.ts
|
|
595
|
+
var Severity = /* @__PURE__ */ ((Severity2) => {
|
|
596
|
+
Severity2[Severity2["Debug"] = 0] = "Debug";
|
|
597
|
+
Severity2[Severity2["Info"] = 1] = "Info";
|
|
598
|
+
Severity2[Severity2["Warning"] = 2] = "Warning";
|
|
599
|
+
Severity2[Severity2["Error"] = 3] = "Error";
|
|
600
|
+
Severity2[Severity2["Fatal"] = 4] = "Fatal";
|
|
601
|
+
return Severity2;
|
|
602
|
+
})(Severity || {});
|
|
603
|
+
|
|
604
|
+
// ../../lib/diagnostics/src/policy.ts
|
|
605
|
+
var DefaultPolicy = class {
|
|
606
|
+
reportThreshold;
|
|
607
|
+
throwThreshold;
|
|
608
|
+
constructor({
|
|
609
|
+
reportThreshold = 1 /* Info */,
|
|
610
|
+
throwThreshold = 4 /* Fatal */
|
|
611
|
+
} = {}) {
|
|
612
|
+
this.reportThreshold = reportThreshold;
|
|
613
|
+
this.throwThreshold = throwThreshold;
|
|
614
|
+
}
|
|
615
|
+
resolve(diagnostic) {
|
|
616
|
+
if (diagnostic.severity >= this.throwThreshold) return 2 /* Throw */;
|
|
617
|
+
if (diagnostic.severity >= this.reportThreshold) return 1 /* Report */;
|
|
618
|
+
return 0 /* Ignore */;
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
// ../../lib/diagnostics/src/diagnostics.ts
|
|
623
|
+
var Diagnostics = class {
|
|
624
|
+
reporter;
|
|
625
|
+
policy;
|
|
626
|
+
// Pre-computed at construction time: true if Warning-level diagnostics are not ignored.
|
|
627
|
+
active;
|
|
628
|
+
constructor(reporter, policy = new DefaultPolicy()) {
|
|
629
|
+
this.reporter = reporter;
|
|
630
|
+
this.policy = policy;
|
|
631
|
+
this.active = policy.resolve({ severity: 2 /* Warning */ }) !== 0 /* Ignore */;
|
|
632
|
+
}
|
|
633
|
+
report(diagnostic) {
|
|
634
|
+
const enforcement = this.policy.resolve(diagnostic);
|
|
635
|
+
if (enforcement === 0 /* Ignore */) return diagnostic;
|
|
636
|
+
if (enforcement === 2 /* Throw */) throw new PraxisError(diagnostic);
|
|
637
|
+
this.reporter.report(diagnostic);
|
|
638
|
+
return diagnostic;
|
|
639
|
+
}
|
|
640
|
+
warn(input) {
|
|
641
|
+
return this.report({ ...input, severity: 2 /* Warning */ });
|
|
642
|
+
}
|
|
643
|
+
error(input) {
|
|
644
|
+
return this.report({ ...input, severity: 3 /* Error */ });
|
|
645
|
+
}
|
|
646
|
+
info(input) {
|
|
647
|
+
return this.report({ ...input, severity: 1 /* Info */ });
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
|
|
651
|
+
// ../../lib/diagnostics/src/formatter.ts
|
|
652
|
+
function formatDiagnostic(diagnostic) {
|
|
653
|
+
const level = Severity[diagnostic.severity];
|
|
654
|
+
const category = DiagnosticCategory[diagnostic.category];
|
|
655
|
+
const prefix = category !== void 0 ? `[${category}] ` : "";
|
|
656
|
+
return `${level} ${diagnostic.code}: ${prefix}${diagnostic.message}`;
|
|
736
657
|
}
|
|
658
|
+
|
|
659
|
+
// ../../lib/diagnostics/src/console-reporter.ts
|
|
660
|
+
var ConsoleReporter = class {
|
|
661
|
+
report(diagnostic) {
|
|
662
|
+
const message = formatDiagnostic(diagnostic);
|
|
663
|
+
switch (diagnostic.severity) {
|
|
664
|
+
case 0 /* Debug */:
|
|
665
|
+
console.debug(message);
|
|
666
|
+
break;
|
|
667
|
+
case 1 /* Info */:
|
|
668
|
+
console.info(message);
|
|
669
|
+
break;
|
|
670
|
+
case 2 /* Warning */:
|
|
671
|
+
console.warn(message);
|
|
672
|
+
break;
|
|
673
|
+
case 3 /* Error */:
|
|
674
|
+
case 4 /* Fatal */:
|
|
675
|
+
console.error(message);
|
|
676
|
+
break;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
};
|
|
680
|
+
|
|
681
|
+
// ../../lib/diagnostics/src/null-reporter.ts
|
|
682
|
+
var nullReporter = {
|
|
683
|
+
report() {
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
// ../../lib/diagnostics/src/presets.ts
|
|
688
|
+
var ignoreAllPolicy = {
|
|
689
|
+
resolve(_) {
|
|
690
|
+
return 0 /* Ignore */;
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
var warnOnlyReporter = {
|
|
694
|
+
report(diagnostic) {
|
|
695
|
+
console.warn(formatDiagnostic(diagnostic));
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
var silentDiagnostics = new Diagnostics(nullReporter, ignoreAllPolicy);
|
|
699
|
+
var warnDiagnostics = new Diagnostics(
|
|
700
|
+
warnOnlyReporter,
|
|
701
|
+
new DefaultPolicy({ reportThreshold: 2 /* Warning */, throwThreshold: 4 /* Fatal */ })
|
|
702
|
+
);
|
|
703
|
+
var throwDiagnostics = new Diagnostics(
|
|
704
|
+
new ConsoleReporter(),
|
|
705
|
+
new DefaultPolicy({ reportThreshold: 2 /* Warning */, throwThreshold: 3 /* Error */ })
|
|
706
|
+
);
|
|
707
|
+
|
|
708
|
+
// ../../lib/contract/src/diagnostics/aria.ts
|
|
709
|
+
var AriaDiagnostics = {
|
|
710
|
+
/** Generic bridge for violations produced by external AriaRule functions. */
|
|
711
|
+
fromViolation(v) {
|
|
712
|
+
return {
|
|
713
|
+
code: "ARIA2002" /* AriaViolation */,
|
|
714
|
+
category: 2 /* ARIA */,
|
|
715
|
+
message: v.message
|
|
716
|
+
};
|
|
717
|
+
},
|
|
718
|
+
attributeInvalid(key, role) {
|
|
719
|
+
return {
|
|
720
|
+
code: "ARIA2003" /* AriaAttributeInvalid */,
|
|
721
|
+
category: 2 /* ARIA */,
|
|
722
|
+
message: `"${key}" is not valid on role="${role}". It will be removed.`,
|
|
723
|
+
rationale: "Invalid ARIA attributes are ignored by assistive technology and may trigger accessibility-tree warnings in browser devtools.",
|
|
724
|
+
suggestions: [
|
|
725
|
+
{
|
|
726
|
+
title: "Remove the attribute",
|
|
727
|
+
description: `"${key}" is not in the allowed attribute set for role="${role}".`
|
|
728
|
+
}
|
|
729
|
+
]
|
|
730
|
+
};
|
|
731
|
+
},
|
|
732
|
+
missingLiveRegion(role, impliedLive) {
|
|
733
|
+
return {
|
|
734
|
+
code: "ARIA2004" /* AriaMissingLiveRegion */,
|
|
735
|
+
category: 2 /* ARIA */,
|
|
736
|
+
message: `role="${role}" implies aria-live="${impliedLive}" but it is missing. It has been injected.`,
|
|
737
|
+
rationale: "Live-region roles announce dynamic content changes to screen readers. Without aria-live the politeness level is unspecified and announcements may be silent.",
|
|
738
|
+
suggestions: [
|
|
739
|
+
{
|
|
740
|
+
title: `Add aria-live="${impliedLive}"`,
|
|
741
|
+
description: `role="${role}" conventionally implies aria-live="${impliedLive}".`,
|
|
742
|
+
fix: `aria-live="${impliedLive}"`
|
|
743
|
+
}
|
|
744
|
+
]
|
|
745
|
+
};
|
|
746
|
+
},
|
|
747
|
+
missingAtomic(role) {
|
|
748
|
+
return {
|
|
749
|
+
code: "ARIA2005" /* AriaMissingAtomic */,
|
|
750
|
+
category: 2 /* ARIA */,
|
|
751
|
+
message: `role="${role}" 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.`,
|
|
752
|
+
rationale: "aria-atomic controls whether assistive technology announces the entire live region or only the changed nodes. Omitting it leaves the behaviour browser-defined."
|
|
753
|
+
};
|
|
754
|
+
},
|
|
755
|
+
relevantInvalidTokens(invalid) {
|
|
756
|
+
const quoted = invalid.map((t) => `"${t}"`).join(", ");
|
|
757
|
+
return {
|
|
758
|
+
code: "ARIA2006" /* AriaRelevantInvalidToken */,
|
|
759
|
+
category: 2 /* ARIA */,
|
|
760
|
+
message: `aria-relevant contains invalid token(s): ${quoted}. Valid tokens are: additions, removals, text, all.`,
|
|
761
|
+
rationale: "aria-relevant accepts a space-separated list of change types. Unrecognised tokens are silently ignored by assistive technology, making the attribute ineffective.",
|
|
762
|
+
suggestions: [
|
|
763
|
+
{
|
|
764
|
+
title: "Use only valid tokens",
|
|
765
|
+
description: "Valid values are: additions, removals, text, all (or a space-separated combination)."
|
|
766
|
+
}
|
|
767
|
+
]
|
|
768
|
+
};
|
|
769
|
+
},
|
|
770
|
+
relevantSuperseded() {
|
|
771
|
+
return {
|
|
772
|
+
code: "ARIA2007" /* AriaRelevantSuperseded */,
|
|
773
|
+
category: 2 /* ARIA */,
|
|
774
|
+
message: 'aria-relevant includes "all" alongside other tokens. "all" supersedes additions, removals, and text \u2014 use aria-relevant="all" alone.',
|
|
775
|
+
rationale: '"all" is equivalent to "additions removals text". Combining it with other tokens is redundant and may confuse readers of the markup.',
|
|
776
|
+
suggestions: [
|
|
777
|
+
{
|
|
778
|
+
title: 'Use aria-relevant="all"',
|
|
779
|
+
fix: 'aria-relevant="all"'
|
|
780
|
+
}
|
|
781
|
+
]
|
|
782
|
+
};
|
|
783
|
+
},
|
|
784
|
+
missingAccessibleName(tag) {
|
|
785
|
+
return {
|
|
786
|
+
code: "ARIA2009" /* AriaMissingAccessibleName */,
|
|
787
|
+
category: 2 /* ARIA */,
|
|
788
|
+
message: `<${tag}> has no accessible name. Add aria-label or aria-labelledby.`,
|
|
789
|
+
rationale: "Elements with a landmark or interactive role must have an accessible name so that assistive technology can identify them when presenting the page outline.",
|
|
790
|
+
suggestions: [
|
|
791
|
+
{
|
|
792
|
+
title: "Add aria-label",
|
|
793
|
+
description: `Add aria-label="\u2026" directly to the <${tag}> element.`
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
title: "Add aria-labelledby",
|
|
797
|
+
description: "Point aria-labelledby at the id of an existing heading or label element."
|
|
798
|
+
}
|
|
799
|
+
]
|
|
800
|
+
};
|
|
801
|
+
},
|
|
802
|
+
attributeOnPresentational(attr, tag) {
|
|
803
|
+
return {
|
|
804
|
+
code: "ARIA2010" /* AriaAttributeOnPresentational */,
|
|
805
|
+
category: 2 /* ARIA */,
|
|
806
|
+
message: `"${attr}" is not allowed on a presentational <${tag}>. Presentational elements are invisible to assistive technology.`,
|
|
807
|
+
rationale: 'role="none" and role="presentation" (including <img alt="">) remove an element from the accessibility tree. ARIA attributes on such elements are ignored by assistive technology.',
|
|
808
|
+
suggestions: [
|
|
809
|
+
{
|
|
810
|
+
title: "Remove the attribute",
|
|
811
|
+
description: `"${attr}" has no effect when the element has role="none" or role="presentation".`
|
|
812
|
+
}
|
|
813
|
+
]
|
|
814
|
+
};
|
|
815
|
+
},
|
|
816
|
+
ariaHiddenOnFocusable(tag) {
|
|
817
|
+
return {
|
|
818
|
+
code: "ARIA2011" /* AriaHiddenOnFocusable */,
|
|
819
|
+
category: 2 /* ARIA */,
|
|
820
|
+
message: `aria-hidden="true" must not be used on focusable <${tag}> elements. Screen reader users who navigate by keyboard will encounter the element but receive no information about it.`,
|
|
821
|
+
rationale: 'aria-hidden removes an element from the accessibility tree while leaving it keyboard-reachable. This creates a "ghost" \u2014 a focusable element assistive technology cannot describe.',
|
|
822
|
+
suggestions: [
|
|
823
|
+
{
|
|
824
|
+
title: "Remove aria-hidden",
|
|
825
|
+
description: "If the element should be hidden from all users, use the HTML hidden attribute or CSS display:none instead."
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
title: "Make the element non-focusable",
|
|
829
|
+
description: 'If the element is intentionally decorative, add tabindex="-1" and disable it so it is not reachable by keyboard.'
|
|
830
|
+
}
|
|
831
|
+
]
|
|
832
|
+
};
|
|
833
|
+
},
|
|
834
|
+
invalidAttributeValue(attr, value, expected) {
|
|
835
|
+
const got = value === null ? "null" : value === void 0 ? "undefined" : typeof value === "string" ? `"${value}"` : String(value);
|
|
836
|
+
return {
|
|
837
|
+
code: "ARIA2013" /* AriaInvalidAttributeValue */,
|
|
838
|
+
category: 2 /* ARIA */,
|
|
839
|
+
message: `"${attr}" has an invalid value (${got}). Expected: ${expected}.`,
|
|
840
|
+
rationale: "ARIA attributes with invalid values are silently ignored by assistive technology, making the markup semantically inert.",
|
|
841
|
+
suggestions: [
|
|
842
|
+
{
|
|
843
|
+
title: `Use a valid value for ${attr}`,
|
|
844
|
+
description: `Valid values are: ${expected}.`
|
|
845
|
+
}
|
|
846
|
+
]
|
|
847
|
+
};
|
|
848
|
+
},
|
|
849
|
+
redundantAriaLevel(tag, level) {
|
|
850
|
+
return {
|
|
851
|
+
code: "ARIA2014" /* AriaRedundantLevelAttribute */,
|
|
852
|
+
category: 2 /* ARIA */,
|
|
853
|
+
message: `aria-level="${level}" is redundant on <${tag}>: the element already has an implicit heading level of ${level}. Remove the attribute.`,
|
|
854
|
+
rationale: 'Restating the implicit aria-level adds noise without semantic value. Use aria-level only to override the native heading level (e.g. aria-level="3" on <h2>).',
|
|
855
|
+
suggestions: [
|
|
856
|
+
{
|
|
857
|
+
title: "Remove aria-level",
|
|
858
|
+
description: `<${tag}> already implies aria-level="${level}".`
|
|
859
|
+
}
|
|
860
|
+
]
|
|
861
|
+
};
|
|
862
|
+
},
|
|
863
|
+
requiredProperty(attr, role) {
|
|
864
|
+
return {
|
|
865
|
+
code: "ARIA2012" /* AriaRequiredProperty */,
|
|
866
|
+
category: 2 /* ARIA */,
|
|
867
|
+
message: `"${attr}" is required for role="${role}" but is missing.`,
|
|
868
|
+
rationale: `WAI-ARIA 1.2 specifies required states and properties for certain roles. Without "${attr}", assistive technology cannot correctly communicate the element's state to users.`,
|
|
869
|
+
suggestions: [
|
|
870
|
+
{
|
|
871
|
+
title: `Add ${attr}`,
|
|
872
|
+
description: `role="${role}" requires "${attr}" to be present.`
|
|
873
|
+
}
|
|
874
|
+
]
|
|
875
|
+
};
|
|
876
|
+
},
|
|
877
|
+
invalidRole(role, tag) {
|
|
878
|
+
return {
|
|
879
|
+
code: "ARIA2008" /* AriaInvalidRole */,
|
|
880
|
+
category: 2 /* ARIA */,
|
|
881
|
+
message: `Invalid role "${role ?? ""}" on <${tag}>.`,
|
|
882
|
+
rationale: "An unrecognised or misapplied ARIA role is ignored by assistive technology and may degrade the accessibility of the element."
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
// ../../lib/contract/src/diagnostics/contract.ts
|
|
888
|
+
var ContractDiagnostics = {
|
|
889
|
+
unexpectedChild(typeName, index, context) {
|
|
890
|
+
return {
|
|
891
|
+
code: "COMP1004" /* UnexpectedChild */,
|
|
892
|
+
category: 0 /* Contract */,
|
|
893
|
+
component: context,
|
|
894
|
+
message: `${context}: unexpected child "${typeName}" at index ${index}.`
|
|
895
|
+
};
|
|
896
|
+
},
|
|
897
|
+
ambiguousChild(typeName, index, ruleNames, context) {
|
|
898
|
+
const quoted = ruleNames.map((n) => `"${n}"`).join(" and ");
|
|
899
|
+
return {
|
|
900
|
+
code: "COMP1005" /* AmbiguousChild */,
|
|
901
|
+
category: 0 /* Contract */,
|
|
902
|
+
component: context,
|
|
903
|
+
message: `${context}: child "${typeName}" at index ${index} matches multiple child rules: ${quoted}.`
|
|
904
|
+
};
|
|
905
|
+
},
|
|
906
|
+
cardinalityMin(ruleName, min, context) {
|
|
907
|
+
return {
|
|
908
|
+
code: "COMP1006" /* CardinalityMin */,
|
|
909
|
+
category: 0 /* Contract */,
|
|
910
|
+
component: context,
|
|
911
|
+
message: `${context}: "${ruleName}" requires at least ${min}.`
|
|
912
|
+
};
|
|
913
|
+
},
|
|
914
|
+
cardinalityMax(ruleName, max, context) {
|
|
915
|
+
return {
|
|
916
|
+
code: "COMP1007" /* CardinalityMax */,
|
|
917
|
+
category: 0 /* Contract */,
|
|
918
|
+
component: context,
|
|
919
|
+
message: `${context}: "${ruleName}" allows at most ${max}.`
|
|
920
|
+
};
|
|
921
|
+
},
|
|
922
|
+
positionViolation(ruleName, position, index, context) {
|
|
923
|
+
return {
|
|
924
|
+
code: "COMP1008" /* PositionViolation */,
|
|
925
|
+
category: 0 /* Contract */,
|
|
926
|
+
component: context,
|
|
927
|
+
message: `${context}: "${ruleName}" must be ${position}, got index ${index}`
|
|
928
|
+
};
|
|
929
|
+
},
|
|
930
|
+
unknownVariantDim(component, label, dim) {
|
|
931
|
+
return {
|
|
932
|
+
code: "COMP1010" /* ContractUnknownVariantDim */,
|
|
933
|
+
category: 0 /* Contract */,
|
|
934
|
+
message: `${component}: ${label} references unknown variant "${dim}".`
|
|
935
|
+
};
|
|
936
|
+
},
|
|
937
|
+
unknownVariantValue(component, label, dim, value, valid) {
|
|
938
|
+
return {
|
|
939
|
+
code: "COMP1011" /* ContractUnknownVariantValue */,
|
|
940
|
+
category: 0 /* Contract */,
|
|
941
|
+
message: `${component}: ${label} sets "${dim}" to unknown value "${value}" (valid: ${valid.join(", ")}).`
|
|
942
|
+
};
|
|
943
|
+
},
|
|
944
|
+
unknownRecipeKey(component, key) {
|
|
945
|
+
return {
|
|
946
|
+
code: "COMP1012" /* ContractUnknownRecipeKey */,
|
|
947
|
+
category: 0 /* Contract */,
|
|
948
|
+
message: `${component} Unknown recipeKey "${key}" \u2014 no preset with that name exists.`
|
|
949
|
+
};
|
|
950
|
+
},
|
|
951
|
+
invalidVariantValue(component, key, value) {
|
|
952
|
+
return {
|
|
953
|
+
code: "COMP1013" /* ContractInvalidVariantValue */,
|
|
954
|
+
category: 0 /* Contract */,
|
|
955
|
+
message: `${component} Variant "${key}=${value}" is not a defined value for the "${key}" dimension.`
|
|
956
|
+
};
|
|
957
|
+
},
|
|
958
|
+
allowedAsViolation(tag, allowedAs, component) {
|
|
959
|
+
const allowed = allowedAs.map((t) => `"${String(t)}"`).join(", ");
|
|
960
|
+
return {
|
|
961
|
+
code: "COMP1009" /* AllowedAsViolation */,
|
|
962
|
+
category: 0 /* Contract */,
|
|
963
|
+
component,
|
|
964
|
+
message: `<${component}>: "as" prop received "${tag}" but only [${allowed}] are allowed.`
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
|
|
969
|
+
// ../../lib/contract/src/diagnostics/html.ts
|
|
970
|
+
var HtmlDiagnostics = {
|
|
971
|
+
emptyRole(tag) {
|
|
972
|
+
return {
|
|
973
|
+
code: "HTML3002" /* HtmlEmptyRole */,
|
|
974
|
+
category: 1 /* HTML */,
|
|
975
|
+
message: `<${tag}> has an explicit empty role="". Omit the attribute instead.`
|
|
976
|
+
};
|
|
977
|
+
},
|
|
978
|
+
implicitRoleRedundant(tag, implicitRole) {
|
|
979
|
+
return {
|
|
980
|
+
code: "HTML3003" /* HtmlImplicitRoleRedundant */,
|
|
981
|
+
category: 1 /* HTML */,
|
|
982
|
+
message: `<${tag}> already has implicit role="${implicitRole}". Avoid redundant role assignment.`
|
|
983
|
+
};
|
|
984
|
+
},
|
|
985
|
+
implicitRoleOverride(tag, implicitRole, role) {
|
|
986
|
+
return {
|
|
987
|
+
code: "HTML3004" /* HtmlImplicitRoleOverride */,
|
|
988
|
+
category: 1 /* HTML */,
|
|
989
|
+
message: `<${tag}> should not override its implicit role="${implicitRole}" with role="${role}".`
|
|
990
|
+
};
|
|
991
|
+
},
|
|
992
|
+
standaloneRegionOverride(tag, implicitRole) {
|
|
993
|
+
return {
|
|
994
|
+
code: "HTML3005" /* HtmlStandaloneRegionOverride */,
|
|
995
|
+
category: 1 /* HTML */,
|
|
996
|
+
message: `<${tag}> is a self-contained element with implicit role="${implicitRole}". Assigning role="region" has been removed.`
|
|
997
|
+
};
|
|
998
|
+
},
|
|
999
|
+
landmarkRoleOverride(tag, implicitRole, role) {
|
|
1000
|
+
return {
|
|
1001
|
+
code: "HTML3006" /* HtmlLandmarkRoleOverride */,
|
|
1002
|
+
category: 1 /* HTML */,
|
|
1003
|
+
message: `<${tag}> has a fixed landmark role="${implicitRole}". role="${role}" overrides it and confuses assistive technology. The override has been removed.`
|
|
1004
|
+
};
|
|
1005
|
+
},
|
|
1006
|
+
invalidChild(child, parent, allowed) {
|
|
1007
|
+
return {
|
|
1008
|
+
code: "HTML3007" /* HtmlInvalidChild */,
|
|
1009
|
+
category: 1 /* HTML */,
|
|
1010
|
+
message: `<${child}> is not a valid direct child of <${parent}>. Allowed: ${allowed}.`
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
};
|
|
1014
|
+
|
|
1015
|
+
// ../../lib/contract/src/diagnostics/slot.ts
|
|
1016
|
+
var SlotDiagnostics = {
|
|
1017
|
+
exclusive(name) {
|
|
1018
|
+
return {
|
|
1019
|
+
code: "SLOT1001" /* SlotExclusive */,
|
|
1020
|
+
category: 0 /* Contract */,
|
|
1021
|
+
component: name,
|
|
1022
|
+
message: `${name}: "as" and "asChild" are mutually exclusive`
|
|
1023
|
+
};
|
|
1024
|
+
},
|
|
1025
|
+
singleChildRequired(name, elementTerm) {
|
|
1026
|
+
return {
|
|
1027
|
+
code: "SLOT1002" /* SlotSingleChild */,
|
|
1028
|
+
category: 0 /* Contract */,
|
|
1029
|
+
component: name,
|
|
1030
|
+
message: `${name}: asChild requires a ${elementTerm} child`
|
|
1031
|
+
};
|
|
1032
|
+
},
|
|
1033
|
+
singleChildExceeded(name, elementTerm, count) {
|
|
1034
|
+
return {
|
|
1035
|
+
code: "SLOT1002" /* SlotSingleChild */,
|
|
1036
|
+
category: 0 /* Contract */,
|
|
1037
|
+
component: name,
|
|
1038
|
+
message: `${name}: asChild requires exactly one ${elementTerm} child, got ${count}`
|
|
1039
|
+
};
|
|
1040
|
+
},
|
|
1041
|
+
discardedChildren(name, elementTerm, count) {
|
|
1042
|
+
const suffix = count === 1 ? "" : "ren";
|
|
1043
|
+
return {
|
|
1044
|
+
code: "SLOT1003" /* SlotDiscardedChildren */,
|
|
1045
|
+
category: 0 /* Contract */,
|
|
1046
|
+
component: name,
|
|
1047
|
+
message: `${name}: asChild discarded ${count} non-element child${suffix} \u2014 only ${elementTerm}s are valid asChild children.`
|
|
1048
|
+
};
|
|
1049
|
+
},
|
|
1050
|
+
renderFnRequired(name, received) {
|
|
1051
|
+
return {
|
|
1052
|
+
code: "SLOT1004" /* SlotRenderFn */,
|
|
1053
|
+
category: 0 /* Contract */,
|
|
1054
|
+
component: name,
|
|
1055
|
+
message: `${name}: asChild requires a render function as children, got ${received}`
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
};
|
|
1059
|
+
|
|
1060
|
+
// ../../lib/contract/src/aria/polymorphic-validator.ts
|
|
737
1061
|
var VALID = [{ valid: true }];
|
|
738
1062
|
function isIntrinsicTag(tag) {
|
|
739
1063
|
return isString(tag);
|
|
@@ -742,26 +1066,28 @@ function omitProp(obj, key) {
|
|
|
742
1066
|
const { [key]: _, ...rest } = obj;
|
|
743
1067
|
return rest;
|
|
744
1068
|
}
|
|
745
|
-
var AriaPolicyEngine = class _AriaPolicyEngine extends
|
|
1069
|
+
var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
746
1070
|
#extraRules;
|
|
747
1071
|
#planCache = /* @__PURE__ */ new Map();
|
|
748
1072
|
static #MAX_CACHE = 100;
|
|
749
1073
|
// Memoized AriaFix objects keyed by attribute name — the ARIA attribute set is
|
|
750
1074
|
// finite so this Map is bounded and avoids recreating closures on every cache miss.
|
|
751
1075
|
static #removeAttributeFixCache = /* @__PURE__ */ new Map();
|
|
752
|
-
constructor(
|
|
753
|
-
super(
|
|
1076
|
+
constructor(diagnostics, options) {
|
|
1077
|
+
super(diagnostics);
|
|
754
1078
|
this.#extraRules = options?.rules ?? [];
|
|
755
1079
|
}
|
|
756
1080
|
static #normalizeEmptyRole(tag, props) {
|
|
757
1081
|
if (props.role !== "") return { normalized: false };
|
|
1082
|
+
const d = HtmlDiagnostics.emptyRole(tag);
|
|
758
1083
|
return {
|
|
759
1084
|
normalized: true,
|
|
760
1085
|
result: {
|
|
761
1086
|
props: omitProp(props, "role"),
|
|
762
1087
|
violations: [
|
|
763
1088
|
{
|
|
764
|
-
message:
|
|
1089
|
+
message: d.message,
|
|
1090
|
+
diagnostic: d,
|
|
765
1091
|
tag,
|
|
766
1092
|
role: "",
|
|
767
1093
|
attribute: void 0,
|
|
@@ -774,10 +1100,9 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
774
1100
|
}
|
|
775
1101
|
static #deriveContext(tag, props) {
|
|
776
1102
|
if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
|
|
777
|
-
const implicitRole = getImplicitRole(tag);
|
|
778
|
-
const
|
|
779
|
-
if (!
|
|
780
|
-
return { proceed: false, result: { props, violations: [] } };
|
|
1103
|
+
const implicitRole = getImplicitRole(tag, props);
|
|
1104
|
+
const hasRole2 = implicitRole != null || isString(props.role) && props.role.length > 0;
|
|
1105
|
+
if (!hasRole2) return { proceed: false, result: { props, violations: [] } };
|
|
781
1106
|
const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
|
|
782
1107
|
if (normalized.normalized) return { proceed: false, result: normalized.result };
|
|
783
1108
|
const effectiveRole = props.role ?? implicitRole;
|
|
@@ -792,25 +1117,36 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
792
1117
|
static #runRules(rules, context) {
|
|
793
1118
|
const violations = [];
|
|
794
1119
|
const fixes = [];
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
if (
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
1120
|
+
iterate.forEach(rules, (rule) => {
|
|
1121
|
+
iterate.forEach(rule(context), (result) => {
|
|
1122
|
+
if (result.valid) return;
|
|
1123
|
+
const {
|
|
1124
|
+
tag,
|
|
1125
|
+
props: { role }
|
|
1126
|
+
} = context;
|
|
1127
|
+
const { message, attribute, severity } = result;
|
|
1128
|
+
const resolvedMessage = message ?? result.diagnostic?.message;
|
|
1129
|
+
const fallbackDiag = resolvedMessage == null ? AriaDiagnostics.invalidRole(role, tag) : void 0;
|
|
1130
|
+
violations.push({
|
|
1131
|
+
message: resolvedMessage ?? fallbackDiag.message,
|
|
1132
|
+
tag,
|
|
1133
|
+
role,
|
|
1134
|
+
attribute,
|
|
1135
|
+
severity,
|
|
1136
|
+
phase: "evaluate",
|
|
1137
|
+
...result.diagnostic != null && { diagnostic: result.diagnostic },
|
|
1138
|
+
...fallbackDiag != null && { diagnostic: fallbackDiag }
|
|
1139
|
+
});
|
|
1140
|
+
if (result.fixable) fixes.push(result.fix);
|
|
1141
|
+
});
|
|
1142
|
+
});
|
|
810
1143
|
return { violations, fixes };
|
|
811
1144
|
}
|
|
812
1145
|
static #getRules(context) {
|
|
813
|
-
|
|
1146
|
+
if (_AriaPolicyEngine.#hasRole(context.props) || context.effectiveRole != null && _AriaPolicyEngine.#LIVE_REGION_ROLES.has(context.effectiveRole)) {
|
|
1147
|
+
return _AriaPolicyEngine.#pipeline;
|
|
1148
|
+
}
|
|
1149
|
+
return _AriaPolicyEngine.#implicitOnlyRules;
|
|
814
1150
|
}
|
|
815
1151
|
static evaluate(tag, props) {
|
|
816
1152
|
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
@@ -835,10 +1171,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
835
1171
|
return { props: next, violations };
|
|
836
1172
|
}
|
|
837
1173
|
report(violations) {
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
1174
|
+
iterate.forEach(violations, (v) => {
|
|
1175
|
+
const d = v.diagnostic ?? AriaDiagnostics.fromViolation(v);
|
|
1176
|
+
if (v.severity === "error") this.violate(d);
|
|
1177
|
+
else this.warn(d);
|
|
1178
|
+
});
|
|
842
1179
|
}
|
|
843
1180
|
// Cache key covers only the aria-relevant subset of props (tag + role + aria-* attrs).
|
|
844
1181
|
// Non-aria props (className, onClick, etc.) do not affect ARIA decisions and are excluded
|
|
@@ -850,27 +1187,26 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
850
1187
|
if (!isIntrinsicTag(tag)) return null;
|
|
851
1188
|
const parts = [tag];
|
|
852
1189
|
if (typeof props.role === "string") parts.push(`role:${props.role}`);
|
|
1190
|
+
if (tag === "input" && typeof props.type === "string") parts.push(`type:${props.type}`);
|
|
1191
|
+
if (tag === "img") parts.push(`alt:${props.alt === "" ? "empty" : "present"}`);
|
|
853
1192
|
const ariaEntries = [];
|
|
854
|
-
|
|
855
|
-
if (!
|
|
856
|
-
|
|
857
|
-
if (!isString(v) && !isNumber(v) && typeof v !== "boolean") continue;
|
|
1193
|
+
iterate.forEachEntry(props, (k, v) => {
|
|
1194
|
+
if (!k.startsWith("aria-")) return;
|
|
1195
|
+
if (!isString(v) && !isNumber(v) && typeof v !== "boolean") return;
|
|
858
1196
|
ariaEntries.push(`${k}:${String(v)}`);
|
|
859
|
-
}
|
|
1197
|
+
});
|
|
860
1198
|
if (ariaEntries.length > 0) parts.push(...ariaEntries.sort());
|
|
861
1199
|
return parts.join("|");
|
|
862
1200
|
}
|
|
863
1201
|
static #computePlan(inputProps, resultProps) {
|
|
864
1202
|
const removals = /* @__PURE__ */ new Set();
|
|
865
1203
|
const updates = {};
|
|
866
|
-
|
|
867
|
-
if (
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
if (!Object.hasOwn(resultProps, key)) continue;
|
|
871
|
-
const resultVal = resultProps[key];
|
|
1204
|
+
iterate.forEachKey(inputProps, (key) => {
|
|
1205
|
+
if (!(key in resultProps)) removals.add(key);
|
|
1206
|
+
});
|
|
1207
|
+
iterate.forEachEntry(resultProps, (key, resultVal) => {
|
|
872
1208
|
if (inputProps[key] !== resultVal) updates[key] = resultVal;
|
|
873
|
-
}
|
|
1209
|
+
});
|
|
874
1210
|
return { removals, updates };
|
|
875
1211
|
}
|
|
876
1212
|
static #applyPlan(props, removals, updates) {
|
|
@@ -878,15 +1214,15 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
878
1214
|
const hasUpdates = Object.keys(updates).length > 0;
|
|
879
1215
|
if (!hasRemovals && !hasUpdates) return props;
|
|
880
1216
|
const next = {};
|
|
881
|
-
|
|
882
|
-
if (
|
|
883
|
-
}
|
|
1217
|
+
iterate.forEachEntry(props, (k, v) => {
|
|
1218
|
+
if (!removals.has(k)) next[k] = v;
|
|
1219
|
+
});
|
|
884
1220
|
Object.assign(next, updates);
|
|
885
1221
|
return next;
|
|
886
1222
|
}
|
|
887
1223
|
validate(tag, props) {
|
|
888
1224
|
const key = _AriaPolicyEngine.#createPlanKey(tag, props);
|
|
889
|
-
if (!
|
|
1225
|
+
if (!isNull(key)) {
|
|
890
1226
|
const cached = this.#planCache.get(key);
|
|
891
1227
|
if (cached !== void 0) {
|
|
892
1228
|
this.#planCache.delete(key);
|
|
@@ -900,7 +1236,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
900
1236
|
}
|
|
901
1237
|
const result = this.#extraRules.length ? _AriaPolicyEngine.#evaluateWithRules(tag, props, this.#extraRules) : _AriaPolicyEngine.evaluate(tag, props);
|
|
902
1238
|
if (result.violations.length > 0) this.report(result.violations);
|
|
903
|
-
if (!
|
|
1239
|
+
if (!isNull(key)) {
|
|
904
1240
|
const { removals, updates } = _AriaPolicyEngine.#computePlan(
|
|
905
1241
|
props,
|
|
906
1242
|
result.props
|
|
@@ -921,12 +1257,12 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
921
1257
|
if (fixes.length === 0) return props;
|
|
922
1258
|
const sorted = [...fixes].sort((a, b) => (a.priority ?? Infinity) - (b.priority ?? Infinity));
|
|
923
1259
|
let next = props;
|
|
924
|
-
|
|
1260
|
+
iterate.forEach(sorted, ({ apply }) => {
|
|
925
1261
|
const effectiveRole = next.role ?? implicitRole;
|
|
926
1262
|
const fixContext = { tag, implicitRole, effectiveRole, props: next };
|
|
927
1263
|
const fixResult = apply(fixContext);
|
|
928
1264
|
if (fixResult.applied) next = fixResult.next;
|
|
929
|
-
}
|
|
1265
|
+
});
|
|
930
1266
|
return next;
|
|
931
1267
|
}
|
|
932
1268
|
static #removeRole = {
|
|
@@ -954,10 +1290,26 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
954
1290
|
_AriaPolicyEngine.#checkInvalidRoleOverride,
|
|
955
1291
|
_AriaPolicyEngine.#checkRedundantRole,
|
|
956
1292
|
_AriaPolicyEngine.#checkStandaloneRegion,
|
|
1293
|
+
_AriaPolicyEngine.#checkAriaAttributeValues,
|
|
957
1294
|
_AriaPolicyEngine.#checkInvalidAriaAttributes,
|
|
1295
|
+
_AriaPolicyEngine.#checkRequiredAriaProperties,
|
|
1296
|
+
_AriaPolicyEngine.#checkNameRequiredRoles,
|
|
1297
|
+
_AriaPolicyEngine.#checkRedundantAriaLevel,
|
|
958
1298
|
_AriaPolicyEngine.#checkMissingLiveRegion,
|
|
959
1299
|
_AriaPolicyEngine.#checkMissingAtomic,
|
|
960
|
-
_AriaPolicyEngine.#checkInvalidAriaRelevant
|
|
1300
|
+
_AriaPolicyEngine.#checkInvalidAriaRelevant,
|
|
1301
|
+
_AriaPolicyEngine.#checkAriaHiddenOnFocusable,
|
|
1302
|
+
_AriaPolicyEngine.#checkPresentationalAriaAttributes
|
|
1303
|
+
];
|
|
1304
|
+
// Rules for elements with an implicit role but no explicit role (not a live region).
|
|
1305
|
+
static #implicitOnlyRules = [
|
|
1306
|
+
_AriaPolicyEngine.#checkAriaAttributeValues,
|
|
1307
|
+
_AriaPolicyEngine.#checkInvalidAriaAttributes,
|
|
1308
|
+
_AriaPolicyEngine.#checkRequiredAriaProperties,
|
|
1309
|
+
_AriaPolicyEngine.#checkNameRequiredRoles,
|
|
1310
|
+
_AriaPolicyEngine.#checkRedundantAriaLevel,
|
|
1311
|
+
_AriaPolicyEngine.#checkAriaHiddenOnFocusable,
|
|
1312
|
+
_AriaPolicyEngine.#checkPresentationalAriaAttributes
|
|
961
1313
|
];
|
|
962
1314
|
static #checkInvalidRoleOverride({
|
|
963
1315
|
tag,
|
|
@@ -973,7 +1325,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
973
1325
|
fixable: true,
|
|
974
1326
|
severity: "error",
|
|
975
1327
|
fix: _AriaPolicyEngine.#removeRole,
|
|
976
|
-
|
|
1328
|
+
diagnostic: HtmlDiagnostics.implicitRoleOverride(tag, implicitRole, role)
|
|
977
1329
|
}
|
|
978
1330
|
];
|
|
979
1331
|
}
|
|
@@ -985,47 +1337,304 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
985
1337
|
return [
|
|
986
1338
|
{
|
|
987
1339
|
valid: false,
|
|
988
|
-
fixable: true,
|
|
1340
|
+
fixable: true,
|
|
1341
|
+
severity: "warning",
|
|
1342
|
+
fix: _AriaPolicyEngine.#removeRole,
|
|
1343
|
+
diagnostic: HtmlDiagnostics.implicitRoleRedundant(tag, implicitRole)
|
|
1344
|
+
}
|
|
1345
|
+
];
|
|
1346
|
+
}
|
|
1347
|
+
static #checkStandaloneRegion({ tag, props, implicitRole }) {
|
|
1348
|
+
const role = props.role;
|
|
1349
|
+
if (role !== "region") return VALID;
|
|
1350
|
+
if (!isStandaloneTag(tag)) return VALID;
|
|
1351
|
+
return [
|
|
1352
|
+
{
|
|
1353
|
+
valid: false,
|
|
1354
|
+
fixable: true,
|
|
1355
|
+
severity: "error",
|
|
1356
|
+
fix: _AriaPolicyEngine.#removeRole,
|
|
1357
|
+
diagnostic: HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag)
|
|
1358
|
+
}
|
|
1359
|
+
];
|
|
1360
|
+
}
|
|
1361
|
+
static #checkInvalidAriaAttributes({
|
|
1362
|
+
tag,
|
|
1363
|
+
props,
|
|
1364
|
+
effectiveRole
|
|
1365
|
+
}) {
|
|
1366
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
|
|
1367
|
+
const results = [];
|
|
1368
|
+
iterate.forEachEntry(props, (key) => {
|
|
1369
|
+
if (!key.startsWith("aria-")) return;
|
|
1370
|
+
if (isGlobalAriaAttribute(key)) return;
|
|
1371
|
+
if (isAriaAttributeValidForRole(key, effectiveRole)) return;
|
|
1372
|
+
results.push({
|
|
1373
|
+
valid: false,
|
|
1374
|
+
severity: "warning",
|
|
1375
|
+
fixable: true,
|
|
1376
|
+
attribute: key,
|
|
1377
|
+
diagnostic: AriaDiagnostics.attributeInvalid(key, effectiveRole ?? tag),
|
|
1378
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix(key)
|
|
1379
|
+
});
|
|
1380
|
+
});
|
|
1381
|
+
return results;
|
|
1382
|
+
}
|
|
1383
|
+
// ─── ARIA attribute value validation ──────────────────────────────────────
|
|
1384
|
+
// Accepted value shapes for typed ARIA attributes.
|
|
1385
|
+
// Attributes not in this map are unconstrained (arbitrary string values permitted).
|
|
1386
|
+
static #ARIA_VALUE_TYPES = /* @__PURE__ */ new Map([
|
|
1387
|
+
// Boolean (true | false)
|
|
1388
|
+
["aria-atomic", { kind: "boolean" }],
|
|
1389
|
+
["aria-busy", { kind: "boolean" }],
|
|
1390
|
+
["aria-disabled", { kind: "boolean" }],
|
|
1391
|
+
["aria-expanded", { kind: "boolean" }],
|
|
1392
|
+
["aria-hidden", { kind: "boolean" }],
|
|
1393
|
+
["aria-modal", { kind: "boolean" }],
|
|
1394
|
+
["aria-multiline", { kind: "boolean" }],
|
|
1395
|
+
["aria-multiselectable", { kind: "boolean" }],
|
|
1396
|
+
["aria-readonly", { kind: "boolean" }],
|
|
1397
|
+
["aria-required", { kind: "boolean" }],
|
|
1398
|
+
["aria-selected", { kind: "boolean" }],
|
|
1399
|
+
// Tristate (true | false | mixed)
|
|
1400
|
+
["aria-checked", { kind: "tristate" }],
|
|
1401
|
+
["aria-pressed", { kind: "tristate" }],
|
|
1402
|
+
// Numeric (any finite number)
|
|
1403
|
+
["aria-valuenow", { kind: "number" }],
|
|
1404
|
+
["aria-valuemin", { kind: "number" }],
|
|
1405
|
+
["aria-valuemax", { kind: "number" }],
|
|
1406
|
+
// Integer with optional range
|
|
1407
|
+
["aria-level", { kind: "integer", min: 1, max: 6 }],
|
|
1408
|
+
["aria-posinset", { kind: "integer", min: 1 }],
|
|
1409
|
+
["aria-setsize", { kind: "integer", min: -1 }],
|
|
1410
|
+
["aria-rowcount", { kind: "integer", min: -1 }],
|
|
1411
|
+
["aria-colcount", { kind: "integer", min: -1 }],
|
|
1412
|
+
["aria-rowindex", { kind: "integer", min: 1 }],
|
|
1413
|
+
["aria-colindex", { kind: "integer", min: 1 }],
|
|
1414
|
+
["aria-rowspan", { kind: "integer", min: 0 }],
|
|
1415
|
+
["aria-colspan", { kind: "integer", min: 0 }],
|
|
1416
|
+
// Enum (specific allowed tokens)
|
|
1417
|
+
["aria-autocomplete", { kind: "enum", values: /* @__PURE__ */ new Set(["inline", "list", "both", "none"]) }],
|
|
1418
|
+
[
|
|
1419
|
+
"aria-current",
|
|
1420
|
+
{
|
|
1421
|
+
kind: "enum",
|
|
1422
|
+
values: /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"])
|
|
1423
|
+
}
|
|
1424
|
+
],
|
|
1425
|
+
[
|
|
1426
|
+
"aria-haspopup",
|
|
1427
|
+
{
|
|
1428
|
+
kind: "enum",
|
|
1429
|
+
values: /* @__PURE__ */ new Set(["false", "true", "menu", "listbox", "tree", "grid", "dialog"])
|
|
1430
|
+
}
|
|
1431
|
+
],
|
|
1432
|
+
["aria-invalid", { kind: "enum", values: /* @__PURE__ */ new Set(["grammar", "false", "spelling", "true"]) }],
|
|
1433
|
+
["aria-live", { kind: "enum", values: /* @__PURE__ */ new Set(["assertive", "off", "polite"]) }],
|
|
1434
|
+
[
|
|
1435
|
+
"aria-orientation",
|
|
1436
|
+
{ kind: "enum", values: /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]) }
|
|
1437
|
+
],
|
|
1438
|
+
["aria-sort", { kind: "enum", values: /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"]) }]
|
|
1439
|
+
]);
|
|
1440
|
+
static #isValidAriaValue(value, type) {
|
|
1441
|
+
switch (type.kind) {
|
|
1442
|
+
case "boolean":
|
|
1443
|
+
return value === "true" || value === "false" || value === true || value === false;
|
|
1444
|
+
case "tristate":
|
|
1445
|
+
return value === "true" || value === "false" || value === "mixed" || value === true || value === false;
|
|
1446
|
+
case "number": {
|
|
1447
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
1448
|
+
if (typeof value !== "string") return false;
|
|
1449
|
+
const n = parseFloat(value);
|
|
1450
|
+
return Number.isFinite(n);
|
|
1451
|
+
}
|
|
1452
|
+
case "integer": {
|
|
1453
|
+
const n = typeof value === "number" ? value : typeof value === "string" ? parseInt(value, 10) : NaN;
|
|
1454
|
+
if (!Number.isFinite(n) || !Number.isInteger(n)) return false;
|
|
1455
|
+
if (type.min !== void 0 && n < type.min) return false;
|
|
1456
|
+
if (type.max !== void 0 && n > type.max) return false;
|
|
1457
|
+
return true;
|
|
1458
|
+
}
|
|
1459
|
+
case "enum":
|
|
1460
|
+
return typeof value === "string" && type.values.has(value);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
static #describeExpected(type) {
|
|
1464
|
+
switch (type.kind) {
|
|
1465
|
+
case "boolean":
|
|
1466
|
+
return '"true" or "false"';
|
|
1467
|
+
case "tristate":
|
|
1468
|
+
return '"true", "false", or "mixed"';
|
|
1469
|
+
case "number":
|
|
1470
|
+
return "a finite number";
|
|
1471
|
+
case "integer": {
|
|
1472
|
+
const parts = ["an integer"];
|
|
1473
|
+
if (type.min !== void 0 && type.max !== void 0)
|
|
1474
|
+
parts.push(`between ${type.min} and ${type.max}`);
|
|
1475
|
+
else if (type.min !== void 0) parts.push(`\u2265 ${type.min}`);
|
|
1476
|
+
else if (type.max !== void 0) parts.push(`\u2264 ${type.max}`);
|
|
1477
|
+
return parts.join(" ");
|
|
1478
|
+
}
|
|
1479
|
+
case "enum":
|
|
1480
|
+
return [...type.values].map((v) => `"${v}"`).join(", ");
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
static #checkAriaAttributeValues({ props, effectiveRole }) {
|
|
1484
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
|
|
1485
|
+
const results = [];
|
|
1486
|
+
iterate.forEachEntry(props, (key, value) => {
|
|
1487
|
+
if (!key.startsWith("aria-")) return;
|
|
1488
|
+
const type = _AriaPolicyEngine.#ARIA_VALUE_TYPES.get(key);
|
|
1489
|
+
if (type == null) return;
|
|
1490
|
+
if (_AriaPolicyEngine.#isValidAriaValue(value, type)) return;
|
|
1491
|
+
results.push({
|
|
1492
|
+
valid: false,
|
|
1493
|
+
fixable: true,
|
|
1494
|
+
severity: "warning",
|
|
1495
|
+
attribute: key,
|
|
1496
|
+
diagnostic: AriaDiagnostics.invalidAttributeValue(
|
|
1497
|
+
key,
|
|
1498
|
+
value,
|
|
1499
|
+
_AriaPolicyEngine.#describeExpected(type)
|
|
1500
|
+
),
|
|
1501
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix(key)
|
|
1502
|
+
});
|
|
1503
|
+
});
|
|
1504
|
+
return results;
|
|
1505
|
+
}
|
|
1506
|
+
// ─── Heading implicit level ────────────────────────────────────────────────
|
|
1507
|
+
static #HEADING_IMPLICIT_LEVELS = /* @__PURE__ */ new Map([
|
|
1508
|
+
["h1", 1],
|
|
1509
|
+
["h2", 2],
|
|
1510
|
+
["h3", 3],
|
|
1511
|
+
["h4", 4],
|
|
1512
|
+
["h5", 5],
|
|
1513
|
+
["h6", 6]
|
|
1514
|
+
]);
|
|
1515
|
+
static #checkRedundantAriaLevel({
|
|
1516
|
+
tag,
|
|
1517
|
+
props,
|
|
1518
|
+
effectiveRole
|
|
1519
|
+
}) {
|
|
1520
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
|
|
1521
|
+
const implicitLevel = _AriaPolicyEngine.#HEADING_IMPLICIT_LEVELS.get(tag);
|
|
1522
|
+
if (implicitLevel == null) return VALID;
|
|
1523
|
+
const raw = props["aria-level"];
|
|
1524
|
+
if (raw == null) return VALID;
|
|
1525
|
+
const n = typeof raw === "number" ? raw : typeof raw === "string" ? parseInt(raw, 10) : NaN;
|
|
1526
|
+
if (!Number.isFinite(n) || n !== implicitLevel) return VALID;
|
|
1527
|
+
return [
|
|
1528
|
+
{
|
|
1529
|
+
valid: false,
|
|
1530
|
+
fixable: true,
|
|
1531
|
+
severity: "warning",
|
|
1532
|
+
attribute: "aria-level",
|
|
1533
|
+
diagnostic: AriaDiagnostics.redundantAriaLevel(tag, implicitLevel),
|
|
1534
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix("aria-level")
|
|
1535
|
+
}
|
|
1536
|
+
];
|
|
1537
|
+
}
|
|
1538
|
+
// ─── Name-required roles ───────────────────────────────────────────────────
|
|
1539
|
+
// Roles that always require an accessible name per WAI-ARIA APG.
|
|
1540
|
+
// Dialog and landmark names are enforced via contracts (ariaContract) rather than
|
|
1541
|
+
// the built-in pipeline so consumers can opt in; img is built in because role=img
|
|
1542
|
+
// on any element (including bare <img>) is definitionally useless without a name.
|
|
1543
|
+
static #NAME_REQUIRED_ROLES = /* @__PURE__ */ new Set(["img"]);
|
|
1544
|
+
static #checkNameRequiredRoles({
|
|
1545
|
+
tag,
|
|
1546
|
+
props,
|
|
1547
|
+
effectiveRole
|
|
1548
|
+
}) {
|
|
1549
|
+
if (!effectiveRole || !_AriaPolicyEngine.#NAME_REQUIRED_ROLES.has(effectiveRole)) return VALID;
|
|
1550
|
+
if ("aria-label" in props || "aria-labelledby" in props) return VALID;
|
|
1551
|
+
if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return VALID;
|
|
1552
|
+
return [
|
|
1553
|
+
{
|
|
1554
|
+
valid: false,
|
|
1555
|
+
fixable: false,
|
|
1556
|
+
severity: "warning",
|
|
1557
|
+
diagnostic: AriaDiagnostics.missingAccessibleName(tag)
|
|
1558
|
+
}
|
|
1559
|
+
];
|
|
1560
|
+
}
|
|
1561
|
+
// WAI-ARIA 1.2 required states and properties, keyed by role.
|
|
1562
|
+
// Source: https://www.w3.org/TR/wai-aria-1.2/#requiredState
|
|
1563
|
+
static #REQUIRED_PROPERTIES = /* @__PURE__ */ new Map([
|
|
1564
|
+
["combobox", ["aria-expanded"]],
|
|
1565
|
+
["option", ["aria-selected"]],
|
|
1566
|
+
["slider", ["aria-valuenow"]],
|
|
1567
|
+
["scrollbar", ["aria-controls", "aria-valuenow"]],
|
|
1568
|
+
["spinbutton", ["aria-valuenow"]]
|
|
1569
|
+
]);
|
|
1570
|
+
static #checkRequiredAriaProperties({
|
|
1571
|
+
props,
|
|
1572
|
+
effectiveRole
|
|
1573
|
+
}) {
|
|
1574
|
+
if (!effectiveRole) return VALID;
|
|
1575
|
+
const required = _AriaPolicyEngine.#REQUIRED_PROPERTIES.get(effectiveRole);
|
|
1576
|
+
if (required == null) return VALID;
|
|
1577
|
+
const results = [];
|
|
1578
|
+
iterate.forEach(required, (attr) => {
|
|
1579
|
+
if (attr in props) return;
|
|
1580
|
+
results.push({
|
|
1581
|
+
valid: false,
|
|
1582
|
+
fixable: false,
|
|
989
1583
|
severity: "warning",
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
}
|
|
993
|
-
|
|
1584
|
+
attribute: attr,
|
|
1585
|
+
diagnostic: AriaDiagnostics.requiredProperty(attr, effectiveRole)
|
|
1586
|
+
});
|
|
1587
|
+
});
|
|
1588
|
+
return results;
|
|
994
1589
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1590
|
+
// Natively interactive HTML elements — always keyboard-reachable unless explicitly disabled.
|
|
1591
|
+
static #INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
1592
|
+
"a",
|
|
1593
|
+
"button",
|
|
1594
|
+
"input",
|
|
1595
|
+
"select",
|
|
1596
|
+
"textarea"
|
|
1597
|
+
]);
|
|
1598
|
+
// WAI-ARIA 1.2 §6.6: aria-hidden="true" must not be placed on focusable elements.
|
|
1599
|
+
static #checkAriaHiddenOnFocusable({ tag, props }) {
|
|
1600
|
+
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return VALID;
|
|
1601
|
+
const isInteractive = _AriaPolicyEngine.#INTERACTIVE_TAGS.has(tag);
|
|
1602
|
+
if (!isInteractive) {
|
|
1603
|
+
const tabindex = props.tabindex;
|
|
1604
|
+
const n = typeof tabindex === "number" ? tabindex : typeof tabindex === "string" ? parseInt(tabindex, 10) : NaN;
|
|
1605
|
+
if (!Number.isFinite(n) || n < 0) return VALID;
|
|
1606
|
+
}
|
|
999
1607
|
return [
|
|
1000
1608
|
{
|
|
1001
1609
|
valid: false,
|
|
1002
|
-
fixable:
|
|
1610
|
+
fixable: false,
|
|
1003
1611
|
severity: "error",
|
|
1004
|
-
|
|
1005
|
-
|
|
1612
|
+
attribute: "aria-hidden",
|
|
1613
|
+
diagnostic: AriaDiagnostics.ariaHiddenOnFocusable(tag)
|
|
1006
1614
|
}
|
|
1007
1615
|
];
|
|
1008
1616
|
}
|
|
1009
|
-
|
|
1617
|
+
// Presentational elements (role=none/presentation, including <img alt="">) are removed
|
|
1618
|
+
// from the accessibility tree — ARIA attributes on them are meaningless and misleading.
|
|
1619
|
+
static #checkPresentationalAriaAttributes({
|
|
1010
1620
|
tag,
|
|
1011
1621
|
props,
|
|
1012
1622
|
effectiveRole
|
|
1013
1623
|
}) {
|
|
1624
|
+
if (effectiveRole !== "none" && effectiveRole !== "presentation") return VALID;
|
|
1014
1625
|
const results = [];
|
|
1015
|
-
|
|
1016
|
-
if (!
|
|
1017
|
-
if (
|
|
1018
|
-
if (isGlobalAriaAttribute(key)) continue;
|
|
1019
|
-
if (isAriaAttributeValidForRole(key, effectiveRole)) continue;
|
|
1626
|
+
iterate.forEachEntry(props, (key) => {
|
|
1627
|
+
if (!key.startsWith("aria-")) return;
|
|
1628
|
+
if (key === "aria-hidden") return;
|
|
1020
1629
|
results.push({
|
|
1021
1630
|
valid: false,
|
|
1022
|
-
severity: "warning",
|
|
1023
1631
|
fixable: true,
|
|
1632
|
+
severity: "warning",
|
|
1024
1633
|
attribute: key,
|
|
1025
|
-
|
|
1634
|
+
diagnostic: AriaDiagnostics.attributeOnPresentational(key, tag),
|
|
1026
1635
|
fix: _AriaPolicyEngine.#makeRemoveAttributeFix(key)
|
|
1027
1636
|
});
|
|
1028
|
-
}
|
|
1637
|
+
});
|
|
1029
1638
|
return results;
|
|
1030
1639
|
}
|
|
1031
1640
|
// WAI-ARIA live region roles and their implied aria-live politeness values.
|
|
@@ -1054,7 +1663,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1054
1663
|
fixable: true,
|
|
1055
1664
|
severity: "warning",
|
|
1056
1665
|
fix: injectLive,
|
|
1057
|
-
|
|
1666
|
+
diagnostic: AriaDiagnostics.missingLiveRegion(effectiveRole, impliedLive)
|
|
1058
1667
|
}
|
|
1059
1668
|
];
|
|
1060
1669
|
}
|
|
@@ -1066,7 +1675,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1066
1675
|
valid: false,
|
|
1067
1676
|
fixable: false,
|
|
1068
1677
|
severity: "warning",
|
|
1069
|
-
|
|
1678
|
+
diagnostic: AriaDiagnostics.missingAtomic(effectiveRole)
|
|
1070
1679
|
}
|
|
1071
1680
|
];
|
|
1072
1681
|
}
|
|
@@ -1095,7 +1704,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1095
1704
|
fixable: true,
|
|
1096
1705
|
severity: "warning",
|
|
1097
1706
|
attribute: "aria-relevant",
|
|
1098
|
-
|
|
1707
|
+
diagnostic: AriaDiagnostics.relevantInvalidTokens(invalid),
|
|
1099
1708
|
fix: _AriaPolicyEngine.#makeRemoveAttributeFix("aria-relevant")
|
|
1100
1709
|
}
|
|
1101
1710
|
];
|
|
@@ -1107,7 +1716,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1107
1716
|
fixable: true,
|
|
1108
1717
|
severity: "warning",
|
|
1109
1718
|
attribute: "aria-relevant",
|
|
1110
|
-
|
|
1719
|
+
diagnostic: AriaDiagnostics.relevantSuperseded(),
|
|
1111
1720
|
fix: _AriaPolicyEngine.#normalizeRelevantAllFix
|
|
1112
1721
|
}
|
|
1113
1722
|
];
|
|
@@ -1115,6 +1724,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1115
1724
|
return VALID;
|
|
1116
1725
|
}
|
|
1117
1726
|
};
|
|
1727
|
+
|
|
1728
|
+
// ../../lib/contract/src/children/get-type-name.ts
|
|
1118
1729
|
function getTypeName(value) {
|
|
1119
1730
|
if (value === null) return "null";
|
|
1120
1731
|
if (value === void 0) return "undefined";
|
|
@@ -1125,39 +1736,8 @@ function getTypeName(value) {
|
|
|
1125
1736
|
const name = value.constructor?.name;
|
|
1126
1737
|
return typeof name === "string" && name !== "Object" ? name : "object";
|
|
1127
1738
|
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
constructor(ctx = "") {
|
|
1131
|
-
this.#prefix = ctx ? `${ctx}:
|
|
1132
|
-
` : "";
|
|
1133
|
-
}
|
|
1134
|
-
#template(typeName, index, prefix = "", suffix = "") {
|
|
1135
|
-
const leadingStr = prefix ? `${prefix} ` : "";
|
|
1136
|
-
const followingStr = suffix ? ` ${suffix}` : "";
|
|
1137
|
-
return `${leadingStr}child "${typeName}" at index ${index}${followingStr}.`;
|
|
1138
|
-
}
|
|
1139
|
-
unexpectedChild(typeName, index) {
|
|
1140
|
-
return this.#template(typeName, index, "unexpected");
|
|
1141
|
-
}
|
|
1142
|
-
multipleMatches(typeName, index, ruleNames) {
|
|
1143
|
-
const quoted = ruleNames.map((n) => `"${n}"`);
|
|
1144
|
-
return this.#template(
|
|
1145
|
-
typeName,
|
|
1146
|
-
index,
|
|
1147
|
-
"",
|
|
1148
|
-
`matches multiple child rules: ${quoted.join(" and ")}`
|
|
1149
|
-
);
|
|
1150
|
-
}
|
|
1151
|
-
#format(errors) {
|
|
1152
|
-
return this.#prefix + errors.join("\n");
|
|
1153
|
-
}
|
|
1154
|
-
toError(errors) {
|
|
1155
|
-
if (errors.length === 0) {
|
|
1156
|
-
return new Error(this.#prefix + "Unknown validation error.");
|
|
1157
|
-
}
|
|
1158
|
-
return new Error(this.#format(errors));
|
|
1159
|
-
}
|
|
1160
|
-
};
|
|
1739
|
+
|
|
1740
|
+
// ../../lib/contract/src/children/normalize-child-rule.ts
|
|
1161
1741
|
function normalizeCardinality(input, impliesSingleton) {
|
|
1162
1742
|
const min = input?.min ?? 0;
|
|
1163
1743
|
const max = input?.max ?? (impliesSingleton ? 1 : Infinity);
|
|
@@ -1182,16 +1762,18 @@ function normalizeChildRule(rule) {
|
|
|
1182
1762
|
cardinality: normalizeCardinality(rule.cardinality, impliesSingleton)
|
|
1183
1763
|
};
|
|
1184
1764
|
}
|
|
1765
|
+
|
|
1766
|
+
// ../../lib/contract/src/children/rules-matcher.ts
|
|
1185
1767
|
function getChildType(child) {
|
|
1186
|
-
if (!
|
|
1768
|
+
if (!isObject(child) || !("type" in child)) return void 0;
|
|
1187
1769
|
return child.type;
|
|
1188
1770
|
}
|
|
1189
1771
|
function buildPartialIndex(rules) {
|
|
1190
1772
|
const typeIndex = /* @__PURE__ */ new Map();
|
|
1191
1773
|
const duplicateTypes = /* @__PURE__ */ new Set();
|
|
1192
1774
|
const untypedIndices = [];
|
|
1193
|
-
|
|
1194
|
-
const t =
|
|
1775
|
+
iterate.forEach(rules, (rule, ri) => {
|
|
1776
|
+
const t = rule.type;
|
|
1195
1777
|
if (t === void 0) {
|
|
1196
1778
|
untypedIndices.push(ri);
|
|
1197
1779
|
} else if (typeIndex.has(t)) {
|
|
@@ -1199,12 +1781,14 @@ function buildPartialIndex(rules) {
|
|
|
1199
1781
|
} else {
|
|
1200
1782
|
typeIndex.set(t, ri);
|
|
1201
1783
|
}
|
|
1202
|
-
}
|
|
1784
|
+
});
|
|
1203
1785
|
if (duplicateTypes.size > 0) {
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1786
|
+
iterate.forEachSet(duplicateTypes, (t) => {
|
|
1787
|
+
typeIndex.delete(t);
|
|
1788
|
+
});
|
|
1789
|
+
iterate.forEach(rules, (rule, ri) => {
|
|
1790
|
+
if (duplicateTypes.has(rule.type)) untypedIndices.push(ri);
|
|
1791
|
+
});
|
|
1208
1792
|
}
|
|
1209
1793
|
return { typeIndex, untypedIndices };
|
|
1210
1794
|
}
|
|
@@ -1223,10 +1807,10 @@ var RuleMatcher = class {
|
|
|
1223
1807
|
const reverse = /* @__PURE__ */ new Map();
|
|
1224
1808
|
const unexpectedIndices = /* @__PURE__ */ new Set();
|
|
1225
1809
|
const ambiguousIndices = /* @__PURE__ */ new Set();
|
|
1226
|
-
|
|
1810
|
+
iterate.forEach(this.#rules, (_, ri) => {
|
|
1227
1811
|
reverse.set(ri, /* @__PURE__ */ new Set());
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1812
|
+
});
|
|
1813
|
+
iterate.forEach(children, (child, ci) => {
|
|
1230
1814
|
const t = getChildType(child);
|
|
1231
1815
|
if (t !== void 0) {
|
|
1232
1816
|
const ri = this.#typeIndex.get(t);
|
|
@@ -1240,8 +1824,8 @@ var RuleMatcher = class {
|
|
|
1240
1824
|
reverse.get(ri).add(ci);
|
|
1241
1825
|
}
|
|
1242
1826
|
}
|
|
1243
|
-
|
|
1244
|
-
if (!this.#rules[ri].match(child))
|
|
1827
|
+
iterate.forEach(this.#untypedIndices, (ri) => {
|
|
1828
|
+
if (!this.#rules[ri].match(child)) return;
|
|
1245
1829
|
let childEntry = forward.get(ci);
|
|
1246
1830
|
if (!childEntry) {
|
|
1247
1831
|
childEntry = /* @__PURE__ */ new Set();
|
|
@@ -1249,33 +1833,35 @@ var RuleMatcher = class {
|
|
|
1249
1833
|
}
|
|
1250
1834
|
childEntry.add(ri);
|
|
1251
1835
|
reverse.get(ri).add(ci);
|
|
1252
|
-
}
|
|
1836
|
+
});
|
|
1253
1837
|
const entry = forward.get(ci);
|
|
1254
1838
|
if (!entry) {
|
|
1255
1839
|
unexpectedIndices.add(ci);
|
|
1256
1840
|
} else if (entry.size > 1) {
|
|
1257
1841
|
ambiguousIndices.add(ci);
|
|
1258
1842
|
}
|
|
1259
|
-
}
|
|
1843
|
+
});
|
|
1260
1844
|
return { matrix: { childToRules: { forward, reverse } }, unexpectedIndices, ambiguousIndices };
|
|
1261
1845
|
}
|
|
1262
1846
|
};
|
|
1263
|
-
|
|
1847
|
+
|
|
1848
|
+
// ../../lib/contract/src/children/rule-validator.ts
|
|
1849
|
+
var RuleValidator = class _RuleValidator extends InvariantBase {
|
|
1264
1850
|
#context;
|
|
1265
|
-
constructor(context,
|
|
1266
|
-
super(
|
|
1851
|
+
constructor(context, diagnostics) {
|
|
1852
|
+
super(diagnostics);
|
|
1267
1853
|
this.#context = context;
|
|
1268
1854
|
}
|
|
1269
1855
|
validate(rules, matrix, childCount) {
|
|
1270
1856
|
const firstIndex = 0;
|
|
1271
1857
|
const lastIndex = childCount - 1;
|
|
1272
|
-
|
|
1858
|
+
iterate.forEach(rules, (rule, ri) => {
|
|
1273
1859
|
const matches = matrix.childToRules.reverse.get(ri);
|
|
1274
1860
|
const matchCount = matches.size;
|
|
1275
1861
|
this.#validateCardinality(rule, matchCount);
|
|
1276
|
-
if (matchCount === 0)
|
|
1862
|
+
if (matchCount === 0) return;
|
|
1277
1863
|
this.#validatePositions(rule, matches, firstIndex, lastIndex);
|
|
1278
|
-
}
|
|
1864
|
+
});
|
|
1279
1865
|
}
|
|
1280
1866
|
#validateCardinality(rule, matchCount) {
|
|
1281
1867
|
const { cardinality, name } = rule;
|
|
@@ -1284,21 +1870,21 @@ var RuleValidator = class _RuleValidator extends StrictBase {
|
|
|
1284
1870
|
}
|
|
1285
1871
|
const { min, max } = cardinality;
|
|
1286
1872
|
if (matchCount < min) {
|
|
1287
|
-
this.violate(
|
|
1873
|
+
this.violate(ContractDiagnostics.cardinalityMin(name, min, this.#context));
|
|
1288
1874
|
return;
|
|
1289
1875
|
}
|
|
1290
1876
|
if (matchCount > max) {
|
|
1291
|
-
this.violate(
|
|
1877
|
+
this.violate(ContractDiagnostics.cardinalityMax(name, max, this.#context));
|
|
1292
1878
|
}
|
|
1293
1879
|
}
|
|
1294
1880
|
#validatePositions(rule, matches, firstIndex, lastIndex) {
|
|
1295
1881
|
const { name, position } = rule;
|
|
1296
|
-
|
|
1882
|
+
iterate.forEachSet(matches, (index) => {
|
|
1297
1883
|
if (_RuleValidator.#isValidPosition(index, position, firstIndex, lastIndex)) {
|
|
1298
|
-
|
|
1884
|
+
return;
|
|
1299
1885
|
}
|
|
1300
|
-
this.violate(
|
|
1301
|
-
}
|
|
1886
|
+
this.violate(ContractDiagnostics.positionViolation(name, position, index, this.#context));
|
|
1887
|
+
});
|
|
1302
1888
|
}
|
|
1303
1889
|
static #isValidPosition(matchIndex, position, firstIndex, lastIndex) {
|
|
1304
1890
|
switch (position) {
|
|
@@ -1313,48 +1899,50 @@ var RuleValidator = class _RuleValidator extends StrictBase {
|
|
|
1313
1899
|
}
|
|
1314
1900
|
}
|
|
1315
1901
|
};
|
|
1316
|
-
|
|
1902
|
+
|
|
1903
|
+
// ../../lib/contract/src/children/children-evaluator.ts
|
|
1904
|
+
var ChildrenEvaluator = class extends InvariantBase {
|
|
1905
|
+
#context;
|
|
1317
1906
|
#rules;
|
|
1318
1907
|
#ruleNames;
|
|
1319
1908
|
#matcher;
|
|
1320
1909
|
#ruleValidator;
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
this.#rules = rules.map((
|
|
1325
|
-
this.#ruleNames = this.#rules.map((
|
|
1326
|
-
|
|
1910
|
+
constructor(rules, diagnostics, context = "Component") {
|
|
1911
|
+
super(diagnostics);
|
|
1912
|
+
this.#context = context;
|
|
1913
|
+
this.#rules = rules.map((r) => normalizeChildRule(r));
|
|
1914
|
+
this.#ruleNames = this.#rules.map((r) => r.name);
|
|
1915
|
+
iterate.forEach(this.#rules, (rule) => {
|
|
1327
1916
|
const { name, position, cardinality } = rule;
|
|
1328
1917
|
if ((position === "first" || position === "last") && (cardinality.kind === "unbounded" || cardinality.max > 1)) {
|
|
1329
1918
|
throw new RangeError(
|
|
1330
1919
|
`ChildrenEvaluator [${context}]: rule "${name}" sets position="${position}" with an unbound or >1 max. position="first|last" implies max=1.`
|
|
1331
1920
|
);
|
|
1332
1921
|
}
|
|
1333
|
-
}
|
|
1922
|
+
});
|
|
1334
1923
|
this.#matcher = new RuleMatcher(this.#rules);
|
|
1335
|
-
this.#ruleValidator = new RuleValidator(context,
|
|
1336
|
-
this.#matchBuilder = new MatchValidationErrorBuilder(context);
|
|
1924
|
+
this.#ruleValidator = new RuleValidator(context, diagnostics);
|
|
1337
1925
|
}
|
|
1338
1926
|
evaluate(children) {
|
|
1339
|
-
if (!this.
|
|
1927
|
+
if (!this.active) return;
|
|
1340
1928
|
const { matrix, unexpectedIndices, ambiguousIndices } = this.#matcher.match(children);
|
|
1341
1929
|
this.#ruleValidator.validate(this.#rules, matrix, children.length);
|
|
1342
1930
|
if (unexpectedIndices.size === 0 && ambiguousIndices.size === 0) return;
|
|
1343
|
-
const errors = [];
|
|
1344
1931
|
const violating = [...unexpectedIndices, ...ambiguousIndices].sort((a, b) => a - b);
|
|
1345
|
-
|
|
1932
|
+
iterate.forEach(violating, (ci) => {
|
|
1346
1933
|
const typeName = getTypeName(children[ci]);
|
|
1347
1934
|
if (unexpectedIndices.has(ci)) {
|
|
1348
|
-
|
|
1935
|
+
this.violate(ContractDiagnostics.unexpectedChild(typeName, ci, this.#context));
|
|
1349
1936
|
} else {
|
|
1350
1937
|
const matches = matrix.childToRules.forward.get(ci);
|
|
1351
1938
|
const names = [...matches].map((ri) => this.#ruleNames[ri] ?? `#${ri}`);
|
|
1352
|
-
|
|
1939
|
+
this.violate(ContractDiagnostics.ambiguousChild(typeName, ci, names, this.#context));
|
|
1353
1940
|
}
|
|
1354
|
-
}
|
|
1355
|
-
this.invariant(errors.length === 0, this.#matchBuilder.toError(errors).message);
|
|
1941
|
+
});
|
|
1356
1942
|
}
|
|
1357
1943
|
};
|
|
1944
|
+
|
|
1945
|
+
// ../../lib/contract/src/props/get-disabled-props.ts
|
|
1358
1946
|
var disabledProps = ({
|
|
1359
1947
|
disabled,
|
|
1360
1948
|
"aria-disabled": ariaDisabled,
|
|
@@ -1366,6 +1954,8 @@ var disabledProps = ({
|
|
|
1366
1954
|
...dataDisabled === void 0 && { "data-disabled": "" }
|
|
1367
1955
|
};
|
|
1368
1956
|
};
|
|
1957
|
+
|
|
1958
|
+
// ../../lib/contract/src/props/get-invalid-props.ts
|
|
1369
1959
|
var invalidProps = ({
|
|
1370
1960
|
invalid,
|
|
1371
1961
|
"aria-invalid": ariaInvalid,
|
|
@@ -1377,6 +1967,8 @@ var invalidProps = ({
|
|
|
1377
1967
|
...dataInvalid === void 0 && { "data-invalid": "" }
|
|
1378
1968
|
};
|
|
1379
1969
|
};
|
|
1970
|
+
|
|
1971
|
+
// ../../lib/contract/src/props/get-readonly-props.ts
|
|
1380
1972
|
var readonlyProps = ({
|
|
1381
1973
|
readOnly,
|
|
1382
1974
|
"aria-readonly": ariaReadonly,
|
|
@@ -1392,6 +1984,8 @@ var readonlyProps = ({
|
|
|
1392
1984
|
}
|
|
1393
1985
|
};
|
|
1394
1986
|
};
|
|
1987
|
+
|
|
1988
|
+
// ../core/src/html/aria-rules.ts
|
|
1395
1989
|
var LANDMARK_TAG_SET = /* @__PURE__ */ new Set(["article", "aside", "footer", "header", "main", "nav"]);
|
|
1396
1990
|
var removeLandmarkRoleOverride = {
|
|
1397
1991
|
kind: "removeRole",
|
|
@@ -1411,14 +2005,31 @@ function landmarkRoleRule({ tag, props, implicitRole }) {
|
|
|
1411
2005
|
fixable: true,
|
|
1412
2006
|
severity: "error",
|
|
1413
2007
|
fix: removeLandmarkRoleOverride,
|
|
1414
|
-
|
|
2008
|
+
diagnostic: HtmlDiagnostics.landmarkRoleOverride(tag, implicitRole, role)
|
|
1415
2009
|
}
|
|
1416
2010
|
];
|
|
1417
2011
|
}
|
|
1418
|
-
|
|
2012
|
+
function requireAccessibleName({ tag, props }) {
|
|
2013
|
+
if ("aria-label" in props || "aria-labelledby" in props) return [];
|
|
2014
|
+
return [
|
|
2015
|
+
{
|
|
2016
|
+
valid: false,
|
|
2017
|
+
fixable: false,
|
|
2018
|
+
severity: "warning",
|
|
2019
|
+
diagnostic: AriaDiagnostics.missingAccessibleName(tag)
|
|
2020
|
+
}
|
|
2021
|
+
];
|
|
2022
|
+
}
|
|
2023
|
+
var NAMED_LANDMARK_TAGS = /* @__PURE__ */ new Set(["nav", "aside"]);
|
|
2024
|
+
function landmarkNameAdvisory(ctx) {
|
|
2025
|
+
if (!ctx.implicitRole || !NAMED_LANDMARK_TAGS.has(ctx.tag)) return [];
|
|
2026
|
+
return requireAccessibleName(ctx);
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
// ../core/src/html/contracts.ts
|
|
1419
2030
|
function isOpenContent(...blockedTags) {
|
|
1420
|
-
const
|
|
1421
|
-
return (child) =>
|
|
2031
|
+
const set2 = new Set(blockedTags);
|
|
2032
|
+
return (child) => isObject(child) && "type" in child && (!isString(child.type) || !set2.has(child.type));
|
|
1422
2033
|
}
|
|
1423
2034
|
var METADATA_TAGS = ["script", "template"];
|
|
1424
2035
|
var metadataMatch = isTag(...METADATA_TAGS);
|
|
@@ -1429,10 +2040,10 @@ function firstOptional(name, tag) {
|
|
|
1429
2040
|
return { name, match: isTag(tag), cardinality: { max: 1 }, position: "first" };
|
|
1430
2041
|
}
|
|
1431
2042
|
function contract(children) {
|
|
1432
|
-
return {
|
|
2043
|
+
return { diagnostics: warnDiagnostics, children };
|
|
1433
2044
|
}
|
|
1434
2045
|
function ariaContract(aria) {
|
|
1435
|
-
return {
|
|
2046
|
+
return { diagnostics: warnDiagnostics, aria };
|
|
1436
2047
|
}
|
|
1437
2048
|
function firstChildContract(name, tag) {
|
|
1438
2049
|
return contract([firstOptional(name, tag), { name: "content", match: isOpenContent(tag) }]);
|
|
@@ -1519,7 +2130,15 @@ var textOnlyContract = contract([
|
|
|
1519
2130
|
match: (child) => isString(child) || isNumber(child)
|
|
1520
2131
|
}
|
|
1521
2132
|
]);
|
|
1522
|
-
var landmarkContract = ariaContract([landmarkRoleRule]);
|
|
2133
|
+
var landmarkContract = ariaContract([landmarkRoleRule, landmarkNameAdvisory]);
|
|
2134
|
+
var dialogContract = ariaContract([requireAccessibleName]);
|
|
2135
|
+
var menuContract = ariaContract([requireAccessibleName]);
|
|
2136
|
+
var menubarContract = ariaContract([requireAccessibleName]);
|
|
2137
|
+
var treeContract = ariaContract([requireAccessibleName]);
|
|
2138
|
+
var gridContract = ariaContract([requireAccessibleName]);
|
|
2139
|
+
var listboxContract = ariaContract([requireAccessibleName]);
|
|
2140
|
+
var tablistContract = ariaContract([requireAccessibleName]);
|
|
2141
|
+
var radiogroupContract = ariaContract([requireAccessibleName]);
|
|
1523
2142
|
var CONTRACT_GROUPS = [
|
|
1524
2143
|
[VOID_TAGS, voidContract],
|
|
1525
2144
|
[TEXT_ONLY_TAGS, textOnlyContract],
|
|
@@ -1546,19 +2165,28 @@ var htmlContracts = {
|
|
|
1546
2165
|
figure: figureContract,
|
|
1547
2166
|
details: detailsContract,
|
|
1548
2167
|
fieldset: fieldsetContract,
|
|
2168
|
+
dialog: dialogContract,
|
|
1549
2169
|
head: headContract,
|
|
1550
2170
|
html: htmlContract
|
|
1551
2171
|
};
|
|
2172
|
+
|
|
2173
|
+
// ../core/src/html/evaluators.ts
|
|
2174
|
+
var htmlDiagnostics = warnDiagnostics;
|
|
1552
2175
|
function buildEvaluatorMap() {
|
|
1553
|
-
const
|
|
1554
|
-
|
|
2176
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
2177
|
+
iterate.forEachEntry(htmlContracts, (tag, { children }) => {
|
|
1555
2178
|
if (children?.length) {
|
|
1556
|
-
|
|
2179
|
+
map2.set(tag, new ChildrenEvaluator(children, htmlDiagnostics, `<${tag}>`));
|
|
1557
2180
|
}
|
|
1558
|
-
}
|
|
1559
|
-
return
|
|
2181
|
+
});
|
|
2182
|
+
return map2;
|
|
1560
2183
|
}
|
|
1561
2184
|
var HTML_EVALUATORS = buildEvaluatorMap();
|
|
2185
|
+
function getHtmlChildrenEvaluator(tag) {
|
|
2186
|
+
return typeof tag === "string" ? HTML_EVALUATORS.get(tag) : void 0;
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
// ../core/src/html/prop-normalizers.ts
|
|
1562
2190
|
var HTML_FORM_NORMALIZERS = /* @__PURE__ */ new Map([
|
|
1563
2191
|
["button", [disabledProps]],
|
|
1564
2192
|
["input", [disabledProps, readonlyProps, invalidProps]],
|
|
@@ -1571,241 +2199,93 @@ function getHtmlPropNormalizers(tag) {
|
|
|
1571
2199
|
return typeof tag === "string" ? HTML_FORM_NORMALIZERS.get(tag) : void 0;
|
|
1572
2200
|
}
|
|
1573
2201
|
|
|
1574
|
-
//
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
return Array.isArray(value) ? value.includes({
|
|
1601
|
-
...defaultVariants,
|
|
1602
|
-
...propsWithoutUndefined
|
|
1603
|
-
}[key]) : {
|
|
1604
|
-
...defaultVariants,
|
|
1605
|
-
...propsWithoutUndefined
|
|
1606
|
-
}[key] === value;
|
|
1607
|
-
}) ? [
|
|
1608
|
-
...acc,
|
|
1609
|
-
cvClass,
|
|
1610
|
-
cvClassName
|
|
1611
|
-
] : acc;
|
|
1612
|
-
}, []);
|
|
1613
|
-
return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
|
|
1614
|
-
};
|
|
1615
|
-
function cva2(base, config) {
|
|
1616
|
-
const fn = cva(base, config);
|
|
1617
|
-
return (props) => cn(fn(props));
|
|
1618
|
-
}
|
|
1619
|
-
var StaticClassResolver = class {
|
|
1620
|
-
#baseClass;
|
|
1621
|
-
#cache = /* @__PURE__ */ new Map();
|
|
1622
|
-
#resolveTag;
|
|
1623
|
-
constructor(baseClass, tagMap) {
|
|
1624
|
-
this.#baseClass = Array.isArray(baseClass) ? baseClass.join(" ") : baseClass;
|
|
1625
|
-
this.#resolveTag = tagMap ? (tag) => {
|
|
1626
|
-
const extra = tagMap[tag];
|
|
1627
|
-
if (!extra) return this.#baseClass;
|
|
1628
|
-
const extraStr = Array.isArray(extra) ? extra.join(" ") : extra;
|
|
1629
|
-
return `${this.#baseClass} ${extraStr}`;
|
|
1630
|
-
} : () => this.#baseClass;
|
|
1631
|
-
}
|
|
1632
|
-
resolve(tag, skipTagMap = false) {
|
|
1633
|
-
if (typeof tag !== "string" || skipTagMap) return this.#baseClass;
|
|
1634
|
-
const cached = this.#cache.get(tag);
|
|
1635
|
-
if (cached !== void 0) {
|
|
1636
|
-
this.#cache.delete(tag);
|
|
1637
|
-
this.#cache.set(tag, cached);
|
|
1638
|
-
return cached;
|
|
1639
|
-
}
|
|
1640
|
-
const result = this.#resolveTag(tag);
|
|
1641
|
-
this.#cache.set(tag, result);
|
|
1642
|
-
if (this.#cache.size > 200) {
|
|
1643
|
-
const lru = this.#cache.keys().next().value;
|
|
1644
|
-
if (lru !== void 0) this.#cache.delete(lru);
|
|
1645
|
-
}
|
|
1646
|
-
return result;
|
|
1647
|
-
}
|
|
1648
|
-
};
|
|
1649
|
-
var VariantClassResolver = class _VariantClassResolver {
|
|
1650
|
-
#cvaFn;
|
|
1651
|
-
#recipeMap;
|
|
1652
|
-
#variantKeys;
|
|
1653
|
-
#precomputedClasses;
|
|
1654
|
-
#cache = /* @__PURE__ */ new Map();
|
|
1655
|
-
constructor(cvaFn, recipeMap, variantKeys, precomputedClasses) {
|
|
1656
|
-
this.#cvaFn = cvaFn ?? null;
|
|
1657
|
-
this.#recipeMap = Object.freeze(recipeMap ?? {});
|
|
1658
|
-
this.#variantKeys = variantKeys ?? null;
|
|
1659
|
-
this.#precomputedClasses = precomputedClasses ?? null;
|
|
1660
|
-
}
|
|
1661
|
-
resolve({ props, recipe }) {
|
|
1662
|
-
const normalizedKey = recipe ?? "__none__";
|
|
1663
|
-
const cacheKey = this.#createCacheKey(props, normalizedKey);
|
|
1664
|
-
if (this.#precomputedClasses !== null) {
|
|
1665
|
-
const precomputed = this.#precomputedClasses[cacheKey];
|
|
1666
|
-
if (precomputed !== void 0) return precomputed;
|
|
1667
|
-
}
|
|
1668
|
-
const cached = this.#cache.get(cacheKey);
|
|
1669
|
-
if (cached !== void 0) {
|
|
1670
|
-
this.#cache.delete(cacheKey);
|
|
1671
|
-
this.#cache.set(cacheKey, cached);
|
|
1672
|
-
return cached;
|
|
1673
|
-
}
|
|
1674
|
-
const result = this.#compute(props, recipe);
|
|
1675
|
-
this.#cache.set(cacheKey, result);
|
|
1676
|
-
if (this.#cache.size > 1e3) {
|
|
1677
|
-
const lru = this.#cache.keys().next().value;
|
|
1678
|
-
if (lru !== void 0) this.#cache.delete(lru);
|
|
1679
|
-
}
|
|
1680
|
-
return result;
|
|
1681
|
-
}
|
|
1682
|
-
#compute(props, recipe) {
|
|
1683
|
-
if (!this.#cvaFn) return "";
|
|
1684
|
-
if (!recipe) return this.#cvaFn(props);
|
|
1685
|
-
const preset = this.#recipeMap[recipe];
|
|
1686
|
-
if (!preset) return this.#cvaFn(props);
|
|
1687
|
-
return this.#cvaFn({ ...preset, ...props });
|
|
1688
|
-
}
|
|
1689
|
-
// When variantKeys is provided, only those keys are included in the cache key — non-variant
|
|
1690
|
-
// props (className, id, etc.) produce identical CVA output and must not fragment the cache.
|
|
1691
|
-
// Iterating #variantKeys directly (fixed Set insertion order) avoids Object.keys + filter + sort.
|
|
1692
|
-
// String is built incrementally to avoid a parts[] array allocation on every render.
|
|
1693
|
-
#createCacheKey(props, recipe) {
|
|
1694
|
-
if (this.#variantKeys !== null) {
|
|
1695
|
-
let key2 = recipe;
|
|
1696
|
-
for (const k of this.#variantKeys) {
|
|
1697
|
-
if (k in props) key2 += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
1698
|
-
}
|
|
1699
|
-
return key2;
|
|
1700
|
-
}
|
|
1701
|
-
let key = recipe;
|
|
1702
|
-
for (const k of Object.keys(props).sort()) {
|
|
1703
|
-
key += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
2202
|
+
// ../../lib/styling/src/variant-pass/compile-variant-lookup.ts
|
|
2203
|
+
function buildPrecomputedKey(props) {
|
|
2204
|
+
return Object.entries(props).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}:${v}`).join("|");
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
// ../../lib/styling/src/variant-pass/variant-pass.ts
|
|
2208
|
+
function createVariantPass(activeProps, config) {
|
|
2209
|
+
return {
|
|
2210
|
+
name: "variant",
|
|
2211
|
+
execute() {
|
|
2212
|
+
const preset = typeof activeProps["preset"] === "string" ? activeProps["preset"] : void 0;
|
|
2213
|
+
const presetDefaults = preset !== void 0 && config.presets?.[preset] !== void 0 ? config.presets[preset] : {};
|
|
2214
|
+
const resolved = {
|
|
2215
|
+
...config.defaults,
|
|
2216
|
+
...presetDefaults,
|
|
2217
|
+
...activeProps
|
|
2218
|
+
};
|
|
2219
|
+
const classes = [];
|
|
2220
|
+
iterate.forEachEntry(config.variants, (key, valueMap) => {
|
|
2221
|
+
const active = resolved[key];
|
|
2222
|
+
if (typeof active === "string") {
|
|
2223
|
+
const cls = valueMap[active];
|
|
2224
|
+
if (cls !== void 0) classes.push(cls);
|
|
2225
|
+
}
|
|
2226
|
+
});
|
|
2227
|
+
return { context: { classes } };
|
|
1704
2228
|
}
|
|
1705
|
-
return key;
|
|
1706
|
-
}
|
|
1707
|
-
static #serializeValue(value) {
|
|
1708
|
-
if (value === void 0) return "u";
|
|
1709
|
-
if (value === null) return "n";
|
|
1710
|
-
if (typeof value === "boolean") return `b:${value}`;
|
|
1711
|
-
if (typeof value === "string") return `s:${value}`;
|
|
1712
|
-
return `x:${String(value)}`;
|
|
1713
|
-
}
|
|
1714
|
-
};
|
|
1715
|
-
function createClassPipeline(resolved) {
|
|
1716
|
-
const baseClass = resolved.baseClassName ?? "";
|
|
1717
|
-
const cvaFn = resolved.variants ? cva2("", {
|
|
1718
|
-
variants: resolved.variants,
|
|
1719
|
-
defaultVariants: resolved.defaultVariants,
|
|
1720
|
-
compoundVariants: resolved.compoundVariants
|
|
1721
|
-
}) : null;
|
|
1722
|
-
const variantKeys = resolved.variants ? new Set(Object.keys(resolved.variants)) : void 0;
|
|
1723
|
-
const staticResolver = new StaticClassResolver(baseClass, resolved.tagMap);
|
|
1724
|
-
const variantResolver = new VariantClassResolver(
|
|
1725
|
-
cvaFn,
|
|
1726
|
-
resolved.recipeMap,
|
|
1727
|
-
variantKeys,
|
|
1728
|
-
resolved.precomputedClasses
|
|
1729
|
-
);
|
|
1730
|
-
return function resolveClasses(tag, props, className, recipe) {
|
|
1731
|
-
const staticClasses = staticResolver.resolve(tag, recipe !== void 0);
|
|
1732
|
-
const variantClasses = variantResolver.resolve({ props, recipe });
|
|
1733
|
-
if (!className)
|
|
1734
|
-
return staticClasses && variantClasses ? `${staticClasses} ${variantClasses}` : staticClasses || variantClasses;
|
|
1735
|
-
return cn(staticClasses, variantClasses, className);
|
|
1736
2229
|
};
|
|
1737
2230
|
}
|
|
1738
2231
|
|
|
1739
|
-
// ../core/
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
};
|
|
1746
|
-
function createPolymorphic2(options = {}) {
|
|
1747
|
-
return createPolymorphic(options, FULL_CAPABILITIES);
|
|
2232
|
+
// ../core/src/resolver/resolver.ts
|
|
2233
|
+
function enforceAllowedAs(tag, allowedAs, diagnostics, displayName) {
|
|
2234
|
+
if (allowedAs.includes(tag)) return;
|
|
2235
|
+
if (!diagnostics) return;
|
|
2236
|
+
const component = displayName ?? String(tag);
|
|
2237
|
+
diagnostics.error(ContractDiagnostics.allowedAsViolation(String(tag), allowedAs, component));
|
|
1748
2238
|
}
|
|
1749
2239
|
|
|
1750
|
-
// ../../lib/adapter-utils/src/
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
return { runtime, ownedKeys };
|
|
2240
|
+
// ../../lib/adapter-utils/src/apply-prop-normalizers.ts
|
|
2241
|
+
function applyPropNormalizers(tag, props, additional) {
|
|
2242
|
+
const normalizers = [...getHtmlPropNormalizers(tag) ?? [], ...additional ?? []];
|
|
2243
|
+
if (normalizers.length === 0) return props;
|
|
2244
|
+
return normalizers.reduce((acc, fn) => ({ ...acc, ...fn(acc) }), props);
|
|
1756
2245
|
}
|
|
1757
2246
|
|
|
1758
|
-
// ../../lib/adapter-utils/src/
|
|
1759
|
-
function
|
|
1760
|
-
return
|
|
2247
|
+
// ../../lib/adapter-utils/src/define-component.ts
|
|
2248
|
+
function defineContractComponent(options) {
|
|
2249
|
+
return (factory) => factory(options);
|
|
1761
2250
|
}
|
|
1762
2251
|
|
|
1763
|
-
// ../../lib/adapter-utils/src/
|
|
1764
|
-
function
|
|
1765
|
-
|
|
1766
|
-
if (!filterProps) {
|
|
1767
|
-
return defaultFilter;
|
|
1768
|
-
}
|
|
1769
|
-
return (key, variantKeys) => defaultFilter(key, variantKeys) || filterProps(key, variantKeys);
|
|
2252
|
+
// ../../lib/adapter-utils/src/build-engines.ts
|
|
2253
|
+
function buildEngines(diagnostics, childRules, context) {
|
|
2254
|
+
return childRules?.length ? { childrenEvaluator: new ChildrenEvaluator(childRules, diagnostics, context) } : {};
|
|
1770
2255
|
}
|
|
1771
2256
|
|
|
1772
2257
|
// ../../lib/adapter-utils/src/resolve-adapter-common-options.ts
|
|
1773
|
-
function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent",
|
|
2258
|
+
function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics) {
|
|
1774
2259
|
return {
|
|
1775
2260
|
name: options.name ?? defaultName,
|
|
1776
|
-
|
|
2261
|
+
diagnostics: options.enforcement?.diagnostics ?? defaultDiagnostics
|
|
1777
2262
|
};
|
|
1778
2263
|
}
|
|
1779
2264
|
|
|
1780
2265
|
// ../../lib/adapter-utils/src/slot-validator.ts
|
|
1781
|
-
var SlotValidator = class extends
|
|
2266
|
+
var SlotValidator = class extends InvariantBase {
|
|
1782
2267
|
#name;
|
|
1783
2268
|
#elementTerm;
|
|
1784
|
-
constructor(name,
|
|
1785
|
-
super(
|
|
2269
|
+
constructor(name, diagnostics, elementTerm) {
|
|
2270
|
+
super(diagnostics);
|
|
1786
2271
|
this.#name = name;
|
|
1787
2272
|
this.#elementTerm = elementTerm;
|
|
1788
2273
|
}
|
|
1789
2274
|
assertExclusive() {
|
|
1790
|
-
this.violate(
|
|
2275
|
+
this.violate(SlotDiagnostics.exclusive(this.#name));
|
|
1791
2276
|
}
|
|
1792
2277
|
warnDiscardedChildren(count) {
|
|
1793
|
-
|
|
1794
|
-
this.warn(
|
|
1795
|
-
`${this.#name}: asChild discarded ${count} non-element child${suffix} \u2014 only ${this.#elementTerm}s are valid asChild children.`
|
|
1796
|
-
);
|
|
2278
|
+
this.warn(SlotDiagnostics.discardedChildren(this.#name, this.#elementTerm, count));
|
|
1797
2279
|
}
|
|
1798
2280
|
assertSingleChild(count) {
|
|
1799
|
-
|
|
1800
|
-
|
|
2281
|
+
this.violate(
|
|
2282
|
+
count === 0 ? SlotDiagnostics.singleChildRequired(this.#name, this.#elementTerm) : SlotDiagnostics.singleChildExceeded(this.#name, this.#elementTerm, count)
|
|
2283
|
+
);
|
|
1801
2284
|
}
|
|
1802
2285
|
};
|
|
1803
2286
|
|
|
1804
|
-
// ../shared/src/constants/primitive/slot-name.ts
|
|
1805
|
-
var SLOT_NAME = "Slot";
|
|
1806
|
-
|
|
1807
2287
|
// ../../lib/adapter-utils/src/slot/policies.ts
|
|
1808
|
-
import { clsx
|
|
2288
|
+
import { clsx } from "clsx";
|
|
1809
2289
|
function chainHandlers(childHandler, slotHandler) {
|
|
1810
2290
|
return (...args) => {
|
|
1811
2291
|
childHandler(...args);
|
|
@@ -1816,7 +2296,7 @@ function chainHandlers(childHandler, slotHandler) {
|
|
|
1816
2296
|
};
|
|
1817
2297
|
}
|
|
1818
2298
|
function mergeClassNames(slot, child) {
|
|
1819
|
-
return
|
|
2299
|
+
return clsx(slot, child);
|
|
1820
2300
|
}
|
|
1821
2301
|
function mergeStyles(slot, child) {
|
|
1822
2302
|
if (!isPlainObject(slot) || !isPlainObject(child)) return child;
|
|
@@ -1832,10 +2312,10 @@ var policyHandlers = {
|
|
|
1832
2312
|
// ../../lib/adapter-utils/src/slot/merge-slot-props.ts
|
|
1833
2313
|
function mergeSlotProps(slotProps, childProps) {
|
|
1834
2314
|
const merged = { ...slotProps };
|
|
1835
|
-
|
|
1836
|
-
if (!Object.hasOwn(childProps, key))
|
|
2315
|
+
iterate.forEachKey(childProps, (key) => {
|
|
2316
|
+
if (!Object.hasOwn(childProps, key)) return;
|
|
1837
2317
|
merged[key] = applyMergePolicy(key, slotProps[key], childProps[key]);
|
|
1838
|
-
}
|
|
2318
|
+
});
|
|
1839
2319
|
return merged;
|
|
1840
2320
|
}
|
|
1841
2321
|
function classifyProp(key, slotVal, childVal) {
|
|
@@ -1848,270 +2328,451 @@ function applyMergePolicy(key, slotVal, childVal) {
|
|
|
1848
2328
|
return policyHandlers[classifyProp(key, slotVal, childVal)](slotVal, childVal);
|
|
1849
2329
|
}
|
|
1850
2330
|
|
|
1851
|
-
// ../../
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
}
|
|
1861
|
-
|
|
1862
|
-
|
|
2331
|
+
// ../../lib/adapter-utils/src/build-definition.ts
|
|
2332
|
+
function buildDefinition(name, tag) {
|
|
2333
|
+
return {
|
|
2334
|
+
identity: {
|
|
2335
|
+
id: name,
|
|
2336
|
+
name,
|
|
2337
|
+
tag
|
|
2338
|
+
},
|
|
2339
|
+
capabilities: {},
|
|
2340
|
+
metadata: {},
|
|
2341
|
+
diagnostics: []
|
|
2342
|
+
};
|
|
1863
2343
|
}
|
|
1864
2344
|
|
|
1865
|
-
// ../../
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
import { jsx } from "preact/jsx-runtime";
|
|
1874
|
-
function Slottable({ children }) {
|
|
1875
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
1876
|
-
}
|
|
1877
|
-
|
|
1878
|
-
// ../../adapters/preact/src/slot/predicates.ts
|
|
1879
|
-
function isSlottableElement(value) {
|
|
1880
|
-
return isValidElement2(value) && value.type === Slottable;
|
|
1881
|
-
}
|
|
1882
|
-
|
|
1883
|
-
// ../../adapters/preact/src/slot/extractSlottable.ts
|
|
1884
|
-
function extractSlottable(children) {
|
|
1885
|
-
const childrenArray = Array.isArray(children) ? children : [children];
|
|
1886
|
-
const slottables = childrenArray.filter(isSlottableElement);
|
|
1887
|
-
invariant(slottables.length <= 1, "Slot: multiple Slottable children are not allowed");
|
|
1888
|
-
if (slottables.length === 0) return null;
|
|
1889
|
-
const [slottable] = slottables;
|
|
1890
|
-
invariant(slottable, "Missing Slottable element");
|
|
1891
|
-
const child = slottable.props.children;
|
|
1892
|
-
invariant(
|
|
1893
|
-
child !== null && child !== void 0,
|
|
1894
|
-
"Slottable expects exactly one Preact element child, received null"
|
|
2345
|
+
// ../../lib/adapter-utils/src/build-variant-config.ts
|
|
2346
|
+
function flattenClassName(cls) {
|
|
2347
|
+
return Array.isArray(cls) ? cls.join(" ") : cls;
|
|
2348
|
+
}
|
|
2349
|
+
function mapVariantRecord(source, mapper) {
|
|
2350
|
+
return iterate.mapValues(
|
|
2351
|
+
source,
|
|
2352
|
+
(inner) => iterate.mapValues(inner, mapper)
|
|
1895
2353
|
);
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
"Slottable expects exactly one Preact element child, received text content"
|
|
1899
|
-
);
|
|
1900
|
-
invariant(isValidElement3(child), "Slottable expects exactly one Preact element child");
|
|
1901
|
-
invariant(child.type !== Fragment2, "Slottable child cannot be a Fragment");
|
|
1902
|
-
const index = childrenArray.indexOf(slottable);
|
|
2354
|
+
}
|
|
2355
|
+
function buildVariantConfig(variants, presets, defaults, compounds) {
|
|
1903
2356
|
return {
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
2357
|
+
variants: mapVariantRecord(variants ?? {}, flattenClassName),
|
|
2358
|
+
...presets !== void 0 && Object.keys(presets).length > 0 && { presets },
|
|
2359
|
+
...defaults !== void 0 && Object.keys(defaults).length > 0 && { defaults },
|
|
2360
|
+
...compounds !== void 0 && compounds.length > 0 && {
|
|
2361
|
+
compounds
|
|
1908
2362
|
}
|
|
1909
2363
|
};
|
|
1910
2364
|
}
|
|
1911
2365
|
|
|
1912
|
-
// ../../
|
|
1913
|
-
function
|
|
1914
|
-
const
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
2366
|
+
// ../../runtime/core/src/apply-attributes.ts
|
|
2367
|
+
function applyAttributes(nodeId, incoming, decoration, removedKeys) {
|
|
2368
|
+
const existing = decoration[nodeId] ?? {};
|
|
2369
|
+
const next = { ...existing.attributes };
|
|
2370
|
+
if (removedKeys !== void 0) {
|
|
2371
|
+
iterate.forEachSet(removedKeys, (key) => {
|
|
2372
|
+
delete next[key];
|
|
2373
|
+
});
|
|
1918
2374
|
}
|
|
1919
|
-
|
|
1920
|
-
|
|
2375
|
+
Object.assign(next, incoming);
|
|
2376
|
+
const { attributes: _dropped, ...rest } = existing;
|
|
2377
|
+
const nextDecoration = Object.keys(next).length > 0 ? { ...rest, attributes: next } : rest;
|
|
2378
|
+
return { ...decoration, [nodeId]: nextDecoration };
|
|
1921
2379
|
}
|
|
1922
2380
|
|
|
1923
|
-
// ../../
|
|
1924
|
-
|
|
2381
|
+
// ../../runtime/core/src/get-active-props.ts
|
|
2382
|
+
function getActiveProps(nodeId, decoration) {
|
|
2383
|
+
const dec = decoration[nodeId];
|
|
2384
|
+
return { ...dec?.attributes ?? {}, ...dec?.variants ?? {} };
|
|
2385
|
+
}
|
|
1925
2386
|
|
|
1926
|
-
// ../../
|
|
1927
|
-
function
|
|
1928
|
-
|
|
1929
|
-
if (active.length === 0) return null;
|
|
1930
|
-
if (active.length === 1) return active[0];
|
|
1931
|
-
return (value) => {
|
|
1932
|
-
for (const ref of active) {
|
|
1933
|
-
if (typeof ref === "function") {
|
|
1934
|
-
ref(value);
|
|
1935
|
-
} else {
|
|
1936
|
-
ref.current = value;
|
|
1937
|
-
}
|
|
1938
|
-
}
|
|
1939
|
-
};
|
|
2387
|
+
// ../../runtime/core/src/render-component.ts
|
|
2388
|
+
function renderComponent(definition, tree, render, backend) {
|
|
2389
|
+
return backend.render({ definition, tree, render });
|
|
1940
2390
|
}
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
2391
|
+
|
|
2392
|
+
// ../../runtime/core/src/build-tree-context.ts
|
|
2393
|
+
function buildNode(input, slotAssignments, seenIds, diagnostics) {
|
|
2394
|
+
if (seenIds.has(input.id)) {
|
|
2395
|
+
diagnostics.push({
|
|
2396
|
+
code: "duplicate-node-id",
|
|
2397
|
+
message: `Duplicate node id "${input.id}"`,
|
|
2398
|
+
severity: "error"
|
|
2399
|
+
});
|
|
2400
|
+
} else {
|
|
2401
|
+
seenIds.add(input.id);
|
|
2402
|
+
}
|
|
2403
|
+
if (input.slot !== void 0) {
|
|
2404
|
+
slotAssignments.set(input.id, input.slot);
|
|
2405
|
+
}
|
|
2406
|
+
const children = Object.freeze(
|
|
2407
|
+
(input.children ?? []).map((child) => buildNode(child, slotAssignments, seenIds, diagnostics))
|
|
2408
|
+
);
|
|
2409
|
+
if (input.kind === "native") {
|
|
2410
|
+
return Object.freeze({ kind: "native", id: input.id, tag: input.tag, children });
|
|
2411
|
+
}
|
|
2412
|
+
return Object.freeze({ kind: "component", id: input.id, children });
|
|
2413
|
+
}
|
|
2414
|
+
function buildTreeContext(root) {
|
|
2415
|
+
const slotAssignments = /* @__PURE__ */ new Map();
|
|
2416
|
+
const diagnostics = [];
|
|
2417
|
+
const rootNode = buildNode(root, slotAssignments, /* @__PURE__ */ new Set(), diagnostics);
|
|
2418
|
+
return Object.freeze({ root: rootNode, slotAssignments, diagnostics });
|
|
1944
2419
|
}
|
|
1945
2420
|
|
|
1946
|
-
// ../../
|
|
1947
|
-
function
|
|
1948
|
-
|
|
1949
|
-
const isFragment = child.type === Fragment3;
|
|
1950
|
-
const childRef = isFragment ? null : getChildRef(child);
|
|
1951
|
-
const mergedRef = isFragment ? null : mergeRefs(ref, childRef);
|
|
1952
|
-
const merged = mergeSlotProps(slotProps, childProps);
|
|
1953
|
-
return cloneElement(child, mergedRef !== null ? { ...merged, ref: mergedRef } : merged);
|
|
2421
|
+
// ../../runtime/core/src/build-render-context.ts
|
|
2422
|
+
function buildRenderContext(decoration = {}) {
|
|
2423
|
+
return { decoration: new Map(Object.entries(decoration)) };
|
|
1954
2424
|
}
|
|
1955
2425
|
|
|
1956
|
-
// ../../
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
2426
|
+
// ../../lib/adapter-utils/src/resolve-compounds.ts
|
|
2427
|
+
function matchesCompound(active, compound) {
|
|
2428
|
+
const { class: _, ...conditions } = compound;
|
|
2429
|
+
return Object.entries(conditions).every(([key, expected]) => {
|
|
2430
|
+
const actual = active[key];
|
|
2431
|
+
return Array.isArray(expected) ? expected.includes(actual) : actual === expected;
|
|
2432
|
+
});
|
|
2433
|
+
}
|
|
2434
|
+
function resolveCompounds(active, compounds) {
|
|
2435
|
+
if (!compounds?.length) return [];
|
|
2436
|
+
const out = [];
|
|
2437
|
+
iterate.forEach(compounds, (compound) => {
|
|
2438
|
+
if (matchesCompound(active, compound)) {
|
|
2439
|
+
out.push(flattenClassName(compound.class));
|
|
2440
|
+
}
|
|
2441
|
+
});
|
|
2442
|
+
return out;
|
|
2443
|
+
}
|
|
1961
2444
|
|
|
1962
|
-
// ../../
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
2445
|
+
// ../../lib/adapter-utils/src/resolve-classes.ts
|
|
2446
|
+
function resolveClasses(decoration, variantConfig, variantDefaults, recipe, compounds, variantLookup) {
|
|
2447
|
+
const active = getActiveProps("root", decoration);
|
|
2448
|
+
if (variantLookup !== void 0 && recipe === void 0) {
|
|
2449
|
+
const activeVariants = {};
|
|
2450
|
+
iterate.forEachKey(variantConfig.variants, (key) => {
|
|
2451
|
+
const value = active[key];
|
|
2452
|
+
if (typeof value === "string") activeVariants[key] = value;
|
|
2453
|
+
});
|
|
2454
|
+
const lookupKey = buildPrecomputedKey(activeVariants);
|
|
2455
|
+
const precomputedValue = variantLookup[lookupKey];
|
|
2456
|
+
if (precomputedValue !== void 0) {
|
|
2457
|
+
return {
|
|
2458
|
+
variantClasses: precomputedValue !== "" ? [precomputedValue] : [],
|
|
2459
|
+
compoundClasses: []
|
|
2460
|
+
};
|
|
2461
|
+
}
|
|
1966
2462
|
}
|
|
1967
|
-
};
|
|
2463
|
+
const passInput = recipe !== void 0 ? { ...active, preset: recipe } : active;
|
|
2464
|
+
const { context } = createVariantPass(passInput, variantConfig).execute({ classes: [] });
|
|
2465
|
+
const variantClasses = context.classes;
|
|
2466
|
+
const presetOverrides = recipe !== void 0 ? variantConfig.presets?.[recipe] ?? {} : {};
|
|
2467
|
+
const resolvedValues = {
|
|
2468
|
+
...variantDefaults,
|
|
2469
|
+
...presetOverrides,
|
|
2470
|
+
...active
|
|
2471
|
+
};
|
|
2472
|
+
const compoundClasses = resolveCompounds(resolvedValues, compounds);
|
|
2473
|
+
return { variantClasses, compoundClasses };
|
|
2474
|
+
}
|
|
1968
2475
|
|
|
1969
|
-
// ../../
|
|
1970
|
-
function
|
|
2476
|
+
// ../../lib/adapter-utils/src/build-pipeline.ts
|
|
2477
|
+
function buildStylePipeline(variants, presets, defaults, compounds, variantLookup) {
|
|
2478
|
+
if (variants === void 0 && compounds === void 0 && presets === void 0 && variantLookup === void 0) {
|
|
2479
|
+
return void 0;
|
|
2480
|
+
}
|
|
2481
|
+
const variantConfig = buildVariantConfig(variants, presets, defaults, compounds);
|
|
1971
2482
|
return {
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
2483
|
+
execute(decoration, recipe) {
|
|
2484
|
+
return resolveClasses(decoration, variantConfig, defaults, recipe, compounds, variantLookup);
|
|
2485
|
+
}
|
|
1975
2486
|
};
|
|
1976
2487
|
}
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
2488
|
+
|
|
2489
|
+
// ../../lib/adapter-utils/src/join-classes.ts
|
|
2490
|
+
function joinClasses(...classes) {
|
|
2491
|
+
return classes.filter(Boolean).join(" ");
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
// ../../lib/adapter-utils/src/decoration-utils.ts
|
|
2495
|
+
function withAttributes(dec, attributes) {
|
|
2496
|
+
const { attributes: _a, ...rest } = dec;
|
|
2497
|
+
return attributes !== void 0 ? { ...rest, attributes } : rest;
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2500
|
+
// ../../lib/adapter-utils/src/apply-aria.ts
|
|
2501
|
+
function applyAria(decoration, tag, ariaEngine) {
|
|
2502
|
+
if (ariaEngine === void 0) return decoration;
|
|
2503
|
+
const dec = decoration["root"];
|
|
2504
|
+
if (dec?.attributes === void 0) return decoration;
|
|
2505
|
+
const result = ariaEngine.validate(tag, dec.attributes);
|
|
2506
|
+
const cleaned = result.props;
|
|
1987
2507
|
return {
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
normalizeChildren,
|
|
1991
|
-
slotValidator,
|
|
1992
|
-
filterProps,
|
|
1993
|
-
...childrenEvaluator !== void 0 && { childrenEvaluator }
|
|
2508
|
+
...decoration,
|
|
2509
|
+
root: withAttributes(dec, Object.keys(cleaned).length > 0 ? cleaned : void 0)
|
|
1994
2510
|
};
|
|
1995
2511
|
}
|
|
1996
2512
|
|
|
1997
|
-
// ../../
|
|
1998
|
-
|
|
1999
|
-
|
|
2513
|
+
// ../../lib/adapter-utils/src/apply-filter-props.ts
|
|
2514
|
+
function applyFilterProps(decoration, filterFn, variantKeys) {
|
|
2515
|
+
if (filterFn === void 0) return decoration;
|
|
2516
|
+
const dec = decoration["root"];
|
|
2517
|
+
if (dec?.attributes === void 0) return decoration;
|
|
2518
|
+
const kept = Object.fromEntries(
|
|
2519
|
+
Object.entries(dec.attributes).filter(([k]) => !filterFn(k, variantKeys))
|
|
2520
|
+
);
|
|
2000
2521
|
return {
|
|
2001
|
-
...
|
|
2002
|
-
|
|
2522
|
+
...decoration,
|
|
2523
|
+
root: withAttributes(dec, Object.keys(kept).length > 0 ? kept : void 0)
|
|
2003
2524
|
};
|
|
2004
2525
|
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
return
|
|
2009
|
-
}
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
if (
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
return arr.length === 1;
|
|
2028
|
-
}
|
|
2029
|
-
function resolveSlotChildren(children, normalized, validator) {
|
|
2030
|
-
warnDiscardedChildren(children, normalized, validator);
|
|
2031
|
-
if (isSingleElementArray(normalized)) {
|
|
2032
|
-
return normalized[0];
|
|
2033
|
-
}
|
|
2034
|
-
if (normalized.length > 1 && normalized.some(isSlottableElement)) {
|
|
2035
|
-
return normalized;
|
|
2036
|
-
}
|
|
2037
|
-
validator.assertSingleChild(normalized.length);
|
|
2038
|
-
return null;
|
|
2526
|
+
|
|
2527
|
+
// ../../lib/adapter-utils/src/apply-ref.ts
|
|
2528
|
+
function applyRef(decoration, ref) {
|
|
2529
|
+
if (ref == null) return decoration;
|
|
2530
|
+
const existing = decoration["root"] ?? {};
|
|
2531
|
+
return { ...decoration, root: { ...existing, ref } };
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
// ../../adapters/preact/src/create-contract-component.ts
|
|
2535
|
+
import { forwardRef } from "preact/compat";
|
|
2536
|
+
|
|
2537
|
+
// ../../adapters/preact/src/backend/extract-decoration.ts
|
|
2538
|
+
function isStyleValue(v) {
|
|
2539
|
+
return isString(v) || isNumber(v);
|
|
2540
|
+
}
|
|
2541
|
+
function isAttributeValue(v) {
|
|
2542
|
+
return isString(v) || isNumber(v) || typeof v === "boolean";
|
|
2543
|
+
}
|
|
2544
|
+
function assignIfNotEmpty(target, key, value) {
|
|
2545
|
+
if (Object.keys(value).length > 0) {
|
|
2546
|
+
target[key] = value;
|
|
2547
|
+
}
|
|
2039
2548
|
}
|
|
2040
|
-
function
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2549
|
+
function extractStyles(value, styles) {
|
|
2550
|
+
if (!isObject(value)) return false;
|
|
2551
|
+
iterate.forEachEntry(value, (k, v) => {
|
|
2552
|
+
if (isStyleValue(v)) {
|
|
2553
|
+
styles[k] = v;
|
|
2554
|
+
}
|
|
2555
|
+
});
|
|
2556
|
+
return true;
|
|
2557
|
+
}
|
|
2558
|
+
function extractListener(key, value, listeners) {
|
|
2559
|
+
if (!key.startsWith("on") || !isFunction(value)) {
|
|
2045
2560
|
return false;
|
|
2046
2561
|
}
|
|
2562
|
+
listeners[key] = value;
|
|
2047
2563
|
return true;
|
|
2048
2564
|
}
|
|
2049
|
-
function
|
|
2050
|
-
if (
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
}
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2565
|
+
function extractAttributeOrVariant(key, value, attributes, variants, variantKeys) {
|
|
2566
|
+
if (variantKeys?.has(key)) {
|
|
2567
|
+
variants[key] = value;
|
|
2568
|
+
} else {
|
|
2569
|
+
attributes[key] = value;
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
function extractDecoration(props, variantKeys) {
|
|
2573
|
+
const attributes = {};
|
|
2574
|
+
const styles = {};
|
|
2575
|
+
const listeners = {};
|
|
2576
|
+
const variants = {};
|
|
2577
|
+
const dec = {};
|
|
2578
|
+
iterate.forEachEntry(props, (key, value) => {
|
|
2579
|
+
if (key === "children" || key === "slot" || key === "ref") return;
|
|
2580
|
+
if (key === "style" && extractStyles(value, styles)) return;
|
|
2581
|
+
if (extractListener(key, value, listeners)) return;
|
|
2582
|
+
if (isAttributeValue(value)) {
|
|
2583
|
+
extractAttributeOrVariant(key, value, attributes, variants, variantKeys);
|
|
2584
|
+
}
|
|
2061
2585
|
});
|
|
2586
|
+
assignIfNotEmpty(dec, "attributes", attributes);
|
|
2587
|
+
assignIfNotEmpty(dec, "styles", styles);
|
|
2588
|
+
assignIfNotEmpty(dec, "listeners", listeners);
|
|
2589
|
+
assignIfNotEmpty(dec, "variants", variants);
|
|
2590
|
+
const ref = props.ref;
|
|
2591
|
+
if (ref !== void 0) {
|
|
2592
|
+
dec.ref = ref;
|
|
2593
|
+
}
|
|
2594
|
+
return dec;
|
|
2062
2595
|
}
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2596
|
+
|
|
2597
|
+
// ../../adapters/preact/src/helpers/render-normally.ts
|
|
2598
|
+
import { cloneElement } from "preact";
|
|
2599
|
+
|
|
2600
|
+
// ../../adapters/preact/src/backend/preact-backend.ts
|
|
2601
|
+
import { Fragment, h } from "preact";
|
|
2602
|
+
|
|
2603
|
+
// ../../adapters/preact/src/backend/build-props.ts
|
|
2604
|
+
function buildPropsFromDecoration(id, decoration) {
|
|
2070
2605
|
return {
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
...
|
|
2075
|
-
...
|
|
2606
|
+
key: id,
|
|
2607
|
+
...decoration?.attributes,
|
|
2608
|
+
...decoration?.styles !== void 0 ? { style: decoration.styles } : {},
|
|
2609
|
+
...decoration?.listeners,
|
|
2610
|
+
...decoration?.ref !== void 0 ? { ref: decoration.ref } : {}
|
|
2611
|
+
};
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2614
|
+
// ../../adapters/preact/src/backend/preact-backend.ts
|
|
2615
|
+
function renderNode(node, render) {
|
|
2616
|
+
const children = node.children.map((child) => renderNode(child, render));
|
|
2617
|
+
if (node.kind === "component") {
|
|
2618
|
+
return h(Fragment, { key: node.id }, ...children);
|
|
2619
|
+
}
|
|
2620
|
+
const decoration = render.decoration.get(node.id);
|
|
2621
|
+
const props = buildPropsFromDecoration(node.id, decoration);
|
|
2622
|
+
return h(node.tag, props, ...children);
|
|
2623
|
+
}
|
|
2624
|
+
var preactBackend = {
|
|
2625
|
+
render(context) {
|
|
2626
|
+
return renderNode(context.tree.root, context.render);
|
|
2627
|
+
}
|
|
2628
|
+
};
|
|
2629
|
+
|
|
2630
|
+
// ../../adapters/preact/src/helpers/render-normally.ts
|
|
2631
|
+
function renderNormally(definition, tag, decoration, children) {
|
|
2632
|
+
const treeCtx = buildTreeContext({ kind: "native", tag, id: "root", children: [] });
|
|
2633
|
+
const rendered = renderComponent(
|
|
2634
|
+
definition,
|
|
2635
|
+
treeCtx,
|
|
2636
|
+
buildRenderContext(decoration),
|
|
2637
|
+
preactBackend
|
|
2638
|
+
);
|
|
2639
|
+
return children === void 0 ? rendered : cloneElement(rendered, {}, children);
|
|
2640
|
+
}
|
|
2641
|
+
|
|
2642
|
+
// ../../adapters/preact/src/helpers/make-render-as-child.ts
|
|
2643
|
+
import { isValidElement } from "preact";
|
|
2644
|
+
function makeRenderAsChild(cloneSlotChild2) {
|
|
2645
|
+
return function renderAsChild(children, className, ref) {
|
|
2646
|
+
if (!isValidElement(children)) throw new Error("asChild requires a Preact element child");
|
|
2647
|
+
const slotProps = className ? { className } : {};
|
|
2648
|
+
return cloneSlotChild2({ child: children, slotProps, ref: ref ?? null });
|
|
2076
2649
|
};
|
|
2077
2650
|
}
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
const
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2651
|
+
|
|
2652
|
+
// ../../adapters/preact/src/normalize-children.ts
|
|
2653
|
+
import { isValidElement as isValidElement2 } from "preact";
|
|
2654
|
+
function normalizeChildren(children) {
|
|
2655
|
+
if (isValidElement2(children)) return [children];
|
|
2656
|
+
if (Array.isArray(children)) return children.filter(isValidElement2);
|
|
2657
|
+
return [];
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
// ../../adapters/preact/src/slot/cloneSlotChild.ts
|
|
2661
|
+
import { cloneElement as cloneElement2, Fragment as Fragment2 } from "preact";
|
|
2662
|
+
|
|
2663
|
+
// ../../adapters/preact/src/slot/composeRefs.ts
|
|
2664
|
+
function mergeRefs(...refs) {
|
|
2665
|
+
return mergeRefsCore(...refs);
|
|
2666
|
+
}
|
|
2667
|
+
function getChildRef(child) {
|
|
2668
|
+
const ref = child.ref;
|
|
2669
|
+
return ref ?? null;
|
|
2670
|
+
}
|
|
2671
|
+
|
|
2672
|
+
// ../../adapters/preact/src/slot/cloneSlotChild.ts
|
|
2673
|
+
function cloneSlotChild({ child, slotProps, ref }) {
|
|
2674
|
+
const childProps = child.props;
|
|
2675
|
+
const isFragment = child.type === Fragment2;
|
|
2676
|
+
const childRef = isFragment ? null : getChildRef(child);
|
|
2677
|
+
const mergedRef = isFragment ? null : mergeRefs(ref, childRef);
|
|
2678
|
+
const merged = mergeSlotProps(slotProps, childProps);
|
|
2679
|
+
return cloneElement2(child, mergedRef !== null ? { ...merged, ref: mergedRef } : merged);
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
// ../../adapters/preact/src/slot/Slottable.tsx
|
|
2683
|
+
import { Fragment as Fragment3 } from "preact";
|
|
2684
|
+
import { jsx } from "preact/jsx-runtime";
|
|
2685
|
+
function Slottable({ children }) {
|
|
2686
|
+
return /* @__PURE__ */ jsx(Fragment3, { children });
|
|
2099
2687
|
}
|
|
2100
2688
|
|
|
2101
2689
|
// ../../adapters/preact/src/create-contract-component.ts
|
|
2690
|
+
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
2102
2691
|
function createContractComponent(options) {
|
|
2103
|
-
const
|
|
2104
|
-
const
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2692
|
+
const resolved = resolveAdapterCommonOptions(options);
|
|
2693
|
+
const displayName = resolved.name;
|
|
2694
|
+
const defaultTag = options.tag ?? "div";
|
|
2695
|
+
const definition = buildDefinition(displayName, defaultTag);
|
|
2696
|
+
const variantKeys = new Set(Object.keys(options.styling?.variants ?? {}));
|
|
2697
|
+
const domDefaults = options.defaults;
|
|
2698
|
+
const stylePipeline = buildStylePipeline(
|
|
2699
|
+
options.styling?.variants,
|
|
2700
|
+
options.styling?.presets,
|
|
2701
|
+
options.styling?.defaults ?? {},
|
|
2702
|
+
options.styling?.compounds,
|
|
2703
|
+
void 0
|
|
2704
|
+
);
|
|
2705
|
+
const base = options.styling?.base !== void 0 ? flattenClassName(options.styling.base) : void 0;
|
|
2706
|
+
const filterFn = options.filterProps;
|
|
2707
|
+
const allowedAs = options.enforcement?.allowedAs;
|
|
2708
|
+
const normalizeFn = options.normalize;
|
|
2709
|
+
const enforcementNormalizers = options.enforcement?.props;
|
|
2710
|
+
const classPlugin = options.styling?.plugin !== void 0 ? options.styling.plugin(
|
|
2711
|
+
options.styling,
|
|
2712
|
+
resolved.diagnostics
|
|
2713
|
+
) : void 0;
|
|
2714
|
+
const pluginKeys = classPlugin?.ownedKeys ?? EMPTY_SET;
|
|
2715
|
+
const { childrenEvaluator: explicitEvaluator } = buildEngines(
|
|
2716
|
+
resolved.diagnostics,
|
|
2717
|
+
options.enforcement?.children,
|
|
2718
|
+
displayName
|
|
2719
|
+
);
|
|
2720
|
+
const ariaEngine = options.enforcement !== void 0 ? new AriaPolicyEngine(resolved.diagnostics) : void 0;
|
|
2721
|
+
const slotValidator = new SlotValidator(displayName, resolved.diagnostics, "Preact element");
|
|
2722
|
+
const renderAsChild = makeRenderAsChild(cloneSlotChild);
|
|
2723
|
+
const Component = forwardRef(function Component2(props, ref) {
|
|
2724
|
+
const {
|
|
2725
|
+
as,
|
|
2726
|
+
asChild,
|
|
2727
|
+
children,
|
|
2728
|
+
className: callerClassName,
|
|
2729
|
+
recipe,
|
|
2730
|
+
...ownProps
|
|
2731
|
+
} = props;
|
|
2732
|
+
const tag = typeof as === "string" ? as : defaultTag;
|
|
2733
|
+
if (allowedAs !== void 0) enforceAllowedAs(tag, allowedAs, resolved.diagnostics, displayName);
|
|
2734
|
+
const rawBaseProps = domDefaults !== void 0 ? { ...domDefaults, ...ownProps } : ownProps;
|
|
2735
|
+
const normalizedProps = applyPropNormalizers(tag, rawBaseProps, enforcementNormalizers);
|
|
2736
|
+
const baseProps = normalizeFn !== void 0 ? normalizeFn(normalizedProps) : normalizedProps;
|
|
2737
|
+
const pluginProps = {};
|
|
2738
|
+
const propsForExtraction = pluginKeys.size > 0 ? Object.fromEntries(
|
|
2739
|
+
Object.entries(baseProps).filter(([k]) => {
|
|
2740
|
+
if (pluginKeys.has(k)) {
|
|
2741
|
+
pluginProps[k] = baseProps[k];
|
|
2742
|
+
return false;
|
|
2743
|
+
}
|
|
2744
|
+
return true;
|
|
2745
|
+
})
|
|
2746
|
+
) : baseProps;
|
|
2747
|
+
const rootDec = extractDecoration(propsForExtraction, variantKeys);
|
|
2748
|
+
const decoration = applyAria(
|
|
2749
|
+
Object.keys(rootDec).length > 0 ? { root: rootDec } : {},
|
|
2750
|
+
tag,
|
|
2751
|
+
ariaEngine
|
|
2752
|
+
);
|
|
2753
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2754
|
+
const childEval = explicitEvaluator ?? getHtmlChildrenEvaluator(tag);
|
|
2755
|
+
childEval?.evaluate(normalizeChildren(children));
|
|
2756
|
+
}
|
|
2757
|
+
const recipeName = typeof recipe === "string" ? recipe : void 0;
|
|
2758
|
+
const { variantClasses, compoundClasses } = stylePipeline ? stylePipeline.execute(decoration, recipeName) : { variantClasses: [], compoundClasses: [] };
|
|
2759
|
+
const rawClassName = joinClasses(base, ...variantClasses, ...compoundClasses, callerClassName);
|
|
2760
|
+
const className = classPlugin !== void 0 ? classPlugin.pipeline(tag, pluginProps, rawClassName, recipeName) : rawClassName;
|
|
2761
|
+
if (asChild === true) {
|
|
2762
|
+
if (typeof as === "string") {
|
|
2763
|
+
slotValidator.assertExclusive();
|
|
2764
|
+
} else {
|
|
2765
|
+
return renderAsChild(children, className, ref ?? null);
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
let finalDecoration = className ? applyAttributes("root", { className }, decoration, variantKeys) : decoration;
|
|
2769
|
+
finalDecoration = applyFilterProps(finalDecoration, filterFn, variantKeys);
|
|
2770
|
+
finalDecoration = applyRef(finalDecoration, ref ?? null);
|
|
2771
|
+
return renderNormally(definition, tag, finalDecoration, children);
|
|
2111
2772
|
});
|
|
2112
2773
|
applyDisplayName(Component, options.name);
|
|
2113
|
-
if (typeof
|
|
2114
|
-
Object.assign(Component, { [COMPONENT_DEFAULT_TAG]:
|
|
2774
|
+
if (typeof defaultTag === "string") {
|
|
2775
|
+
Object.assign(Component, { [COMPONENT_DEFAULT_TAG]: defaultTag });
|
|
2115
2776
|
}
|
|
2116
2777
|
return Component;
|
|
2117
2778
|
}
|