praxis-kit 3.1.1 → 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 +5 -235
- package/dist/lit/index.js +1384 -747
- package/dist/merge-refs-DUuHyTRO.d.ts +144 -0
- package/dist/preact/index.d.ts +9 -254
- package/dist/preact/index.js +1686 -1025
- package/dist/react/index.d.ts +23 -11
- package/dist/react/index.js +115 -116
- package/dist/react/legacy.d.ts +7 -11
- package/dist/react/legacy.js +116 -136
- package/dist/solid/index.d.ts +5 -250
- package/dist/solid/index.js +1476 -706
- package/dist/svelte/index.d.ts +5 -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 +12 -257
- package/dist/vue/index.js +1701 -926
- package/dist/web/index.d.ts +9 -238
- package/dist/web/index.js +1369 -732
- package/package.json +4 -3
- package/dist/chunk-6RJN5B6L.js +0 -2221
- package/dist/merge-refs-BKyE8h8M.d.ts +0 -381
package/dist/web/index.js
CHANGED
|
@@ -1,55 +1,14 @@
|
|
|
1
|
-
// ../../lib/
|
|
2
|
-
function applyFilter(props, filterProps, variantKeys) {
|
|
3
|
-
const out = {};
|
|
4
|
-
for (const k in props) {
|
|
5
|
-
if (!Object.hasOwn(props, k)) continue;
|
|
6
|
-
if (filterProps(k, variantKeys)) continue;
|
|
7
|
-
out[k] = props[k];
|
|
8
|
-
}
|
|
9
|
-
return out;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// ../../lib/adapter-utils/src/define-component.ts
|
|
13
|
-
function defineContractComponent(options) {
|
|
14
|
-
return (factory) => factory(options);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// ../core/dist/chunk-KKSHJDE7.js
|
|
1
|
+
// ../../lib/primitive/src/tag/resolve-tag.ts
|
|
18
2
|
function makeResolveTag(defaultTag) {
|
|
19
3
|
return function tag(as) {
|
|
20
4
|
return as ?? defaultTag;
|
|
21
5
|
};
|
|
22
6
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
29
|
-
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
30
|
-
var o = e.length;
|
|
31
|
-
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
32
|
-
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
33
|
-
return n;
|
|
34
|
-
}
|
|
35
|
-
function clsx() {
|
|
36
|
-
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
37
|
-
return n;
|
|
38
|
-
}
|
|
39
|
-
function cn(...inputs) {
|
|
40
|
-
return clsx(...inputs);
|
|
41
|
-
}
|
|
42
|
-
function mergeProps(defaultProps, props) {
|
|
43
|
-
return {
|
|
44
|
-
...defaultProps ?? {},
|
|
45
|
-
...props
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
function isNull(value) {
|
|
49
|
-
return value === null;
|
|
50
|
-
}
|
|
51
|
-
function isObject(value) {
|
|
52
|
-
return !isNull(value) && typeof value === "object";
|
|
7
|
+
|
|
8
|
+
// ../../lib/primitive/src/utils/is-object.ts
|
|
9
|
+
function isObject(value, excludeArrays = false) {
|
|
10
|
+
if (value === null || typeof value !== "object") return false;
|
|
11
|
+
return excludeArrays ? !Array.isArray(value) : true;
|
|
53
12
|
}
|
|
54
13
|
function isString(value) {
|
|
55
14
|
return typeof value === "string";
|
|
@@ -57,308 +16,197 @@ function isString(value) {
|
|
|
57
16
|
function isNumber(value) {
|
|
58
17
|
return typeof value === "number";
|
|
59
18
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const patched = normalizers.reduce(
|
|
65
|
-
(acc, normalizer) => ({ ...acc, ...normalizer(acc) }),
|
|
66
|
-
props
|
|
67
|
-
);
|
|
68
|
-
return fn ? fn(patched) : patched;
|
|
69
|
-
});
|
|
19
|
+
|
|
20
|
+
// ../../lib/primitive/src/utils/assert-never.ts
|
|
21
|
+
function assertNever(value) {
|
|
22
|
+
throw new Error(`Unexpected value: ${String(value)}`);
|
|
70
23
|
}
|
|
71
|
-
|
|
72
|
-
|
|
24
|
+
|
|
25
|
+
// ../../lib/primitive/src/utils/cn.ts
|
|
26
|
+
import { clsx } from "clsx";
|
|
27
|
+
function cn(...inputs) {
|
|
28
|
+
return clsx(...inputs);
|
|
73
29
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
...whenDefined("baseClassName", styling?.base),
|
|
85
|
-
...whenDefined("tagMap", styling?.tags),
|
|
86
|
-
...whenDefined("recipeMap", styling?.presets),
|
|
87
|
-
...whenDefined("variants", styling?.variants),
|
|
88
|
-
...whenDefined("defaultVariants", styling?.defaults),
|
|
89
|
-
...whenDefined("compoundVariants", styling?.compounds),
|
|
90
|
-
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
91
|
-
...whenDefined("ariaRules", enforcement?.aria),
|
|
92
|
-
...whenDefined("childRules", enforcement?.children),
|
|
93
|
-
...whenDefined("allowedAs", enforcement?.allowedAs),
|
|
94
|
-
...whenDefined("precomputedClasses", styling?.precomputedClasses)
|
|
95
|
-
});
|
|
30
|
+
|
|
31
|
+
// ../../lib/primitive/src/utils/iterate.ts
|
|
32
|
+
function find(iterable, callback) {
|
|
33
|
+
for (const value of iterable) {
|
|
34
|
+
const result = callback(value);
|
|
35
|
+
if (result != null) {
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
96
40
|
}
|
|
97
|
-
function
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
41
|
+
function some(iterable, predicate) {
|
|
42
|
+
for (const value of iterable) {
|
|
43
|
+
if (predicate(value)) return true;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
102
46
|
}
|
|
103
|
-
function
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const checkSelection = (label2, selection) => {
|
|
109
|
-
const record = selection;
|
|
110
|
-
for (const dim in record) {
|
|
111
|
-
const value = record[dim];
|
|
112
|
-
if (value === void 0 || value === null) continue;
|
|
113
|
-
if (!variants || !Object.hasOwn(variants, dim)) {
|
|
114
|
-
report(strict, `${name}: ${label2} references unknown variant "${dim}".`);
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
const states = variants[dim];
|
|
118
|
-
const stateKey = String(value);
|
|
119
|
-
if (!Object.hasOwn(states, stateKey)) {
|
|
120
|
-
report(
|
|
121
|
-
strict,
|
|
122
|
-
`${name}: ${label2} sets "${dim}" to unknown value "${stateKey}" (valid: ${Object.keys(states).join(", ")}).`
|
|
123
|
-
);
|
|
124
|
-
}
|
|
47
|
+
function every(iterable, predicate) {
|
|
48
|
+
let index = 0;
|
|
49
|
+
for (const value of iterable) {
|
|
50
|
+
if (!predicate(value, index++)) {
|
|
51
|
+
return false;
|
|
125
52
|
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
function* filter(iterable, predicate) {
|
|
57
|
+
let index = 0;
|
|
58
|
+
for (const value of iterable) {
|
|
59
|
+
if (predicate(value, index++)) {
|
|
60
|
+
yield value;
|
|
131
61
|
}
|
|
132
62
|
}
|
|
133
|
-
if (resolved.defaultVariants) checkSelection("defaults", resolved.defaultVariants);
|
|
134
63
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
64
|
+
function* map(iterable, callback) {
|
|
65
|
+
let index = 0;
|
|
66
|
+
for (const value of iterable) {
|
|
67
|
+
yield callback(value, index++);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function forEach(iterable, callback) {
|
|
71
|
+
let index = 0;
|
|
72
|
+
for (const value of iterable) {
|
|
73
|
+
callback(value, index++);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function reduce(iterable, initial, callback) {
|
|
77
|
+
let accumulator = initial;
|
|
78
|
+
let index = 0;
|
|
79
|
+
for (const value of iterable) {
|
|
80
|
+
accumulator = callback(accumulator, value, index++);
|
|
81
|
+
}
|
|
82
|
+
return accumulator;
|
|
83
|
+
}
|
|
84
|
+
function collect(iterable, callback) {
|
|
85
|
+
const result = {};
|
|
86
|
+
let index = 0;
|
|
87
|
+
for (const value of iterable) {
|
|
88
|
+
const entry = callback(value, index++);
|
|
89
|
+
if (entry === null) {
|
|
90
|
+
return null;
|
|
156
91
|
}
|
|
157
|
-
|
|
92
|
+
result[entry[0]] = entry[1];
|
|
158
93
|
}
|
|
159
|
-
|
|
160
|
-
warned.add(message);
|
|
161
|
-
console.warn(message);
|
|
94
|
+
return result;
|
|
162
95
|
}
|
|
163
|
-
function
|
|
164
|
-
|
|
96
|
+
function findLast(value, callback) {
|
|
97
|
+
for (let index = value.length - 1; index >= 0; index--) {
|
|
98
|
+
const result = callback(value[index], index);
|
|
99
|
+
if (result != null) {
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
165
104
|
}
|
|
166
|
-
function
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
105
|
+
function* items(collection) {
|
|
106
|
+
for (let i = 0; i < collection.length; i++) {
|
|
107
|
+
const item = collection.item(i);
|
|
108
|
+
if (item !== null) {
|
|
109
|
+
yield item;
|
|
110
|
+
}
|
|
172
111
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
`${tag} Variant "${key}=${String(value)}" is not a defined value for the "${key}" dimension.`
|
|
183
|
-
);
|
|
112
|
+
}
|
|
113
|
+
function nodeList(list) {
|
|
114
|
+
return {
|
|
115
|
+
*[Symbol.iterator]() {
|
|
116
|
+
for (let i = 0; i < list.length; i++) {
|
|
117
|
+
const node = list.item(i);
|
|
118
|
+
if (node !== null) {
|
|
119
|
+
yield node;
|
|
120
|
+
}
|
|
184
121
|
}
|
|
185
122
|
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function mapEntries(m) {
|
|
126
|
+
return m.entries();
|
|
127
|
+
}
|
|
128
|
+
function set(s) {
|
|
129
|
+
return s.values();
|
|
130
|
+
}
|
|
131
|
+
function hasOwn(object, key) {
|
|
132
|
+
return Object.hasOwn(object, key);
|
|
133
|
+
}
|
|
134
|
+
function* entries(object) {
|
|
135
|
+
for (const key in object) {
|
|
136
|
+
if (!hasOwn(object, key)) continue;
|
|
137
|
+
yield [key, object[key]];
|
|
186
138
|
}
|
|
187
139
|
}
|
|
188
|
-
function
|
|
189
|
-
|
|
140
|
+
function* keys(object) {
|
|
141
|
+
for (const [key] of entries(object)) {
|
|
142
|
+
yield key;
|
|
143
|
+
}
|
|
190
144
|
}
|
|
191
|
-
function
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
145
|
+
function* values(object) {
|
|
146
|
+
for (const [, value] of entries(object)) {
|
|
147
|
+
yield value;
|
|
148
|
+
}
|
|
195
149
|
}
|
|
196
|
-
function
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (typeof plugin.pipeline !== "function")
|
|
203
|
-
panic(
|
|
204
|
-
`[praxis-kit] Plugin factory return value is missing a 'pipeline' function. Got pipeline: ${typeof plugin.pipeline}.`
|
|
205
|
-
);
|
|
150
|
+
function mapValues(object, callback) {
|
|
151
|
+
const result = {};
|
|
152
|
+
for (const [key, value] of entries(object)) {
|
|
153
|
+
result[key] = callback(value, key);
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
206
156
|
}
|
|
207
|
-
function
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (typeof result !== "string")
|
|
212
|
-
panic(`[praxis-kit] Plugin pipeline must return a string. Got: ${describe(result)}.`);
|
|
213
|
-
return result;
|
|
214
|
-
};
|
|
157
|
+
function forEachEntry(object, callback) {
|
|
158
|
+
for (const [key, value] of entries(object)) {
|
|
159
|
+
callback(key, value);
|
|
160
|
+
}
|
|
215
161
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (!factory) {
|
|
220
|
-
const createClassPipeline2 = capabilities?.createClassPipeline;
|
|
221
|
-
const classPipeline2 = createClassPipeline2 ? createClassPipeline2(resolved) : NOOP_CLASS_PIPELINE;
|
|
222
|
-
return { pluginResult: void 0, classPipeline: classPipeline2 };
|
|
162
|
+
function forEachKey(object, callback) {
|
|
163
|
+
for (const key of keys(object)) {
|
|
164
|
+
callback(key);
|
|
223
165
|
}
|
|
224
|
-
const pluginResult = factory(resolved, strict);
|
|
225
|
-
assertPluginShape(pluginResult);
|
|
226
|
-
const classPipeline = guardPipeline(pluginResult.pipeline);
|
|
227
|
-
return { pluginResult, classPipeline };
|
|
228
166
|
}
|
|
229
|
-
function
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
return mergeProps(resolved.defaultProps, props);
|
|
234
|
-
},
|
|
235
|
-
resolveClasses(tag, props, className, recipe) {
|
|
236
|
-
if (process.env.NODE_ENV !== "production") {
|
|
237
|
-
validateRenderProps(resolved, props, recipe);
|
|
238
|
-
}
|
|
239
|
-
return classPipeline(tag, props, className, recipe);
|
|
240
|
-
},
|
|
241
|
-
resolveAria(tag, props) {
|
|
242
|
-
if (!engine) return { props };
|
|
243
|
-
const result = engine.validate(tag, props);
|
|
244
|
-
return { props: result.props };
|
|
245
|
-
}
|
|
246
|
-
};
|
|
167
|
+
function forEachValue(object, callback) {
|
|
168
|
+
for (const value of values(object)) {
|
|
169
|
+
callback(value);
|
|
170
|
+
}
|
|
247
171
|
}
|
|
248
|
-
function
|
|
249
|
-
|
|
172
|
+
function forEachSet(s, callback) {
|
|
173
|
+
for (const value of s) {
|
|
174
|
+
callback(value);
|
|
175
|
+
}
|
|
250
176
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
177
|
+
var iterate = Object.freeze({
|
|
178
|
+
entries,
|
|
179
|
+
filter,
|
|
180
|
+
find,
|
|
181
|
+
findLast,
|
|
182
|
+
forEach,
|
|
183
|
+
forEachEntry,
|
|
184
|
+
forEachKey,
|
|
185
|
+
forEachSet,
|
|
186
|
+
forEachValue,
|
|
187
|
+
items,
|
|
188
|
+
keys,
|
|
189
|
+
map,
|
|
190
|
+
mapEntries,
|
|
191
|
+
mapValues,
|
|
192
|
+
nodeList,
|
|
193
|
+
reduce,
|
|
194
|
+
collect,
|
|
195
|
+
set,
|
|
196
|
+
some,
|
|
197
|
+
every,
|
|
198
|
+
values
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// ../../lib/primitive/src/utils/merge-props.ts
|
|
202
|
+
function mergeProps(defaultProps, props) {
|
|
203
|
+
return {
|
|
204
|
+
...defaultProps ?? {},
|
|
205
|
+
...props
|
|
206
|
+
};
|
|
277
207
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
"alertdialog",
|
|
281
|
-
"application",
|
|
282
|
-
"article",
|
|
283
|
-
"banner",
|
|
284
|
-
"blockquote",
|
|
285
|
-
"button",
|
|
286
|
-
"caption",
|
|
287
|
-
"cell",
|
|
288
|
-
"checkbox",
|
|
289
|
-
"code",
|
|
290
|
-
"columnheader",
|
|
291
|
-
"combobox",
|
|
292
|
-
"complementary",
|
|
293
|
-
"contentinfo",
|
|
294
|
-
"definition",
|
|
295
|
-
"deletion",
|
|
296
|
-
"dialog",
|
|
297
|
-
"document",
|
|
298
|
-
"emphasis",
|
|
299
|
-
"feed",
|
|
300
|
-
"figure",
|
|
301
|
-
"form",
|
|
302
|
-
"generic",
|
|
303
|
-
"grid",
|
|
304
|
-
"gridcell",
|
|
305
|
-
"group",
|
|
306
|
-
"heading",
|
|
307
|
-
"img",
|
|
308
|
-
"insertion",
|
|
309
|
-
"link",
|
|
310
|
-
"list",
|
|
311
|
-
"listbox",
|
|
312
|
-
"listitem",
|
|
313
|
-
"log",
|
|
314
|
-
"main",
|
|
315
|
-
"marquee",
|
|
316
|
-
"math",
|
|
317
|
-
"menu",
|
|
318
|
-
"menubar",
|
|
319
|
-
"menuitem",
|
|
320
|
-
"menuitemcheckbox",
|
|
321
|
-
"menuitemradio",
|
|
322
|
-
"meter",
|
|
323
|
-
"navigation",
|
|
324
|
-
"none",
|
|
325
|
-
"note",
|
|
326
|
-
"option",
|
|
327
|
-
"paragraph",
|
|
328
|
-
"presentation",
|
|
329
|
-
"progressbar",
|
|
330
|
-
"radio",
|
|
331
|
-
"radiogroup",
|
|
332
|
-
"region",
|
|
333
|
-
"row",
|
|
334
|
-
"rowgroup",
|
|
335
|
-
"rowheader",
|
|
336
|
-
"scrollbar",
|
|
337
|
-
"search",
|
|
338
|
-
"searchbox",
|
|
339
|
-
"separator",
|
|
340
|
-
"slider",
|
|
341
|
-
"spinbutton",
|
|
342
|
-
"status",
|
|
343
|
-
"strong",
|
|
344
|
-
"subscript",
|
|
345
|
-
"superscript",
|
|
346
|
-
"switch",
|
|
347
|
-
"tab",
|
|
348
|
-
"table",
|
|
349
|
-
"tablist",
|
|
350
|
-
"tabpanel",
|
|
351
|
-
"term",
|
|
352
|
-
"textbox",
|
|
353
|
-
"time",
|
|
354
|
-
"timer",
|
|
355
|
-
"toolbar",
|
|
356
|
-
"tooltip",
|
|
357
|
-
"tree",
|
|
358
|
-
"treegrid",
|
|
359
|
-
"treeitem"
|
|
360
|
-
];
|
|
361
|
-
var KNOWN_ARIA_ROLES_SET = new Set(KNOWN_ARIA_ROLES);
|
|
208
|
+
|
|
209
|
+
// ../../lib/primitive/src/constants/aria/global-aria-attributes.ts
|
|
362
210
|
var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
363
211
|
"aria-atomic",
|
|
364
212
|
"aria-busy",
|
|
@@ -378,29 +226,59 @@ var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
378
226
|
"aria-relevant",
|
|
379
227
|
"aria-roledescription"
|
|
380
228
|
]);
|
|
229
|
+
|
|
230
|
+
// ../../lib/primitive/src/constants/aria/implicit-role-record.ts
|
|
381
231
|
var IMPLICIT_ROLE_RECORD = {
|
|
232
|
+
// Landmarks
|
|
382
233
|
article: "article",
|
|
383
234
|
aside: "complementary",
|
|
384
235
|
footer: "contentinfo",
|
|
385
236
|
header: "banner",
|
|
386
237
|
main: "main",
|
|
387
238
|
nav: "navigation",
|
|
388
|
-
|
|
239
|
+
// Interactive
|
|
389
240
|
a: "link",
|
|
241
|
+
button: "button",
|
|
390
242
|
select: "listbox",
|
|
243
|
+
textarea: "textbox",
|
|
244
|
+
// Headings
|
|
391
245
|
h1: "heading",
|
|
392
246
|
h2: "heading",
|
|
393
247
|
h3: "heading",
|
|
394
248
|
h4: "heading",
|
|
395
249
|
h5: "heading",
|
|
396
250
|
h6: "heading",
|
|
251
|
+
// Lists
|
|
397
252
|
ul: "list",
|
|
398
253
|
ol: "list",
|
|
399
254
|
li: "listitem",
|
|
255
|
+
// Tables
|
|
400
256
|
table: "table",
|
|
401
257
|
tr: "row",
|
|
402
258
|
td: "cell",
|
|
403
|
-
th: "columnheader"
|
|
259
|
+
th: "columnheader",
|
|
260
|
+
// Structural / semantic
|
|
261
|
+
dialog: "dialog",
|
|
262
|
+
fieldset: "group",
|
|
263
|
+
figure: "figure",
|
|
264
|
+
meter: "meter",
|
|
265
|
+
output: "status",
|
|
266
|
+
progress: "progressbar"
|
|
267
|
+
};
|
|
268
|
+
var INPUT_TYPE_ROLE_MAP = {
|
|
269
|
+
checkbox: "checkbox",
|
|
270
|
+
radio: "radio",
|
|
271
|
+
range: "slider",
|
|
272
|
+
number: "spinbutton",
|
|
273
|
+
search: "searchbox",
|
|
274
|
+
text: "textbox",
|
|
275
|
+
email: "textbox",
|
|
276
|
+
tel: "textbox",
|
|
277
|
+
url: "textbox",
|
|
278
|
+
button: "button",
|
|
279
|
+
submit: "button",
|
|
280
|
+
reset: "button",
|
|
281
|
+
image: "button"
|
|
404
282
|
};
|
|
405
283
|
var STRONG_ROLES = [
|
|
406
284
|
"main",
|
|
@@ -412,6 +290,8 @@ var STRONG_ROLES = [
|
|
|
412
290
|
var STANDALONE_ROLES = ["article"];
|
|
413
291
|
var STRONG_ROLES_SET = new Set(STRONG_ROLES);
|
|
414
292
|
var STANDALONE_ROLES_SET = new Set(STANDALONE_ROLES);
|
|
293
|
+
|
|
294
|
+
// ../../lib/primitive/src/constants/aria/role-restricted-attributes.ts
|
|
415
295
|
var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
|
|
416
296
|
[
|
|
417
297
|
"aria-activedescendant",
|
|
@@ -561,9 +441,18 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
|
|
|
561
441
|
/* @__PURE__ */ new Set(["meter", "progressbar", "scrollbar", "separator", "slider", "spinbutton"])
|
|
562
442
|
]
|
|
563
443
|
]);
|
|
444
|
+
|
|
445
|
+
// ../../lib/primitive/src/guards/foundational/is-defined.ts
|
|
564
446
|
function isUndefined(value) {
|
|
565
447
|
return value === void 0;
|
|
566
448
|
}
|
|
449
|
+
|
|
450
|
+
// ../../lib/primitive/src/guards/foundational/is-null.ts
|
|
451
|
+
function isNull(value) {
|
|
452
|
+
return value === null;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// ../../lib/primitive/src/guards/aria/is-aria-attribute.ts
|
|
567
456
|
function isGlobalAriaAttribute(attr) {
|
|
568
457
|
return GLOBAL_ARIA_ATTRIBUTES.has(attr);
|
|
569
458
|
}
|
|
@@ -573,6 +462,8 @@ function isAriaAttributeValidForRole(attr, role) {
|
|
|
573
462
|
if (isUndefined(role)) return false;
|
|
574
463
|
return allowedRoles.has(role);
|
|
575
464
|
}
|
|
465
|
+
|
|
466
|
+
// ../../lib/primitive/src/guards/aria/is-aria-role.ts
|
|
576
467
|
function isStrongImplicitRole(tag) {
|
|
577
468
|
if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
|
|
578
469
|
return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
|
|
@@ -581,116 +472,509 @@ function isStandaloneTag(tag) {
|
|
|
581
472
|
if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
|
|
582
473
|
return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
|
|
583
474
|
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
button: "button",
|
|
594
|
-
a: "link",
|
|
595
|
-
select: "listbox",
|
|
596
|
-
h1: "heading",
|
|
597
|
-
h2: "heading",
|
|
598
|
-
h3: "heading",
|
|
599
|
-
h4: "heading",
|
|
600
|
-
h5: "heading",
|
|
601
|
-
h6: "heading",
|
|
602
|
-
ul: "list",
|
|
603
|
-
ol: "list",
|
|
604
|
-
li: "listitem",
|
|
605
|
-
table: "table",
|
|
606
|
-
tr: "row",
|
|
607
|
-
td: "cell",
|
|
608
|
-
th: "columnheader"
|
|
609
|
-
};
|
|
610
|
-
function getImplicitRole(tag) {
|
|
611
|
-
if (tag in IMPLICIT_ROLE_RECORD2) return IMPLICIT_ROLE_RECORD2[tag];
|
|
475
|
+
function getInputImplicitRole(type) {
|
|
476
|
+
if (type == null || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
|
|
477
|
+
return INPUT_TYPE_ROLE_MAP[type];
|
|
478
|
+
}
|
|
479
|
+
function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
|
|
480
|
+
const isNamed = typeof ariaLabel === "string" || typeof ariaLabelledBy === "string";
|
|
481
|
+
if (!isNamed) return void 0;
|
|
482
|
+
if (tag === "section") return "region";
|
|
483
|
+
if (tag === "form") return "form";
|
|
612
484
|
return void 0;
|
|
613
485
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
486
|
+
|
|
487
|
+
// ../../lib/adapter-utils/src/apply-filter.ts
|
|
488
|
+
function applyFilter(props, filterProps, variantKeys) {
|
|
489
|
+
const out = {};
|
|
490
|
+
iterate.forEachEntry(props, (k) => {
|
|
491
|
+
if (!Object.hasOwn(props, k)) return;
|
|
492
|
+
if (filterProps(k, variantKeys)) return;
|
|
493
|
+
out[k] = props[k];
|
|
494
|
+
});
|
|
495
|
+
return out;
|
|
621
496
|
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
if (
|
|
626
|
-
if (
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
return
|
|
497
|
+
|
|
498
|
+
// ../../lib/contract/src/aria/aria-role-policy.ts
|
|
499
|
+
function getImplicitRole(tag, props) {
|
|
500
|
+
if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
|
|
501
|
+
if (tag === "input") return getInputImplicitRole(props?.type);
|
|
502
|
+
if (tag === "img") return props?.alt === "" ? "none" : "img";
|
|
503
|
+
if (tag === "section" || tag === "form") {
|
|
504
|
+
return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
|
|
630
505
|
}
|
|
631
506
|
return void 0;
|
|
632
507
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
};
|
|
508
|
+
|
|
509
|
+
// ../../lib/contract/src/strict/invariant-base.ts
|
|
510
|
+
var InvariantBase = class {
|
|
511
|
+
diagnostics;
|
|
512
|
+
constructor(diagnostics) {
|
|
513
|
+
this.diagnostics = diagnostics;
|
|
640
514
|
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
const tag = getTag(child);
|
|
644
|
-
return tag !== void 0 && set.has(tag);
|
|
645
|
-
}
|
|
646
|
-
var pendingAsyncWarns2 = /* @__PURE__ */ new Set();
|
|
647
|
-
var asyncWarnScheduled2 = false;
|
|
648
|
-
function flushAsyncWarns2() {
|
|
649
|
-
asyncWarnScheduled2 = false;
|
|
650
|
-
const messages = [...pendingAsyncWarns2];
|
|
651
|
-
pendingAsyncWarns2.clear();
|
|
652
|
-
for (const msg of messages) {
|
|
653
|
-
console.warn(msg);
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
function scheduleAsyncWarn(message) {
|
|
657
|
-
if (pendingAsyncWarns2.has(message)) return;
|
|
658
|
-
pendingAsyncWarns2.add(message);
|
|
659
|
-
if (!asyncWarnScheduled2) {
|
|
660
|
-
asyncWarnScheduled2 = true;
|
|
661
|
-
queueMicrotask(flushAsyncWarns2);
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
var StrictBase = class {
|
|
665
|
-
strict;
|
|
666
|
-
constructor(strict) {
|
|
667
|
-
this.strict = strict;
|
|
668
|
-
}
|
|
669
|
-
violate(message) {
|
|
670
|
-
if (this.strict === true || this.strict === "throw") {
|
|
671
|
-
throw new Error(message);
|
|
672
|
-
}
|
|
673
|
-
this.warn(message);
|
|
515
|
+
get active() {
|
|
516
|
+
return this.diagnostics.active;
|
|
674
517
|
}
|
|
675
|
-
|
|
518
|
+
violate(input) {
|
|
519
|
+
this.diagnostics.error(input);
|
|
520
|
+
}
|
|
521
|
+
// Always caps at warn — never throws. ARIA 'warning' violations route here
|
|
676
522
|
// so they surface even in strict='throw' mode without aborting a render.
|
|
677
|
-
warn(
|
|
678
|
-
|
|
679
|
-
if (this.strict === "async-warn") {
|
|
680
|
-
scheduleAsyncWarn(message);
|
|
681
|
-
return;
|
|
682
|
-
}
|
|
683
|
-
console.warn(message);
|
|
523
|
+
warn(input) {
|
|
524
|
+
this.diagnostics.warn(input);
|
|
684
525
|
}
|
|
685
|
-
invariant(condition,
|
|
686
|
-
if (!condition)
|
|
687
|
-
this.violate(message);
|
|
688
|
-
}
|
|
526
|
+
invariant(condition, input) {
|
|
527
|
+
if (!condition) this.violate(input);
|
|
689
528
|
}
|
|
690
529
|
};
|
|
691
|
-
|
|
692
|
-
|
|
530
|
+
|
|
531
|
+
// ../../lib/diagnostics/src/category.ts
|
|
532
|
+
var DiagnosticCategory = /* @__PURE__ */ ((DiagnosticCategory2) => {
|
|
533
|
+
DiagnosticCategory2[DiagnosticCategory2["Contract"] = 0] = "Contract";
|
|
534
|
+
DiagnosticCategory2[DiagnosticCategory2["HTML"] = 1] = "HTML";
|
|
535
|
+
DiagnosticCategory2[DiagnosticCategory2["ARIA"] = 2] = "ARIA";
|
|
536
|
+
DiagnosticCategory2[DiagnosticCategory2["Composition"] = 3] = "Composition";
|
|
537
|
+
DiagnosticCategory2[DiagnosticCategory2["Rendering"] = 4] = "Rendering";
|
|
538
|
+
DiagnosticCategory2[DiagnosticCategory2["Accessibility"] = 5] = "Accessibility";
|
|
539
|
+
DiagnosticCategory2[DiagnosticCategory2["Performance"] = 6] = "Performance";
|
|
540
|
+
DiagnosticCategory2[DiagnosticCategory2["Internal"] = 7] = "Internal";
|
|
541
|
+
DiagnosticCategory2[DiagnosticCategory2["Deprecation"] = 8] = "Deprecation";
|
|
542
|
+
DiagnosticCategory2[DiagnosticCategory2["Lint"] = 9] = "Lint";
|
|
543
|
+
return DiagnosticCategory2;
|
|
544
|
+
})(DiagnosticCategory || {});
|
|
545
|
+
|
|
546
|
+
// ../../lib/diagnostics/src/error.ts
|
|
547
|
+
var PraxisError = class extends Error {
|
|
548
|
+
diagnostic;
|
|
549
|
+
constructor(diagnostic) {
|
|
550
|
+
super(diagnostic.message);
|
|
551
|
+
this.name = "PraxisError";
|
|
552
|
+
this.diagnostic = diagnostic;
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
// ../../lib/diagnostics/src/severity.ts
|
|
557
|
+
var Severity = /* @__PURE__ */ ((Severity2) => {
|
|
558
|
+
Severity2[Severity2["Debug"] = 0] = "Debug";
|
|
559
|
+
Severity2[Severity2["Info"] = 1] = "Info";
|
|
560
|
+
Severity2[Severity2["Warning"] = 2] = "Warning";
|
|
561
|
+
Severity2[Severity2["Error"] = 3] = "Error";
|
|
562
|
+
Severity2[Severity2["Fatal"] = 4] = "Fatal";
|
|
563
|
+
return Severity2;
|
|
564
|
+
})(Severity || {});
|
|
565
|
+
|
|
566
|
+
// ../../lib/diagnostics/src/policy.ts
|
|
567
|
+
var DefaultPolicy = class {
|
|
568
|
+
reportThreshold;
|
|
569
|
+
throwThreshold;
|
|
570
|
+
constructor({
|
|
571
|
+
reportThreshold = 1 /* Info */,
|
|
572
|
+
throwThreshold = 4 /* Fatal */
|
|
573
|
+
} = {}) {
|
|
574
|
+
this.reportThreshold = reportThreshold;
|
|
575
|
+
this.throwThreshold = throwThreshold;
|
|
576
|
+
}
|
|
577
|
+
resolve(diagnostic) {
|
|
578
|
+
if (diagnostic.severity >= this.throwThreshold) return 2 /* Throw */;
|
|
579
|
+
if (diagnostic.severity >= this.reportThreshold) return 1 /* Report */;
|
|
580
|
+
return 0 /* Ignore */;
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
// ../../lib/diagnostics/src/diagnostics.ts
|
|
585
|
+
var Diagnostics = class {
|
|
586
|
+
reporter;
|
|
587
|
+
policy;
|
|
588
|
+
// Pre-computed at construction time: true if Warning-level diagnostics are not ignored.
|
|
589
|
+
active;
|
|
590
|
+
constructor(reporter, policy = new DefaultPolicy()) {
|
|
591
|
+
this.reporter = reporter;
|
|
592
|
+
this.policy = policy;
|
|
593
|
+
this.active = policy.resolve({ severity: 2 /* Warning */ }) !== 0 /* Ignore */;
|
|
594
|
+
}
|
|
595
|
+
report(diagnostic) {
|
|
596
|
+
const enforcement = this.policy.resolve(diagnostic);
|
|
597
|
+
if (enforcement === 0 /* Ignore */) return diagnostic;
|
|
598
|
+
if (enforcement === 2 /* Throw */) throw new PraxisError(diagnostic);
|
|
599
|
+
this.reporter.report(diagnostic);
|
|
600
|
+
return diagnostic;
|
|
601
|
+
}
|
|
602
|
+
warn(input) {
|
|
603
|
+
return this.report({ ...input, severity: 2 /* Warning */ });
|
|
604
|
+
}
|
|
605
|
+
error(input) {
|
|
606
|
+
return this.report({ ...input, severity: 3 /* Error */ });
|
|
607
|
+
}
|
|
608
|
+
info(input) {
|
|
609
|
+
return this.report({ ...input, severity: 1 /* Info */ });
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
// ../../lib/diagnostics/src/formatter.ts
|
|
614
|
+
function formatDiagnostic(diagnostic) {
|
|
615
|
+
const level = Severity[diagnostic.severity];
|
|
616
|
+
const category = DiagnosticCategory[diagnostic.category];
|
|
617
|
+
const prefix = category !== void 0 ? `[${category}] ` : "";
|
|
618
|
+
return `${level} ${diagnostic.code}: ${prefix}${diagnostic.message}`;
|
|
693
619
|
}
|
|
620
|
+
|
|
621
|
+
// ../../lib/diagnostics/src/console-reporter.ts
|
|
622
|
+
var ConsoleReporter = class {
|
|
623
|
+
report(diagnostic) {
|
|
624
|
+
const message = formatDiagnostic(diagnostic);
|
|
625
|
+
switch (diagnostic.severity) {
|
|
626
|
+
case 0 /* Debug */:
|
|
627
|
+
console.debug(message);
|
|
628
|
+
break;
|
|
629
|
+
case 1 /* Info */:
|
|
630
|
+
console.info(message);
|
|
631
|
+
break;
|
|
632
|
+
case 2 /* Warning */:
|
|
633
|
+
console.warn(message);
|
|
634
|
+
break;
|
|
635
|
+
case 3 /* Error */:
|
|
636
|
+
case 4 /* Fatal */:
|
|
637
|
+
console.error(message);
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
// ../../lib/diagnostics/src/null-reporter.ts
|
|
644
|
+
var nullReporter = {
|
|
645
|
+
report() {
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
// ../../lib/diagnostics/src/presets.ts
|
|
650
|
+
var ignoreAllPolicy = {
|
|
651
|
+
resolve(_) {
|
|
652
|
+
return 0 /* Ignore */;
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
var warnOnlyReporter = {
|
|
656
|
+
report(diagnostic) {
|
|
657
|
+
console.warn(formatDiagnostic(diagnostic));
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
var silentDiagnostics = new Diagnostics(nullReporter, ignoreAllPolicy);
|
|
661
|
+
var warnDiagnostics = new Diagnostics(
|
|
662
|
+
warnOnlyReporter,
|
|
663
|
+
new DefaultPolicy({ reportThreshold: 2 /* Warning */, throwThreshold: 4 /* Fatal */ })
|
|
664
|
+
);
|
|
665
|
+
var throwDiagnostics = new Diagnostics(
|
|
666
|
+
new ConsoleReporter(),
|
|
667
|
+
new DefaultPolicy({ reportThreshold: 2 /* Warning */, throwThreshold: 3 /* Error */ })
|
|
668
|
+
);
|
|
669
|
+
|
|
670
|
+
// ../../lib/contract/src/diagnostics/aria.ts
|
|
671
|
+
var AriaDiagnostics = {
|
|
672
|
+
/** Generic bridge for violations produced by external AriaRule functions. */
|
|
673
|
+
fromViolation(v) {
|
|
674
|
+
return {
|
|
675
|
+
code: "ARIA2002" /* AriaViolation */,
|
|
676
|
+
category: 2 /* ARIA */,
|
|
677
|
+
message: v.message
|
|
678
|
+
};
|
|
679
|
+
},
|
|
680
|
+
attributeInvalid(key, role) {
|
|
681
|
+
return {
|
|
682
|
+
code: "ARIA2003" /* AriaAttributeInvalid */,
|
|
683
|
+
category: 2 /* ARIA */,
|
|
684
|
+
message: `"${key}" is not valid on role="${role}". It will be removed.`,
|
|
685
|
+
rationale: "Invalid ARIA attributes are ignored by assistive technology and may trigger accessibility-tree warnings in browser devtools.",
|
|
686
|
+
suggestions: [
|
|
687
|
+
{
|
|
688
|
+
title: "Remove the attribute",
|
|
689
|
+
description: `"${key}" is not in the allowed attribute set for role="${role}".`
|
|
690
|
+
}
|
|
691
|
+
]
|
|
692
|
+
};
|
|
693
|
+
},
|
|
694
|
+
missingLiveRegion(role, impliedLive) {
|
|
695
|
+
return {
|
|
696
|
+
code: "ARIA2004" /* AriaMissingLiveRegion */,
|
|
697
|
+
category: 2 /* ARIA */,
|
|
698
|
+
message: `role="${role}" implies aria-live="${impliedLive}" but it is missing. It has been injected.`,
|
|
699
|
+
rationale: "Live-region roles announce dynamic content changes to screen readers. Without aria-live the politeness level is unspecified and announcements may be silent.",
|
|
700
|
+
suggestions: [
|
|
701
|
+
{
|
|
702
|
+
title: `Add aria-live="${impliedLive}"`,
|
|
703
|
+
description: `role="${role}" conventionally implies aria-live="${impliedLive}".`,
|
|
704
|
+
fix: `aria-live="${impliedLive}"`
|
|
705
|
+
}
|
|
706
|
+
]
|
|
707
|
+
};
|
|
708
|
+
},
|
|
709
|
+
missingAtomic(role) {
|
|
710
|
+
return {
|
|
711
|
+
code: "ARIA2005" /* AriaMissingAtomic */,
|
|
712
|
+
category: 2 /* ARIA */,
|
|
713
|
+
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.`,
|
|
714
|
+
rationale: "aria-atomic controls whether assistive technology announces the entire live region or only the changed nodes. Omitting it leaves the behaviour browser-defined."
|
|
715
|
+
};
|
|
716
|
+
},
|
|
717
|
+
relevantInvalidTokens(invalid) {
|
|
718
|
+
const quoted = invalid.map((t) => `"${t}"`).join(", ");
|
|
719
|
+
return {
|
|
720
|
+
code: "ARIA2006" /* AriaRelevantInvalidToken */,
|
|
721
|
+
category: 2 /* ARIA */,
|
|
722
|
+
message: `aria-relevant contains invalid token(s): ${quoted}. Valid tokens are: additions, removals, text, all.`,
|
|
723
|
+
rationale: "aria-relevant accepts a space-separated list of change types. Unrecognised tokens are silently ignored by assistive technology, making the attribute ineffective.",
|
|
724
|
+
suggestions: [
|
|
725
|
+
{
|
|
726
|
+
title: "Use only valid tokens",
|
|
727
|
+
description: "Valid values are: additions, removals, text, all (or a space-separated combination)."
|
|
728
|
+
}
|
|
729
|
+
]
|
|
730
|
+
};
|
|
731
|
+
},
|
|
732
|
+
relevantSuperseded() {
|
|
733
|
+
return {
|
|
734
|
+
code: "ARIA2007" /* AriaRelevantSuperseded */,
|
|
735
|
+
category: 2 /* ARIA */,
|
|
736
|
+
message: 'aria-relevant includes "all" alongside other tokens. "all" supersedes additions, removals, and text \u2014 use aria-relevant="all" alone.',
|
|
737
|
+
rationale: '"all" is equivalent to "additions removals text". Combining it with other tokens is redundant and may confuse readers of the markup.',
|
|
738
|
+
suggestions: [
|
|
739
|
+
{
|
|
740
|
+
title: 'Use aria-relevant="all"',
|
|
741
|
+
fix: 'aria-relevant="all"'
|
|
742
|
+
}
|
|
743
|
+
]
|
|
744
|
+
};
|
|
745
|
+
},
|
|
746
|
+
missingAccessibleName(tag) {
|
|
747
|
+
return {
|
|
748
|
+
code: "ARIA2009" /* AriaMissingAccessibleName */,
|
|
749
|
+
category: 2 /* ARIA */,
|
|
750
|
+
message: `<${tag}> has no accessible name. Add aria-label or aria-labelledby.`,
|
|
751
|
+
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.",
|
|
752
|
+
suggestions: [
|
|
753
|
+
{
|
|
754
|
+
title: "Add aria-label",
|
|
755
|
+
description: `Add aria-label="\u2026" directly to the <${tag}> element.`
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
title: "Add aria-labelledby",
|
|
759
|
+
description: "Point aria-labelledby at the id of an existing heading or label element."
|
|
760
|
+
}
|
|
761
|
+
]
|
|
762
|
+
};
|
|
763
|
+
},
|
|
764
|
+
attributeOnPresentational(attr, tag) {
|
|
765
|
+
return {
|
|
766
|
+
code: "ARIA2010" /* AriaAttributeOnPresentational */,
|
|
767
|
+
category: 2 /* ARIA */,
|
|
768
|
+
message: `"${attr}" is not allowed on a presentational <${tag}>. Presentational elements are invisible to assistive technology.`,
|
|
769
|
+
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.',
|
|
770
|
+
suggestions: [
|
|
771
|
+
{
|
|
772
|
+
title: "Remove the attribute",
|
|
773
|
+
description: `"${attr}" has no effect when the element has role="none" or role="presentation".`
|
|
774
|
+
}
|
|
775
|
+
]
|
|
776
|
+
};
|
|
777
|
+
},
|
|
778
|
+
ariaHiddenOnFocusable(tag) {
|
|
779
|
+
return {
|
|
780
|
+
code: "ARIA2011" /* AriaHiddenOnFocusable */,
|
|
781
|
+
category: 2 /* ARIA */,
|
|
782
|
+
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.`,
|
|
783
|
+
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.',
|
|
784
|
+
suggestions: [
|
|
785
|
+
{
|
|
786
|
+
title: "Remove aria-hidden",
|
|
787
|
+
description: "If the element should be hidden from all users, use the HTML hidden attribute or CSS display:none instead."
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
title: "Make the element non-focusable",
|
|
791
|
+
description: 'If the element is intentionally decorative, add tabindex="-1" and disable it so it is not reachable by keyboard.'
|
|
792
|
+
}
|
|
793
|
+
]
|
|
794
|
+
};
|
|
795
|
+
},
|
|
796
|
+
invalidAttributeValue(attr, value, expected) {
|
|
797
|
+
const got = value === null ? "null" : value === void 0 ? "undefined" : typeof value === "string" ? `"${value}"` : String(value);
|
|
798
|
+
return {
|
|
799
|
+
code: "ARIA2013" /* AriaInvalidAttributeValue */,
|
|
800
|
+
category: 2 /* ARIA */,
|
|
801
|
+
message: `"${attr}" has an invalid value (${got}). Expected: ${expected}.`,
|
|
802
|
+
rationale: "ARIA attributes with invalid values are silently ignored by assistive technology, making the markup semantically inert.",
|
|
803
|
+
suggestions: [
|
|
804
|
+
{
|
|
805
|
+
title: `Use a valid value for ${attr}`,
|
|
806
|
+
description: `Valid values are: ${expected}.`
|
|
807
|
+
}
|
|
808
|
+
]
|
|
809
|
+
};
|
|
810
|
+
},
|
|
811
|
+
redundantAriaLevel(tag, level) {
|
|
812
|
+
return {
|
|
813
|
+
code: "ARIA2014" /* AriaRedundantLevelAttribute */,
|
|
814
|
+
category: 2 /* ARIA */,
|
|
815
|
+
message: `aria-level="${level}" is redundant on <${tag}>: the element already has an implicit heading level of ${level}. Remove the attribute.`,
|
|
816
|
+
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>).',
|
|
817
|
+
suggestions: [
|
|
818
|
+
{
|
|
819
|
+
title: "Remove aria-level",
|
|
820
|
+
description: `<${tag}> already implies aria-level="${level}".`
|
|
821
|
+
}
|
|
822
|
+
]
|
|
823
|
+
};
|
|
824
|
+
},
|
|
825
|
+
requiredProperty(attr, role) {
|
|
826
|
+
return {
|
|
827
|
+
code: "ARIA2012" /* AriaRequiredProperty */,
|
|
828
|
+
category: 2 /* ARIA */,
|
|
829
|
+
message: `"${attr}" is required for role="${role}" but is missing.`,
|
|
830
|
+
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.`,
|
|
831
|
+
suggestions: [
|
|
832
|
+
{
|
|
833
|
+
title: `Add ${attr}`,
|
|
834
|
+
description: `role="${role}" requires "${attr}" to be present.`
|
|
835
|
+
}
|
|
836
|
+
]
|
|
837
|
+
};
|
|
838
|
+
},
|
|
839
|
+
invalidRole(role, tag) {
|
|
840
|
+
return {
|
|
841
|
+
code: "ARIA2008" /* AriaInvalidRole */,
|
|
842
|
+
category: 2 /* ARIA */,
|
|
843
|
+
message: `Invalid role "${role ?? ""}" on <${tag}>.`,
|
|
844
|
+
rationale: "An unrecognised or misapplied ARIA role is ignored by assistive technology and may degrade the accessibility of the element."
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
// ../../lib/contract/src/diagnostics/contract.ts
|
|
850
|
+
var ContractDiagnostics = {
|
|
851
|
+
unexpectedChild(typeName, index, context) {
|
|
852
|
+
return {
|
|
853
|
+
code: "COMP1004" /* UnexpectedChild */,
|
|
854
|
+
category: 0 /* Contract */,
|
|
855
|
+
component: context,
|
|
856
|
+
message: `${context}: unexpected child "${typeName}" at index ${index}.`
|
|
857
|
+
};
|
|
858
|
+
},
|
|
859
|
+
ambiguousChild(typeName, index, ruleNames, context) {
|
|
860
|
+
const quoted = ruleNames.map((n) => `"${n}"`).join(" and ");
|
|
861
|
+
return {
|
|
862
|
+
code: "COMP1005" /* AmbiguousChild */,
|
|
863
|
+
category: 0 /* Contract */,
|
|
864
|
+
component: context,
|
|
865
|
+
message: `${context}: child "${typeName}" at index ${index} matches multiple child rules: ${quoted}.`
|
|
866
|
+
};
|
|
867
|
+
},
|
|
868
|
+
cardinalityMin(ruleName, min, context) {
|
|
869
|
+
return {
|
|
870
|
+
code: "COMP1006" /* CardinalityMin */,
|
|
871
|
+
category: 0 /* Contract */,
|
|
872
|
+
component: context,
|
|
873
|
+
message: `${context}: "${ruleName}" requires at least ${min}.`
|
|
874
|
+
};
|
|
875
|
+
},
|
|
876
|
+
cardinalityMax(ruleName, max, context) {
|
|
877
|
+
return {
|
|
878
|
+
code: "COMP1007" /* CardinalityMax */,
|
|
879
|
+
category: 0 /* Contract */,
|
|
880
|
+
component: context,
|
|
881
|
+
message: `${context}: "${ruleName}" allows at most ${max}.`
|
|
882
|
+
};
|
|
883
|
+
},
|
|
884
|
+
positionViolation(ruleName, position, index, context) {
|
|
885
|
+
return {
|
|
886
|
+
code: "COMP1008" /* PositionViolation */,
|
|
887
|
+
category: 0 /* Contract */,
|
|
888
|
+
component: context,
|
|
889
|
+
message: `${context}: "${ruleName}" must be ${position}, got index ${index}`
|
|
890
|
+
};
|
|
891
|
+
},
|
|
892
|
+
unknownVariantDim(component, label2, dim) {
|
|
893
|
+
return {
|
|
894
|
+
code: "COMP1010" /* ContractUnknownVariantDim */,
|
|
895
|
+
category: 0 /* Contract */,
|
|
896
|
+
message: `${component}: ${label2} references unknown variant "${dim}".`
|
|
897
|
+
};
|
|
898
|
+
},
|
|
899
|
+
unknownVariantValue(component, label2, dim, value, valid) {
|
|
900
|
+
return {
|
|
901
|
+
code: "COMP1011" /* ContractUnknownVariantValue */,
|
|
902
|
+
category: 0 /* Contract */,
|
|
903
|
+
message: `${component}: ${label2} sets "${dim}" to unknown value "${value}" (valid: ${valid.join(", ")}).`
|
|
904
|
+
};
|
|
905
|
+
},
|
|
906
|
+
unknownRecipeKey(component, key) {
|
|
907
|
+
return {
|
|
908
|
+
code: "COMP1012" /* ContractUnknownRecipeKey */,
|
|
909
|
+
category: 0 /* Contract */,
|
|
910
|
+
message: `${component} Unknown recipeKey "${key}" \u2014 no preset with that name exists.`
|
|
911
|
+
};
|
|
912
|
+
},
|
|
913
|
+
invalidVariantValue(component, key, value) {
|
|
914
|
+
return {
|
|
915
|
+
code: "COMP1013" /* ContractInvalidVariantValue */,
|
|
916
|
+
category: 0 /* Contract */,
|
|
917
|
+
message: `${component} Variant "${key}=${value}" is not a defined value for the "${key}" dimension.`
|
|
918
|
+
};
|
|
919
|
+
},
|
|
920
|
+
allowedAsViolation(tag, allowedAs, component) {
|
|
921
|
+
const allowed = allowedAs.map((t) => `"${String(t)}"`).join(", ");
|
|
922
|
+
return {
|
|
923
|
+
code: "COMP1009" /* AllowedAsViolation */,
|
|
924
|
+
category: 0 /* Contract */,
|
|
925
|
+
component,
|
|
926
|
+
message: `<${component}>: "as" prop received "${tag}" but only [${allowed}] are allowed.`
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
// ../../lib/contract/src/diagnostics/html.ts
|
|
932
|
+
var HtmlDiagnostics = {
|
|
933
|
+
emptyRole(tag) {
|
|
934
|
+
return {
|
|
935
|
+
code: "HTML3002" /* HtmlEmptyRole */,
|
|
936
|
+
category: 1 /* HTML */,
|
|
937
|
+
message: `<${tag}> has an explicit empty role="". Omit the attribute instead.`
|
|
938
|
+
};
|
|
939
|
+
},
|
|
940
|
+
implicitRoleRedundant(tag, implicitRole) {
|
|
941
|
+
return {
|
|
942
|
+
code: "HTML3003" /* HtmlImplicitRoleRedundant */,
|
|
943
|
+
category: 1 /* HTML */,
|
|
944
|
+
message: `<${tag}> already has implicit role="${implicitRole}". Avoid redundant role assignment.`
|
|
945
|
+
};
|
|
946
|
+
},
|
|
947
|
+
implicitRoleOverride(tag, implicitRole, role) {
|
|
948
|
+
return {
|
|
949
|
+
code: "HTML3004" /* HtmlImplicitRoleOverride */,
|
|
950
|
+
category: 1 /* HTML */,
|
|
951
|
+
message: `<${tag}> should not override its implicit role="${implicitRole}" with role="${role}".`
|
|
952
|
+
};
|
|
953
|
+
},
|
|
954
|
+
standaloneRegionOverride(tag, implicitRole) {
|
|
955
|
+
return {
|
|
956
|
+
code: "HTML3005" /* HtmlStandaloneRegionOverride */,
|
|
957
|
+
category: 1 /* HTML */,
|
|
958
|
+
message: `<${tag}> is a self-contained element with implicit role="${implicitRole}". Assigning role="region" has been removed.`
|
|
959
|
+
};
|
|
960
|
+
},
|
|
961
|
+
landmarkRoleOverride(tag, implicitRole, role) {
|
|
962
|
+
return {
|
|
963
|
+
code: "HTML3006" /* HtmlLandmarkRoleOverride */,
|
|
964
|
+
category: 1 /* HTML */,
|
|
965
|
+
message: `<${tag}> has a fixed landmark role="${implicitRole}". role="${role}" overrides it and confuses assistive technology. The override has been removed.`
|
|
966
|
+
};
|
|
967
|
+
},
|
|
968
|
+
invalidChild(child, parent, allowed) {
|
|
969
|
+
return {
|
|
970
|
+
code: "HTML3007" /* HtmlInvalidChild */,
|
|
971
|
+
category: 1 /* HTML */,
|
|
972
|
+
message: `<${child}> is not a valid direct child of <${parent}>. Allowed: ${allowed}.`
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
};
|
|
976
|
+
|
|
977
|
+
// ../../lib/contract/src/aria/polymorphic-validator.ts
|
|
694
978
|
var VALID = [{ valid: true }];
|
|
695
979
|
function isIntrinsicTag(tag) {
|
|
696
980
|
return isString(tag);
|
|
@@ -699,26 +983,28 @@ function omitProp(obj, key) {
|
|
|
699
983
|
const { [key]: _, ...rest } = obj;
|
|
700
984
|
return rest;
|
|
701
985
|
}
|
|
702
|
-
var AriaPolicyEngine = class _AriaPolicyEngine extends
|
|
986
|
+
var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
703
987
|
#extraRules;
|
|
704
988
|
#planCache = /* @__PURE__ */ new Map();
|
|
705
989
|
static #MAX_CACHE = 100;
|
|
706
990
|
// Memoized AriaFix objects keyed by attribute name — the ARIA attribute set is
|
|
707
991
|
// finite so this Map is bounded and avoids recreating closures on every cache miss.
|
|
708
992
|
static #removeAttributeFixCache = /* @__PURE__ */ new Map();
|
|
709
|
-
constructor(
|
|
710
|
-
super(
|
|
993
|
+
constructor(diagnostics, options) {
|
|
994
|
+
super(diagnostics);
|
|
711
995
|
this.#extraRules = options?.rules ?? [];
|
|
712
996
|
}
|
|
713
997
|
static #normalizeEmptyRole(tag, props) {
|
|
714
998
|
if (props.role !== "") return { normalized: false };
|
|
999
|
+
const d = HtmlDiagnostics.emptyRole(tag);
|
|
715
1000
|
return {
|
|
716
1001
|
normalized: true,
|
|
717
1002
|
result: {
|
|
718
1003
|
props: omitProp(props, "role"),
|
|
719
1004
|
violations: [
|
|
720
1005
|
{
|
|
721
|
-
message:
|
|
1006
|
+
message: d.message,
|
|
1007
|
+
diagnostic: d,
|
|
722
1008
|
tag,
|
|
723
1009
|
role: "",
|
|
724
1010
|
attribute: void 0,
|
|
@@ -731,10 +1017,9 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
731
1017
|
}
|
|
732
1018
|
static #deriveContext(tag, props) {
|
|
733
1019
|
if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
|
|
734
|
-
const implicitRole = getImplicitRole(tag);
|
|
735
|
-
const
|
|
736
|
-
if (!
|
|
737
|
-
return { proceed: false, result: { props, violations: [] } };
|
|
1020
|
+
const implicitRole = getImplicitRole(tag, props);
|
|
1021
|
+
const hasRole = implicitRole != null || isString(props.role) && props.role.length > 0;
|
|
1022
|
+
if (!hasRole) return { proceed: false, result: { props, violations: [] } };
|
|
738
1023
|
const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
|
|
739
1024
|
if (normalized.normalized) return { proceed: false, result: normalized.result };
|
|
740
1025
|
const effectiveRole = props.role ?? implicitRole;
|
|
@@ -749,25 +1034,36 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
749
1034
|
static #runRules(rules, context) {
|
|
750
1035
|
const violations = [];
|
|
751
1036
|
const fixes = [];
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
if (
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1037
|
+
iterate.forEach(rules, (rule) => {
|
|
1038
|
+
iterate.forEach(rule(context), (result) => {
|
|
1039
|
+
if (result.valid) return;
|
|
1040
|
+
const {
|
|
1041
|
+
tag,
|
|
1042
|
+
props: { role }
|
|
1043
|
+
} = context;
|
|
1044
|
+
const { message, attribute, severity } = result;
|
|
1045
|
+
const resolvedMessage = message ?? result.diagnostic?.message;
|
|
1046
|
+
const fallbackDiag = resolvedMessage == null ? AriaDiagnostics.invalidRole(role, tag) : void 0;
|
|
1047
|
+
violations.push({
|
|
1048
|
+
message: resolvedMessage ?? fallbackDiag.message,
|
|
1049
|
+
tag,
|
|
1050
|
+
role,
|
|
1051
|
+
attribute,
|
|
1052
|
+
severity,
|
|
1053
|
+
phase: "evaluate",
|
|
1054
|
+
...result.diagnostic != null && { diagnostic: result.diagnostic },
|
|
1055
|
+
...fallbackDiag != null && { diagnostic: fallbackDiag }
|
|
1056
|
+
});
|
|
1057
|
+
if (result.fixable) fixes.push(result.fix);
|
|
1058
|
+
});
|
|
1059
|
+
});
|
|
767
1060
|
return { violations, fixes };
|
|
768
1061
|
}
|
|
769
1062
|
static #getRules(context) {
|
|
770
|
-
|
|
1063
|
+
if (_AriaPolicyEngine.#hasRole(context.props) || context.effectiveRole != null && _AriaPolicyEngine.#LIVE_REGION_ROLES.has(context.effectiveRole)) {
|
|
1064
|
+
return _AriaPolicyEngine.#pipeline;
|
|
1065
|
+
}
|
|
1066
|
+
return _AriaPolicyEngine.#implicitOnlyRules;
|
|
771
1067
|
}
|
|
772
1068
|
static evaluate(tag, props) {
|
|
773
1069
|
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
@@ -792,10 +1088,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
792
1088
|
return { props: next, violations };
|
|
793
1089
|
}
|
|
794
1090
|
report(violations) {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
1091
|
+
iterate.forEach(violations, (v) => {
|
|
1092
|
+
const d = v.diagnostic ?? AriaDiagnostics.fromViolation(v);
|
|
1093
|
+
if (v.severity === "error") this.violate(d);
|
|
1094
|
+
else this.warn(d);
|
|
1095
|
+
});
|
|
799
1096
|
}
|
|
800
1097
|
// Cache key covers only the aria-relevant subset of props (tag + role + aria-* attrs).
|
|
801
1098
|
// Non-aria props (className, onClick, etc.) do not affect ARIA decisions and are excluded
|
|
@@ -807,27 +1104,26 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
807
1104
|
if (!isIntrinsicTag(tag)) return null;
|
|
808
1105
|
const parts = [tag];
|
|
809
1106
|
if (typeof props.role === "string") parts.push(`role:${props.role}`);
|
|
1107
|
+
if (tag === "input" && typeof props.type === "string") parts.push(`type:${props.type}`);
|
|
1108
|
+
if (tag === "img") parts.push(`alt:${props.alt === "" ? "empty" : "present"}`);
|
|
810
1109
|
const ariaEntries = [];
|
|
811
|
-
|
|
812
|
-
if (!
|
|
813
|
-
|
|
814
|
-
if (!isString(v) && !isNumber(v) && typeof v !== "boolean") continue;
|
|
1110
|
+
iterate.forEachEntry(props, (k, v) => {
|
|
1111
|
+
if (!k.startsWith("aria-")) return;
|
|
1112
|
+
if (!isString(v) && !isNumber(v) && typeof v !== "boolean") return;
|
|
815
1113
|
ariaEntries.push(`${k}:${String(v)}`);
|
|
816
|
-
}
|
|
1114
|
+
});
|
|
817
1115
|
if (ariaEntries.length > 0) parts.push(...ariaEntries.sort());
|
|
818
1116
|
return parts.join("|");
|
|
819
1117
|
}
|
|
820
1118
|
static #computePlan(inputProps, resultProps) {
|
|
821
1119
|
const removals = /* @__PURE__ */ new Set();
|
|
822
1120
|
const updates = {};
|
|
823
|
-
|
|
824
|
-
if (
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
if (!Object.hasOwn(resultProps, key)) continue;
|
|
828
|
-
const resultVal = resultProps[key];
|
|
1121
|
+
iterate.forEachKey(inputProps, (key) => {
|
|
1122
|
+
if (!(key in resultProps)) removals.add(key);
|
|
1123
|
+
});
|
|
1124
|
+
iterate.forEachEntry(resultProps, (key, resultVal) => {
|
|
829
1125
|
if (inputProps[key] !== resultVal) updates[key] = resultVal;
|
|
830
|
-
}
|
|
1126
|
+
});
|
|
831
1127
|
return { removals, updates };
|
|
832
1128
|
}
|
|
833
1129
|
static #applyPlan(props, removals, updates) {
|
|
@@ -835,15 +1131,15 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
835
1131
|
const hasUpdates = Object.keys(updates).length > 0;
|
|
836
1132
|
if (!hasRemovals && !hasUpdates) return props;
|
|
837
1133
|
const next = {};
|
|
838
|
-
|
|
839
|
-
if (
|
|
840
|
-
}
|
|
1134
|
+
iterate.forEachEntry(props, (k, v) => {
|
|
1135
|
+
if (!removals.has(k)) next[k] = v;
|
|
1136
|
+
});
|
|
841
1137
|
Object.assign(next, updates);
|
|
842
1138
|
return next;
|
|
843
1139
|
}
|
|
844
1140
|
validate(tag, props) {
|
|
845
1141
|
const key = _AriaPolicyEngine.#createPlanKey(tag, props);
|
|
846
|
-
if (!
|
|
1142
|
+
if (!isNull(key)) {
|
|
847
1143
|
const cached = this.#planCache.get(key);
|
|
848
1144
|
if (cached !== void 0) {
|
|
849
1145
|
this.#planCache.delete(key);
|
|
@@ -857,7 +1153,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
857
1153
|
}
|
|
858
1154
|
const result = this.#extraRules.length ? _AriaPolicyEngine.#evaluateWithRules(tag, props, this.#extraRules) : _AriaPolicyEngine.evaluate(tag, props);
|
|
859
1155
|
if (result.violations.length > 0) this.report(result.violations);
|
|
860
|
-
if (!
|
|
1156
|
+
if (!isNull(key)) {
|
|
861
1157
|
const { removals, updates } = _AriaPolicyEngine.#computePlan(
|
|
862
1158
|
props,
|
|
863
1159
|
result.props
|
|
@@ -878,12 +1174,12 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
878
1174
|
if (fixes.length === 0) return props;
|
|
879
1175
|
const sorted = [...fixes].sort((a, b) => (a.priority ?? Infinity) - (b.priority ?? Infinity));
|
|
880
1176
|
let next = props;
|
|
881
|
-
|
|
1177
|
+
iterate.forEach(sorted, ({ apply }) => {
|
|
882
1178
|
const effectiveRole = next.role ?? implicitRole;
|
|
883
1179
|
const fixContext = { tag, implicitRole, effectiveRole, props: next };
|
|
884
1180
|
const fixResult = apply(fixContext);
|
|
885
1181
|
if (fixResult.applied) next = fixResult.next;
|
|
886
|
-
}
|
|
1182
|
+
});
|
|
887
1183
|
return next;
|
|
888
1184
|
}
|
|
889
1185
|
static #removeRole = {
|
|
@@ -911,10 +1207,26 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
911
1207
|
_AriaPolicyEngine.#checkInvalidRoleOverride,
|
|
912
1208
|
_AriaPolicyEngine.#checkRedundantRole,
|
|
913
1209
|
_AriaPolicyEngine.#checkStandaloneRegion,
|
|
1210
|
+
_AriaPolicyEngine.#checkAriaAttributeValues,
|
|
914
1211
|
_AriaPolicyEngine.#checkInvalidAriaAttributes,
|
|
1212
|
+
_AriaPolicyEngine.#checkRequiredAriaProperties,
|
|
1213
|
+
_AriaPolicyEngine.#checkNameRequiredRoles,
|
|
1214
|
+
_AriaPolicyEngine.#checkRedundantAriaLevel,
|
|
915
1215
|
_AriaPolicyEngine.#checkMissingLiveRegion,
|
|
916
1216
|
_AriaPolicyEngine.#checkMissingAtomic,
|
|
917
|
-
_AriaPolicyEngine.#checkInvalidAriaRelevant
|
|
1217
|
+
_AriaPolicyEngine.#checkInvalidAriaRelevant,
|
|
1218
|
+
_AriaPolicyEngine.#checkAriaHiddenOnFocusable,
|
|
1219
|
+
_AriaPolicyEngine.#checkPresentationalAriaAttributes
|
|
1220
|
+
];
|
|
1221
|
+
// Rules for elements with an implicit role but no explicit role (not a live region).
|
|
1222
|
+
static #implicitOnlyRules = [
|
|
1223
|
+
_AriaPolicyEngine.#checkAriaAttributeValues,
|
|
1224
|
+
_AriaPolicyEngine.#checkInvalidAriaAttributes,
|
|
1225
|
+
_AriaPolicyEngine.#checkRequiredAriaProperties,
|
|
1226
|
+
_AriaPolicyEngine.#checkNameRequiredRoles,
|
|
1227
|
+
_AriaPolicyEngine.#checkRedundantAriaLevel,
|
|
1228
|
+
_AriaPolicyEngine.#checkAriaHiddenOnFocusable,
|
|
1229
|
+
_AriaPolicyEngine.#checkPresentationalAriaAttributes
|
|
918
1230
|
];
|
|
919
1231
|
static #checkInvalidRoleOverride({
|
|
920
1232
|
tag,
|
|
@@ -930,7 +1242,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
930
1242
|
fixable: true,
|
|
931
1243
|
severity: "error",
|
|
932
1244
|
fix: _AriaPolicyEngine.#removeRole,
|
|
933
|
-
|
|
1245
|
+
diagnostic: HtmlDiagnostics.implicitRoleOverride(tag, implicitRole, role)
|
|
934
1246
|
}
|
|
935
1247
|
];
|
|
936
1248
|
}
|
|
@@ -944,45 +1256,302 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
944
1256
|
valid: false,
|
|
945
1257
|
fixable: true,
|
|
946
1258
|
severity: "warning",
|
|
947
|
-
fix: _AriaPolicyEngine.#removeRole,
|
|
948
|
-
|
|
1259
|
+
fix: _AriaPolicyEngine.#removeRole,
|
|
1260
|
+
diagnostic: HtmlDiagnostics.implicitRoleRedundant(tag, implicitRole)
|
|
1261
|
+
}
|
|
1262
|
+
];
|
|
1263
|
+
}
|
|
1264
|
+
static #checkStandaloneRegion({ tag, props, implicitRole }) {
|
|
1265
|
+
const role = props.role;
|
|
1266
|
+
if (role !== "region") return VALID;
|
|
1267
|
+
if (!isStandaloneTag(tag)) return VALID;
|
|
1268
|
+
return [
|
|
1269
|
+
{
|
|
1270
|
+
valid: false,
|
|
1271
|
+
fixable: true,
|
|
1272
|
+
severity: "error",
|
|
1273
|
+
fix: _AriaPolicyEngine.#removeRole,
|
|
1274
|
+
diagnostic: HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag)
|
|
1275
|
+
}
|
|
1276
|
+
];
|
|
1277
|
+
}
|
|
1278
|
+
static #checkInvalidAriaAttributes({
|
|
1279
|
+
tag,
|
|
1280
|
+
props,
|
|
1281
|
+
effectiveRole
|
|
1282
|
+
}) {
|
|
1283
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
|
|
1284
|
+
const results = [];
|
|
1285
|
+
iterate.forEachEntry(props, (key) => {
|
|
1286
|
+
if (!key.startsWith("aria-")) return;
|
|
1287
|
+
if (isGlobalAriaAttribute(key)) return;
|
|
1288
|
+
if (isAriaAttributeValidForRole(key, effectiveRole)) return;
|
|
1289
|
+
results.push({
|
|
1290
|
+
valid: false,
|
|
1291
|
+
severity: "warning",
|
|
1292
|
+
fixable: true,
|
|
1293
|
+
attribute: key,
|
|
1294
|
+
diagnostic: AriaDiagnostics.attributeInvalid(key, effectiveRole ?? tag),
|
|
1295
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix(key)
|
|
1296
|
+
});
|
|
1297
|
+
});
|
|
1298
|
+
return results;
|
|
1299
|
+
}
|
|
1300
|
+
// ─── ARIA attribute value validation ──────────────────────────────────────
|
|
1301
|
+
// Accepted value shapes for typed ARIA attributes.
|
|
1302
|
+
// Attributes not in this map are unconstrained (arbitrary string values permitted).
|
|
1303
|
+
static #ARIA_VALUE_TYPES = /* @__PURE__ */ new Map([
|
|
1304
|
+
// Boolean (true | false)
|
|
1305
|
+
["aria-atomic", { kind: "boolean" }],
|
|
1306
|
+
["aria-busy", { kind: "boolean" }],
|
|
1307
|
+
["aria-disabled", { kind: "boolean" }],
|
|
1308
|
+
["aria-expanded", { kind: "boolean" }],
|
|
1309
|
+
["aria-hidden", { kind: "boolean" }],
|
|
1310
|
+
["aria-modal", { kind: "boolean" }],
|
|
1311
|
+
["aria-multiline", { kind: "boolean" }],
|
|
1312
|
+
["aria-multiselectable", { kind: "boolean" }],
|
|
1313
|
+
["aria-readonly", { kind: "boolean" }],
|
|
1314
|
+
["aria-required", { kind: "boolean" }],
|
|
1315
|
+
["aria-selected", { kind: "boolean" }],
|
|
1316
|
+
// Tristate (true | false | mixed)
|
|
1317
|
+
["aria-checked", { kind: "tristate" }],
|
|
1318
|
+
["aria-pressed", { kind: "tristate" }],
|
|
1319
|
+
// Numeric (any finite number)
|
|
1320
|
+
["aria-valuenow", { kind: "number" }],
|
|
1321
|
+
["aria-valuemin", { kind: "number" }],
|
|
1322
|
+
["aria-valuemax", { kind: "number" }],
|
|
1323
|
+
// Integer with optional range
|
|
1324
|
+
["aria-level", { kind: "integer", min: 1, max: 6 }],
|
|
1325
|
+
["aria-posinset", { kind: "integer", min: 1 }],
|
|
1326
|
+
["aria-setsize", { kind: "integer", min: -1 }],
|
|
1327
|
+
["aria-rowcount", { kind: "integer", min: -1 }],
|
|
1328
|
+
["aria-colcount", { kind: "integer", min: -1 }],
|
|
1329
|
+
["aria-rowindex", { kind: "integer", min: 1 }],
|
|
1330
|
+
["aria-colindex", { kind: "integer", min: 1 }],
|
|
1331
|
+
["aria-rowspan", { kind: "integer", min: 0 }],
|
|
1332
|
+
["aria-colspan", { kind: "integer", min: 0 }],
|
|
1333
|
+
// Enum (specific allowed tokens)
|
|
1334
|
+
["aria-autocomplete", { kind: "enum", values: /* @__PURE__ */ new Set(["inline", "list", "both", "none"]) }],
|
|
1335
|
+
[
|
|
1336
|
+
"aria-current",
|
|
1337
|
+
{
|
|
1338
|
+
kind: "enum",
|
|
1339
|
+
values: /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"])
|
|
1340
|
+
}
|
|
1341
|
+
],
|
|
1342
|
+
[
|
|
1343
|
+
"aria-haspopup",
|
|
1344
|
+
{
|
|
1345
|
+
kind: "enum",
|
|
1346
|
+
values: /* @__PURE__ */ new Set(["false", "true", "menu", "listbox", "tree", "grid", "dialog"])
|
|
1347
|
+
}
|
|
1348
|
+
],
|
|
1349
|
+
["aria-invalid", { kind: "enum", values: /* @__PURE__ */ new Set(["grammar", "false", "spelling", "true"]) }],
|
|
1350
|
+
["aria-live", { kind: "enum", values: /* @__PURE__ */ new Set(["assertive", "off", "polite"]) }],
|
|
1351
|
+
[
|
|
1352
|
+
"aria-orientation",
|
|
1353
|
+
{ kind: "enum", values: /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]) }
|
|
1354
|
+
],
|
|
1355
|
+
["aria-sort", { kind: "enum", values: /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"]) }]
|
|
1356
|
+
]);
|
|
1357
|
+
static #isValidAriaValue(value, type) {
|
|
1358
|
+
switch (type.kind) {
|
|
1359
|
+
case "boolean":
|
|
1360
|
+
return value === "true" || value === "false" || value === true || value === false;
|
|
1361
|
+
case "tristate":
|
|
1362
|
+
return value === "true" || value === "false" || value === "mixed" || value === true || value === false;
|
|
1363
|
+
case "number": {
|
|
1364
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
1365
|
+
if (typeof value !== "string") return false;
|
|
1366
|
+
const n = parseFloat(value);
|
|
1367
|
+
return Number.isFinite(n);
|
|
1368
|
+
}
|
|
1369
|
+
case "integer": {
|
|
1370
|
+
const n = typeof value === "number" ? value : typeof value === "string" ? parseInt(value, 10) : NaN;
|
|
1371
|
+
if (!Number.isFinite(n) || !Number.isInteger(n)) return false;
|
|
1372
|
+
if (type.min !== void 0 && n < type.min) return false;
|
|
1373
|
+
if (type.max !== void 0 && n > type.max) return false;
|
|
1374
|
+
return true;
|
|
1375
|
+
}
|
|
1376
|
+
case "enum":
|
|
1377
|
+
return typeof value === "string" && type.values.has(value);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
static #describeExpected(type) {
|
|
1381
|
+
switch (type.kind) {
|
|
1382
|
+
case "boolean":
|
|
1383
|
+
return '"true" or "false"';
|
|
1384
|
+
case "tristate":
|
|
1385
|
+
return '"true", "false", or "mixed"';
|
|
1386
|
+
case "number":
|
|
1387
|
+
return "a finite number";
|
|
1388
|
+
case "integer": {
|
|
1389
|
+
const parts = ["an integer"];
|
|
1390
|
+
if (type.min !== void 0 && type.max !== void 0)
|
|
1391
|
+
parts.push(`between ${type.min} and ${type.max}`);
|
|
1392
|
+
else if (type.min !== void 0) parts.push(`\u2265 ${type.min}`);
|
|
1393
|
+
else if (type.max !== void 0) parts.push(`\u2264 ${type.max}`);
|
|
1394
|
+
return parts.join(" ");
|
|
1395
|
+
}
|
|
1396
|
+
case "enum":
|
|
1397
|
+
return [...type.values].map((v) => `"${v}"`).join(", ");
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
static #checkAriaAttributeValues({ props, effectiveRole }) {
|
|
1401
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
|
|
1402
|
+
const results = [];
|
|
1403
|
+
iterate.forEachEntry(props, (key, value) => {
|
|
1404
|
+
if (!key.startsWith("aria-")) return;
|
|
1405
|
+
const type = _AriaPolicyEngine.#ARIA_VALUE_TYPES.get(key);
|
|
1406
|
+
if (type == null) return;
|
|
1407
|
+
if (_AriaPolicyEngine.#isValidAriaValue(value, type)) return;
|
|
1408
|
+
results.push({
|
|
1409
|
+
valid: false,
|
|
1410
|
+
fixable: true,
|
|
1411
|
+
severity: "warning",
|
|
1412
|
+
attribute: key,
|
|
1413
|
+
diagnostic: AriaDiagnostics.invalidAttributeValue(
|
|
1414
|
+
key,
|
|
1415
|
+
value,
|
|
1416
|
+
_AriaPolicyEngine.#describeExpected(type)
|
|
1417
|
+
),
|
|
1418
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix(key)
|
|
1419
|
+
});
|
|
1420
|
+
});
|
|
1421
|
+
return results;
|
|
1422
|
+
}
|
|
1423
|
+
// ─── Heading implicit level ────────────────────────────────────────────────
|
|
1424
|
+
static #HEADING_IMPLICIT_LEVELS = /* @__PURE__ */ new Map([
|
|
1425
|
+
["h1", 1],
|
|
1426
|
+
["h2", 2],
|
|
1427
|
+
["h3", 3],
|
|
1428
|
+
["h4", 4],
|
|
1429
|
+
["h5", 5],
|
|
1430
|
+
["h6", 6]
|
|
1431
|
+
]);
|
|
1432
|
+
static #checkRedundantAriaLevel({
|
|
1433
|
+
tag,
|
|
1434
|
+
props,
|
|
1435
|
+
effectiveRole
|
|
1436
|
+
}) {
|
|
1437
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
|
|
1438
|
+
const implicitLevel = _AriaPolicyEngine.#HEADING_IMPLICIT_LEVELS.get(tag);
|
|
1439
|
+
if (implicitLevel == null) return VALID;
|
|
1440
|
+
const raw = props["aria-level"];
|
|
1441
|
+
if (raw == null) return VALID;
|
|
1442
|
+
const n = typeof raw === "number" ? raw : typeof raw === "string" ? parseInt(raw, 10) : NaN;
|
|
1443
|
+
if (!Number.isFinite(n) || n !== implicitLevel) return VALID;
|
|
1444
|
+
return [
|
|
1445
|
+
{
|
|
1446
|
+
valid: false,
|
|
1447
|
+
fixable: true,
|
|
1448
|
+
severity: "warning",
|
|
1449
|
+
attribute: "aria-level",
|
|
1450
|
+
diagnostic: AriaDiagnostics.redundantAriaLevel(tag, implicitLevel),
|
|
1451
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix("aria-level")
|
|
949
1452
|
}
|
|
950
1453
|
];
|
|
951
1454
|
}
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
1455
|
+
// ─── Name-required roles ───────────────────────────────────────────────────
|
|
1456
|
+
// Roles that always require an accessible name per WAI-ARIA APG.
|
|
1457
|
+
// Dialog and landmark names are enforced via contracts (ariaContract) rather than
|
|
1458
|
+
// the built-in pipeline so consumers can opt in; img is built in because role=img
|
|
1459
|
+
// on any element (including bare <img>) is definitionally useless without a name.
|
|
1460
|
+
static #NAME_REQUIRED_ROLES = /* @__PURE__ */ new Set(["img"]);
|
|
1461
|
+
static #checkNameRequiredRoles({
|
|
1462
|
+
tag,
|
|
1463
|
+
props,
|
|
1464
|
+
effectiveRole
|
|
1465
|
+
}) {
|
|
1466
|
+
if (!effectiveRole || !_AriaPolicyEngine.#NAME_REQUIRED_ROLES.has(effectiveRole)) return VALID;
|
|
1467
|
+
if ("aria-label" in props || "aria-labelledby" in props) return VALID;
|
|
1468
|
+
if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return VALID;
|
|
956
1469
|
return [
|
|
957
1470
|
{
|
|
958
1471
|
valid: false,
|
|
959
|
-
fixable:
|
|
1472
|
+
fixable: false,
|
|
1473
|
+
severity: "warning",
|
|
1474
|
+
diagnostic: AriaDiagnostics.missingAccessibleName(tag)
|
|
1475
|
+
}
|
|
1476
|
+
];
|
|
1477
|
+
}
|
|
1478
|
+
// WAI-ARIA 1.2 required states and properties, keyed by role.
|
|
1479
|
+
// Source: https://www.w3.org/TR/wai-aria-1.2/#requiredState
|
|
1480
|
+
static #REQUIRED_PROPERTIES = /* @__PURE__ */ new Map([
|
|
1481
|
+
["combobox", ["aria-expanded"]],
|
|
1482
|
+
["option", ["aria-selected"]],
|
|
1483
|
+
["slider", ["aria-valuenow"]],
|
|
1484
|
+
["scrollbar", ["aria-controls", "aria-valuenow"]],
|
|
1485
|
+
["spinbutton", ["aria-valuenow"]]
|
|
1486
|
+
]);
|
|
1487
|
+
static #checkRequiredAriaProperties({
|
|
1488
|
+
props,
|
|
1489
|
+
effectiveRole
|
|
1490
|
+
}) {
|
|
1491
|
+
if (!effectiveRole) return VALID;
|
|
1492
|
+
const required = _AriaPolicyEngine.#REQUIRED_PROPERTIES.get(effectiveRole);
|
|
1493
|
+
if (required == null) return VALID;
|
|
1494
|
+
const results = [];
|
|
1495
|
+
iterate.forEach(required, (attr) => {
|
|
1496
|
+
if (attr in props) return;
|
|
1497
|
+
results.push({
|
|
1498
|
+
valid: false,
|
|
1499
|
+
fixable: false,
|
|
1500
|
+
severity: "warning",
|
|
1501
|
+
attribute: attr,
|
|
1502
|
+
diagnostic: AriaDiagnostics.requiredProperty(attr, effectiveRole)
|
|
1503
|
+
});
|
|
1504
|
+
});
|
|
1505
|
+
return results;
|
|
1506
|
+
}
|
|
1507
|
+
// Natively interactive HTML elements — always keyboard-reachable unless explicitly disabled.
|
|
1508
|
+
static #INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
1509
|
+
"a",
|
|
1510
|
+
"button",
|
|
1511
|
+
"input",
|
|
1512
|
+
"select",
|
|
1513
|
+
"textarea"
|
|
1514
|
+
]);
|
|
1515
|
+
// WAI-ARIA 1.2 §6.6: aria-hidden="true" must not be placed on focusable elements.
|
|
1516
|
+
static #checkAriaHiddenOnFocusable({ tag, props }) {
|
|
1517
|
+
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return VALID;
|
|
1518
|
+
const isInteractive = _AriaPolicyEngine.#INTERACTIVE_TAGS.has(tag);
|
|
1519
|
+
if (!isInteractive) {
|
|
1520
|
+
const tabindex = props.tabindex;
|
|
1521
|
+
const n = typeof tabindex === "number" ? tabindex : typeof tabindex === "string" ? parseInt(tabindex, 10) : NaN;
|
|
1522
|
+
if (!Number.isFinite(n) || n < 0) return VALID;
|
|
1523
|
+
}
|
|
1524
|
+
return [
|
|
1525
|
+
{
|
|
1526
|
+
valid: false,
|
|
1527
|
+
fixable: false,
|
|
960
1528
|
severity: "error",
|
|
961
|
-
|
|
962
|
-
|
|
1529
|
+
attribute: "aria-hidden",
|
|
1530
|
+
diagnostic: AriaDiagnostics.ariaHiddenOnFocusable(tag)
|
|
963
1531
|
}
|
|
964
1532
|
];
|
|
965
1533
|
}
|
|
966
|
-
|
|
1534
|
+
// Presentational elements (role=none/presentation, including <img alt="">) are removed
|
|
1535
|
+
// from the accessibility tree — ARIA attributes on them are meaningless and misleading.
|
|
1536
|
+
static #checkPresentationalAriaAttributes({
|
|
967
1537
|
tag,
|
|
968
1538
|
props,
|
|
969
1539
|
effectiveRole
|
|
970
1540
|
}) {
|
|
1541
|
+
if (effectiveRole !== "none" && effectiveRole !== "presentation") return VALID;
|
|
971
1542
|
const results = [];
|
|
972
|
-
|
|
973
|
-
if (!
|
|
974
|
-
if (
|
|
975
|
-
if (isGlobalAriaAttribute(key)) continue;
|
|
976
|
-
if (isAriaAttributeValidForRole(key, effectiveRole)) continue;
|
|
1543
|
+
iterate.forEachEntry(props, (key) => {
|
|
1544
|
+
if (!key.startsWith("aria-")) return;
|
|
1545
|
+
if (key === "aria-hidden") return;
|
|
977
1546
|
results.push({
|
|
978
1547
|
valid: false,
|
|
979
|
-
severity: "warning",
|
|
980
1548
|
fixable: true,
|
|
1549
|
+
severity: "warning",
|
|
981
1550
|
attribute: key,
|
|
982
|
-
|
|
1551
|
+
diagnostic: AriaDiagnostics.attributeOnPresentational(key, tag),
|
|
983
1552
|
fix: _AriaPolicyEngine.#makeRemoveAttributeFix(key)
|
|
984
1553
|
});
|
|
985
|
-
}
|
|
1554
|
+
});
|
|
986
1555
|
return results;
|
|
987
1556
|
}
|
|
988
1557
|
// WAI-ARIA live region roles and their implied aria-live politeness values.
|
|
@@ -1011,7 +1580,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1011
1580
|
fixable: true,
|
|
1012
1581
|
severity: "warning",
|
|
1013
1582
|
fix: injectLive,
|
|
1014
|
-
|
|
1583
|
+
diagnostic: AriaDiagnostics.missingLiveRegion(effectiveRole, impliedLive)
|
|
1015
1584
|
}
|
|
1016
1585
|
];
|
|
1017
1586
|
}
|
|
@@ -1023,7 +1592,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1023
1592
|
valid: false,
|
|
1024
1593
|
fixable: false,
|
|
1025
1594
|
severity: "warning",
|
|
1026
|
-
|
|
1595
|
+
diagnostic: AriaDiagnostics.missingAtomic(effectiveRole)
|
|
1027
1596
|
}
|
|
1028
1597
|
];
|
|
1029
1598
|
}
|
|
@@ -1052,7 +1621,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1052
1621
|
fixable: true,
|
|
1053
1622
|
severity: "warning",
|
|
1054
1623
|
attribute: "aria-relevant",
|
|
1055
|
-
|
|
1624
|
+
diagnostic: AriaDiagnostics.relevantInvalidTokens(invalid),
|
|
1056
1625
|
fix: _AriaPolicyEngine.#makeRemoveAttributeFix("aria-relevant")
|
|
1057
1626
|
}
|
|
1058
1627
|
];
|
|
@@ -1064,7 +1633,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1064
1633
|
fixable: true,
|
|
1065
1634
|
severity: "warning",
|
|
1066
1635
|
attribute: "aria-relevant",
|
|
1067
|
-
|
|
1636
|
+
diagnostic: AriaDiagnostics.relevantSuperseded(),
|
|
1068
1637
|
fix: _AriaPolicyEngine.#normalizeRelevantAllFix
|
|
1069
1638
|
}
|
|
1070
1639
|
];
|
|
@@ -1072,6 +1641,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1072
1641
|
return VALID;
|
|
1073
1642
|
}
|
|
1074
1643
|
};
|
|
1644
|
+
|
|
1645
|
+
// ../../lib/contract/src/children/get-type-name.ts
|
|
1075
1646
|
function getTypeName(value) {
|
|
1076
1647
|
if (value === null) return "null";
|
|
1077
1648
|
if (value === void 0) return "undefined";
|
|
@@ -1082,39 +1653,8 @@ function getTypeName(value) {
|
|
|
1082
1653
|
const name = value.constructor?.name;
|
|
1083
1654
|
return typeof name === "string" && name !== "Object" ? name : "object";
|
|
1084
1655
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
constructor(ctx = "") {
|
|
1088
|
-
this.#prefix = ctx ? `${ctx}:
|
|
1089
|
-
` : "";
|
|
1090
|
-
}
|
|
1091
|
-
#template(typeName, index, prefix = "", suffix = "") {
|
|
1092
|
-
const leadingStr = prefix ? `${prefix} ` : "";
|
|
1093
|
-
const followingStr = suffix ? ` ${suffix}` : "";
|
|
1094
|
-
return `${leadingStr}child "${typeName}" at index ${index}${followingStr}.`;
|
|
1095
|
-
}
|
|
1096
|
-
unexpectedChild(typeName, index) {
|
|
1097
|
-
return this.#template(typeName, index, "unexpected");
|
|
1098
|
-
}
|
|
1099
|
-
multipleMatches(typeName, index, ruleNames) {
|
|
1100
|
-
const quoted = ruleNames.map((n) => `"${n}"`);
|
|
1101
|
-
return this.#template(
|
|
1102
|
-
typeName,
|
|
1103
|
-
index,
|
|
1104
|
-
"",
|
|
1105
|
-
`matches multiple child rules: ${quoted.join(" and ")}`
|
|
1106
|
-
);
|
|
1107
|
-
}
|
|
1108
|
-
#format(errors) {
|
|
1109
|
-
return this.#prefix + errors.join("\n");
|
|
1110
|
-
}
|
|
1111
|
-
toError(errors) {
|
|
1112
|
-
if (errors.length === 0) {
|
|
1113
|
-
return new Error(this.#prefix + "Unknown validation error.");
|
|
1114
|
-
}
|
|
1115
|
-
return new Error(this.#format(errors));
|
|
1116
|
-
}
|
|
1117
|
-
};
|
|
1656
|
+
|
|
1657
|
+
// ../../lib/contract/src/children/normalize-child-rule.ts
|
|
1118
1658
|
function normalizeCardinality(input, impliesSingleton) {
|
|
1119
1659
|
const min = input?.min ?? 0;
|
|
1120
1660
|
const max = input?.max ?? (impliesSingleton ? 1 : Infinity);
|
|
@@ -1139,6 +1679,8 @@ function normalizeChildRule(rule) {
|
|
|
1139
1679
|
cardinality: normalizeCardinality(rule.cardinality, impliesSingleton)
|
|
1140
1680
|
};
|
|
1141
1681
|
}
|
|
1682
|
+
|
|
1683
|
+
// ../../lib/contract/src/children/rules-matcher.ts
|
|
1142
1684
|
function getChildType(child) {
|
|
1143
1685
|
if (!isObject(child) || !("type" in child)) return void 0;
|
|
1144
1686
|
return child.type;
|
|
@@ -1147,8 +1689,8 @@ function buildPartialIndex(rules) {
|
|
|
1147
1689
|
const typeIndex = /* @__PURE__ */ new Map();
|
|
1148
1690
|
const duplicateTypes = /* @__PURE__ */ new Set();
|
|
1149
1691
|
const untypedIndices = [];
|
|
1150
|
-
|
|
1151
|
-
const t =
|
|
1692
|
+
iterate.forEach(rules, (rule, ri) => {
|
|
1693
|
+
const t = rule.type;
|
|
1152
1694
|
if (t === void 0) {
|
|
1153
1695
|
untypedIndices.push(ri);
|
|
1154
1696
|
} else if (typeIndex.has(t)) {
|
|
@@ -1156,12 +1698,14 @@ function buildPartialIndex(rules) {
|
|
|
1156
1698
|
} else {
|
|
1157
1699
|
typeIndex.set(t, ri);
|
|
1158
1700
|
}
|
|
1159
|
-
}
|
|
1701
|
+
});
|
|
1160
1702
|
if (duplicateTypes.size > 0) {
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1703
|
+
iterate.forEachSet(duplicateTypes, (t) => {
|
|
1704
|
+
typeIndex.delete(t);
|
|
1705
|
+
});
|
|
1706
|
+
iterate.forEach(rules, (rule, ri) => {
|
|
1707
|
+
if (duplicateTypes.has(rule.type)) untypedIndices.push(ri);
|
|
1708
|
+
});
|
|
1165
1709
|
}
|
|
1166
1710
|
return { typeIndex, untypedIndices };
|
|
1167
1711
|
}
|
|
@@ -1180,10 +1724,10 @@ var RuleMatcher = class {
|
|
|
1180
1724
|
const reverse = /* @__PURE__ */ new Map();
|
|
1181
1725
|
const unexpectedIndices = /* @__PURE__ */ new Set();
|
|
1182
1726
|
const ambiguousIndices = /* @__PURE__ */ new Set();
|
|
1183
|
-
|
|
1727
|
+
iterate.forEach(this.#rules, (_, ri) => {
|
|
1184
1728
|
reverse.set(ri, /* @__PURE__ */ new Set());
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1729
|
+
});
|
|
1730
|
+
iterate.forEach(children, (child, ci) => {
|
|
1187
1731
|
const t = getChildType(child);
|
|
1188
1732
|
if (t !== void 0) {
|
|
1189
1733
|
const ri = this.#typeIndex.get(t);
|
|
@@ -1197,8 +1741,8 @@ var RuleMatcher = class {
|
|
|
1197
1741
|
reverse.get(ri).add(ci);
|
|
1198
1742
|
}
|
|
1199
1743
|
}
|
|
1200
|
-
|
|
1201
|
-
if (!this.#rules[ri].match(child))
|
|
1744
|
+
iterate.forEach(this.#untypedIndices, (ri) => {
|
|
1745
|
+
if (!this.#rules[ri].match(child)) return;
|
|
1202
1746
|
let childEntry = forward.get(ci);
|
|
1203
1747
|
if (!childEntry) {
|
|
1204
1748
|
childEntry = /* @__PURE__ */ new Set();
|
|
@@ -1206,33 +1750,35 @@ var RuleMatcher = class {
|
|
|
1206
1750
|
}
|
|
1207
1751
|
childEntry.add(ri);
|
|
1208
1752
|
reverse.get(ri).add(ci);
|
|
1209
|
-
}
|
|
1753
|
+
});
|
|
1210
1754
|
const entry = forward.get(ci);
|
|
1211
1755
|
if (!entry) {
|
|
1212
1756
|
unexpectedIndices.add(ci);
|
|
1213
1757
|
} else if (entry.size > 1) {
|
|
1214
1758
|
ambiguousIndices.add(ci);
|
|
1215
1759
|
}
|
|
1216
|
-
}
|
|
1760
|
+
});
|
|
1217
1761
|
return { matrix: { childToRules: { forward, reverse } }, unexpectedIndices, ambiguousIndices };
|
|
1218
1762
|
}
|
|
1219
1763
|
};
|
|
1220
|
-
|
|
1764
|
+
|
|
1765
|
+
// ../../lib/contract/src/children/rule-validator.ts
|
|
1766
|
+
var RuleValidator = class _RuleValidator extends InvariantBase {
|
|
1221
1767
|
#context;
|
|
1222
|
-
constructor(context,
|
|
1223
|
-
super(
|
|
1768
|
+
constructor(context, diagnostics) {
|
|
1769
|
+
super(diagnostics);
|
|
1224
1770
|
this.#context = context;
|
|
1225
1771
|
}
|
|
1226
1772
|
validate(rules, matrix, childCount) {
|
|
1227
1773
|
const firstIndex = 0;
|
|
1228
1774
|
const lastIndex = childCount - 1;
|
|
1229
|
-
|
|
1775
|
+
iterate.forEach(rules, (rule, ri) => {
|
|
1230
1776
|
const matches = matrix.childToRules.reverse.get(ri);
|
|
1231
1777
|
const matchCount = matches.size;
|
|
1232
1778
|
this.#validateCardinality(rule, matchCount);
|
|
1233
|
-
if (matchCount === 0)
|
|
1779
|
+
if (matchCount === 0) return;
|
|
1234
1780
|
this.#validatePositions(rule, matches, firstIndex, lastIndex);
|
|
1235
|
-
}
|
|
1781
|
+
});
|
|
1236
1782
|
}
|
|
1237
1783
|
#validateCardinality(rule, matchCount) {
|
|
1238
1784
|
const { cardinality, name } = rule;
|
|
@@ -1241,21 +1787,21 @@ var RuleValidator = class _RuleValidator extends StrictBase {
|
|
|
1241
1787
|
}
|
|
1242
1788
|
const { min, max } = cardinality;
|
|
1243
1789
|
if (matchCount < min) {
|
|
1244
|
-
this.violate(
|
|
1790
|
+
this.violate(ContractDiagnostics.cardinalityMin(name, min, this.#context));
|
|
1245
1791
|
return;
|
|
1246
1792
|
}
|
|
1247
1793
|
if (matchCount > max) {
|
|
1248
|
-
this.violate(
|
|
1794
|
+
this.violate(ContractDiagnostics.cardinalityMax(name, max, this.#context));
|
|
1249
1795
|
}
|
|
1250
1796
|
}
|
|
1251
1797
|
#validatePositions(rule, matches, firstIndex, lastIndex) {
|
|
1252
1798
|
const { name, position } = rule;
|
|
1253
|
-
|
|
1799
|
+
iterate.forEachSet(matches, (index) => {
|
|
1254
1800
|
if (_RuleValidator.#isValidPosition(index, position, firstIndex, lastIndex)) {
|
|
1255
|
-
|
|
1801
|
+
return;
|
|
1256
1802
|
}
|
|
1257
|
-
this.violate(
|
|
1258
|
-
}
|
|
1803
|
+
this.violate(ContractDiagnostics.positionViolation(name, position, index, this.#context));
|
|
1804
|
+
});
|
|
1259
1805
|
}
|
|
1260
1806
|
static #isValidPosition(matchIndex, position, firstIndex, lastIndex) {
|
|
1261
1807
|
switch (position) {
|
|
@@ -1270,48 +1816,50 @@ var RuleValidator = class _RuleValidator extends StrictBase {
|
|
|
1270
1816
|
}
|
|
1271
1817
|
}
|
|
1272
1818
|
};
|
|
1273
|
-
|
|
1819
|
+
|
|
1820
|
+
// ../../lib/contract/src/children/children-evaluator.ts
|
|
1821
|
+
var ChildrenEvaluator = class extends InvariantBase {
|
|
1822
|
+
#context;
|
|
1274
1823
|
#rules;
|
|
1275
1824
|
#ruleNames;
|
|
1276
1825
|
#matcher;
|
|
1277
1826
|
#ruleValidator;
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
this.#rules = rules.map((
|
|
1282
|
-
this.#ruleNames = this.#rules.map((
|
|
1283
|
-
|
|
1827
|
+
constructor(rules, diagnostics, context = "Component") {
|
|
1828
|
+
super(diagnostics);
|
|
1829
|
+
this.#context = context;
|
|
1830
|
+
this.#rules = rules.map((r) => normalizeChildRule(r));
|
|
1831
|
+
this.#ruleNames = this.#rules.map((r) => r.name);
|
|
1832
|
+
iterate.forEach(this.#rules, (rule) => {
|
|
1284
1833
|
const { name, position, cardinality } = rule;
|
|
1285
1834
|
if ((position === "first" || position === "last") && (cardinality.kind === "unbounded" || cardinality.max > 1)) {
|
|
1286
1835
|
throw new RangeError(
|
|
1287
1836
|
`ChildrenEvaluator [${context}]: rule "${name}" sets position="${position}" with an unbound or >1 max. position="first|last" implies max=1.`
|
|
1288
1837
|
);
|
|
1289
1838
|
}
|
|
1290
|
-
}
|
|
1839
|
+
});
|
|
1291
1840
|
this.#matcher = new RuleMatcher(this.#rules);
|
|
1292
|
-
this.#ruleValidator = new RuleValidator(context,
|
|
1293
|
-
this.#matchBuilder = new MatchValidationErrorBuilder(context);
|
|
1841
|
+
this.#ruleValidator = new RuleValidator(context, diagnostics);
|
|
1294
1842
|
}
|
|
1295
1843
|
evaluate(children) {
|
|
1296
|
-
if (!this.
|
|
1844
|
+
if (!this.active) return;
|
|
1297
1845
|
const { matrix, unexpectedIndices, ambiguousIndices } = this.#matcher.match(children);
|
|
1298
1846
|
this.#ruleValidator.validate(this.#rules, matrix, children.length);
|
|
1299
1847
|
if (unexpectedIndices.size === 0 && ambiguousIndices.size === 0) return;
|
|
1300
|
-
const errors = [];
|
|
1301
1848
|
const violating = [...unexpectedIndices, ...ambiguousIndices].sort((a, b) => a - b);
|
|
1302
|
-
|
|
1849
|
+
iterate.forEach(violating, (ci) => {
|
|
1303
1850
|
const typeName = getTypeName(children[ci]);
|
|
1304
1851
|
if (unexpectedIndices.has(ci)) {
|
|
1305
|
-
|
|
1852
|
+
this.violate(ContractDiagnostics.unexpectedChild(typeName, ci, this.#context));
|
|
1306
1853
|
} else {
|
|
1307
1854
|
const matches = matrix.childToRules.forward.get(ci);
|
|
1308
1855
|
const names = [...matches].map((ri) => this.#ruleNames[ri] ?? `#${ri}`);
|
|
1309
|
-
|
|
1856
|
+
this.violate(ContractDiagnostics.ambiguousChild(typeName, ci, names, this.#context));
|
|
1310
1857
|
}
|
|
1311
|
-
}
|
|
1312
|
-
this.invariant(errors.length === 0, this.#matchBuilder.toError(errors).message);
|
|
1858
|
+
});
|
|
1313
1859
|
}
|
|
1314
1860
|
};
|
|
1861
|
+
|
|
1862
|
+
// ../../lib/contract/src/props/get-disabled-props.ts
|
|
1315
1863
|
var disabledProps = ({
|
|
1316
1864
|
disabled,
|
|
1317
1865
|
"aria-disabled": ariaDisabled,
|
|
@@ -1323,6 +1871,8 @@ var disabledProps = ({
|
|
|
1323
1871
|
...dataDisabled === void 0 && { "data-disabled": "" }
|
|
1324
1872
|
};
|
|
1325
1873
|
};
|
|
1874
|
+
|
|
1875
|
+
// ../../lib/contract/src/props/get-invalid-props.ts
|
|
1326
1876
|
var invalidProps = ({
|
|
1327
1877
|
invalid,
|
|
1328
1878
|
"aria-invalid": ariaInvalid,
|
|
@@ -1334,6 +1884,8 @@ var invalidProps = ({
|
|
|
1334
1884
|
...dataInvalid === void 0 && { "data-invalid": "" }
|
|
1335
1885
|
};
|
|
1336
1886
|
};
|
|
1887
|
+
|
|
1888
|
+
// ../../lib/contract/src/props/get-readonly-props.ts
|
|
1337
1889
|
var readonlyProps = ({
|
|
1338
1890
|
readOnly,
|
|
1339
1891
|
"aria-readonly": ariaReadonly,
|
|
@@ -1349,6 +1901,8 @@ var readonlyProps = ({
|
|
|
1349
1901
|
}
|
|
1350
1902
|
};
|
|
1351
1903
|
};
|
|
1904
|
+
|
|
1905
|
+
// ../core/src/html/aria-rules.ts
|
|
1352
1906
|
var LANDMARK_TAG_SET = /* @__PURE__ */ new Set(["article", "aside", "footer", "header", "main", "nav"]);
|
|
1353
1907
|
var removeLandmarkRoleOverride = {
|
|
1354
1908
|
kind: "removeRole",
|
|
@@ -1368,154 +1922,29 @@ function landmarkRoleRule({ tag, props, implicitRole }) {
|
|
|
1368
1922
|
fixable: true,
|
|
1369
1923
|
severity: "error",
|
|
1370
1924
|
fix: removeLandmarkRoleOverride,
|
|
1371
|
-
|
|
1925
|
+
diagnostic: HtmlDiagnostics.landmarkRoleOverride(tag, implicitRole, role)
|
|
1372
1926
|
}
|
|
1373
1927
|
];
|
|
1374
1928
|
}
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
return { name, match: metadataMatch };
|
|
1384
|
-
}
|
|
1385
|
-
function firstOptional(name, tag) {
|
|
1386
|
-
return { name, match: isTag(tag), cardinality: { max: 1 }, position: "first" };
|
|
1387
|
-
}
|
|
1388
|
-
function contract(children) {
|
|
1389
|
-
return { strict: "warn", children };
|
|
1390
|
-
}
|
|
1391
|
-
function ariaContract(aria) {
|
|
1392
|
-
return { strict: "warn", aria };
|
|
1393
|
-
}
|
|
1394
|
-
function firstChildContract(name, tag) {
|
|
1395
|
-
return contract([firstOptional(name, tag), { name: "content", match: isOpenContent(tag) }]);
|
|
1396
|
-
}
|
|
1397
|
-
var VOID_TAGS = [
|
|
1398
|
-
"area",
|
|
1399
|
-
"base",
|
|
1400
|
-
"br",
|
|
1401
|
-
"col",
|
|
1402
|
-
"embed",
|
|
1403
|
-
"hr",
|
|
1404
|
-
"img",
|
|
1405
|
-
"input",
|
|
1406
|
-
"link",
|
|
1407
|
-
"meta",
|
|
1408
|
-
"param",
|
|
1409
|
-
"source",
|
|
1410
|
-
"track",
|
|
1411
|
-
"wbr"
|
|
1412
|
-
];
|
|
1413
|
-
var TEXT_ONLY_TAGS = ["option", "script", "style", "textarea", "title"];
|
|
1414
|
-
var LANDMARK_TAGS = ["article", "aside", "footer", "header", "main", "nav"];
|
|
1415
|
-
var listContract = contract([{ name: "list-item", match: isTag("li", ...METADATA_TAGS) }]);
|
|
1416
|
-
var tableContract = contract([
|
|
1417
|
-
firstOptional("caption", "caption"),
|
|
1418
|
-
{ name: "colgroup", match: isTag("colgroup") },
|
|
1419
|
-
{ name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
|
|
1420
|
-
{ name: "tbody", match: isTag("tbody") },
|
|
1421
|
-
{ name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
|
|
1422
|
-
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
1423
|
-
]);
|
|
1424
|
-
var tableBodyContract = contract([
|
|
1425
|
-
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
1426
|
-
]);
|
|
1427
|
-
var tableRowContract = contract([
|
|
1428
|
-
{ name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
|
|
1429
|
-
]);
|
|
1430
|
-
var colgroupContract = contract([{ name: "column", match: isTag("col", "template") }]);
|
|
1431
|
-
var dlContract = contract([
|
|
1432
|
-
{ name: "term", match: isTag("dt") },
|
|
1433
|
-
{ name: "description", match: isTag("dd") },
|
|
1434
|
-
{ name: "group", match: isTag("div") },
|
|
1435
|
-
metadata()
|
|
1436
|
-
]);
|
|
1437
|
-
var selectContract = contract([
|
|
1438
|
-
{ name: "option", match: isTag("option", "optgroup", "hr", ...METADATA_TAGS) }
|
|
1439
|
-
]);
|
|
1440
|
-
var optgroupContract = contract([
|
|
1441
|
-
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
1442
|
-
]);
|
|
1443
|
-
var datalistContract = contract([
|
|
1444
|
-
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
1445
|
-
]);
|
|
1446
|
-
var pictureContract = contract([
|
|
1447
|
-
{ name: "source", match: isTag("source", ...METADATA_TAGS) },
|
|
1448
|
-
{ name: "image", match: isTag("img"), cardinality: { min: 1, max: 1 }, position: "last" }
|
|
1449
|
-
]);
|
|
1450
|
-
var figureContract = contract([
|
|
1451
|
-
{ name: "caption", match: isTag("figcaption"), cardinality: { max: 1 } },
|
|
1452
|
-
{ name: "content", match: isOpenContent("figcaption") }
|
|
1453
|
-
]);
|
|
1454
|
-
var detailsContract = firstChildContract("summary", "summary");
|
|
1455
|
-
var fieldsetContract = firstChildContract("legend", "legend");
|
|
1456
|
-
var mediaContract = contract([
|
|
1457
|
-
{ name: "source", match: isTag("source") },
|
|
1458
|
-
{ name: "track", match: isTag("track") },
|
|
1459
|
-
metadata(),
|
|
1460
|
-
{ name: "content", match: isOpenContent("source", "track", ...METADATA_TAGS) }
|
|
1461
|
-
]);
|
|
1462
|
-
var headContract = contract([
|
|
1463
|
-
{
|
|
1464
|
-
name: "metadata",
|
|
1465
|
-
match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
|
|
1466
|
-
}
|
|
1467
|
-
]);
|
|
1468
|
-
var htmlContract = contract([
|
|
1469
|
-
{ name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
|
|
1470
|
-
{ name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
|
|
1471
|
-
]);
|
|
1472
|
-
var voidContract = contract([]);
|
|
1473
|
-
var textOnlyContract = contract([
|
|
1474
|
-
{
|
|
1475
|
-
name: "text",
|
|
1476
|
-
match: (child) => isString(child) || isNumber(child)
|
|
1477
|
-
}
|
|
1478
|
-
]);
|
|
1479
|
-
var landmarkContract = ariaContract([landmarkRoleRule]);
|
|
1480
|
-
var CONTRACT_GROUPS = [
|
|
1481
|
-
[VOID_TAGS, voidContract],
|
|
1482
|
-
[TEXT_ONLY_TAGS, textOnlyContract],
|
|
1483
|
-
[LANDMARK_TAGS, landmarkContract],
|
|
1484
|
-
[["ul", "ol", "menu"], listContract],
|
|
1485
|
-
[["audio", "video"], mediaContract],
|
|
1486
|
-
[["thead", "tbody", "tfoot"], tableBodyContract]
|
|
1487
|
-
];
|
|
1488
|
-
function contractMap(groups) {
|
|
1489
|
-
return Object.fromEntries(
|
|
1490
|
-
groups.flatMap(([tags, enforcement]) => tags.map((tag) => [tag, enforcement]))
|
|
1491
|
-
);
|
|
1492
|
-
}
|
|
1493
|
-
var htmlContracts = {
|
|
1494
|
-
...contractMap(CONTRACT_GROUPS),
|
|
1495
|
-
table: tableContract,
|
|
1496
|
-
tr: tableRowContract,
|
|
1497
|
-
colgroup: colgroupContract,
|
|
1498
|
-
dl: dlContract,
|
|
1499
|
-
select: selectContract,
|
|
1500
|
-
optgroup: optgroupContract,
|
|
1501
|
-
datalist: datalistContract,
|
|
1502
|
-
picture: pictureContract,
|
|
1503
|
-
figure: figureContract,
|
|
1504
|
-
details: detailsContract,
|
|
1505
|
-
fieldset: fieldsetContract,
|
|
1506
|
-
head: headContract,
|
|
1507
|
-
html: htmlContract
|
|
1508
|
-
};
|
|
1509
|
-
function buildEvaluatorMap() {
|
|
1510
|
-
const map = /* @__PURE__ */ new Map();
|
|
1511
|
-
for (const [tag, { children }] of Object.entries(htmlContracts)) {
|
|
1512
|
-
if (children?.length) {
|
|
1513
|
-
map.set(tag, new ChildrenEvaluator(children, "warn", `<${tag}>`));
|
|
1929
|
+
function requireAccessibleName({ tag, props }) {
|
|
1930
|
+
if ("aria-label" in props || "aria-labelledby" in props) return [];
|
|
1931
|
+
return [
|
|
1932
|
+
{
|
|
1933
|
+
valid: false,
|
|
1934
|
+
fixable: false,
|
|
1935
|
+
severity: "warning",
|
|
1936
|
+
diagnostic: AriaDiagnostics.missingAccessibleName(tag)
|
|
1514
1937
|
}
|
|
1515
|
-
|
|
1516
|
-
|
|
1938
|
+
];
|
|
1939
|
+
}
|
|
1940
|
+
var NAMED_LANDMARK_TAGS = /* @__PURE__ */ new Set(["nav", "aside"]);
|
|
1941
|
+
function landmarkNameAdvisory(ctx) {
|
|
1942
|
+
if (!ctx.implicitRole || !NAMED_LANDMARK_TAGS.has(ctx.tag)) return [];
|
|
1943
|
+
return requireAccessibleName(ctx);
|
|
1517
1944
|
}
|
|
1518
|
-
var
|
|
1945
|
+
var HTML_ARIA_RULES = [landmarkRoleRule, landmarkNameAdvisory];
|
|
1946
|
+
|
|
1947
|
+
// ../core/src/html/prop-normalizers.ts
|
|
1519
1948
|
var HTML_FORM_NORMALIZERS = /* @__PURE__ */ new Map([
|
|
1520
1949
|
["button", [disabledProps]],
|
|
1521
1950
|
["input", [disabledProps, readonlyProps, invalidProps]],
|
|
@@ -1528,9 +1957,10 @@ function getHtmlPropNormalizers(tag) {
|
|
|
1528
1957
|
return typeof tag === "string" ? HTML_FORM_NORMALIZERS.get(tag) : void 0;
|
|
1529
1958
|
}
|
|
1530
1959
|
|
|
1531
|
-
//
|
|
1960
|
+
// ../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.mjs
|
|
1961
|
+
import { clsx as clsx2 } from "clsx";
|
|
1532
1962
|
var falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
|
|
1533
|
-
var cx =
|
|
1963
|
+
var cx = clsx2;
|
|
1534
1964
|
var cva = (base, config) => (props) => {
|
|
1535
1965
|
var _config_compoundVariants;
|
|
1536
1966
|
if ((config === null || config === void 0 ? void 0 : config.variants) == null) return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
|
|
@@ -1569,10 +1999,14 @@ var cva = (base, config) => (props) => {
|
|
|
1569
1999
|
}, []);
|
|
1570
2000
|
return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
|
|
1571
2001
|
};
|
|
2002
|
+
|
|
2003
|
+
// ../../lib/styling/src/cva.ts
|
|
1572
2004
|
function cva2(base, config) {
|
|
1573
2005
|
const fn = cva(base, config);
|
|
1574
2006
|
return (props) => cn(fn(props));
|
|
1575
2007
|
}
|
|
2008
|
+
|
|
2009
|
+
// ../../lib/styling/src/static-class-resolver.ts
|
|
1576
2010
|
var StaticClassResolver = class {
|
|
1577
2011
|
#baseClass;
|
|
1578
2012
|
#cache = /* @__PURE__ */ new Map();
|
|
@@ -1603,6 +2037,8 @@ var StaticClassResolver = class {
|
|
|
1603
2037
|
return result;
|
|
1604
2038
|
}
|
|
1605
2039
|
};
|
|
2040
|
+
|
|
2041
|
+
// ../../lib/styling/src/variant-class-resolver.ts
|
|
1606
2042
|
var VariantClassResolver = class _VariantClassResolver {
|
|
1607
2043
|
#cvaFn;
|
|
1608
2044
|
#recipeMap;
|
|
@@ -1650,15 +2086,15 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
1650
2086
|
#createCacheKey(props, recipe) {
|
|
1651
2087
|
if (this.#variantKeys !== null) {
|
|
1652
2088
|
let key2 = recipe;
|
|
1653
|
-
|
|
2089
|
+
iterate.forEachSet(this.#variantKeys, (k) => {
|
|
1654
2090
|
if (k in props) key2 += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
1655
|
-
}
|
|
2091
|
+
});
|
|
1656
2092
|
return key2;
|
|
1657
2093
|
}
|
|
1658
2094
|
let key = recipe;
|
|
1659
|
-
|
|
2095
|
+
iterate.forEach(Object.keys(props).sort(), (k) => {
|
|
1660
2096
|
key += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
1661
|
-
}
|
|
2097
|
+
});
|
|
1662
2098
|
return key;
|
|
1663
2099
|
}
|
|
1664
2100
|
static #serializeValue(value) {
|
|
@@ -1669,6 +2105,8 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
1669
2105
|
return `x:${String(value)}`;
|
|
1670
2106
|
}
|
|
1671
2107
|
};
|
|
2108
|
+
|
|
2109
|
+
// ../../lib/styling/src/create-class-pipeline.ts
|
|
1672
2110
|
function createClassPipeline(resolved) {
|
|
1673
2111
|
const baseClass = resolved.baseClassName ?? "";
|
|
1674
2112
|
const cvaFn = resolved.variants ? cva2("", {
|
|
@@ -1693,7 +2131,203 @@ function createClassPipeline(resolved) {
|
|
|
1693
2131
|
};
|
|
1694
2132
|
}
|
|
1695
2133
|
|
|
1696
|
-
// ../core/
|
|
2134
|
+
// ../core/src/options/resolve-factory-options.ts
|
|
2135
|
+
var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
|
|
2136
|
+
function composeNormalizers(normalizers, fn) {
|
|
2137
|
+
if (!normalizers?.length) return fn;
|
|
2138
|
+
return ((props) => {
|
|
2139
|
+
const patched = normalizers.reduce(
|
|
2140
|
+
(acc, normalizer) => ({ ...acc, ...normalizer(acc) }),
|
|
2141
|
+
props
|
|
2142
|
+
);
|
|
2143
|
+
return fn ? fn(patched) : patched;
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
2146
|
+
function whenDefined(key, value) {
|
|
2147
|
+
return value === void 0 ? {} : { [key]: value };
|
|
2148
|
+
}
|
|
2149
|
+
function resolveFactoryOptions(options = {}) {
|
|
2150
|
+
const { styling, enforcement } = options;
|
|
2151
|
+
const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
|
|
2152
|
+
const variantKeys = styling?.variants === void 0 ? EMPTY_VARIANT_KEYS : new Set(Object.keys(styling.variants));
|
|
2153
|
+
return Object.freeze({
|
|
2154
|
+
defaultTag: options.tag ?? "div",
|
|
2155
|
+
diagnostics: enforcement?.diagnostics ?? silentDiagnostics,
|
|
2156
|
+
variantKeys,
|
|
2157
|
+
...whenDefined("displayName", options.name),
|
|
2158
|
+
...whenDefined("defaultProps", options.defaults),
|
|
2159
|
+
...whenDefined("baseClassName", styling?.base),
|
|
2160
|
+
...whenDefined("tagMap", styling?.tags),
|
|
2161
|
+
...whenDefined("recipeMap", styling?.presets),
|
|
2162
|
+
...whenDefined("variants", styling?.variants),
|
|
2163
|
+
...whenDefined("defaultVariants", styling?.defaults),
|
|
2164
|
+
...whenDefined("compoundVariants", styling?.compounds),
|
|
2165
|
+
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
2166
|
+
...whenDefined("ariaRules", enforcement?.aria),
|
|
2167
|
+
...whenDefined("childRules", enforcement?.children),
|
|
2168
|
+
...whenDefined("allowedAs", enforcement?.allowedAs),
|
|
2169
|
+
...whenDefined("precomputedClasses", styling?.precomputedClasses)
|
|
2170
|
+
});
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
// ../core/src/options/validate-factory-options.ts
|
|
2174
|
+
function validateFactoryOptions(resolved, diagnostics) {
|
|
2175
|
+
if (!diagnostics.active) return;
|
|
2176
|
+
const name = resolved.displayName ?? "Component";
|
|
2177
|
+
const { variants } = resolved;
|
|
2178
|
+
const checkSelection = (label2, selection) => {
|
|
2179
|
+
iterate.forEachEntry(selection, (dim, value) => {
|
|
2180
|
+
if (value === void 0 || value === null) return;
|
|
2181
|
+
if (!variants || !Object.hasOwn(variants, dim)) {
|
|
2182
|
+
diagnostics.error(ContractDiagnostics.unknownVariantDim(name, label2, dim));
|
|
2183
|
+
return;
|
|
2184
|
+
}
|
|
2185
|
+
const states = variants[dim];
|
|
2186
|
+
const stateKey = String(value);
|
|
2187
|
+
if (!Object.hasOwn(states, stateKey)) {
|
|
2188
|
+
diagnostics.error(
|
|
2189
|
+
ContractDiagnostics.unknownVariantValue(name, label2, dim, stateKey, Object.keys(states))
|
|
2190
|
+
);
|
|
2191
|
+
}
|
|
2192
|
+
});
|
|
2193
|
+
};
|
|
2194
|
+
const { recipeMap } = resolved;
|
|
2195
|
+
if (recipeMap) {
|
|
2196
|
+
iterate.forEachEntry(recipeMap, (recipeKey, selection) => {
|
|
2197
|
+
checkSelection(`preset "${recipeKey}"`, selection);
|
|
2198
|
+
});
|
|
2199
|
+
}
|
|
2200
|
+
if (resolved.defaultVariants) checkSelection("defaults", resolved.defaultVariants);
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
// ../core/src/options/validate-render-props.ts
|
|
2204
|
+
function label(name) {
|
|
2205
|
+
return name ? `[${name}]` : "[createContractComponent]";
|
|
2206
|
+
}
|
|
2207
|
+
function validateRenderProps(diagnostics, options, props, recipeKey) {
|
|
2208
|
+
const { recipeMap, variants, displayName } = options;
|
|
2209
|
+
const tag = label(displayName);
|
|
2210
|
+
if (recipeKey !== void 0 && (!recipeMap || !Object.hasOwn(recipeMap, recipeKey))) {
|
|
2211
|
+
diagnostics.error(ContractDiagnostics.unknownRecipeKey(tag, recipeKey));
|
|
2212
|
+
}
|
|
2213
|
+
if (variants) {
|
|
2214
|
+
iterate.forEachKey(variants, (key) => {
|
|
2215
|
+
if (!Object.hasOwn(props, key)) return;
|
|
2216
|
+
const value = props[key];
|
|
2217
|
+
if (value === void 0 || value === null) return;
|
|
2218
|
+
const dim = variants[key];
|
|
2219
|
+
if (dim && !Object.hasOwn(dim, String(value))) {
|
|
2220
|
+
diagnostics.error(ContractDiagnostics.invalidVariantValue(tag, key, String(value)));
|
|
2221
|
+
}
|
|
2222
|
+
});
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
// ../core/src/factory/plugin-diagnostics.ts
|
|
2227
|
+
var PluginDiagnostics = {
|
|
2228
|
+
invalidShape(received) {
|
|
2229
|
+
const got = received === null ? "null" : typeof received;
|
|
2230
|
+
return {
|
|
2231
|
+
code: "PLUGIN7001" /* PluginInvalidShape */,
|
|
2232
|
+
category: 7 /* Internal */,
|
|
2233
|
+
message: `[praxis-kit] Plugin factory must return an object with a 'pipeline' function. Got: ${got}.`
|
|
2234
|
+
};
|
|
2235
|
+
},
|
|
2236
|
+
pipelineReturnType(received) {
|
|
2237
|
+
const got = received === null ? "null" : Array.isArray(received) ? "array" : typeof received;
|
|
2238
|
+
return {
|
|
2239
|
+
code: "PLUGIN7002" /* PluginPipelineReturnType */,
|
|
2240
|
+
category: 7 /* Internal */,
|
|
2241
|
+
message: `[praxis-kit] Plugin pipeline must return a string. Got: ${got}.`
|
|
2242
|
+
};
|
|
2243
|
+
}
|
|
2244
|
+
};
|
|
2245
|
+
|
|
2246
|
+
// ../core/src/factory/plugin-invariants.ts
|
|
2247
|
+
function assertPluginShape(result) {
|
|
2248
|
+
if (result === null || typeof result !== "object")
|
|
2249
|
+
throwDiagnostics.error(PluginDiagnostics.invalidShape(result));
|
|
2250
|
+
const plugin = result;
|
|
2251
|
+
if (typeof plugin.pipeline !== "function")
|
|
2252
|
+
throwDiagnostics.error(PluginDiagnostics.invalidShape(result));
|
|
2253
|
+
}
|
|
2254
|
+
function guardPipeline(pipeline) {
|
|
2255
|
+
if (process.env.NODE_ENV === "production") return pipeline;
|
|
2256
|
+
return function guardedPipeline(tag, props, className, recipe) {
|
|
2257
|
+
const result = pipeline(tag, props, className, recipe);
|
|
2258
|
+
if (typeof result !== "string")
|
|
2259
|
+
throwDiagnostics.error(PluginDiagnostics.pipelineReturnType(result));
|
|
2260
|
+
return result;
|
|
2261
|
+
};
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
// ../core/src/factory/create-polymorphic.ts
|
|
2265
|
+
var NOOP_CLASS_PIPELINE = (_tag, _props, className) => Array.isArray(className) ? className.join(" ") : className ?? "";
|
|
2266
|
+
function resolveClassPipeline(options, resolved, diagnostics, capabilities) {
|
|
2267
|
+
const factory = options.styling?.plugin;
|
|
2268
|
+
if (!factory) {
|
|
2269
|
+
const createClassPipeline2 = capabilities?.createClassPipeline;
|
|
2270
|
+
const classPipeline2 = createClassPipeline2 ? createClassPipeline2(resolved) : NOOP_CLASS_PIPELINE;
|
|
2271
|
+
return { pluginResult: void 0, classPipeline: classPipeline2 };
|
|
2272
|
+
}
|
|
2273
|
+
const pluginResult = factory(resolved, diagnostics);
|
|
2274
|
+
assertPluginShape(pluginResult);
|
|
2275
|
+
const classPipeline = guardPipeline(pluginResult.pipeline);
|
|
2276
|
+
return { pluginResult, classPipeline };
|
|
2277
|
+
}
|
|
2278
|
+
function createRuntimeMethods(resolved, classPipeline, engine, renderDiagnostics) {
|
|
2279
|
+
return {
|
|
2280
|
+
resolveTag: makeResolveTag(resolved.defaultTag),
|
|
2281
|
+
resolveProps(props) {
|
|
2282
|
+
return mergeProps(resolved.defaultProps, props);
|
|
2283
|
+
},
|
|
2284
|
+
resolveClasses(tag, props, className, recipe) {
|
|
2285
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2286
|
+
validateRenderProps(renderDiagnostics, resolved, props, recipe);
|
|
2287
|
+
}
|
|
2288
|
+
return classPipeline(tag, props, className, recipe);
|
|
2289
|
+
},
|
|
2290
|
+
resolveAria(tag, props) {
|
|
2291
|
+
if (!engine) return { props };
|
|
2292
|
+
const result = engine.validate(tag, props);
|
|
2293
|
+
return { props: result.props };
|
|
2294
|
+
}
|
|
2295
|
+
};
|
|
2296
|
+
}
|
|
2297
|
+
function createRuntimeObject(methods, resolved, pluginResult) {
|
|
2298
|
+
return pluginResult ? { ...methods, options: resolved, hasStyling: true, classPlugin: pluginResult } : { ...methods, options: resolved };
|
|
2299
|
+
}
|
|
2300
|
+
function createPolymorphic(options = {}, capabilities) {
|
|
2301
|
+
const baseResolved = resolveFactoryOptions(options);
|
|
2302
|
+
const resolved = capabilities?.htmlPropNormalizersFn !== void 0 ? Object.freeze({
|
|
2303
|
+
...baseResolved,
|
|
2304
|
+
htmlPropNormalizersFn: capabilities.htmlPropNormalizersFn
|
|
2305
|
+
}) : baseResolved;
|
|
2306
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2307
|
+
validateFactoryOptions(resolved, resolved.diagnostics);
|
|
2308
|
+
}
|
|
2309
|
+
const { pluginResult, classPipeline } = resolveClassPipeline(
|
|
2310
|
+
options,
|
|
2311
|
+
resolved,
|
|
2312
|
+
resolved.diagnostics,
|
|
2313
|
+
capabilities
|
|
2314
|
+
);
|
|
2315
|
+
const allAriaRules = [
|
|
2316
|
+
.../* @__PURE__ */ new Set([...capabilities?.htmlAriaRules ?? [], ...resolved.ariaRules ?? []])
|
|
2317
|
+
];
|
|
2318
|
+
const engine = options.enforcement !== void 0 && capabilities?.AriaEngine ? new capabilities.AriaEngine(
|
|
2319
|
+
resolved.diagnostics,
|
|
2320
|
+
allAriaRules.length ? { rules: allAriaRules } : void 0
|
|
2321
|
+
) : null;
|
|
2322
|
+
const methods = createRuntimeMethods(resolved, classPipeline, engine, resolved.diagnostics);
|
|
2323
|
+
return createRuntimeObject(
|
|
2324
|
+
methods,
|
|
2325
|
+
resolved,
|
|
2326
|
+
pluginResult
|
|
2327
|
+
);
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
// ../core/src/factory/create-polymorphic-full.ts
|
|
1697
2331
|
var FULL_CAPABILITIES = {
|
|
1698
2332
|
createClassPipeline,
|
|
1699
2333
|
AriaEngine: AriaPolicyEngine,
|
|
@@ -1704,6 +2338,11 @@ function createPolymorphic2(options = {}) {
|
|
|
1704
2338
|
return createPolymorphic(options, FULL_CAPABILITIES);
|
|
1705
2339
|
}
|
|
1706
2340
|
|
|
2341
|
+
// ../../lib/adapter-utils/src/define-component.ts
|
|
2342
|
+
function defineContractComponent(options) {
|
|
2343
|
+
return (factory) => factory(options);
|
|
2344
|
+
}
|
|
2345
|
+
|
|
1707
2346
|
// ../../lib/adapter-utils/src/build-core-runtime.ts
|
|
1708
2347
|
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
1709
2348
|
function buildCoreRuntime(normalized) {
|
|
@@ -1713,8 +2352,8 @@ function buildCoreRuntime(normalized) {
|
|
|
1713
2352
|
}
|
|
1714
2353
|
|
|
1715
2354
|
// ../../lib/adapter-utils/src/build-engines.ts
|
|
1716
|
-
function buildEngines(
|
|
1717
|
-
return childRules?.length ? { childrenEvaluator: new ChildrenEvaluator(childRules,
|
|
2355
|
+
function buildEngines(diagnostics, childRules, context) {
|
|
2356
|
+
return childRules?.length ? { childrenEvaluator: new ChildrenEvaluator(childRules, diagnostics, context) } : {};
|
|
1718
2357
|
}
|
|
1719
2358
|
|
|
1720
2359
|
// ../../lib/adapter-utils/src/compose-filter.ts
|
|
@@ -1727,10 +2366,10 @@ function composeFilter(ownedKeys, filterProps) {
|
|
|
1727
2366
|
}
|
|
1728
2367
|
|
|
1729
2368
|
// ../../lib/adapter-utils/src/resolve-adapter-common-options.ts
|
|
1730
|
-
function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent",
|
|
2369
|
+
function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics) {
|
|
1731
2370
|
return {
|
|
1732
2371
|
name: options.name ?? defaultName,
|
|
1733
|
-
|
|
2372
|
+
diagnostics: options.enforcement?.diagnostics ?? defaultDiagnostics
|
|
1734
2373
|
};
|
|
1735
2374
|
}
|
|
1736
2375
|
|
|
@@ -1738,12 +2377,12 @@ function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponen
|
|
|
1738
2377
|
function buildRuntime(options) {
|
|
1739
2378
|
const normalized = {
|
|
1740
2379
|
...options,
|
|
1741
|
-
...resolveAdapterCommonOptions(options, "PolymorphicElement",
|
|
2380
|
+
...resolveAdapterCommonOptions(options, "PolymorphicElement", silentDiagnostics)
|
|
1742
2381
|
};
|
|
1743
2382
|
const { filterProps: customFilter, enforcement } = normalized;
|
|
1744
2383
|
const { runtime, ownedKeys } = buildCoreRuntime(normalized);
|
|
1745
2384
|
const { childrenEvaluator } = buildEngines(
|
|
1746
|
-
normalized.
|
|
2385
|
+
normalized.diagnostics,
|
|
1747
2386
|
enforcement?.children,
|
|
1748
2387
|
normalized.name
|
|
1749
2388
|
);
|
|
@@ -1751,7 +2390,7 @@ function buildRuntime(options) {
|
|
|
1751
2390
|
return {
|
|
1752
2391
|
runtime,
|
|
1753
2392
|
filterProps,
|
|
1754
|
-
|
|
2393
|
+
diagnostics: normalized.diagnostics,
|
|
1755
2394
|
...childrenEvaluator !== void 0 && { childrenEvaluator }
|
|
1756
2395
|
};
|
|
1757
2396
|
}
|
|
@@ -1766,16 +2405,14 @@ function escapeAttr(value) {
|
|
|
1766
2405
|
}
|
|
1767
2406
|
function buildAttrString(attributes) {
|
|
1768
2407
|
const parts = [];
|
|
1769
|
-
|
|
1770
|
-
if (
|
|
1771
|
-
const value = attributes[key];
|
|
1772
|
-
if (value === false || value === null || value === void 0) continue;
|
|
2408
|
+
iterate.forEachEntry(attributes, (key, value) => {
|
|
2409
|
+
if (value === false || value === null || value === void 0) return;
|
|
1773
2410
|
if (value === true) {
|
|
1774
2411
|
parts.push(key);
|
|
1775
2412
|
} else {
|
|
1776
2413
|
parts.push(`${key}="${escapeAttr(String(value))}"`);
|
|
1777
2414
|
}
|
|
1778
|
-
}
|
|
2415
|
+
});
|
|
1779
2416
|
return parts.length > 0 ? " " + parts.join(" ") : "";
|
|
1780
2417
|
}
|
|
1781
2418
|
function renderToString(component, props = {}, innerHTML = "") {
|
|
@@ -1933,7 +2570,7 @@ function createContractComponent(options) {
|
|
|
1933
2570
|
if (options.name) {
|
|
1934
2571
|
Object.defineProperty(PolymorphicWebElement, "name", { value: options.name });
|
|
1935
2572
|
}
|
|
1936
|
-
Object.defineProperty(PolymorphicWebElement, "
|
|
2573
|
+
Object.defineProperty(PolymorphicWebElement, "diagnostics", { value: bundle.diagnostics });
|
|
1937
2574
|
registerForSsr(PolymorphicWebElement, looseBundle);
|
|
1938
2575
|
return PolymorphicWebElement;
|
|
1939
2576
|
}
|