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/solid/index.js
CHANGED
|
@@ -1,288 +1,315 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../../lib/primitive/src/guards/children/component-id.ts
|
|
2
2
|
var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol.for("praxis.component-default-tag");
|
|
3
3
|
|
|
4
|
-
// ../../
|
|
5
|
-
function
|
|
6
|
-
|
|
4
|
+
// ../../lib/primitive/src/utils/is-object.ts
|
|
5
|
+
function isObject(value, excludeArrays = false) {
|
|
6
|
+
if (value === null || typeof value !== "object") return false;
|
|
7
|
+
return excludeArrays ? !Array.isArray(value) : true;
|
|
8
|
+
}
|
|
9
|
+
function isString(value) {
|
|
10
|
+
return typeof value === "string";
|
|
11
|
+
}
|
|
12
|
+
function isNumber(value) {
|
|
13
|
+
return typeof value === "number";
|
|
7
14
|
}
|
|
8
15
|
|
|
9
|
-
// ../../lib/
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
for (const k in props) {
|
|
13
|
-
if (!Object.hasOwn(props, k)) continue;
|
|
14
|
-
if (filterProps(k, variantKeys)) continue;
|
|
15
|
-
out[k] = props[k];
|
|
16
|
-
}
|
|
17
|
-
return out;
|
|
16
|
+
// ../../lib/primitive/src/guards/foundational/is-defined.ts
|
|
17
|
+
function isUndefined(value) {
|
|
18
|
+
return value === void 0;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
// ../../lib/
|
|
21
|
-
function
|
|
22
|
-
return
|
|
21
|
+
// ../../lib/primitive/src/guards/foundational/is-null.ts
|
|
22
|
+
function isNull(value) {
|
|
23
|
+
return value === null;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
//
|
|
26
|
+
// ../../lib/adapter-utils/src/apply-display-name.ts
|
|
27
|
+
function applyDisplayName(component, name) {
|
|
28
|
+
Object.assign(component, { displayName: name ?? "PolymorphicComponent" });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ../../lib/primitive/src/tag/resolve-tag.ts
|
|
26
32
|
function makeResolveTag(defaultTag) {
|
|
27
33
|
return function tag(as) {
|
|
28
34
|
return as ?? defaultTag;
|
|
29
35
|
};
|
|
30
36
|
}
|
|
37
|
+
|
|
38
|
+
// ../../lib/primitive/src/utils/assert-never.ts
|
|
31
39
|
function assertNever(value) {
|
|
32
40
|
throw new Error(`Unexpected value: ${String(value)}`);
|
|
33
41
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
38
|
-
var o = e.length;
|
|
39
|
-
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
40
|
-
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
41
|
-
return n;
|
|
42
|
-
}
|
|
43
|
-
function clsx() {
|
|
44
|
-
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
45
|
-
return n;
|
|
46
|
-
}
|
|
42
|
+
|
|
43
|
+
// ../../lib/primitive/src/utils/cn.ts
|
|
44
|
+
import { clsx } from "clsx";
|
|
47
45
|
function cn(...inputs) {
|
|
48
46
|
return clsx(...inputs);
|
|
49
47
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return !isNull(value) && typeof value === "object";
|
|
48
|
+
|
|
49
|
+
// ../../lib/primitive/src/utils/iterate.ts
|
|
50
|
+
function find(iterable, callback) {
|
|
51
|
+
for (const value of iterable) {
|
|
52
|
+
const result = callback(value);
|
|
53
|
+
if (result != null) {
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
61
58
|
}
|
|
62
|
-
function
|
|
63
|
-
|
|
59
|
+
function some(iterable, predicate) {
|
|
60
|
+
for (const value of iterable) {
|
|
61
|
+
if (predicate(value)) return true;
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
64
|
}
|
|
65
|
-
function
|
|
66
|
-
|
|
65
|
+
function every(iterable, predicate) {
|
|
66
|
+
let index = 0;
|
|
67
|
+
for (const value of iterable) {
|
|
68
|
+
if (!predicate(value, index++)) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
67
73
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
);
|
|
76
|
-
return fn ? fn(patched) : patched;
|
|
77
|
-
});
|
|
74
|
+
function* filter(iterable, predicate) {
|
|
75
|
+
let index = 0;
|
|
76
|
+
for (const value of iterable) {
|
|
77
|
+
if (predicate(value, index++)) {
|
|
78
|
+
yield value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
78
81
|
}
|
|
79
|
-
function
|
|
80
|
-
|
|
82
|
+
function* map(iterable, callback) {
|
|
83
|
+
let index = 0;
|
|
84
|
+
for (const value of iterable) {
|
|
85
|
+
yield callback(value, index++);
|
|
86
|
+
}
|
|
81
87
|
}
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
defaultTag: options.tag ?? "div",
|
|
88
|
-
strict: enforcement?.strict ?? false,
|
|
89
|
-
variantKeys,
|
|
90
|
-
...whenDefined("displayName", options.name),
|
|
91
|
-
...whenDefined("defaultProps", options.defaults),
|
|
92
|
-
...whenDefined("baseClassName", styling?.base),
|
|
93
|
-
...whenDefined("tagMap", styling?.tags),
|
|
94
|
-
...whenDefined("recipeMap", styling?.presets),
|
|
95
|
-
...whenDefined("variants", styling?.variants),
|
|
96
|
-
...whenDefined("defaultVariants", styling?.defaults),
|
|
97
|
-
...whenDefined("compoundVariants", styling?.compounds),
|
|
98
|
-
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
99
|
-
...whenDefined("ariaRules", enforcement?.aria),
|
|
100
|
-
...whenDefined("childRules", enforcement?.children),
|
|
101
|
-
...whenDefined("allowedAs", enforcement?.allowedAs),
|
|
102
|
-
...whenDefined("precomputedClasses", styling?.precomputedClasses)
|
|
103
|
-
});
|
|
88
|
+
function forEach(iterable, callback) {
|
|
89
|
+
let index = 0;
|
|
90
|
+
for (const value of iterable) {
|
|
91
|
+
callback(value, index++);
|
|
92
|
+
}
|
|
104
93
|
}
|
|
105
|
-
function
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
94
|
+
function reduce(iterable, initial, callback) {
|
|
95
|
+
let accumulator = initial;
|
|
96
|
+
let index = 0;
|
|
97
|
+
for (const value of iterable) {
|
|
98
|
+
accumulator = callback(accumulator, value, index++);
|
|
99
|
+
}
|
|
100
|
+
return accumulator;
|
|
110
101
|
}
|
|
111
|
-
function
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
for (const dim in record) {
|
|
119
|
-
const value = record[dim];
|
|
120
|
-
if (value === void 0 || value === null) continue;
|
|
121
|
-
if (!variants || !Object.hasOwn(variants, dim)) {
|
|
122
|
-
report(strict, `${name}: ${label2} references unknown variant "${dim}".`);
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
const states = variants[dim];
|
|
126
|
-
const stateKey = String(value);
|
|
127
|
-
if (!Object.hasOwn(states, stateKey)) {
|
|
128
|
-
report(
|
|
129
|
-
strict,
|
|
130
|
-
`${name}: ${label2} sets "${dim}" to unknown value "${stateKey}" (valid: ${Object.keys(states).join(", ")}).`
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
const { recipeMap } = resolved;
|
|
136
|
-
if (recipeMap) {
|
|
137
|
-
for (const recipeKey in recipeMap) {
|
|
138
|
-
checkSelection(`preset "${recipeKey}"`, recipeMap[recipeKey]);
|
|
102
|
+
function collect(iterable, callback) {
|
|
103
|
+
const result = {};
|
|
104
|
+
let index = 0;
|
|
105
|
+
for (const value of iterable) {
|
|
106
|
+
const entry = callback(value, index++);
|
|
107
|
+
if (entry === null) {
|
|
108
|
+
return null;
|
|
139
109
|
}
|
|
110
|
+
result[entry[0]] = entry[1];
|
|
140
111
|
}
|
|
141
|
-
|
|
112
|
+
return result;
|
|
142
113
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const messages = [...pendingAsyncWarns];
|
|
149
|
-
pendingAsyncWarns.clear();
|
|
150
|
-
for (const msg of messages) {
|
|
151
|
-
console.warn(msg);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
function report2(strict, message) {
|
|
155
|
-
if (!strict) return;
|
|
156
|
-
const mode = strict === true ? "throw" : strict;
|
|
157
|
-
if (mode === "throw") throw new Error(message);
|
|
158
|
-
if (mode === "async-warn") {
|
|
159
|
-
if (pendingAsyncWarns.has(message)) return;
|
|
160
|
-
pendingAsyncWarns.add(message);
|
|
161
|
-
if (!asyncWarnScheduled) {
|
|
162
|
-
asyncWarnScheduled = true;
|
|
163
|
-
queueMicrotask(flushAsyncWarns);
|
|
114
|
+
function findLast(value, callback) {
|
|
115
|
+
for (let index = value.length - 1; index >= 0; index--) {
|
|
116
|
+
const result = callback(value[index], index);
|
|
117
|
+
if (result != null) {
|
|
118
|
+
return result;
|
|
164
119
|
}
|
|
165
|
-
return;
|
|
166
120
|
}
|
|
167
|
-
|
|
168
|
-
warned.add(message);
|
|
169
|
-
console.warn(message);
|
|
121
|
+
return null;
|
|
170
122
|
}
|
|
171
|
-
function
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const tag = label(displayName);
|
|
178
|
-
if (recipeKey !== void 0 && (!recipeMap || !Object.hasOwn(recipeMap, recipeKey))) {
|
|
179
|
-
report2(strict, `${tag} Unknown recipeKey "${recipeKey}" \u2014 no preset with that name exists.`);
|
|
123
|
+
function* items(collection) {
|
|
124
|
+
for (let i = 0; i < collection.length; i++) {
|
|
125
|
+
const item = collection.item(i);
|
|
126
|
+
if (item !== null) {
|
|
127
|
+
yield item;
|
|
128
|
+
}
|
|
180
129
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
`${tag} Variant "${key}=${String(value)}" is not a defined value for the "${key}" dimension.`
|
|
191
|
-
);
|
|
130
|
+
}
|
|
131
|
+
function nodeList(list) {
|
|
132
|
+
return {
|
|
133
|
+
*[Symbol.iterator]() {
|
|
134
|
+
for (let i = 0; i < list.length; i++) {
|
|
135
|
+
const node = list.item(i);
|
|
136
|
+
if (node !== null) {
|
|
137
|
+
yield node;
|
|
138
|
+
}
|
|
192
139
|
}
|
|
193
140
|
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function mapEntries(m) {
|
|
144
|
+
return m.entries();
|
|
145
|
+
}
|
|
146
|
+
function set(s) {
|
|
147
|
+
return s.values();
|
|
148
|
+
}
|
|
149
|
+
function hasOwn(object, key) {
|
|
150
|
+
return Object.hasOwn(object, key);
|
|
151
|
+
}
|
|
152
|
+
function* entries(object) {
|
|
153
|
+
for (const key in object) {
|
|
154
|
+
if (!hasOwn(object, key)) continue;
|
|
155
|
+
yield [key, object[key]];
|
|
194
156
|
}
|
|
195
157
|
}
|
|
196
|
-
function
|
|
197
|
-
|
|
158
|
+
function* keys(object) {
|
|
159
|
+
for (const [key] of entries(object)) {
|
|
160
|
+
yield key;
|
|
161
|
+
}
|
|
198
162
|
}
|
|
199
|
-
function
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
163
|
+
function* values(object) {
|
|
164
|
+
for (const [, value] of entries(object)) {
|
|
165
|
+
yield value;
|
|
166
|
+
}
|
|
203
167
|
}
|
|
204
|
-
function
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if (typeof plugin.pipeline !== "function")
|
|
211
|
-
panic(
|
|
212
|
-
`[praxis-kit] Plugin factory return value is missing a 'pipeline' function. Got pipeline: ${typeof plugin.pipeline}.`
|
|
213
|
-
);
|
|
168
|
+
function mapValues(object, callback) {
|
|
169
|
+
const result = {};
|
|
170
|
+
for (const [key, value] of entries(object)) {
|
|
171
|
+
result[key] = callback(value, key);
|
|
172
|
+
}
|
|
173
|
+
return result;
|
|
214
174
|
}
|
|
215
|
-
function
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (typeof result !== "string")
|
|
220
|
-
panic(`[praxis-kit] Plugin pipeline must return a string. Got: ${describe(result)}.`);
|
|
221
|
-
return result;
|
|
222
|
-
};
|
|
175
|
+
function forEachEntry(object, callback) {
|
|
176
|
+
for (const [key, value] of entries(object)) {
|
|
177
|
+
callback(key, value);
|
|
178
|
+
}
|
|
223
179
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (!factory) {
|
|
228
|
-
const createClassPipeline2 = capabilities?.createClassPipeline;
|
|
229
|
-
const classPipeline2 = createClassPipeline2 ? createClassPipeline2(resolved) : NOOP_CLASS_PIPELINE;
|
|
230
|
-
return { pluginResult: void 0, classPipeline: classPipeline2 };
|
|
180
|
+
function forEachKey(object, callback) {
|
|
181
|
+
for (const key of keys(object)) {
|
|
182
|
+
callback(key);
|
|
231
183
|
}
|
|
232
|
-
const pluginResult = factory(resolved, strict);
|
|
233
|
-
assertPluginShape(pluginResult);
|
|
234
|
-
const classPipeline = guardPipeline(pluginResult.pipeline);
|
|
235
|
-
return { pluginResult, classPipeline };
|
|
236
184
|
}
|
|
237
|
-
function
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
return mergeProps(resolved.defaultProps, props);
|
|
242
|
-
},
|
|
243
|
-
resolveClasses(tag, props, className, recipe) {
|
|
244
|
-
if (process.env.NODE_ENV !== "production") {
|
|
245
|
-
validateRenderProps(resolved, props, recipe);
|
|
246
|
-
}
|
|
247
|
-
return classPipeline(tag, props, className, recipe);
|
|
248
|
-
},
|
|
249
|
-
resolveAria(tag, props) {
|
|
250
|
-
if (!engine) return { props };
|
|
251
|
-
const result = engine.validate(tag, props);
|
|
252
|
-
return { props: result.props };
|
|
253
|
-
}
|
|
254
|
-
};
|
|
185
|
+
function forEachValue(object, callback) {
|
|
186
|
+
for (const value of values(object)) {
|
|
187
|
+
callback(value);
|
|
188
|
+
}
|
|
255
189
|
}
|
|
256
|
-
function
|
|
257
|
-
|
|
190
|
+
function forEachSet(s, callback) {
|
|
191
|
+
for (const value of s) {
|
|
192
|
+
callback(value);
|
|
193
|
+
}
|
|
258
194
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
195
|
+
var iterate = Object.freeze({
|
|
196
|
+
entries,
|
|
197
|
+
filter,
|
|
198
|
+
find,
|
|
199
|
+
findLast,
|
|
200
|
+
forEach,
|
|
201
|
+
forEachEntry,
|
|
202
|
+
forEachKey,
|
|
203
|
+
forEachSet,
|
|
204
|
+
forEachValue,
|
|
205
|
+
items,
|
|
206
|
+
keys,
|
|
207
|
+
map,
|
|
208
|
+
mapEntries,
|
|
209
|
+
mapValues,
|
|
210
|
+
nodeList,
|
|
211
|
+
reduce,
|
|
212
|
+
collect,
|
|
213
|
+
set,
|
|
214
|
+
some,
|
|
215
|
+
every,
|
|
216
|
+
values
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// ../../lib/primitive/src/utils/merge-props.ts
|
|
220
|
+
function mergeProps(defaultProps, props) {
|
|
221
|
+
return {
|
|
222
|
+
...defaultProps ?? {},
|
|
223
|
+
...props
|
|
224
|
+
};
|
|
285
225
|
}
|
|
226
|
+
|
|
227
|
+
// ../../lib/primitive/src/constants/aria/global-aria-attributes.ts
|
|
228
|
+
var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
229
|
+
"aria-atomic",
|
|
230
|
+
"aria-busy",
|
|
231
|
+
"aria-controls",
|
|
232
|
+
"aria-current",
|
|
233
|
+
"aria-describedby",
|
|
234
|
+
"aria-details",
|
|
235
|
+
"aria-disabled",
|
|
236
|
+
"aria-errormessage",
|
|
237
|
+
"aria-flowto",
|
|
238
|
+
"aria-hidden",
|
|
239
|
+
"aria-keyshortcuts",
|
|
240
|
+
"aria-label",
|
|
241
|
+
"aria-labelledby",
|
|
242
|
+
"aria-live",
|
|
243
|
+
"aria-owns",
|
|
244
|
+
"aria-relevant",
|
|
245
|
+
"aria-roledescription"
|
|
246
|
+
]);
|
|
247
|
+
|
|
248
|
+
// ../../lib/primitive/src/constants/aria/implicit-role-record.ts
|
|
249
|
+
var IMPLICIT_ROLE_RECORD = {
|
|
250
|
+
// Landmarks
|
|
251
|
+
article: "article",
|
|
252
|
+
aside: "complementary",
|
|
253
|
+
footer: "contentinfo",
|
|
254
|
+
header: "banner",
|
|
255
|
+
main: "main",
|
|
256
|
+
nav: "navigation",
|
|
257
|
+
// Interactive
|
|
258
|
+
a: "link",
|
|
259
|
+
button: "button",
|
|
260
|
+
select: "listbox",
|
|
261
|
+
textarea: "textbox",
|
|
262
|
+
// Headings
|
|
263
|
+
h1: "heading",
|
|
264
|
+
h2: "heading",
|
|
265
|
+
h3: "heading",
|
|
266
|
+
h4: "heading",
|
|
267
|
+
h5: "heading",
|
|
268
|
+
h6: "heading",
|
|
269
|
+
// Lists
|
|
270
|
+
ul: "list",
|
|
271
|
+
ol: "list",
|
|
272
|
+
li: "listitem",
|
|
273
|
+
// Tables
|
|
274
|
+
table: "table",
|
|
275
|
+
tr: "row",
|
|
276
|
+
td: "cell",
|
|
277
|
+
th: "columnheader",
|
|
278
|
+
// Structural / semantic
|
|
279
|
+
dialog: "dialog",
|
|
280
|
+
fieldset: "group",
|
|
281
|
+
figure: "figure",
|
|
282
|
+
meter: "meter",
|
|
283
|
+
output: "status",
|
|
284
|
+
progress: "progressbar"
|
|
285
|
+
};
|
|
286
|
+
var INPUT_TYPE_ROLE_MAP = {
|
|
287
|
+
checkbox: "checkbox",
|
|
288
|
+
radio: "radio",
|
|
289
|
+
range: "slider",
|
|
290
|
+
number: "spinbutton",
|
|
291
|
+
search: "searchbox",
|
|
292
|
+
text: "textbox",
|
|
293
|
+
email: "textbox",
|
|
294
|
+
tel: "textbox",
|
|
295
|
+
url: "textbox",
|
|
296
|
+
button: "button",
|
|
297
|
+
submit: "button",
|
|
298
|
+
reset: "button",
|
|
299
|
+
image: "button"
|
|
300
|
+
};
|
|
301
|
+
var STRONG_ROLES = [
|
|
302
|
+
"main",
|
|
303
|
+
"navigation",
|
|
304
|
+
"complementary",
|
|
305
|
+
"contentinfo",
|
|
306
|
+
"banner"
|
|
307
|
+
];
|
|
308
|
+
var STANDALONE_ROLES = ["article"];
|
|
309
|
+
var STRONG_ROLES_SET = new Set(STRONG_ROLES);
|
|
310
|
+
var STANDALONE_ROLES_SET = new Set(STANDALONE_ROLES);
|
|
311
|
+
|
|
312
|
+
// ../../lib/primitive/src/constants/aria/known-aria-roles.ts
|
|
286
313
|
var KNOWN_ARIA_ROLES = [
|
|
287
314
|
"alert",
|
|
288
315
|
"alertdialog",
|
|
@@ -367,59 +394,8 @@ var KNOWN_ARIA_ROLES = [
|
|
|
367
394
|
"treeitem"
|
|
368
395
|
];
|
|
369
396
|
var KNOWN_ARIA_ROLES_SET = new Set(KNOWN_ARIA_ROLES);
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
"aria-busy",
|
|
373
|
-
"aria-controls",
|
|
374
|
-
"aria-current",
|
|
375
|
-
"aria-describedby",
|
|
376
|
-
"aria-details",
|
|
377
|
-
"aria-disabled",
|
|
378
|
-
"aria-errormessage",
|
|
379
|
-
"aria-flowto",
|
|
380
|
-
"aria-hidden",
|
|
381
|
-
"aria-keyshortcuts",
|
|
382
|
-
"aria-label",
|
|
383
|
-
"aria-labelledby",
|
|
384
|
-
"aria-live",
|
|
385
|
-
"aria-owns",
|
|
386
|
-
"aria-relevant",
|
|
387
|
-
"aria-roledescription"
|
|
388
|
-
]);
|
|
389
|
-
var IMPLICIT_ROLE_RECORD = {
|
|
390
|
-
article: "article",
|
|
391
|
-
aside: "complementary",
|
|
392
|
-
footer: "contentinfo",
|
|
393
|
-
header: "banner",
|
|
394
|
-
main: "main",
|
|
395
|
-
nav: "navigation",
|
|
396
|
-
button: "button",
|
|
397
|
-
a: "link",
|
|
398
|
-
select: "listbox",
|
|
399
|
-
h1: "heading",
|
|
400
|
-
h2: "heading",
|
|
401
|
-
h3: "heading",
|
|
402
|
-
h4: "heading",
|
|
403
|
-
h5: "heading",
|
|
404
|
-
h6: "heading",
|
|
405
|
-
ul: "list",
|
|
406
|
-
ol: "list",
|
|
407
|
-
li: "listitem",
|
|
408
|
-
table: "table",
|
|
409
|
-
tr: "row",
|
|
410
|
-
td: "cell",
|
|
411
|
-
th: "columnheader"
|
|
412
|
-
};
|
|
413
|
-
var STRONG_ROLES = [
|
|
414
|
-
"main",
|
|
415
|
-
"navigation",
|
|
416
|
-
"complementary",
|
|
417
|
-
"contentinfo",
|
|
418
|
-
"banner"
|
|
419
|
-
];
|
|
420
|
-
var STANDALONE_ROLES = ["article"];
|
|
421
|
-
var STRONG_ROLES_SET = new Set(STRONG_ROLES);
|
|
422
|
-
var STANDALONE_ROLES_SET = new Set(STANDALONE_ROLES);
|
|
397
|
+
|
|
398
|
+
// ../../lib/primitive/src/constants/aria/role-restricted-attributes.ts
|
|
423
399
|
var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
|
|
424
400
|
[
|
|
425
401
|
"aria-activedescendant",
|
|
@@ -569,9 +545,8 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
|
|
|
569
545
|
/* @__PURE__ */ new Set(["meter", "progressbar", "scrollbar", "separator", "slider", "spinbutton"])
|
|
570
546
|
]
|
|
571
547
|
]);
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
}
|
|
548
|
+
|
|
549
|
+
// ../../lib/primitive/src/guards/aria/is-aria-attribute.ts
|
|
575
550
|
function isGlobalAriaAttribute(attr) {
|
|
576
551
|
return GLOBAL_ARIA_ATTRIBUTES.has(attr);
|
|
577
552
|
}
|
|
@@ -581,6 +556,8 @@ function isAriaAttributeValidForRole(attr, role) {
|
|
|
581
556
|
if (isUndefined(role)) return false;
|
|
582
557
|
return allowedRoles.has(role);
|
|
583
558
|
}
|
|
559
|
+
|
|
560
|
+
// ../../lib/primitive/src/guards/aria/is-aria-role.ts
|
|
584
561
|
function isStrongImplicitRole(tag) {
|
|
585
562
|
if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
|
|
586
563
|
return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
|
|
@@ -589,119 +566,559 @@ function isStandaloneTag(tag) {
|
|
|
589
566
|
if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
|
|
590
567
|
return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
|
|
591
568
|
}
|
|
569
|
+
function getInputImplicitRole(type) {
|
|
570
|
+
if (type == null || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
|
|
571
|
+
return INPUT_TYPE_ROLE_MAP[type];
|
|
572
|
+
}
|
|
573
|
+
function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
|
|
574
|
+
const isNamed = typeof ariaLabel === "string" || typeof ariaLabelledBy === "string";
|
|
575
|
+
if (!isNamed) return void 0;
|
|
576
|
+
if (tag === "section") return "region";
|
|
577
|
+
if (tag === "form") return "form";
|
|
578
|
+
return void 0;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// ../../lib/primitive/src/guards/aria/is-known-aria-role.ts
|
|
592
582
|
function isKnownAriaRole(value) {
|
|
593
583
|
return isString(value) && KNOWN_ARIA_ROLES_SET.has(value);
|
|
594
584
|
}
|
|
595
585
|
|
|
596
|
-
//
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
a: "link",
|
|
606
|
-
select: "listbox",
|
|
607
|
-
h1: "heading",
|
|
608
|
-
h2: "heading",
|
|
609
|
-
h3: "heading",
|
|
610
|
-
h4: "heading",
|
|
611
|
-
h5: "heading",
|
|
612
|
-
h6: "heading",
|
|
613
|
-
ul: "list",
|
|
614
|
-
ol: "list",
|
|
615
|
-
li: "listitem",
|
|
616
|
-
table: "table",
|
|
617
|
-
tr: "row",
|
|
618
|
-
td: "cell",
|
|
619
|
-
th: "columnheader"
|
|
620
|
-
};
|
|
621
|
-
function getImplicitRole(tag) {
|
|
622
|
-
if (tag in IMPLICIT_ROLE_RECORD2) return IMPLICIT_ROLE_RECORD2[tag];
|
|
623
|
-
return void 0;
|
|
624
|
-
}
|
|
625
|
-
var COMPONENT_DEFAULT_TAG2 = /* @__PURE__ */ Symbol.for("praxis.component-default-tag");
|
|
626
|
-
function getAsProp(child) {
|
|
627
|
-
if (!isObject(child) || !("props" in child)) return void 0;
|
|
628
|
-
const props = child.props;
|
|
629
|
-
if (!isObject(props)) return void 0;
|
|
630
|
-
const as = props.as;
|
|
631
|
-
return isString(as) && as !== "" ? as : void 0;
|
|
586
|
+
// ../../lib/adapter-utils/src/apply-filter.ts
|
|
587
|
+
function applyFilter(props, filterProps, variantKeys) {
|
|
588
|
+
const out = {};
|
|
589
|
+
iterate.forEachEntry(props, (k) => {
|
|
590
|
+
if (!Object.hasOwn(props, k)) return;
|
|
591
|
+
if (filterProps(k, variantKeys)) return;
|
|
592
|
+
out[k] = props[k];
|
|
593
|
+
});
|
|
594
|
+
return out;
|
|
632
595
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
if (
|
|
637
|
-
if (
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
return
|
|
596
|
+
|
|
597
|
+
// ../../lib/contract/src/aria/aria-role-policy.ts
|
|
598
|
+
function getImplicitRole(tag, props) {
|
|
599
|
+
if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
|
|
600
|
+
if (tag === "input") return getInputImplicitRole(props?.type);
|
|
601
|
+
if (tag === "img") return props?.alt === "" ? "none" : "img";
|
|
602
|
+
if (tag === "section" || tag === "form") {
|
|
603
|
+
return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
|
|
641
604
|
}
|
|
642
605
|
return void 0;
|
|
643
606
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
};
|
|
607
|
+
|
|
608
|
+
// ../../lib/contract/src/strict/invariant-base.ts
|
|
609
|
+
var InvariantBase = class {
|
|
610
|
+
diagnostics;
|
|
611
|
+
constructor(diagnostics) {
|
|
612
|
+
this.diagnostics = diagnostics;
|
|
651
613
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
const tag = getTag(child);
|
|
655
|
-
return tag !== void 0 && set.has(tag);
|
|
656
|
-
}
|
|
657
|
-
var pendingAsyncWarns2 = /* @__PURE__ */ new Set();
|
|
658
|
-
var asyncWarnScheduled2 = false;
|
|
659
|
-
function flushAsyncWarns2() {
|
|
660
|
-
asyncWarnScheduled2 = false;
|
|
661
|
-
const messages = [...pendingAsyncWarns2];
|
|
662
|
-
pendingAsyncWarns2.clear();
|
|
663
|
-
for (const msg of messages) {
|
|
664
|
-
console.warn(msg);
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
function scheduleAsyncWarn(message) {
|
|
668
|
-
if (pendingAsyncWarns2.has(message)) return;
|
|
669
|
-
pendingAsyncWarns2.add(message);
|
|
670
|
-
if (!asyncWarnScheduled2) {
|
|
671
|
-
asyncWarnScheduled2 = true;
|
|
672
|
-
queueMicrotask(flushAsyncWarns2);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
var StrictBase = class {
|
|
676
|
-
strict;
|
|
677
|
-
constructor(strict) {
|
|
678
|
-
this.strict = strict;
|
|
679
|
-
}
|
|
680
|
-
violate(message) {
|
|
681
|
-
if (this.strict === true || this.strict === "throw") {
|
|
682
|
-
throw new Error(message);
|
|
683
|
-
}
|
|
684
|
-
this.warn(message);
|
|
614
|
+
get active() {
|
|
615
|
+
return this.diagnostics.active;
|
|
685
616
|
}
|
|
686
|
-
|
|
617
|
+
violate(input) {
|
|
618
|
+
this.diagnostics.error(input);
|
|
619
|
+
}
|
|
620
|
+
// Always caps at warn — never throws. ARIA 'warning' violations route here
|
|
687
621
|
// so they surface even in strict='throw' mode without aborting a render.
|
|
688
|
-
warn(
|
|
689
|
-
|
|
690
|
-
if (this.strict === "async-warn") {
|
|
691
|
-
scheduleAsyncWarn(message);
|
|
692
|
-
return;
|
|
693
|
-
}
|
|
694
|
-
console.warn(message);
|
|
622
|
+
warn(input) {
|
|
623
|
+
this.diagnostics.warn(input);
|
|
695
624
|
}
|
|
696
|
-
invariant(condition,
|
|
697
|
-
if (!condition)
|
|
698
|
-
this.violate(message);
|
|
699
|
-
}
|
|
625
|
+
invariant(condition, input) {
|
|
626
|
+
if (!condition) this.violate(input);
|
|
700
627
|
}
|
|
701
628
|
};
|
|
702
|
-
|
|
703
|
-
|
|
629
|
+
|
|
630
|
+
// ../../lib/diagnostics/src/category.ts
|
|
631
|
+
var DiagnosticCategory = /* @__PURE__ */ ((DiagnosticCategory2) => {
|
|
632
|
+
DiagnosticCategory2[DiagnosticCategory2["Contract"] = 0] = "Contract";
|
|
633
|
+
DiagnosticCategory2[DiagnosticCategory2["HTML"] = 1] = "HTML";
|
|
634
|
+
DiagnosticCategory2[DiagnosticCategory2["ARIA"] = 2] = "ARIA";
|
|
635
|
+
DiagnosticCategory2[DiagnosticCategory2["Composition"] = 3] = "Composition";
|
|
636
|
+
DiagnosticCategory2[DiagnosticCategory2["Rendering"] = 4] = "Rendering";
|
|
637
|
+
DiagnosticCategory2[DiagnosticCategory2["Accessibility"] = 5] = "Accessibility";
|
|
638
|
+
DiagnosticCategory2[DiagnosticCategory2["Performance"] = 6] = "Performance";
|
|
639
|
+
DiagnosticCategory2[DiagnosticCategory2["Internal"] = 7] = "Internal";
|
|
640
|
+
DiagnosticCategory2[DiagnosticCategory2["Deprecation"] = 8] = "Deprecation";
|
|
641
|
+
DiagnosticCategory2[DiagnosticCategory2["Lint"] = 9] = "Lint";
|
|
642
|
+
return DiagnosticCategory2;
|
|
643
|
+
})(DiagnosticCategory || {});
|
|
644
|
+
|
|
645
|
+
// ../../lib/diagnostics/src/error.ts
|
|
646
|
+
var PraxisError = class extends Error {
|
|
647
|
+
diagnostic;
|
|
648
|
+
constructor(diagnostic) {
|
|
649
|
+
super(diagnostic.message);
|
|
650
|
+
this.name = "PraxisError";
|
|
651
|
+
this.diagnostic = diagnostic;
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
// ../../lib/diagnostics/src/severity.ts
|
|
656
|
+
var Severity = /* @__PURE__ */ ((Severity2) => {
|
|
657
|
+
Severity2[Severity2["Debug"] = 0] = "Debug";
|
|
658
|
+
Severity2[Severity2["Info"] = 1] = "Info";
|
|
659
|
+
Severity2[Severity2["Warning"] = 2] = "Warning";
|
|
660
|
+
Severity2[Severity2["Error"] = 3] = "Error";
|
|
661
|
+
Severity2[Severity2["Fatal"] = 4] = "Fatal";
|
|
662
|
+
return Severity2;
|
|
663
|
+
})(Severity || {});
|
|
664
|
+
|
|
665
|
+
// ../../lib/diagnostics/src/policy.ts
|
|
666
|
+
var DefaultPolicy = class {
|
|
667
|
+
reportThreshold;
|
|
668
|
+
throwThreshold;
|
|
669
|
+
constructor({
|
|
670
|
+
reportThreshold = 1 /* Info */,
|
|
671
|
+
throwThreshold = 4 /* Fatal */
|
|
672
|
+
} = {}) {
|
|
673
|
+
this.reportThreshold = reportThreshold;
|
|
674
|
+
this.throwThreshold = throwThreshold;
|
|
675
|
+
}
|
|
676
|
+
resolve(diagnostic) {
|
|
677
|
+
if (diagnostic.severity >= this.throwThreshold) return 2 /* Throw */;
|
|
678
|
+
if (diagnostic.severity >= this.reportThreshold) return 1 /* Report */;
|
|
679
|
+
return 0 /* Ignore */;
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
// ../../lib/diagnostics/src/diagnostics.ts
|
|
684
|
+
var Diagnostics = class {
|
|
685
|
+
reporter;
|
|
686
|
+
policy;
|
|
687
|
+
// Pre-computed at construction time: true if Warning-level diagnostics are not ignored.
|
|
688
|
+
active;
|
|
689
|
+
constructor(reporter, policy = new DefaultPolicy()) {
|
|
690
|
+
this.reporter = reporter;
|
|
691
|
+
this.policy = policy;
|
|
692
|
+
this.active = policy.resolve({ severity: 2 /* Warning */ }) !== 0 /* Ignore */;
|
|
693
|
+
}
|
|
694
|
+
report(diagnostic) {
|
|
695
|
+
const enforcement = this.policy.resolve(diagnostic);
|
|
696
|
+
if (enforcement === 0 /* Ignore */) return diagnostic;
|
|
697
|
+
if (enforcement === 2 /* Throw */) throw new PraxisError(diagnostic);
|
|
698
|
+
this.reporter.report(diagnostic);
|
|
699
|
+
return diagnostic;
|
|
700
|
+
}
|
|
701
|
+
warn(input) {
|
|
702
|
+
return this.report({ ...input, severity: 2 /* Warning */ });
|
|
703
|
+
}
|
|
704
|
+
error(input) {
|
|
705
|
+
return this.report({ ...input, severity: 3 /* Error */ });
|
|
706
|
+
}
|
|
707
|
+
info(input) {
|
|
708
|
+
return this.report({ ...input, severity: 1 /* Info */ });
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
// ../../lib/diagnostics/src/formatter.ts
|
|
713
|
+
function formatDiagnostic(diagnostic) {
|
|
714
|
+
const level = Severity[diagnostic.severity];
|
|
715
|
+
const category = DiagnosticCategory[diagnostic.category];
|
|
716
|
+
const prefix = category !== void 0 ? `[${category}] ` : "";
|
|
717
|
+
return `${level} ${diagnostic.code}: ${prefix}${diagnostic.message}`;
|
|
704
718
|
}
|
|
719
|
+
|
|
720
|
+
// ../../lib/diagnostics/src/console-reporter.ts
|
|
721
|
+
var ConsoleReporter = class {
|
|
722
|
+
report(diagnostic) {
|
|
723
|
+
const message = formatDiagnostic(diagnostic);
|
|
724
|
+
switch (diagnostic.severity) {
|
|
725
|
+
case 0 /* Debug */:
|
|
726
|
+
console.debug(message);
|
|
727
|
+
break;
|
|
728
|
+
case 1 /* Info */:
|
|
729
|
+
console.info(message);
|
|
730
|
+
break;
|
|
731
|
+
case 2 /* Warning */:
|
|
732
|
+
console.warn(message);
|
|
733
|
+
break;
|
|
734
|
+
case 3 /* Error */:
|
|
735
|
+
case 4 /* Fatal */:
|
|
736
|
+
console.error(message);
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
// ../../lib/diagnostics/src/null-reporter.ts
|
|
743
|
+
var nullReporter = {
|
|
744
|
+
report() {
|
|
745
|
+
}
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
// ../../lib/diagnostics/src/presets.ts
|
|
749
|
+
var ignoreAllPolicy = {
|
|
750
|
+
resolve(_) {
|
|
751
|
+
return 0 /* Ignore */;
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
var warnOnlyReporter = {
|
|
755
|
+
report(diagnostic) {
|
|
756
|
+
console.warn(formatDiagnostic(diagnostic));
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
var silentDiagnostics = new Diagnostics(nullReporter, ignoreAllPolicy);
|
|
760
|
+
var warnDiagnostics = new Diagnostics(
|
|
761
|
+
warnOnlyReporter,
|
|
762
|
+
new DefaultPolicy({ reportThreshold: 2 /* Warning */, throwThreshold: 4 /* Fatal */ })
|
|
763
|
+
);
|
|
764
|
+
var throwDiagnostics = new Diagnostics(
|
|
765
|
+
new ConsoleReporter(),
|
|
766
|
+
new DefaultPolicy({ reportThreshold: 2 /* Warning */, throwThreshold: 3 /* Error */ })
|
|
767
|
+
);
|
|
768
|
+
|
|
769
|
+
// ../../lib/contract/src/diagnostics/aria.ts
|
|
770
|
+
var AriaDiagnostics = {
|
|
771
|
+
/** Generic bridge for violations produced by external AriaRule functions. */
|
|
772
|
+
fromViolation(v) {
|
|
773
|
+
return {
|
|
774
|
+
code: "ARIA2002" /* AriaViolation */,
|
|
775
|
+
category: 2 /* ARIA */,
|
|
776
|
+
message: v.message
|
|
777
|
+
};
|
|
778
|
+
},
|
|
779
|
+
attributeInvalid(key, role) {
|
|
780
|
+
return {
|
|
781
|
+
code: "ARIA2003" /* AriaAttributeInvalid */,
|
|
782
|
+
category: 2 /* ARIA */,
|
|
783
|
+
message: `"${key}" is not valid on role="${role}". It will be removed.`,
|
|
784
|
+
rationale: "Invalid ARIA attributes are ignored by assistive technology and may trigger accessibility-tree warnings in browser devtools.",
|
|
785
|
+
suggestions: [
|
|
786
|
+
{
|
|
787
|
+
title: "Remove the attribute",
|
|
788
|
+
description: `"${key}" is not in the allowed attribute set for role="${role}".`
|
|
789
|
+
}
|
|
790
|
+
]
|
|
791
|
+
};
|
|
792
|
+
},
|
|
793
|
+
missingLiveRegion(role, impliedLive) {
|
|
794
|
+
return {
|
|
795
|
+
code: "ARIA2004" /* AriaMissingLiveRegion */,
|
|
796
|
+
category: 2 /* ARIA */,
|
|
797
|
+
message: `role="${role}" implies aria-live="${impliedLive}" but it is missing. It has been injected.`,
|
|
798
|
+
rationale: "Live-region roles announce dynamic content changes to screen readers. Without aria-live the politeness level is unspecified and announcements may be silent.",
|
|
799
|
+
suggestions: [
|
|
800
|
+
{
|
|
801
|
+
title: `Add aria-live="${impliedLive}"`,
|
|
802
|
+
description: `role="${role}" conventionally implies aria-live="${impliedLive}".`,
|
|
803
|
+
fix: `aria-live="${impliedLive}"`
|
|
804
|
+
}
|
|
805
|
+
]
|
|
806
|
+
};
|
|
807
|
+
},
|
|
808
|
+
missingAtomic(role) {
|
|
809
|
+
return {
|
|
810
|
+
code: "ARIA2005" /* AriaMissingAtomic */,
|
|
811
|
+
category: 2 /* ARIA */,
|
|
812
|
+
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.`,
|
|
813
|
+
rationale: "aria-atomic controls whether assistive technology announces the entire live region or only the changed nodes. Omitting it leaves the behaviour browser-defined."
|
|
814
|
+
};
|
|
815
|
+
},
|
|
816
|
+
relevantInvalidTokens(invalid) {
|
|
817
|
+
const quoted = invalid.map((t) => `"${t}"`).join(", ");
|
|
818
|
+
return {
|
|
819
|
+
code: "ARIA2006" /* AriaRelevantInvalidToken */,
|
|
820
|
+
category: 2 /* ARIA */,
|
|
821
|
+
message: `aria-relevant contains invalid token(s): ${quoted}. Valid tokens are: additions, removals, text, all.`,
|
|
822
|
+
rationale: "aria-relevant accepts a space-separated list of change types. Unrecognised tokens are silently ignored by assistive technology, making the attribute ineffective.",
|
|
823
|
+
suggestions: [
|
|
824
|
+
{
|
|
825
|
+
title: "Use only valid tokens",
|
|
826
|
+
description: "Valid values are: additions, removals, text, all (or a space-separated combination)."
|
|
827
|
+
}
|
|
828
|
+
]
|
|
829
|
+
};
|
|
830
|
+
},
|
|
831
|
+
relevantSuperseded() {
|
|
832
|
+
return {
|
|
833
|
+
code: "ARIA2007" /* AriaRelevantSuperseded */,
|
|
834
|
+
category: 2 /* ARIA */,
|
|
835
|
+
message: 'aria-relevant includes "all" alongside other tokens. "all" supersedes additions, removals, and text \u2014 use aria-relevant="all" alone.',
|
|
836
|
+
rationale: '"all" is equivalent to "additions removals text". Combining it with other tokens is redundant and may confuse readers of the markup.',
|
|
837
|
+
suggestions: [
|
|
838
|
+
{
|
|
839
|
+
title: 'Use aria-relevant="all"',
|
|
840
|
+
fix: 'aria-relevant="all"'
|
|
841
|
+
}
|
|
842
|
+
]
|
|
843
|
+
};
|
|
844
|
+
},
|
|
845
|
+
missingAccessibleName(tag) {
|
|
846
|
+
return {
|
|
847
|
+
code: "ARIA2009" /* AriaMissingAccessibleName */,
|
|
848
|
+
category: 2 /* ARIA */,
|
|
849
|
+
message: `<${tag}> has no accessible name. Add aria-label or aria-labelledby.`,
|
|
850
|
+
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.",
|
|
851
|
+
suggestions: [
|
|
852
|
+
{
|
|
853
|
+
title: "Add aria-label",
|
|
854
|
+
description: `Add aria-label="\u2026" directly to the <${tag}> element.`
|
|
855
|
+
},
|
|
856
|
+
{
|
|
857
|
+
title: "Add aria-labelledby",
|
|
858
|
+
description: "Point aria-labelledby at the id of an existing heading or label element."
|
|
859
|
+
}
|
|
860
|
+
]
|
|
861
|
+
};
|
|
862
|
+
},
|
|
863
|
+
attributeOnPresentational(attr, tag) {
|
|
864
|
+
return {
|
|
865
|
+
code: "ARIA2010" /* AriaAttributeOnPresentational */,
|
|
866
|
+
category: 2 /* ARIA */,
|
|
867
|
+
message: `"${attr}" is not allowed on a presentational <${tag}>. Presentational elements are invisible to assistive technology.`,
|
|
868
|
+
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.',
|
|
869
|
+
suggestions: [
|
|
870
|
+
{
|
|
871
|
+
title: "Remove the attribute",
|
|
872
|
+
description: `"${attr}" has no effect when the element has role="none" or role="presentation".`
|
|
873
|
+
}
|
|
874
|
+
]
|
|
875
|
+
};
|
|
876
|
+
},
|
|
877
|
+
ariaHiddenOnFocusable(tag) {
|
|
878
|
+
return {
|
|
879
|
+
code: "ARIA2011" /* AriaHiddenOnFocusable */,
|
|
880
|
+
category: 2 /* ARIA */,
|
|
881
|
+
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.`,
|
|
882
|
+
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.',
|
|
883
|
+
suggestions: [
|
|
884
|
+
{
|
|
885
|
+
title: "Remove aria-hidden",
|
|
886
|
+
description: "If the element should be hidden from all users, use the HTML hidden attribute or CSS display:none instead."
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
title: "Make the element non-focusable",
|
|
890
|
+
description: 'If the element is intentionally decorative, add tabindex="-1" and disable it so it is not reachable by keyboard.'
|
|
891
|
+
}
|
|
892
|
+
]
|
|
893
|
+
};
|
|
894
|
+
},
|
|
895
|
+
invalidAttributeValue(attr, value, expected) {
|
|
896
|
+
const got = value === null ? "null" : value === void 0 ? "undefined" : typeof value === "string" ? `"${value}"` : String(value);
|
|
897
|
+
return {
|
|
898
|
+
code: "ARIA2013" /* AriaInvalidAttributeValue */,
|
|
899
|
+
category: 2 /* ARIA */,
|
|
900
|
+
message: `"${attr}" has an invalid value (${got}). Expected: ${expected}.`,
|
|
901
|
+
rationale: "ARIA attributes with invalid values are silently ignored by assistive technology, making the markup semantically inert.",
|
|
902
|
+
suggestions: [
|
|
903
|
+
{
|
|
904
|
+
title: `Use a valid value for ${attr}`,
|
|
905
|
+
description: `Valid values are: ${expected}.`
|
|
906
|
+
}
|
|
907
|
+
]
|
|
908
|
+
};
|
|
909
|
+
},
|
|
910
|
+
redundantAriaLevel(tag, level) {
|
|
911
|
+
return {
|
|
912
|
+
code: "ARIA2014" /* AriaRedundantLevelAttribute */,
|
|
913
|
+
category: 2 /* ARIA */,
|
|
914
|
+
message: `aria-level="${level}" is redundant on <${tag}>: the element already has an implicit heading level of ${level}. Remove the attribute.`,
|
|
915
|
+
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>).',
|
|
916
|
+
suggestions: [
|
|
917
|
+
{
|
|
918
|
+
title: "Remove aria-level",
|
|
919
|
+
description: `<${tag}> already implies aria-level="${level}".`
|
|
920
|
+
}
|
|
921
|
+
]
|
|
922
|
+
};
|
|
923
|
+
},
|
|
924
|
+
requiredProperty(attr, role) {
|
|
925
|
+
return {
|
|
926
|
+
code: "ARIA2012" /* AriaRequiredProperty */,
|
|
927
|
+
category: 2 /* ARIA */,
|
|
928
|
+
message: `"${attr}" is required for role="${role}" but is missing.`,
|
|
929
|
+
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.`,
|
|
930
|
+
suggestions: [
|
|
931
|
+
{
|
|
932
|
+
title: `Add ${attr}`,
|
|
933
|
+
description: `role="${role}" requires "${attr}" to be present.`
|
|
934
|
+
}
|
|
935
|
+
]
|
|
936
|
+
};
|
|
937
|
+
},
|
|
938
|
+
invalidRole(role, tag) {
|
|
939
|
+
return {
|
|
940
|
+
code: "ARIA2008" /* AriaInvalidRole */,
|
|
941
|
+
category: 2 /* ARIA */,
|
|
942
|
+
message: `Invalid role "${role ?? ""}" on <${tag}>.`,
|
|
943
|
+
rationale: "An unrecognised or misapplied ARIA role is ignored by assistive technology and may degrade the accessibility of the element."
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
|
|
948
|
+
// ../../lib/contract/src/diagnostics/contract.ts
|
|
949
|
+
var ContractDiagnostics = {
|
|
950
|
+
unexpectedChild(typeName, index, context) {
|
|
951
|
+
return {
|
|
952
|
+
code: "COMP1004" /* UnexpectedChild */,
|
|
953
|
+
category: 0 /* Contract */,
|
|
954
|
+
component: context,
|
|
955
|
+
message: `${context}: unexpected child "${typeName}" at index ${index}.`
|
|
956
|
+
};
|
|
957
|
+
},
|
|
958
|
+
ambiguousChild(typeName, index, ruleNames, context) {
|
|
959
|
+
const quoted = ruleNames.map((n) => `"${n}"`).join(" and ");
|
|
960
|
+
return {
|
|
961
|
+
code: "COMP1005" /* AmbiguousChild */,
|
|
962
|
+
category: 0 /* Contract */,
|
|
963
|
+
component: context,
|
|
964
|
+
message: `${context}: child "${typeName}" at index ${index} matches multiple child rules: ${quoted}.`
|
|
965
|
+
};
|
|
966
|
+
},
|
|
967
|
+
cardinalityMin(ruleName, min, context) {
|
|
968
|
+
return {
|
|
969
|
+
code: "COMP1006" /* CardinalityMin */,
|
|
970
|
+
category: 0 /* Contract */,
|
|
971
|
+
component: context,
|
|
972
|
+
message: `${context}: "${ruleName}" requires at least ${min}.`
|
|
973
|
+
};
|
|
974
|
+
},
|
|
975
|
+
cardinalityMax(ruleName, max, context) {
|
|
976
|
+
return {
|
|
977
|
+
code: "COMP1007" /* CardinalityMax */,
|
|
978
|
+
category: 0 /* Contract */,
|
|
979
|
+
component: context,
|
|
980
|
+
message: `${context}: "${ruleName}" allows at most ${max}.`
|
|
981
|
+
};
|
|
982
|
+
},
|
|
983
|
+
positionViolation(ruleName, position, index, context) {
|
|
984
|
+
return {
|
|
985
|
+
code: "COMP1008" /* PositionViolation */,
|
|
986
|
+
category: 0 /* Contract */,
|
|
987
|
+
component: context,
|
|
988
|
+
message: `${context}: "${ruleName}" must be ${position}, got index ${index}`
|
|
989
|
+
};
|
|
990
|
+
},
|
|
991
|
+
unknownVariantDim(component, label2, dim) {
|
|
992
|
+
return {
|
|
993
|
+
code: "COMP1010" /* ContractUnknownVariantDim */,
|
|
994
|
+
category: 0 /* Contract */,
|
|
995
|
+
message: `${component}: ${label2} references unknown variant "${dim}".`
|
|
996
|
+
};
|
|
997
|
+
},
|
|
998
|
+
unknownVariantValue(component, label2, dim, value, valid) {
|
|
999
|
+
return {
|
|
1000
|
+
code: "COMP1011" /* ContractUnknownVariantValue */,
|
|
1001
|
+
category: 0 /* Contract */,
|
|
1002
|
+
message: `${component}: ${label2} sets "${dim}" to unknown value "${value}" (valid: ${valid.join(", ")}).`
|
|
1003
|
+
};
|
|
1004
|
+
},
|
|
1005
|
+
unknownRecipeKey(component, key) {
|
|
1006
|
+
return {
|
|
1007
|
+
code: "COMP1012" /* ContractUnknownRecipeKey */,
|
|
1008
|
+
category: 0 /* Contract */,
|
|
1009
|
+
message: `${component} Unknown recipeKey "${key}" \u2014 no preset with that name exists.`
|
|
1010
|
+
};
|
|
1011
|
+
},
|
|
1012
|
+
invalidVariantValue(component, key, value) {
|
|
1013
|
+
return {
|
|
1014
|
+
code: "COMP1013" /* ContractInvalidVariantValue */,
|
|
1015
|
+
category: 0 /* Contract */,
|
|
1016
|
+
message: `${component} Variant "${key}=${value}" is not a defined value for the "${key}" dimension.`
|
|
1017
|
+
};
|
|
1018
|
+
},
|
|
1019
|
+
allowedAsViolation(tag, allowedAs, component) {
|
|
1020
|
+
const allowed = allowedAs.map((t) => `"${String(t)}"`).join(", ");
|
|
1021
|
+
return {
|
|
1022
|
+
code: "COMP1009" /* AllowedAsViolation */,
|
|
1023
|
+
category: 0 /* Contract */,
|
|
1024
|
+
component,
|
|
1025
|
+
message: `<${component}>: "as" prop received "${tag}" but only [${allowed}] are allowed.`
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
// ../../lib/contract/src/diagnostics/html.ts
|
|
1031
|
+
var HtmlDiagnostics = {
|
|
1032
|
+
emptyRole(tag) {
|
|
1033
|
+
return {
|
|
1034
|
+
code: "HTML3002" /* HtmlEmptyRole */,
|
|
1035
|
+
category: 1 /* HTML */,
|
|
1036
|
+
message: `<${tag}> has an explicit empty role="". Omit the attribute instead.`
|
|
1037
|
+
};
|
|
1038
|
+
},
|
|
1039
|
+
implicitRoleRedundant(tag, implicitRole) {
|
|
1040
|
+
return {
|
|
1041
|
+
code: "HTML3003" /* HtmlImplicitRoleRedundant */,
|
|
1042
|
+
category: 1 /* HTML */,
|
|
1043
|
+
message: `<${tag}> already has implicit role="${implicitRole}". Avoid redundant role assignment.`
|
|
1044
|
+
};
|
|
1045
|
+
},
|
|
1046
|
+
implicitRoleOverride(tag, implicitRole, role) {
|
|
1047
|
+
return {
|
|
1048
|
+
code: "HTML3004" /* HtmlImplicitRoleOverride */,
|
|
1049
|
+
category: 1 /* HTML */,
|
|
1050
|
+
message: `<${tag}> should not override its implicit role="${implicitRole}" with role="${role}".`
|
|
1051
|
+
};
|
|
1052
|
+
},
|
|
1053
|
+
standaloneRegionOverride(tag, implicitRole) {
|
|
1054
|
+
return {
|
|
1055
|
+
code: "HTML3005" /* HtmlStandaloneRegionOverride */,
|
|
1056
|
+
category: 1 /* HTML */,
|
|
1057
|
+
message: `<${tag}> is a self-contained element with implicit role="${implicitRole}". Assigning role="region" has been removed.`
|
|
1058
|
+
};
|
|
1059
|
+
},
|
|
1060
|
+
landmarkRoleOverride(tag, implicitRole, role) {
|
|
1061
|
+
return {
|
|
1062
|
+
code: "HTML3006" /* HtmlLandmarkRoleOverride */,
|
|
1063
|
+
category: 1 /* HTML */,
|
|
1064
|
+
message: `<${tag}> has a fixed landmark role="${implicitRole}". role="${role}" overrides it and confuses assistive technology. The override has been removed.`
|
|
1065
|
+
};
|
|
1066
|
+
},
|
|
1067
|
+
invalidChild(child, parent, allowed) {
|
|
1068
|
+
return {
|
|
1069
|
+
code: "HTML3007" /* HtmlInvalidChild */,
|
|
1070
|
+
category: 1 /* HTML */,
|
|
1071
|
+
message: `<${child}> is not a valid direct child of <${parent}>. Allowed: ${allowed}.`
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
};
|
|
1075
|
+
|
|
1076
|
+
// ../../lib/contract/src/diagnostics/slot.ts
|
|
1077
|
+
var SlotDiagnostics = {
|
|
1078
|
+
exclusive(name) {
|
|
1079
|
+
return {
|
|
1080
|
+
code: "SLOT1001" /* SlotExclusive */,
|
|
1081
|
+
category: 0 /* Contract */,
|
|
1082
|
+
component: name,
|
|
1083
|
+
message: `${name}: "as" and "asChild" are mutually exclusive`
|
|
1084
|
+
};
|
|
1085
|
+
},
|
|
1086
|
+
singleChildRequired(name, elementTerm) {
|
|
1087
|
+
return {
|
|
1088
|
+
code: "SLOT1002" /* SlotSingleChild */,
|
|
1089
|
+
category: 0 /* Contract */,
|
|
1090
|
+
component: name,
|
|
1091
|
+
message: `${name}: asChild requires a ${elementTerm} child`
|
|
1092
|
+
};
|
|
1093
|
+
},
|
|
1094
|
+
singleChildExceeded(name, elementTerm, count) {
|
|
1095
|
+
return {
|
|
1096
|
+
code: "SLOT1002" /* SlotSingleChild */,
|
|
1097
|
+
category: 0 /* Contract */,
|
|
1098
|
+
component: name,
|
|
1099
|
+
message: `${name}: asChild requires exactly one ${elementTerm} child, got ${count}`
|
|
1100
|
+
};
|
|
1101
|
+
},
|
|
1102
|
+
discardedChildren(name, elementTerm, count) {
|
|
1103
|
+
const suffix = count === 1 ? "" : "ren";
|
|
1104
|
+
return {
|
|
1105
|
+
code: "SLOT1003" /* SlotDiscardedChildren */,
|
|
1106
|
+
category: 0 /* Contract */,
|
|
1107
|
+
component: name,
|
|
1108
|
+
message: `${name}: asChild discarded ${count} non-element child${suffix} \u2014 only ${elementTerm}s are valid asChild children.`
|
|
1109
|
+
};
|
|
1110
|
+
},
|
|
1111
|
+
renderFnRequired(name, received) {
|
|
1112
|
+
return {
|
|
1113
|
+
code: "SLOT1004" /* SlotRenderFn */,
|
|
1114
|
+
category: 0 /* Contract */,
|
|
1115
|
+
component: name,
|
|
1116
|
+
message: `${name}: asChild requires a render function as children, got ${received}`
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1119
|
+
};
|
|
1120
|
+
|
|
1121
|
+
// ../../lib/contract/src/aria/polymorphic-validator.ts
|
|
705
1122
|
var VALID = [{ valid: true }];
|
|
706
1123
|
function isIntrinsicTag(tag) {
|
|
707
1124
|
return isString(tag);
|
|
@@ -710,26 +1127,28 @@ function omitProp(obj, key) {
|
|
|
710
1127
|
const { [key]: _, ...rest } = obj;
|
|
711
1128
|
return rest;
|
|
712
1129
|
}
|
|
713
|
-
var AriaPolicyEngine = class _AriaPolicyEngine extends
|
|
1130
|
+
var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
714
1131
|
#extraRules;
|
|
715
1132
|
#planCache = /* @__PURE__ */ new Map();
|
|
716
1133
|
static #MAX_CACHE = 100;
|
|
717
1134
|
// Memoized AriaFix objects keyed by attribute name — the ARIA attribute set is
|
|
718
1135
|
// finite so this Map is bounded and avoids recreating closures on every cache miss.
|
|
719
1136
|
static #removeAttributeFixCache = /* @__PURE__ */ new Map();
|
|
720
|
-
constructor(
|
|
721
|
-
super(
|
|
1137
|
+
constructor(diagnostics, options) {
|
|
1138
|
+
super(diagnostics);
|
|
722
1139
|
this.#extraRules = options?.rules ?? [];
|
|
723
1140
|
}
|
|
724
1141
|
static #normalizeEmptyRole(tag, props) {
|
|
725
1142
|
if (props.role !== "") return { normalized: false };
|
|
1143
|
+
const d = HtmlDiagnostics.emptyRole(tag);
|
|
726
1144
|
return {
|
|
727
1145
|
normalized: true,
|
|
728
1146
|
result: {
|
|
729
1147
|
props: omitProp(props, "role"),
|
|
730
1148
|
violations: [
|
|
731
1149
|
{
|
|
732
|
-
message:
|
|
1150
|
+
message: d.message,
|
|
1151
|
+
diagnostic: d,
|
|
733
1152
|
tag,
|
|
734
1153
|
role: "",
|
|
735
1154
|
attribute: void 0,
|
|
@@ -742,10 +1161,9 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
742
1161
|
}
|
|
743
1162
|
static #deriveContext(tag, props) {
|
|
744
1163
|
if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
|
|
745
|
-
const implicitRole = getImplicitRole(tag);
|
|
746
|
-
const
|
|
747
|
-
if (!
|
|
748
|
-
return { proceed: false, result: { props, violations: [] } };
|
|
1164
|
+
const implicitRole = getImplicitRole(tag, props);
|
|
1165
|
+
const hasRole2 = implicitRole != null || isString(props.role) && props.role.length > 0;
|
|
1166
|
+
if (!hasRole2) return { proceed: false, result: { props, violations: [] } };
|
|
749
1167
|
const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
|
|
750
1168
|
if (normalized.normalized) return { proceed: false, result: normalized.result };
|
|
751
1169
|
const effectiveRole = props.role ?? implicitRole;
|
|
@@ -760,25 +1178,36 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
760
1178
|
static #runRules(rules, context) {
|
|
761
1179
|
const violations = [];
|
|
762
1180
|
const fixes = [];
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
if (
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
1181
|
+
iterate.forEach(rules, (rule) => {
|
|
1182
|
+
iterate.forEach(rule(context), (result) => {
|
|
1183
|
+
if (result.valid) return;
|
|
1184
|
+
const {
|
|
1185
|
+
tag,
|
|
1186
|
+
props: { role }
|
|
1187
|
+
} = context;
|
|
1188
|
+
const { message, attribute, severity } = result;
|
|
1189
|
+
const resolvedMessage = message ?? result.diagnostic?.message;
|
|
1190
|
+
const fallbackDiag = resolvedMessage == null ? AriaDiagnostics.invalidRole(role, tag) : void 0;
|
|
1191
|
+
violations.push({
|
|
1192
|
+
message: resolvedMessage ?? fallbackDiag.message,
|
|
1193
|
+
tag,
|
|
1194
|
+
role,
|
|
1195
|
+
attribute,
|
|
1196
|
+
severity,
|
|
1197
|
+
phase: "evaluate",
|
|
1198
|
+
...result.diagnostic != null && { diagnostic: result.diagnostic },
|
|
1199
|
+
...fallbackDiag != null && { diagnostic: fallbackDiag }
|
|
1200
|
+
});
|
|
1201
|
+
if (result.fixable) fixes.push(result.fix);
|
|
1202
|
+
});
|
|
1203
|
+
});
|
|
778
1204
|
return { violations, fixes };
|
|
779
1205
|
}
|
|
780
1206
|
static #getRules(context) {
|
|
781
|
-
|
|
1207
|
+
if (_AriaPolicyEngine.#hasRole(context.props) || context.effectiveRole != null && _AriaPolicyEngine.#LIVE_REGION_ROLES.has(context.effectiveRole)) {
|
|
1208
|
+
return _AriaPolicyEngine.#pipeline;
|
|
1209
|
+
}
|
|
1210
|
+
return _AriaPolicyEngine.#implicitOnlyRules;
|
|
782
1211
|
}
|
|
783
1212
|
static evaluate(tag, props) {
|
|
784
1213
|
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
@@ -803,10 +1232,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
803
1232
|
return { props: next, violations };
|
|
804
1233
|
}
|
|
805
1234
|
report(violations) {
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
1235
|
+
iterate.forEach(violations, (v) => {
|
|
1236
|
+
const d = v.diagnostic ?? AriaDiagnostics.fromViolation(v);
|
|
1237
|
+
if (v.severity === "error") this.violate(d);
|
|
1238
|
+
else this.warn(d);
|
|
1239
|
+
});
|
|
810
1240
|
}
|
|
811
1241
|
// Cache key covers only the aria-relevant subset of props (tag + role + aria-* attrs).
|
|
812
1242
|
// Non-aria props (className, onClick, etc.) do not affect ARIA decisions and are excluded
|
|
@@ -818,27 +1248,26 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
818
1248
|
if (!isIntrinsicTag(tag)) return null;
|
|
819
1249
|
const parts = [tag];
|
|
820
1250
|
if (typeof props.role === "string") parts.push(`role:${props.role}`);
|
|
1251
|
+
if (tag === "input" && typeof props.type === "string") parts.push(`type:${props.type}`);
|
|
1252
|
+
if (tag === "img") parts.push(`alt:${props.alt === "" ? "empty" : "present"}`);
|
|
821
1253
|
const ariaEntries = [];
|
|
822
|
-
|
|
823
|
-
if (!
|
|
824
|
-
|
|
825
|
-
if (!isString(v) && !isNumber(v) && typeof v !== "boolean") continue;
|
|
1254
|
+
iterate.forEachEntry(props, (k, v) => {
|
|
1255
|
+
if (!k.startsWith("aria-")) return;
|
|
1256
|
+
if (!isString(v) && !isNumber(v) && typeof v !== "boolean") return;
|
|
826
1257
|
ariaEntries.push(`${k}:${String(v)}`);
|
|
827
|
-
}
|
|
1258
|
+
});
|
|
828
1259
|
if (ariaEntries.length > 0) parts.push(...ariaEntries.sort());
|
|
829
1260
|
return parts.join("|");
|
|
830
1261
|
}
|
|
831
1262
|
static #computePlan(inputProps, resultProps) {
|
|
832
1263
|
const removals = /* @__PURE__ */ new Set();
|
|
833
1264
|
const updates = {};
|
|
834
|
-
|
|
835
|
-
if (
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
if (!Object.hasOwn(resultProps, key)) continue;
|
|
839
|
-
const resultVal = resultProps[key];
|
|
1265
|
+
iterate.forEachKey(inputProps, (key) => {
|
|
1266
|
+
if (!(key in resultProps)) removals.add(key);
|
|
1267
|
+
});
|
|
1268
|
+
iterate.forEachEntry(resultProps, (key, resultVal) => {
|
|
840
1269
|
if (inputProps[key] !== resultVal) updates[key] = resultVal;
|
|
841
|
-
}
|
|
1270
|
+
});
|
|
842
1271
|
return { removals, updates };
|
|
843
1272
|
}
|
|
844
1273
|
static #applyPlan(props, removals, updates) {
|
|
@@ -846,15 +1275,15 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
846
1275
|
const hasUpdates = Object.keys(updates).length > 0;
|
|
847
1276
|
if (!hasRemovals && !hasUpdates) return props;
|
|
848
1277
|
const next = {};
|
|
849
|
-
|
|
850
|
-
if (
|
|
851
|
-
}
|
|
1278
|
+
iterate.forEachEntry(props, (k, v) => {
|
|
1279
|
+
if (!removals.has(k)) next[k] = v;
|
|
1280
|
+
});
|
|
852
1281
|
Object.assign(next, updates);
|
|
853
1282
|
return next;
|
|
854
1283
|
}
|
|
855
1284
|
validate(tag, props) {
|
|
856
1285
|
const key = _AriaPolicyEngine.#createPlanKey(tag, props);
|
|
857
|
-
if (!
|
|
1286
|
+
if (!isNull(key)) {
|
|
858
1287
|
const cached = this.#planCache.get(key);
|
|
859
1288
|
if (cached !== void 0) {
|
|
860
1289
|
this.#planCache.delete(key);
|
|
@@ -868,7 +1297,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
868
1297
|
}
|
|
869
1298
|
const result = this.#extraRules.length ? _AriaPolicyEngine.#evaluateWithRules(tag, props, this.#extraRules) : _AriaPolicyEngine.evaluate(tag, props);
|
|
870
1299
|
if (result.violations.length > 0) this.report(result.violations);
|
|
871
|
-
if (!
|
|
1300
|
+
if (!isNull(key)) {
|
|
872
1301
|
const { removals, updates } = _AriaPolicyEngine.#computePlan(
|
|
873
1302
|
props,
|
|
874
1303
|
result.props
|
|
@@ -889,12 +1318,12 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
889
1318
|
if (fixes.length === 0) return props;
|
|
890
1319
|
const sorted = [...fixes].sort((a, b) => (a.priority ?? Infinity) - (b.priority ?? Infinity));
|
|
891
1320
|
let next = props;
|
|
892
|
-
|
|
1321
|
+
iterate.forEach(sorted, ({ apply }) => {
|
|
893
1322
|
const effectiveRole = next.role ?? implicitRole;
|
|
894
1323
|
const fixContext = { tag, implicitRole, effectiveRole, props: next };
|
|
895
1324
|
const fixResult = apply(fixContext);
|
|
896
1325
|
if (fixResult.applied) next = fixResult.next;
|
|
897
|
-
}
|
|
1326
|
+
});
|
|
898
1327
|
return next;
|
|
899
1328
|
}
|
|
900
1329
|
static #removeRole = {
|
|
@@ -922,10 +1351,26 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
922
1351
|
_AriaPolicyEngine.#checkInvalidRoleOverride,
|
|
923
1352
|
_AriaPolicyEngine.#checkRedundantRole,
|
|
924
1353
|
_AriaPolicyEngine.#checkStandaloneRegion,
|
|
1354
|
+
_AriaPolicyEngine.#checkAriaAttributeValues,
|
|
925
1355
|
_AriaPolicyEngine.#checkInvalidAriaAttributes,
|
|
1356
|
+
_AriaPolicyEngine.#checkRequiredAriaProperties,
|
|
1357
|
+
_AriaPolicyEngine.#checkNameRequiredRoles,
|
|
1358
|
+
_AriaPolicyEngine.#checkRedundantAriaLevel,
|
|
926
1359
|
_AriaPolicyEngine.#checkMissingLiveRegion,
|
|
927
1360
|
_AriaPolicyEngine.#checkMissingAtomic,
|
|
928
|
-
_AriaPolicyEngine.#checkInvalidAriaRelevant
|
|
1361
|
+
_AriaPolicyEngine.#checkInvalidAriaRelevant,
|
|
1362
|
+
_AriaPolicyEngine.#checkAriaHiddenOnFocusable,
|
|
1363
|
+
_AriaPolicyEngine.#checkPresentationalAriaAttributes
|
|
1364
|
+
];
|
|
1365
|
+
// Rules for elements with an implicit role but no explicit role (not a live region).
|
|
1366
|
+
static #implicitOnlyRules = [
|
|
1367
|
+
_AriaPolicyEngine.#checkAriaAttributeValues,
|
|
1368
|
+
_AriaPolicyEngine.#checkInvalidAriaAttributes,
|
|
1369
|
+
_AriaPolicyEngine.#checkRequiredAriaProperties,
|
|
1370
|
+
_AriaPolicyEngine.#checkNameRequiredRoles,
|
|
1371
|
+
_AriaPolicyEngine.#checkRedundantAriaLevel,
|
|
1372
|
+
_AriaPolicyEngine.#checkAriaHiddenOnFocusable,
|
|
1373
|
+
_AriaPolicyEngine.#checkPresentationalAriaAttributes
|
|
929
1374
|
];
|
|
930
1375
|
static #checkInvalidRoleOverride({
|
|
931
1376
|
tag,
|
|
@@ -941,7 +1386,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
941
1386
|
fixable: true,
|
|
942
1387
|
severity: "error",
|
|
943
1388
|
fix: _AriaPolicyEngine.#removeRole,
|
|
944
|
-
|
|
1389
|
+
diagnostic: HtmlDiagnostics.implicitRoleOverride(tag, implicitRole, role)
|
|
945
1390
|
}
|
|
946
1391
|
];
|
|
947
1392
|
}
|
|
@@ -953,47 +1398,304 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
953
1398
|
return [
|
|
954
1399
|
{
|
|
955
1400
|
valid: false,
|
|
956
|
-
fixable: true,
|
|
1401
|
+
fixable: true,
|
|
1402
|
+
severity: "warning",
|
|
1403
|
+
fix: _AriaPolicyEngine.#removeRole,
|
|
1404
|
+
diagnostic: HtmlDiagnostics.implicitRoleRedundant(tag, implicitRole)
|
|
1405
|
+
}
|
|
1406
|
+
];
|
|
1407
|
+
}
|
|
1408
|
+
static #checkStandaloneRegion({ tag, props, implicitRole }) {
|
|
1409
|
+
const role = props.role;
|
|
1410
|
+
if (role !== "region") return VALID;
|
|
1411
|
+
if (!isStandaloneTag(tag)) return VALID;
|
|
1412
|
+
return [
|
|
1413
|
+
{
|
|
1414
|
+
valid: false,
|
|
1415
|
+
fixable: true,
|
|
1416
|
+
severity: "error",
|
|
1417
|
+
fix: _AriaPolicyEngine.#removeRole,
|
|
1418
|
+
diagnostic: HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag)
|
|
1419
|
+
}
|
|
1420
|
+
];
|
|
1421
|
+
}
|
|
1422
|
+
static #checkInvalidAriaAttributes({
|
|
1423
|
+
tag,
|
|
1424
|
+
props,
|
|
1425
|
+
effectiveRole
|
|
1426
|
+
}) {
|
|
1427
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
|
|
1428
|
+
const results = [];
|
|
1429
|
+
iterate.forEachEntry(props, (key) => {
|
|
1430
|
+
if (!key.startsWith("aria-")) return;
|
|
1431
|
+
if (isGlobalAriaAttribute(key)) return;
|
|
1432
|
+
if (isAriaAttributeValidForRole(key, effectiveRole)) return;
|
|
1433
|
+
results.push({
|
|
1434
|
+
valid: false,
|
|
1435
|
+
severity: "warning",
|
|
1436
|
+
fixable: true,
|
|
1437
|
+
attribute: key,
|
|
1438
|
+
diagnostic: AriaDiagnostics.attributeInvalid(key, effectiveRole ?? tag),
|
|
1439
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix(key)
|
|
1440
|
+
});
|
|
1441
|
+
});
|
|
1442
|
+
return results;
|
|
1443
|
+
}
|
|
1444
|
+
// ─── ARIA attribute value validation ──────────────────────────────────────
|
|
1445
|
+
// Accepted value shapes for typed ARIA attributes.
|
|
1446
|
+
// Attributes not in this map are unconstrained (arbitrary string values permitted).
|
|
1447
|
+
static #ARIA_VALUE_TYPES = /* @__PURE__ */ new Map([
|
|
1448
|
+
// Boolean (true | false)
|
|
1449
|
+
["aria-atomic", { kind: "boolean" }],
|
|
1450
|
+
["aria-busy", { kind: "boolean" }],
|
|
1451
|
+
["aria-disabled", { kind: "boolean" }],
|
|
1452
|
+
["aria-expanded", { kind: "boolean" }],
|
|
1453
|
+
["aria-hidden", { kind: "boolean" }],
|
|
1454
|
+
["aria-modal", { kind: "boolean" }],
|
|
1455
|
+
["aria-multiline", { kind: "boolean" }],
|
|
1456
|
+
["aria-multiselectable", { kind: "boolean" }],
|
|
1457
|
+
["aria-readonly", { kind: "boolean" }],
|
|
1458
|
+
["aria-required", { kind: "boolean" }],
|
|
1459
|
+
["aria-selected", { kind: "boolean" }],
|
|
1460
|
+
// Tristate (true | false | mixed)
|
|
1461
|
+
["aria-checked", { kind: "tristate" }],
|
|
1462
|
+
["aria-pressed", { kind: "tristate" }],
|
|
1463
|
+
// Numeric (any finite number)
|
|
1464
|
+
["aria-valuenow", { kind: "number" }],
|
|
1465
|
+
["aria-valuemin", { kind: "number" }],
|
|
1466
|
+
["aria-valuemax", { kind: "number" }],
|
|
1467
|
+
// Integer with optional range
|
|
1468
|
+
["aria-level", { kind: "integer", min: 1, max: 6 }],
|
|
1469
|
+
["aria-posinset", { kind: "integer", min: 1 }],
|
|
1470
|
+
["aria-setsize", { kind: "integer", min: -1 }],
|
|
1471
|
+
["aria-rowcount", { kind: "integer", min: -1 }],
|
|
1472
|
+
["aria-colcount", { kind: "integer", min: -1 }],
|
|
1473
|
+
["aria-rowindex", { kind: "integer", min: 1 }],
|
|
1474
|
+
["aria-colindex", { kind: "integer", min: 1 }],
|
|
1475
|
+
["aria-rowspan", { kind: "integer", min: 0 }],
|
|
1476
|
+
["aria-colspan", { kind: "integer", min: 0 }],
|
|
1477
|
+
// Enum (specific allowed tokens)
|
|
1478
|
+
["aria-autocomplete", { kind: "enum", values: /* @__PURE__ */ new Set(["inline", "list", "both", "none"]) }],
|
|
1479
|
+
[
|
|
1480
|
+
"aria-current",
|
|
1481
|
+
{
|
|
1482
|
+
kind: "enum",
|
|
1483
|
+
values: /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"])
|
|
1484
|
+
}
|
|
1485
|
+
],
|
|
1486
|
+
[
|
|
1487
|
+
"aria-haspopup",
|
|
1488
|
+
{
|
|
1489
|
+
kind: "enum",
|
|
1490
|
+
values: /* @__PURE__ */ new Set(["false", "true", "menu", "listbox", "tree", "grid", "dialog"])
|
|
1491
|
+
}
|
|
1492
|
+
],
|
|
1493
|
+
["aria-invalid", { kind: "enum", values: /* @__PURE__ */ new Set(["grammar", "false", "spelling", "true"]) }],
|
|
1494
|
+
["aria-live", { kind: "enum", values: /* @__PURE__ */ new Set(["assertive", "off", "polite"]) }],
|
|
1495
|
+
[
|
|
1496
|
+
"aria-orientation",
|
|
1497
|
+
{ kind: "enum", values: /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]) }
|
|
1498
|
+
],
|
|
1499
|
+
["aria-sort", { kind: "enum", values: /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"]) }]
|
|
1500
|
+
]);
|
|
1501
|
+
static #isValidAriaValue(value, type) {
|
|
1502
|
+
switch (type.kind) {
|
|
1503
|
+
case "boolean":
|
|
1504
|
+
return value === "true" || value === "false" || value === true || value === false;
|
|
1505
|
+
case "tristate":
|
|
1506
|
+
return value === "true" || value === "false" || value === "mixed" || value === true || value === false;
|
|
1507
|
+
case "number": {
|
|
1508
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
1509
|
+
if (typeof value !== "string") return false;
|
|
1510
|
+
const n = parseFloat(value);
|
|
1511
|
+
return Number.isFinite(n);
|
|
1512
|
+
}
|
|
1513
|
+
case "integer": {
|
|
1514
|
+
const n = typeof value === "number" ? value : typeof value === "string" ? parseInt(value, 10) : NaN;
|
|
1515
|
+
if (!Number.isFinite(n) || !Number.isInteger(n)) return false;
|
|
1516
|
+
if (type.min !== void 0 && n < type.min) return false;
|
|
1517
|
+
if (type.max !== void 0 && n > type.max) return false;
|
|
1518
|
+
return true;
|
|
1519
|
+
}
|
|
1520
|
+
case "enum":
|
|
1521
|
+
return typeof value === "string" && type.values.has(value);
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
static #describeExpected(type) {
|
|
1525
|
+
switch (type.kind) {
|
|
1526
|
+
case "boolean":
|
|
1527
|
+
return '"true" or "false"';
|
|
1528
|
+
case "tristate":
|
|
1529
|
+
return '"true", "false", or "mixed"';
|
|
1530
|
+
case "number":
|
|
1531
|
+
return "a finite number";
|
|
1532
|
+
case "integer": {
|
|
1533
|
+
const parts = ["an integer"];
|
|
1534
|
+
if (type.min !== void 0 && type.max !== void 0)
|
|
1535
|
+
parts.push(`between ${type.min} and ${type.max}`);
|
|
1536
|
+
else if (type.min !== void 0) parts.push(`\u2265 ${type.min}`);
|
|
1537
|
+
else if (type.max !== void 0) parts.push(`\u2264 ${type.max}`);
|
|
1538
|
+
return parts.join(" ");
|
|
1539
|
+
}
|
|
1540
|
+
case "enum":
|
|
1541
|
+
return [...type.values].map((v) => `"${v}"`).join(", ");
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
static #checkAriaAttributeValues({ props, effectiveRole }) {
|
|
1545
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
|
|
1546
|
+
const results = [];
|
|
1547
|
+
iterate.forEachEntry(props, (key, value) => {
|
|
1548
|
+
if (!key.startsWith("aria-")) return;
|
|
1549
|
+
const type = _AriaPolicyEngine.#ARIA_VALUE_TYPES.get(key);
|
|
1550
|
+
if (type == null) return;
|
|
1551
|
+
if (_AriaPolicyEngine.#isValidAriaValue(value, type)) return;
|
|
1552
|
+
results.push({
|
|
1553
|
+
valid: false,
|
|
1554
|
+
fixable: true,
|
|
1555
|
+
severity: "warning",
|
|
1556
|
+
attribute: key,
|
|
1557
|
+
diagnostic: AriaDiagnostics.invalidAttributeValue(
|
|
1558
|
+
key,
|
|
1559
|
+
value,
|
|
1560
|
+
_AriaPolicyEngine.#describeExpected(type)
|
|
1561
|
+
),
|
|
1562
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix(key)
|
|
1563
|
+
});
|
|
1564
|
+
});
|
|
1565
|
+
return results;
|
|
1566
|
+
}
|
|
1567
|
+
// ─── Heading implicit level ────────────────────────────────────────────────
|
|
1568
|
+
static #HEADING_IMPLICIT_LEVELS = /* @__PURE__ */ new Map([
|
|
1569
|
+
["h1", 1],
|
|
1570
|
+
["h2", 2],
|
|
1571
|
+
["h3", 3],
|
|
1572
|
+
["h4", 4],
|
|
1573
|
+
["h5", 5],
|
|
1574
|
+
["h6", 6]
|
|
1575
|
+
]);
|
|
1576
|
+
static #checkRedundantAriaLevel({
|
|
1577
|
+
tag,
|
|
1578
|
+
props,
|
|
1579
|
+
effectiveRole
|
|
1580
|
+
}) {
|
|
1581
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
|
|
1582
|
+
const implicitLevel = _AriaPolicyEngine.#HEADING_IMPLICIT_LEVELS.get(tag);
|
|
1583
|
+
if (implicitLevel == null) return VALID;
|
|
1584
|
+
const raw = props["aria-level"];
|
|
1585
|
+
if (raw == null) return VALID;
|
|
1586
|
+
const n = typeof raw === "number" ? raw : typeof raw === "string" ? parseInt(raw, 10) : NaN;
|
|
1587
|
+
if (!Number.isFinite(n) || n !== implicitLevel) return VALID;
|
|
1588
|
+
return [
|
|
1589
|
+
{
|
|
1590
|
+
valid: false,
|
|
1591
|
+
fixable: true,
|
|
1592
|
+
severity: "warning",
|
|
1593
|
+
attribute: "aria-level",
|
|
1594
|
+
diagnostic: AriaDiagnostics.redundantAriaLevel(tag, implicitLevel),
|
|
1595
|
+
fix: _AriaPolicyEngine.#makeRemoveAttributeFix("aria-level")
|
|
1596
|
+
}
|
|
1597
|
+
];
|
|
1598
|
+
}
|
|
1599
|
+
// ─── Name-required roles ───────────────────────────────────────────────────
|
|
1600
|
+
// Roles that always require an accessible name per WAI-ARIA APG.
|
|
1601
|
+
// Dialog and landmark names are enforced via contracts (ariaContract) rather than
|
|
1602
|
+
// the built-in pipeline so consumers can opt in; img is built in because role=img
|
|
1603
|
+
// on any element (including bare <img>) is definitionally useless without a name.
|
|
1604
|
+
static #NAME_REQUIRED_ROLES = /* @__PURE__ */ new Set(["img"]);
|
|
1605
|
+
static #checkNameRequiredRoles({
|
|
1606
|
+
tag,
|
|
1607
|
+
props,
|
|
1608
|
+
effectiveRole
|
|
1609
|
+
}) {
|
|
1610
|
+
if (!effectiveRole || !_AriaPolicyEngine.#NAME_REQUIRED_ROLES.has(effectiveRole)) return VALID;
|
|
1611
|
+
if ("aria-label" in props || "aria-labelledby" in props) return VALID;
|
|
1612
|
+
if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return VALID;
|
|
1613
|
+
return [
|
|
1614
|
+
{
|
|
1615
|
+
valid: false,
|
|
1616
|
+
fixable: false,
|
|
1617
|
+
severity: "warning",
|
|
1618
|
+
diagnostic: AriaDiagnostics.missingAccessibleName(tag)
|
|
1619
|
+
}
|
|
1620
|
+
];
|
|
1621
|
+
}
|
|
1622
|
+
// WAI-ARIA 1.2 required states and properties, keyed by role.
|
|
1623
|
+
// Source: https://www.w3.org/TR/wai-aria-1.2/#requiredState
|
|
1624
|
+
static #REQUIRED_PROPERTIES = /* @__PURE__ */ new Map([
|
|
1625
|
+
["combobox", ["aria-expanded"]],
|
|
1626
|
+
["option", ["aria-selected"]],
|
|
1627
|
+
["slider", ["aria-valuenow"]],
|
|
1628
|
+
["scrollbar", ["aria-controls", "aria-valuenow"]],
|
|
1629
|
+
["spinbutton", ["aria-valuenow"]]
|
|
1630
|
+
]);
|
|
1631
|
+
static #checkRequiredAriaProperties({
|
|
1632
|
+
props,
|
|
1633
|
+
effectiveRole
|
|
1634
|
+
}) {
|
|
1635
|
+
if (!effectiveRole) return VALID;
|
|
1636
|
+
const required = _AriaPolicyEngine.#REQUIRED_PROPERTIES.get(effectiveRole);
|
|
1637
|
+
if (required == null) return VALID;
|
|
1638
|
+
const results = [];
|
|
1639
|
+
iterate.forEach(required, (attr) => {
|
|
1640
|
+
if (attr in props) return;
|
|
1641
|
+
results.push({
|
|
1642
|
+
valid: false,
|
|
1643
|
+
fixable: false,
|
|
957
1644
|
severity: "warning",
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
}
|
|
961
|
-
|
|
1645
|
+
attribute: attr,
|
|
1646
|
+
diagnostic: AriaDiagnostics.requiredProperty(attr, effectiveRole)
|
|
1647
|
+
});
|
|
1648
|
+
});
|
|
1649
|
+
return results;
|
|
962
1650
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1651
|
+
// Natively interactive HTML elements — always keyboard-reachable unless explicitly disabled.
|
|
1652
|
+
static #INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
1653
|
+
"a",
|
|
1654
|
+
"button",
|
|
1655
|
+
"input",
|
|
1656
|
+
"select",
|
|
1657
|
+
"textarea"
|
|
1658
|
+
]);
|
|
1659
|
+
// WAI-ARIA 1.2 §6.6: aria-hidden="true" must not be placed on focusable elements.
|
|
1660
|
+
static #checkAriaHiddenOnFocusable({ tag, props }) {
|
|
1661
|
+
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return VALID;
|
|
1662
|
+
const isInteractive = _AriaPolicyEngine.#INTERACTIVE_TAGS.has(tag);
|
|
1663
|
+
if (!isInteractive) {
|
|
1664
|
+
const tabindex = props.tabindex;
|
|
1665
|
+
const n = typeof tabindex === "number" ? tabindex : typeof tabindex === "string" ? parseInt(tabindex, 10) : NaN;
|
|
1666
|
+
if (!Number.isFinite(n) || n < 0) return VALID;
|
|
1667
|
+
}
|
|
967
1668
|
return [
|
|
968
1669
|
{
|
|
969
1670
|
valid: false,
|
|
970
|
-
fixable:
|
|
1671
|
+
fixable: false,
|
|
971
1672
|
severity: "error",
|
|
972
|
-
|
|
973
|
-
|
|
1673
|
+
attribute: "aria-hidden",
|
|
1674
|
+
diagnostic: AriaDiagnostics.ariaHiddenOnFocusable(tag)
|
|
974
1675
|
}
|
|
975
1676
|
];
|
|
976
1677
|
}
|
|
977
|
-
|
|
1678
|
+
// Presentational elements (role=none/presentation, including <img alt="">) are removed
|
|
1679
|
+
// from the accessibility tree — ARIA attributes on them are meaningless and misleading.
|
|
1680
|
+
static #checkPresentationalAriaAttributes({
|
|
978
1681
|
tag,
|
|
979
1682
|
props,
|
|
980
1683
|
effectiveRole
|
|
981
1684
|
}) {
|
|
1685
|
+
if (effectiveRole !== "none" && effectiveRole !== "presentation") return VALID;
|
|
982
1686
|
const results = [];
|
|
983
|
-
|
|
984
|
-
if (!
|
|
985
|
-
if (
|
|
986
|
-
if (isGlobalAriaAttribute(key)) continue;
|
|
987
|
-
if (isAriaAttributeValidForRole(key, effectiveRole)) continue;
|
|
1687
|
+
iterate.forEachEntry(props, (key) => {
|
|
1688
|
+
if (!key.startsWith("aria-")) return;
|
|
1689
|
+
if (key === "aria-hidden") return;
|
|
988
1690
|
results.push({
|
|
989
1691
|
valid: false,
|
|
990
|
-
severity: "warning",
|
|
991
1692
|
fixable: true,
|
|
1693
|
+
severity: "warning",
|
|
992
1694
|
attribute: key,
|
|
993
|
-
|
|
1695
|
+
diagnostic: AriaDiagnostics.attributeOnPresentational(key, tag),
|
|
994
1696
|
fix: _AriaPolicyEngine.#makeRemoveAttributeFix(key)
|
|
995
1697
|
});
|
|
996
|
-
}
|
|
1698
|
+
});
|
|
997
1699
|
return results;
|
|
998
1700
|
}
|
|
999
1701
|
// WAI-ARIA live region roles and their implied aria-live politeness values.
|
|
@@ -1022,7 +1724,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1022
1724
|
fixable: true,
|
|
1023
1725
|
severity: "warning",
|
|
1024
1726
|
fix: injectLive,
|
|
1025
|
-
|
|
1727
|
+
diagnostic: AriaDiagnostics.missingLiveRegion(effectiveRole, impliedLive)
|
|
1026
1728
|
}
|
|
1027
1729
|
];
|
|
1028
1730
|
}
|
|
@@ -1034,7 +1736,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1034
1736
|
valid: false,
|
|
1035
1737
|
fixable: false,
|
|
1036
1738
|
severity: "warning",
|
|
1037
|
-
|
|
1739
|
+
diagnostic: AriaDiagnostics.missingAtomic(effectiveRole)
|
|
1038
1740
|
}
|
|
1039
1741
|
];
|
|
1040
1742
|
}
|
|
@@ -1063,7 +1765,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1063
1765
|
fixable: true,
|
|
1064
1766
|
severity: "warning",
|
|
1065
1767
|
attribute: "aria-relevant",
|
|
1066
|
-
|
|
1768
|
+
diagnostic: AriaDiagnostics.relevantInvalidTokens(invalid),
|
|
1067
1769
|
fix: _AriaPolicyEngine.#makeRemoveAttributeFix("aria-relevant")
|
|
1068
1770
|
}
|
|
1069
1771
|
];
|
|
@@ -1075,7 +1777,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1075
1777
|
fixable: true,
|
|
1076
1778
|
severity: "warning",
|
|
1077
1779
|
attribute: "aria-relevant",
|
|
1078
|
-
|
|
1780
|
+
diagnostic: AriaDiagnostics.relevantSuperseded(),
|
|
1079
1781
|
fix: _AriaPolicyEngine.#normalizeRelevantAllFix
|
|
1080
1782
|
}
|
|
1081
1783
|
];
|
|
@@ -1083,6 +1785,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends StrictBase {
|
|
|
1083
1785
|
return VALID;
|
|
1084
1786
|
}
|
|
1085
1787
|
};
|
|
1788
|
+
|
|
1789
|
+
// ../../lib/contract/src/children/get-type-name.ts
|
|
1086
1790
|
function getTypeName(value) {
|
|
1087
1791
|
if (value === null) return "null";
|
|
1088
1792
|
if (value === void 0) return "undefined";
|
|
@@ -1093,39 +1797,8 @@ function getTypeName(value) {
|
|
|
1093
1797
|
const name = value.constructor?.name;
|
|
1094
1798
|
return typeof name === "string" && name !== "Object" ? name : "object";
|
|
1095
1799
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
constructor(ctx = "") {
|
|
1099
|
-
this.#prefix = ctx ? `${ctx}:
|
|
1100
|
-
` : "";
|
|
1101
|
-
}
|
|
1102
|
-
#template(typeName, index, prefix = "", suffix = "") {
|
|
1103
|
-
const leadingStr = prefix ? `${prefix} ` : "";
|
|
1104
|
-
const followingStr = suffix ? ` ${suffix}` : "";
|
|
1105
|
-
return `${leadingStr}child "${typeName}" at index ${index}${followingStr}.`;
|
|
1106
|
-
}
|
|
1107
|
-
unexpectedChild(typeName, index) {
|
|
1108
|
-
return this.#template(typeName, index, "unexpected");
|
|
1109
|
-
}
|
|
1110
|
-
multipleMatches(typeName, index, ruleNames) {
|
|
1111
|
-
const quoted = ruleNames.map((n) => `"${n}"`);
|
|
1112
|
-
return this.#template(
|
|
1113
|
-
typeName,
|
|
1114
|
-
index,
|
|
1115
|
-
"",
|
|
1116
|
-
`matches multiple child rules: ${quoted.join(" and ")}`
|
|
1117
|
-
);
|
|
1118
|
-
}
|
|
1119
|
-
#format(errors) {
|
|
1120
|
-
return this.#prefix + errors.join("\n");
|
|
1121
|
-
}
|
|
1122
|
-
toError(errors) {
|
|
1123
|
-
if (errors.length === 0) {
|
|
1124
|
-
return new Error(this.#prefix + "Unknown validation error.");
|
|
1125
|
-
}
|
|
1126
|
-
return new Error(this.#format(errors));
|
|
1127
|
-
}
|
|
1128
|
-
};
|
|
1800
|
+
|
|
1801
|
+
// ../../lib/contract/src/children/normalize-child-rule.ts
|
|
1129
1802
|
function normalizeCardinality(input, impliesSingleton) {
|
|
1130
1803
|
const min = input?.min ?? 0;
|
|
1131
1804
|
const max = input?.max ?? (impliesSingleton ? 1 : Infinity);
|
|
@@ -1150,6 +1823,8 @@ function normalizeChildRule(rule) {
|
|
|
1150
1823
|
cardinality: normalizeCardinality(rule.cardinality, impliesSingleton)
|
|
1151
1824
|
};
|
|
1152
1825
|
}
|
|
1826
|
+
|
|
1827
|
+
// ../../lib/contract/src/children/rules-matcher.ts
|
|
1153
1828
|
function getChildType(child) {
|
|
1154
1829
|
if (!isObject(child) || !("type" in child)) return void 0;
|
|
1155
1830
|
return child.type;
|
|
@@ -1158,8 +1833,8 @@ function buildPartialIndex(rules) {
|
|
|
1158
1833
|
const typeIndex = /* @__PURE__ */ new Map();
|
|
1159
1834
|
const duplicateTypes = /* @__PURE__ */ new Set();
|
|
1160
1835
|
const untypedIndices = [];
|
|
1161
|
-
|
|
1162
|
-
const t =
|
|
1836
|
+
iterate.forEach(rules, (rule, ri) => {
|
|
1837
|
+
const t = rule.type;
|
|
1163
1838
|
if (t === void 0) {
|
|
1164
1839
|
untypedIndices.push(ri);
|
|
1165
1840
|
} else if (typeIndex.has(t)) {
|
|
@@ -1167,12 +1842,14 @@ function buildPartialIndex(rules) {
|
|
|
1167
1842
|
} else {
|
|
1168
1843
|
typeIndex.set(t, ri);
|
|
1169
1844
|
}
|
|
1170
|
-
}
|
|
1845
|
+
});
|
|
1171
1846
|
if (duplicateTypes.size > 0) {
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1847
|
+
iterate.forEachSet(duplicateTypes, (t) => {
|
|
1848
|
+
typeIndex.delete(t);
|
|
1849
|
+
});
|
|
1850
|
+
iterate.forEach(rules, (rule, ri) => {
|
|
1851
|
+
if (duplicateTypes.has(rule.type)) untypedIndices.push(ri);
|
|
1852
|
+
});
|
|
1176
1853
|
}
|
|
1177
1854
|
return { typeIndex, untypedIndices };
|
|
1178
1855
|
}
|
|
@@ -1191,10 +1868,10 @@ var RuleMatcher = class {
|
|
|
1191
1868
|
const reverse = /* @__PURE__ */ new Map();
|
|
1192
1869
|
const unexpectedIndices = /* @__PURE__ */ new Set();
|
|
1193
1870
|
const ambiguousIndices = /* @__PURE__ */ new Set();
|
|
1194
|
-
|
|
1871
|
+
iterate.forEach(this.#rules, (_, ri) => {
|
|
1195
1872
|
reverse.set(ri, /* @__PURE__ */ new Set());
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1873
|
+
});
|
|
1874
|
+
iterate.forEach(children, (child, ci) => {
|
|
1198
1875
|
const t = getChildType(child);
|
|
1199
1876
|
if (t !== void 0) {
|
|
1200
1877
|
const ri = this.#typeIndex.get(t);
|
|
@@ -1208,8 +1885,8 @@ var RuleMatcher = class {
|
|
|
1208
1885
|
reverse.get(ri).add(ci);
|
|
1209
1886
|
}
|
|
1210
1887
|
}
|
|
1211
|
-
|
|
1212
|
-
if (!this.#rules[ri].match(child))
|
|
1888
|
+
iterate.forEach(this.#untypedIndices, (ri) => {
|
|
1889
|
+
if (!this.#rules[ri].match(child)) return;
|
|
1213
1890
|
let childEntry = forward.get(ci);
|
|
1214
1891
|
if (!childEntry) {
|
|
1215
1892
|
childEntry = /* @__PURE__ */ new Set();
|
|
@@ -1217,33 +1894,35 @@ var RuleMatcher = class {
|
|
|
1217
1894
|
}
|
|
1218
1895
|
childEntry.add(ri);
|
|
1219
1896
|
reverse.get(ri).add(ci);
|
|
1220
|
-
}
|
|
1897
|
+
});
|
|
1221
1898
|
const entry = forward.get(ci);
|
|
1222
1899
|
if (!entry) {
|
|
1223
1900
|
unexpectedIndices.add(ci);
|
|
1224
1901
|
} else if (entry.size > 1) {
|
|
1225
1902
|
ambiguousIndices.add(ci);
|
|
1226
1903
|
}
|
|
1227
|
-
}
|
|
1904
|
+
});
|
|
1228
1905
|
return { matrix: { childToRules: { forward, reverse } }, unexpectedIndices, ambiguousIndices };
|
|
1229
1906
|
}
|
|
1230
1907
|
};
|
|
1231
|
-
|
|
1908
|
+
|
|
1909
|
+
// ../../lib/contract/src/children/rule-validator.ts
|
|
1910
|
+
var RuleValidator = class _RuleValidator extends InvariantBase {
|
|
1232
1911
|
#context;
|
|
1233
|
-
constructor(context,
|
|
1234
|
-
super(
|
|
1912
|
+
constructor(context, diagnostics) {
|
|
1913
|
+
super(diagnostics);
|
|
1235
1914
|
this.#context = context;
|
|
1236
1915
|
}
|
|
1237
1916
|
validate(rules, matrix, childCount) {
|
|
1238
1917
|
const firstIndex = 0;
|
|
1239
1918
|
const lastIndex = childCount - 1;
|
|
1240
|
-
|
|
1919
|
+
iterate.forEach(rules, (rule, ri) => {
|
|
1241
1920
|
const matches = matrix.childToRules.reverse.get(ri);
|
|
1242
1921
|
const matchCount = matches.size;
|
|
1243
1922
|
this.#validateCardinality(rule, matchCount);
|
|
1244
|
-
if (matchCount === 0)
|
|
1923
|
+
if (matchCount === 0) return;
|
|
1245
1924
|
this.#validatePositions(rule, matches, firstIndex, lastIndex);
|
|
1246
|
-
}
|
|
1925
|
+
});
|
|
1247
1926
|
}
|
|
1248
1927
|
#validateCardinality(rule, matchCount) {
|
|
1249
1928
|
const { cardinality, name } = rule;
|
|
@@ -1252,21 +1931,21 @@ var RuleValidator = class _RuleValidator extends StrictBase {
|
|
|
1252
1931
|
}
|
|
1253
1932
|
const { min, max } = cardinality;
|
|
1254
1933
|
if (matchCount < min) {
|
|
1255
|
-
this.violate(
|
|
1934
|
+
this.violate(ContractDiagnostics.cardinalityMin(name, min, this.#context));
|
|
1256
1935
|
return;
|
|
1257
1936
|
}
|
|
1258
1937
|
if (matchCount > max) {
|
|
1259
|
-
this.violate(
|
|
1938
|
+
this.violate(ContractDiagnostics.cardinalityMax(name, max, this.#context));
|
|
1260
1939
|
}
|
|
1261
1940
|
}
|
|
1262
1941
|
#validatePositions(rule, matches, firstIndex, lastIndex) {
|
|
1263
1942
|
const { name, position } = rule;
|
|
1264
|
-
|
|
1943
|
+
iterate.forEachSet(matches, (index) => {
|
|
1265
1944
|
if (_RuleValidator.#isValidPosition(index, position, firstIndex, lastIndex)) {
|
|
1266
|
-
|
|
1945
|
+
return;
|
|
1267
1946
|
}
|
|
1268
|
-
this.violate(
|
|
1269
|
-
}
|
|
1947
|
+
this.violate(ContractDiagnostics.positionViolation(name, position, index, this.#context));
|
|
1948
|
+
});
|
|
1270
1949
|
}
|
|
1271
1950
|
static #isValidPosition(matchIndex, position, firstIndex, lastIndex) {
|
|
1272
1951
|
switch (position) {
|
|
@@ -1281,48 +1960,50 @@ var RuleValidator = class _RuleValidator extends StrictBase {
|
|
|
1281
1960
|
}
|
|
1282
1961
|
}
|
|
1283
1962
|
};
|
|
1284
|
-
|
|
1963
|
+
|
|
1964
|
+
// ../../lib/contract/src/children/children-evaluator.ts
|
|
1965
|
+
var ChildrenEvaluator = class extends InvariantBase {
|
|
1966
|
+
#context;
|
|
1285
1967
|
#rules;
|
|
1286
1968
|
#ruleNames;
|
|
1287
1969
|
#matcher;
|
|
1288
1970
|
#ruleValidator;
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
this.#rules = rules.map((
|
|
1293
|
-
this.#ruleNames = this.#rules.map((
|
|
1294
|
-
|
|
1971
|
+
constructor(rules, diagnostics, context = "Component") {
|
|
1972
|
+
super(diagnostics);
|
|
1973
|
+
this.#context = context;
|
|
1974
|
+
this.#rules = rules.map((r) => normalizeChildRule(r));
|
|
1975
|
+
this.#ruleNames = this.#rules.map((r) => r.name);
|
|
1976
|
+
iterate.forEach(this.#rules, (rule) => {
|
|
1295
1977
|
const { name, position, cardinality } = rule;
|
|
1296
1978
|
if ((position === "first" || position === "last") && (cardinality.kind === "unbounded" || cardinality.max > 1)) {
|
|
1297
1979
|
throw new RangeError(
|
|
1298
1980
|
`ChildrenEvaluator [${context}]: rule "${name}" sets position="${position}" with an unbound or >1 max. position="first|last" implies max=1.`
|
|
1299
1981
|
);
|
|
1300
1982
|
}
|
|
1301
|
-
}
|
|
1983
|
+
});
|
|
1302
1984
|
this.#matcher = new RuleMatcher(this.#rules);
|
|
1303
|
-
this.#ruleValidator = new RuleValidator(context,
|
|
1304
|
-
this.#matchBuilder = new MatchValidationErrorBuilder(context);
|
|
1985
|
+
this.#ruleValidator = new RuleValidator(context, diagnostics);
|
|
1305
1986
|
}
|
|
1306
1987
|
evaluate(children) {
|
|
1307
|
-
if (!this.
|
|
1988
|
+
if (!this.active) return;
|
|
1308
1989
|
const { matrix, unexpectedIndices, ambiguousIndices } = this.#matcher.match(children);
|
|
1309
1990
|
this.#ruleValidator.validate(this.#rules, matrix, children.length);
|
|
1310
1991
|
if (unexpectedIndices.size === 0 && ambiguousIndices.size === 0) return;
|
|
1311
|
-
const errors = [];
|
|
1312
1992
|
const violating = [...unexpectedIndices, ...ambiguousIndices].sort((a, b) => a - b);
|
|
1313
|
-
|
|
1993
|
+
iterate.forEach(violating, (ci) => {
|
|
1314
1994
|
const typeName = getTypeName(children[ci]);
|
|
1315
1995
|
if (unexpectedIndices.has(ci)) {
|
|
1316
|
-
|
|
1996
|
+
this.violate(ContractDiagnostics.unexpectedChild(typeName, ci, this.#context));
|
|
1317
1997
|
} else {
|
|
1318
1998
|
const matches = matrix.childToRules.forward.get(ci);
|
|
1319
1999
|
const names = [...matches].map((ri) => this.#ruleNames[ri] ?? `#${ri}`);
|
|
1320
|
-
|
|
2000
|
+
this.violate(ContractDiagnostics.ambiguousChild(typeName, ci, names, this.#context));
|
|
1321
2001
|
}
|
|
1322
|
-
}
|
|
1323
|
-
this.invariant(errors.length === 0, this.#matchBuilder.toError(errors).message);
|
|
2002
|
+
});
|
|
1324
2003
|
}
|
|
1325
2004
|
};
|
|
2005
|
+
|
|
2006
|
+
// ../../lib/contract/src/props/get-disabled-props.ts
|
|
1326
2007
|
var disabledProps = ({
|
|
1327
2008
|
disabled,
|
|
1328
2009
|
"aria-disabled": ariaDisabled,
|
|
@@ -1334,6 +2015,8 @@ var disabledProps = ({
|
|
|
1334
2015
|
...dataDisabled === void 0 && { "data-disabled": "" }
|
|
1335
2016
|
};
|
|
1336
2017
|
};
|
|
2018
|
+
|
|
2019
|
+
// ../../lib/contract/src/props/get-invalid-props.ts
|
|
1337
2020
|
var invalidProps = ({
|
|
1338
2021
|
invalid,
|
|
1339
2022
|
"aria-invalid": ariaInvalid,
|
|
@@ -1345,6 +2028,8 @@ var invalidProps = ({
|
|
|
1345
2028
|
...dataInvalid === void 0 && { "data-invalid": "" }
|
|
1346
2029
|
};
|
|
1347
2030
|
};
|
|
2031
|
+
|
|
2032
|
+
// ../../lib/contract/src/props/get-readonly-props.ts
|
|
1348
2033
|
var readonlyProps = ({
|
|
1349
2034
|
readOnly,
|
|
1350
2035
|
"aria-readonly": ariaReadonly,
|
|
@@ -1360,6 +2045,8 @@ var readonlyProps = ({
|
|
|
1360
2045
|
}
|
|
1361
2046
|
};
|
|
1362
2047
|
};
|
|
2048
|
+
|
|
2049
|
+
// ../core/src/html/aria-rules.ts
|
|
1363
2050
|
var LANDMARK_TAG_SET = /* @__PURE__ */ new Set(["article", "aside", "footer", "header", "main", "nav"]);
|
|
1364
2051
|
var removeLandmarkRoleOverride = {
|
|
1365
2052
|
kind: "removeRole",
|
|
@@ -1379,154 +2066,29 @@ function landmarkRoleRule({ tag, props, implicitRole }) {
|
|
|
1379
2066
|
fixable: true,
|
|
1380
2067
|
severity: "error",
|
|
1381
2068
|
fix: removeLandmarkRoleOverride,
|
|
1382
|
-
|
|
2069
|
+
diagnostic: HtmlDiagnostics.landmarkRoleOverride(tag, implicitRole, role)
|
|
1383
2070
|
}
|
|
1384
2071
|
];
|
|
1385
2072
|
}
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
return { name, match: metadataMatch };
|
|
1395
|
-
}
|
|
1396
|
-
function firstOptional(name, tag) {
|
|
1397
|
-
return { name, match: isTag(tag), cardinality: { max: 1 }, position: "first" };
|
|
1398
|
-
}
|
|
1399
|
-
function contract(children) {
|
|
1400
|
-
return { strict: "warn", children };
|
|
1401
|
-
}
|
|
1402
|
-
function ariaContract(aria) {
|
|
1403
|
-
return { strict: "warn", aria };
|
|
1404
|
-
}
|
|
1405
|
-
function firstChildContract(name, tag) {
|
|
1406
|
-
return contract([firstOptional(name, tag), { name: "content", match: isOpenContent(tag) }]);
|
|
1407
|
-
}
|
|
1408
|
-
var VOID_TAGS = [
|
|
1409
|
-
"area",
|
|
1410
|
-
"base",
|
|
1411
|
-
"br",
|
|
1412
|
-
"col",
|
|
1413
|
-
"embed",
|
|
1414
|
-
"hr",
|
|
1415
|
-
"img",
|
|
1416
|
-
"input",
|
|
1417
|
-
"link",
|
|
1418
|
-
"meta",
|
|
1419
|
-
"param",
|
|
1420
|
-
"source",
|
|
1421
|
-
"track",
|
|
1422
|
-
"wbr"
|
|
1423
|
-
];
|
|
1424
|
-
var TEXT_ONLY_TAGS = ["option", "script", "style", "textarea", "title"];
|
|
1425
|
-
var LANDMARK_TAGS = ["article", "aside", "footer", "header", "main", "nav"];
|
|
1426
|
-
var listContract = contract([{ name: "list-item", match: isTag("li", ...METADATA_TAGS) }]);
|
|
1427
|
-
var tableContract = contract([
|
|
1428
|
-
firstOptional("caption", "caption"),
|
|
1429
|
-
{ name: "colgroup", match: isTag("colgroup") },
|
|
1430
|
-
{ name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
|
|
1431
|
-
{ name: "tbody", match: isTag("tbody") },
|
|
1432
|
-
{ name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
|
|
1433
|
-
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
1434
|
-
]);
|
|
1435
|
-
var tableBodyContract = contract([
|
|
1436
|
-
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
1437
|
-
]);
|
|
1438
|
-
var tableRowContract = contract([
|
|
1439
|
-
{ name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
|
|
1440
|
-
]);
|
|
1441
|
-
var colgroupContract = contract([{ name: "column", match: isTag("col", "template") }]);
|
|
1442
|
-
var dlContract = contract([
|
|
1443
|
-
{ name: "term", match: isTag("dt") },
|
|
1444
|
-
{ name: "description", match: isTag("dd") },
|
|
1445
|
-
{ name: "group", match: isTag("div") },
|
|
1446
|
-
metadata()
|
|
1447
|
-
]);
|
|
1448
|
-
var selectContract = contract([
|
|
1449
|
-
{ name: "option", match: isTag("option", "optgroup", "hr", ...METADATA_TAGS) }
|
|
1450
|
-
]);
|
|
1451
|
-
var optgroupContract = contract([
|
|
1452
|
-
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
1453
|
-
]);
|
|
1454
|
-
var datalistContract = contract([
|
|
1455
|
-
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
1456
|
-
]);
|
|
1457
|
-
var pictureContract = contract([
|
|
1458
|
-
{ name: "source", match: isTag("source", ...METADATA_TAGS) },
|
|
1459
|
-
{ name: "image", match: isTag("img"), cardinality: { min: 1, max: 1 }, position: "last" }
|
|
1460
|
-
]);
|
|
1461
|
-
var figureContract = contract([
|
|
1462
|
-
{ name: "caption", match: isTag("figcaption"), cardinality: { max: 1 } },
|
|
1463
|
-
{ name: "content", match: isOpenContent("figcaption") }
|
|
1464
|
-
]);
|
|
1465
|
-
var detailsContract = firstChildContract("summary", "summary");
|
|
1466
|
-
var fieldsetContract = firstChildContract("legend", "legend");
|
|
1467
|
-
var mediaContract = contract([
|
|
1468
|
-
{ name: "source", match: isTag("source") },
|
|
1469
|
-
{ name: "track", match: isTag("track") },
|
|
1470
|
-
metadata(),
|
|
1471
|
-
{ name: "content", match: isOpenContent("source", "track", ...METADATA_TAGS) }
|
|
1472
|
-
]);
|
|
1473
|
-
var headContract = contract([
|
|
1474
|
-
{
|
|
1475
|
-
name: "metadata",
|
|
1476
|
-
match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
|
|
1477
|
-
}
|
|
1478
|
-
]);
|
|
1479
|
-
var htmlContract = contract([
|
|
1480
|
-
{ name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
|
|
1481
|
-
{ name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
|
|
1482
|
-
]);
|
|
1483
|
-
var voidContract = contract([]);
|
|
1484
|
-
var textOnlyContract = contract([
|
|
1485
|
-
{
|
|
1486
|
-
name: "text",
|
|
1487
|
-
match: (child) => isString(child) || isNumber(child)
|
|
1488
|
-
}
|
|
1489
|
-
]);
|
|
1490
|
-
var landmarkContract = ariaContract([landmarkRoleRule]);
|
|
1491
|
-
var CONTRACT_GROUPS = [
|
|
1492
|
-
[VOID_TAGS, voidContract],
|
|
1493
|
-
[TEXT_ONLY_TAGS, textOnlyContract],
|
|
1494
|
-
[LANDMARK_TAGS, landmarkContract],
|
|
1495
|
-
[["ul", "ol", "menu"], listContract],
|
|
1496
|
-
[["audio", "video"], mediaContract],
|
|
1497
|
-
[["thead", "tbody", "tfoot"], tableBodyContract]
|
|
1498
|
-
];
|
|
1499
|
-
function contractMap(groups) {
|
|
1500
|
-
return Object.fromEntries(
|
|
1501
|
-
groups.flatMap(([tags, enforcement]) => tags.map((tag) => [tag, enforcement]))
|
|
1502
|
-
);
|
|
1503
|
-
}
|
|
1504
|
-
var htmlContracts = {
|
|
1505
|
-
...contractMap(CONTRACT_GROUPS),
|
|
1506
|
-
table: tableContract,
|
|
1507
|
-
tr: tableRowContract,
|
|
1508
|
-
colgroup: colgroupContract,
|
|
1509
|
-
dl: dlContract,
|
|
1510
|
-
select: selectContract,
|
|
1511
|
-
optgroup: optgroupContract,
|
|
1512
|
-
datalist: datalistContract,
|
|
1513
|
-
picture: pictureContract,
|
|
1514
|
-
figure: figureContract,
|
|
1515
|
-
details: detailsContract,
|
|
1516
|
-
fieldset: fieldsetContract,
|
|
1517
|
-
head: headContract,
|
|
1518
|
-
html: htmlContract
|
|
1519
|
-
};
|
|
1520
|
-
function buildEvaluatorMap() {
|
|
1521
|
-
const map = /* @__PURE__ */ new Map();
|
|
1522
|
-
for (const [tag, { children }] of Object.entries(htmlContracts)) {
|
|
1523
|
-
if (children?.length) {
|
|
1524
|
-
map.set(tag, new ChildrenEvaluator(children, "warn", `<${tag}>`));
|
|
2073
|
+
function requireAccessibleName({ tag, props }) {
|
|
2074
|
+
if ("aria-label" in props || "aria-labelledby" in props) return [];
|
|
2075
|
+
return [
|
|
2076
|
+
{
|
|
2077
|
+
valid: false,
|
|
2078
|
+
fixable: false,
|
|
2079
|
+
severity: "warning",
|
|
2080
|
+
diagnostic: AriaDiagnostics.missingAccessibleName(tag)
|
|
1525
2081
|
}
|
|
1526
|
-
|
|
1527
|
-
return map;
|
|
2082
|
+
];
|
|
1528
2083
|
}
|
|
1529
|
-
var
|
|
2084
|
+
var NAMED_LANDMARK_TAGS = /* @__PURE__ */ new Set(["nav", "aside"]);
|
|
2085
|
+
function landmarkNameAdvisory(ctx) {
|
|
2086
|
+
if (!ctx.implicitRole || !NAMED_LANDMARK_TAGS.has(ctx.tag)) return [];
|
|
2087
|
+
return requireAccessibleName(ctx);
|
|
2088
|
+
}
|
|
2089
|
+
var HTML_ARIA_RULES = [landmarkRoleRule, landmarkNameAdvisory];
|
|
2090
|
+
|
|
2091
|
+
// ../core/src/html/prop-normalizers.ts
|
|
1530
2092
|
var HTML_FORM_NORMALIZERS = /* @__PURE__ */ new Map([
|
|
1531
2093
|
["button", [disabledProps]],
|
|
1532
2094
|
["input", [disabledProps, readonlyProps, invalidProps]],
|
|
@@ -1539,9 +2101,10 @@ function getHtmlPropNormalizers(tag) {
|
|
|
1539
2101
|
return typeof tag === "string" ? HTML_FORM_NORMALIZERS.get(tag) : void 0;
|
|
1540
2102
|
}
|
|
1541
2103
|
|
|
1542
|
-
//
|
|
2104
|
+
// ../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.mjs
|
|
2105
|
+
import { clsx as clsx2 } from "clsx";
|
|
1543
2106
|
var falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
|
|
1544
|
-
var cx =
|
|
2107
|
+
var cx = clsx2;
|
|
1545
2108
|
var cva = (base, config) => (props) => {
|
|
1546
2109
|
var _config_compoundVariants;
|
|
1547
2110
|
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);
|
|
@@ -1580,10 +2143,14 @@ var cva = (base, config) => (props) => {
|
|
|
1580
2143
|
}, []);
|
|
1581
2144
|
return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
|
|
1582
2145
|
};
|
|
2146
|
+
|
|
2147
|
+
// ../../lib/styling/src/cva.ts
|
|
1583
2148
|
function cva2(base, config) {
|
|
1584
2149
|
const fn = cva(base, config);
|
|
1585
2150
|
return (props) => cn(fn(props));
|
|
1586
2151
|
}
|
|
2152
|
+
|
|
2153
|
+
// ../../lib/styling/src/static-class-resolver.ts
|
|
1587
2154
|
var StaticClassResolver = class {
|
|
1588
2155
|
#baseClass;
|
|
1589
2156
|
#cache = /* @__PURE__ */ new Map();
|
|
@@ -1614,6 +2181,8 @@ var StaticClassResolver = class {
|
|
|
1614
2181
|
return result;
|
|
1615
2182
|
}
|
|
1616
2183
|
};
|
|
2184
|
+
|
|
2185
|
+
// ../../lib/styling/src/variant-class-resolver.ts
|
|
1617
2186
|
var VariantClassResolver = class _VariantClassResolver {
|
|
1618
2187
|
#cvaFn;
|
|
1619
2188
|
#recipeMap;
|
|
@@ -1661,15 +2230,15 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
1661
2230
|
#createCacheKey(props, recipe) {
|
|
1662
2231
|
if (this.#variantKeys !== null) {
|
|
1663
2232
|
let key2 = recipe;
|
|
1664
|
-
|
|
2233
|
+
iterate.forEachSet(this.#variantKeys, (k) => {
|
|
1665
2234
|
if (k in props) key2 += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
1666
|
-
}
|
|
2235
|
+
});
|
|
1667
2236
|
return key2;
|
|
1668
2237
|
}
|
|
1669
2238
|
let key = recipe;
|
|
1670
|
-
|
|
2239
|
+
iterate.forEach(Object.keys(props).sort(), (k) => {
|
|
1671
2240
|
key += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
1672
|
-
}
|
|
2241
|
+
});
|
|
1673
2242
|
return key;
|
|
1674
2243
|
}
|
|
1675
2244
|
static #serializeValue(value) {
|
|
@@ -1680,6 +2249,8 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
1680
2249
|
return `x:${String(value)}`;
|
|
1681
2250
|
}
|
|
1682
2251
|
};
|
|
2252
|
+
|
|
2253
|
+
// ../../lib/styling/src/create-class-pipeline.ts
|
|
1683
2254
|
function createClassPipeline(resolved) {
|
|
1684
2255
|
const baseClass = resolved.baseClassName ?? "";
|
|
1685
2256
|
const cvaFn = resolved.variants ? cva2("", {
|
|
@@ -1704,7 +2275,203 @@ function createClassPipeline(resolved) {
|
|
|
1704
2275
|
};
|
|
1705
2276
|
}
|
|
1706
2277
|
|
|
1707
|
-
// ../core/
|
|
2278
|
+
// ../core/src/options/resolve-factory-options.ts
|
|
2279
|
+
var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
|
|
2280
|
+
function composeNormalizers(normalizers, fn) {
|
|
2281
|
+
if (!normalizers?.length) return fn;
|
|
2282
|
+
return ((props) => {
|
|
2283
|
+
const patched = normalizers.reduce(
|
|
2284
|
+
(acc, normalizer) => ({ ...acc, ...normalizer(acc) }),
|
|
2285
|
+
props
|
|
2286
|
+
);
|
|
2287
|
+
return fn ? fn(patched) : patched;
|
|
2288
|
+
});
|
|
2289
|
+
}
|
|
2290
|
+
function whenDefined(key, value) {
|
|
2291
|
+
return value === void 0 ? {} : { [key]: value };
|
|
2292
|
+
}
|
|
2293
|
+
function resolveFactoryOptions(options = {}) {
|
|
2294
|
+
const { styling, enforcement } = options;
|
|
2295
|
+
const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
|
|
2296
|
+
const variantKeys = styling?.variants === void 0 ? EMPTY_VARIANT_KEYS : new Set(Object.keys(styling.variants));
|
|
2297
|
+
return Object.freeze({
|
|
2298
|
+
defaultTag: options.tag ?? "div",
|
|
2299
|
+
diagnostics: enforcement?.diagnostics ?? silentDiagnostics,
|
|
2300
|
+
variantKeys,
|
|
2301
|
+
...whenDefined("displayName", options.name),
|
|
2302
|
+
...whenDefined("defaultProps", options.defaults),
|
|
2303
|
+
...whenDefined("baseClassName", styling?.base),
|
|
2304
|
+
...whenDefined("tagMap", styling?.tags),
|
|
2305
|
+
...whenDefined("recipeMap", styling?.presets),
|
|
2306
|
+
...whenDefined("variants", styling?.variants),
|
|
2307
|
+
...whenDefined("defaultVariants", styling?.defaults),
|
|
2308
|
+
...whenDefined("compoundVariants", styling?.compounds),
|
|
2309
|
+
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
2310
|
+
...whenDefined("ariaRules", enforcement?.aria),
|
|
2311
|
+
...whenDefined("childRules", enforcement?.children),
|
|
2312
|
+
...whenDefined("allowedAs", enforcement?.allowedAs),
|
|
2313
|
+
...whenDefined("precomputedClasses", styling?.precomputedClasses)
|
|
2314
|
+
});
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
// ../core/src/options/validate-factory-options.ts
|
|
2318
|
+
function validateFactoryOptions(resolved, diagnostics) {
|
|
2319
|
+
if (!diagnostics.active) return;
|
|
2320
|
+
const name = resolved.displayName ?? "Component";
|
|
2321
|
+
const { variants } = resolved;
|
|
2322
|
+
const checkSelection = (label2, selection) => {
|
|
2323
|
+
iterate.forEachEntry(selection, (dim, value) => {
|
|
2324
|
+
if (value === void 0 || value === null) return;
|
|
2325
|
+
if (!variants || !Object.hasOwn(variants, dim)) {
|
|
2326
|
+
diagnostics.error(ContractDiagnostics.unknownVariantDim(name, label2, dim));
|
|
2327
|
+
return;
|
|
2328
|
+
}
|
|
2329
|
+
const states = variants[dim];
|
|
2330
|
+
const stateKey = String(value);
|
|
2331
|
+
if (!Object.hasOwn(states, stateKey)) {
|
|
2332
|
+
diagnostics.error(
|
|
2333
|
+
ContractDiagnostics.unknownVariantValue(name, label2, dim, stateKey, Object.keys(states))
|
|
2334
|
+
);
|
|
2335
|
+
}
|
|
2336
|
+
});
|
|
2337
|
+
};
|
|
2338
|
+
const { recipeMap } = resolved;
|
|
2339
|
+
if (recipeMap) {
|
|
2340
|
+
iterate.forEachEntry(recipeMap, (recipeKey, selection) => {
|
|
2341
|
+
checkSelection(`preset "${recipeKey}"`, selection);
|
|
2342
|
+
});
|
|
2343
|
+
}
|
|
2344
|
+
if (resolved.defaultVariants) checkSelection("defaults", resolved.defaultVariants);
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2347
|
+
// ../core/src/options/validate-render-props.ts
|
|
2348
|
+
function label(name) {
|
|
2349
|
+
return name ? `[${name}]` : "[createContractComponent]";
|
|
2350
|
+
}
|
|
2351
|
+
function validateRenderProps(diagnostics, options, props, recipeKey) {
|
|
2352
|
+
const { recipeMap, variants, displayName } = options;
|
|
2353
|
+
const tag = label(displayName);
|
|
2354
|
+
if (recipeKey !== void 0 && (!recipeMap || !Object.hasOwn(recipeMap, recipeKey))) {
|
|
2355
|
+
diagnostics.error(ContractDiagnostics.unknownRecipeKey(tag, recipeKey));
|
|
2356
|
+
}
|
|
2357
|
+
if (variants) {
|
|
2358
|
+
iterate.forEachKey(variants, (key) => {
|
|
2359
|
+
if (!Object.hasOwn(props, key)) return;
|
|
2360
|
+
const value = props[key];
|
|
2361
|
+
if (value === void 0 || value === null) return;
|
|
2362
|
+
const dim = variants[key];
|
|
2363
|
+
if (dim && !Object.hasOwn(dim, String(value))) {
|
|
2364
|
+
diagnostics.error(ContractDiagnostics.invalidVariantValue(tag, key, String(value)));
|
|
2365
|
+
}
|
|
2366
|
+
});
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
// ../core/src/factory/plugin-diagnostics.ts
|
|
2371
|
+
var PluginDiagnostics = {
|
|
2372
|
+
invalidShape(received) {
|
|
2373
|
+
const got = received === null ? "null" : typeof received;
|
|
2374
|
+
return {
|
|
2375
|
+
code: "PLUGIN7001" /* PluginInvalidShape */,
|
|
2376
|
+
category: 7 /* Internal */,
|
|
2377
|
+
message: `[praxis-kit] Plugin factory must return an object with a 'pipeline' function. Got: ${got}.`
|
|
2378
|
+
};
|
|
2379
|
+
},
|
|
2380
|
+
pipelineReturnType(received) {
|
|
2381
|
+
const got = received === null ? "null" : Array.isArray(received) ? "array" : typeof received;
|
|
2382
|
+
return {
|
|
2383
|
+
code: "PLUGIN7002" /* PluginPipelineReturnType */,
|
|
2384
|
+
category: 7 /* Internal */,
|
|
2385
|
+
message: `[praxis-kit] Plugin pipeline must return a string. Got: ${got}.`
|
|
2386
|
+
};
|
|
2387
|
+
}
|
|
2388
|
+
};
|
|
2389
|
+
|
|
2390
|
+
// ../core/src/factory/plugin-invariants.ts
|
|
2391
|
+
function assertPluginShape(result) {
|
|
2392
|
+
if (result === null || typeof result !== "object")
|
|
2393
|
+
throwDiagnostics.error(PluginDiagnostics.invalidShape(result));
|
|
2394
|
+
const plugin = result;
|
|
2395
|
+
if (typeof plugin.pipeline !== "function")
|
|
2396
|
+
throwDiagnostics.error(PluginDiagnostics.invalidShape(result));
|
|
2397
|
+
}
|
|
2398
|
+
function guardPipeline(pipeline) {
|
|
2399
|
+
if (process.env.NODE_ENV === "production") return pipeline;
|
|
2400
|
+
return function guardedPipeline(tag, props, className, recipe) {
|
|
2401
|
+
const result = pipeline(tag, props, className, recipe);
|
|
2402
|
+
if (typeof result !== "string")
|
|
2403
|
+
throwDiagnostics.error(PluginDiagnostics.pipelineReturnType(result));
|
|
2404
|
+
return result;
|
|
2405
|
+
};
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
// ../core/src/factory/create-polymorphic.ts
|
|
2409
|
+
var NOOP_CLASS_PIPELINE = (_tag, _props, className) => Array.isArray(className) ? className.join(" ") : className ?? "";
|
|
2410
|
+
function resolveClassPipeline(options, resolved, diagnostics, capabilities) {
|
|
2411
|
+
const factory = options.styling?.plugin;
|
|
2412
|
+
if (!factory) {
|
|
2413
|
+
const createClassPipeline2 = capabilities?.createClassPipeline;
|
|
2414
|
+
const classPipeline2 = createClassPipeline2 ? createClassPipeline2(resolved) : NOOP_CLASS_PIPELINE;
|
|
2415
|
+
return { pluginResult: void 0, classPipeline: classPipeline2 };
|
|
2416
|
+
}
|
|
2417
|
+
const pluginResult = factory(resolved, diagnostics);
|
|
2418
|
+
assertPluginShape(pluginResult);
|
|
2419
|
+
const classPipeline = guardPipeline(pluginResult.pipeline);
|
|
2420
|
+
return { pluginResult, classPipeline };
|
|
2421
|
+
}
|
|
2422
|
+
function createRuntimeMethods(resolved, classPipeline, engine, renderDiagnostics) {
|
|
2423
|
+
return {
|
|
2424
|
+
resolveTag: makeResolveTag(resolved.defaultTag),
|
|
2425
|
+
resolveProps(props) {
|
|
2426
|
+
return mergeProps(resolved.defaultProps, props);
|
|
2427
|
+
},
|
|
2428
|
+
resolveClasses(tag, props, className, recipe) {
|
|
2429
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2430
|
+
validateRenderProps(renderDiagnostics, resolved, props, recipe);
|
|
2431
|
+
}
|
|
2432
|
+
return classPipeline(tag, props, className, recipe);
|
|
2433
|
+
},
|
|
2434
|
+
resolveAria(tag, props) {
|
|
2435
|
+
if (!engine) return { props };
|
|
2436
|
+
const result = engine.validate(tag, props);
|
|
2437
|
+
return { props: result.props };
|
|
2438
|
+
}
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
function createRuntimeObject(methods, resolved, pluginResult) {
|
|
2442
|
+
return pluginResult ? { ...methods, options: resolved, hasStyling: true, classPlugin: pluginResult } : { ...methods, options: resolved };
|
|
2443
|
+
}
|
|
2444
|
+
function createPolymorphic(options = {}, capabilities) {
|
|
2445
|
+
const baseResolved = resolveFactoryOptions(options);
|
|
2446
|
+
const resolved = capabilities?.htmlPropNormalizersFn !== void 0 ? Object.freeze({
|
|
2447
|
+
...baseResolved,
|
|
2448
|
+
htmlPropNormalizersFn: capabilities.htmlPropNormalizersFn
|
|
2449
|
+
}) : baseResolved;
|
|
2450
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2451
|
+
validateFactoryOptions(resolved, resolved.diagnostics);
|
|
2452
|
+
}
|
|
2453
|
+
const { pluginResult, classPipeline } = resolveClassPipeline(
|
|
2454
|
+
options,
|
|
2455
|
+
resolved,
|
|
2456
|
+
resolved.diagnostics,
|
|
2457
|
+
capabilities
|
|
2458
|
+
);
|
|
2459
|
+
const allAriaRules = [
|
|
2460
|
+
.../* @__PURE__ */ new Set([...capabilities?.htmlAriaRules ?? [], ...resolved.ariaRules ?? []])
|
|
2461
|
+
];
|
|
2462
|
+
const engine = options.enforcement !== void 0 && capabilities?.AriaEngine ? new capabilities.AriaEngine(
|
|
2463
|
+
resolved.diagnostics,
|
|
2464
|
+
allAriaRules.length ? { rules: allAriaRules } : void 0
|
|
2465
|
+
) : null;
|
|
2466
|
+
const methods = createRuntimeMethods(resolved, classPipeline, engine, resolved.diagnostics);
|
|
2467
|
+
return createRuntimeObject(
|
|
2468
|
+
methods,
|
|
2469
|
+
resolved,
|
|
2470
|
+
pluginResult
|
|
2471
|
+
);
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
// ../core/src/factory/create-polymorphic-full.ts
|
|
1708
2475
|
var FULL_CAPABILITIES = {
|
|
1709
2476
|
createClassPipeline,
|
|
1710
2477
|
AriaEngine: AriaPolicyEngine,
|
|
@@ -1715,6 +2482,11 @@ function createPolymorphic2(options = {}) {
|
|
|
1715
2482
|
return createPolymorphic(options, FULL_CAPABILITIES);
|
|
1716
2483
|
}
|
|
1717
2484
|
|
|
2485
|
+
// ../../lib/adapter-utils/src/define-component.ts
|
|
2486
|
+
function defineContractComponent(options) {
|
|
2487
|
+
return (factory) => factory(options);
|
|
2488
|
+
}
|
|
2489
|
+
|
|
1718
2490
|
// ../../lib/adapter-utils/src/build-core-runtime.ts
|
|
1719
2491
|
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
1720
2492
|
function buildCoreRuntime(normalized) {
|
|
@@ -1724,8 +2496,8 @@ function buildCoreRuntime(normalized) {
|
|
|
1724
2496
|
}
|
|
1725
2497
|
|
|
1726
2498
|
// ../../lib/adapter-utils/src/build-engines.ts
|
|
1727
|
-
function buildEngines(
|
|
1728
|
-
return childRules?.length ? { childrenEvaluator: new ChildrenEvaluator(childRules,
|
|
2499
|
+
function buildEngines(diagnostics, childRules, context) {
|
|
2500
|
+
return childRules?.length ? { childrenEvaluator: new ChildrenEvaluator(childRules, diagnostics, context) } : {};
|
|
1729
2501
|
}
|
|
1730
2502
|
|
|
1731
2503
|
// ../../lib/adapter-utils/src/compose-filter.ts
|
|
@@ -1738,30 +2510,28 @@ function composeFilter(ownedKeys, filterProps) {
|
|
|
1738
2510
|
}
|
|
1739
2511
|
|
|
1740
2512
|
// ../../lib/adapter-utils/src/resolve-adapter-common-options.ts
|
|
1741
|
-
function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent",
|
|
2513
|
+
function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics) {
|
|
1742
2514
|
return {
|
|
1743
2515
|
name: options.name ?? defaultName,
|
|
1744
|
-
|
|
2516
|
+
diagnostics: options.enforcement?.diagnostics ?? defaultDiagnostics
|
|
1745
2517
|
};
|
|
1746
2518
|
}
|
|
1747
2519
|
|
|
1748
2520
|
// ../../adapters/solid/src/slot/slot-validator.ts
|
|
1749
|
-
var SlotValidator = class extends
|
|
2521
|
+
var SlotValidator = class extends InvariantBase {
|
|
1750
2522
|
#name;
|
|
1751
|
-
constructor(name,
|
|
1752
|
-
super(
|
|
2523
|
+
constructor(name, diagnostics) {
|
|
2524
|
+
super(diagnostics);
|
|
1753
2525
|
this.#name = name;
|
|
1754
2526
|
}
|
|
1755
2527
|
assertExclusive() {
|
|
1756
|
-
this.violate(
|
|
2528
|
+
this.violate(SlotDiagnostics.exclusive(this.#name));
|
|
1757
2529
|
}
|
|
1758
2530
|
// Returns false (instead of throwing) when strict mode caps at warn, so callers can
|
|
1759
2531
|
// fall through to a safe no-op render rather than calling an undefined render function.
|
|
1760
2532
|
assertRenderFn(children) {
|
|
1761
2533
|
if (typeof children !== "function") {
|
|
1762
|
-
this.violate(
|
|
1763
|
-
`${this.#name}: asChild requires a render function as children, got ${typeof children}`
|
|
1764
|
-
);
|
|
2534
|
+
this.violate(SlotDiagnostics.renderFnRequired(this.#name, typeof children));
|
|
1765
2535
|
return false;
|
|
1766
2536
|
}
|
|
1767
2537
|
return true;
|
|
@@ -1776,12 +2546,12 @@ function buildRuntime(options) {
|
|
|
1776
2546
|
const normalized = normalizeOptions(options);
|
|
1777
2547
|
const { runtime, ownedKeys } = buildCoreRuntime(normalized);
|
|
1778
2548
|
const { childrenEvaluator } = buildEngines(
|
|
1779
|
-
normalized.
|
|
2549
|
+
normalized.diagnostics,
|
|
1780
2550
|
normalized.enforcement?.children,
|
|
1781
2551
|
normalized.name
|
|
1782
2552
|
);
|
|
1783
2553
|
const filterProps = composeFilter(ownedKeys, normalized.filterProps);
|
|
1784
|
-
const slotValidator = new SlotValidator(normalized.name, normalized.
|
|
2554
|
+
const slotValidator = new SlotValidator(normalized.name, normalized.diagnostics);
|
|
1785
2555
|
return {
|
|
1786
2556
|
runtime,
|
|
1787
2557
|
filterProps,
|