praxis-kit 6.2.3 → 6.6.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/dist/_shared/diagnostics.d.ts +4 -0
- package/dist/_shared/diagnostics.js +4 -0
- package/dist/{chunk-H3D2JA3J.js → chunk-OCG5VM4H.js} +519 -326
- package/dist/contract/index.d.ts +11 -0
- package/dist/contract/index.js +2 -0
- package/dist/guards/index.d.ts +11 -2
- package/dist/html/index.d.ts +98 -0
- package/dist/html/index.js +860 -0
- package/dist/lit/index.d.ts +11 -0
- package/dist/lit/index.js +519 -326
- package/dist/preact/index.d.ts +20 -0
- package/dist/preact/index.js +519 -326
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -1
- package/dist/react/legacy.d.ts +2 -2
- package/dist/react/legacy.js +1 -1
- package/dist/{react-options-DQTX4YS_.d.ts → react-options-BUBVohU6.d.ts} +50 -33
- package/dist/solid/index.d.ts +20 -0
- package/dist/solid/index.js +519 -326
- package/dist/svelte/index.d.ts +11 -0
- package/dist/svelte/index.js +519 -326
- package/dist/vite-plugin/index.d.ts +4 -0
- package/dist/vue/index.d.ts +11 -0
- package/dist/vue/index.js +519 -326
- package/dist/web/index.d.ts +11 -0
- package/dist/web/index.js +519 -326
- package/package.json +12 -5
package/dist/lit/index.js
CHANGED
|
@@ -25,6 +25,9 @@ function isNull(value) {
|
|
|
25
25
|
function isNonNull(value) {
|
|
26
26
|
return value != null;
|
|
27
27
|
}
|
|
28
|
+
function isNullish(value) {
|
|
29
|
+
return isNull(value) || value === void 0;
|
|
30
|
+
}
|
|
28
31
|
|
|
29
32
|
// ../../lib/primitive/src/utils/type-guards.ts
|
|
30
33
|
function isObject(value, excludeArrays = false) {
|
|
@@ -526,20 +529,29 @@ function isAriaAttributeValidForRole(attr, role) {
|
|
|
526
529
|
}
|
|
527
530
|
|
|
528
531
|
// ../../lib/primitive/src/guards/aria/is-aria-role.ts
|
|
532
|
+
function lookupImplicitRole(tag) {
|
|
533
|
+
return IMPLICIT_ROLE_RECORD[tag];
|
|
534
|
+
}
|
|
529
535
|
function isStrongImplicitRole(tag) {
|
|
530
|
-
|
|
531
|
-
return STRONG_ROLES_SET.has(
|
|
536
|
+
const role = lookupImplicitRole(tag);
|
|
537
|
+
return !isNullish(role) && STRONG_ROLES_SET.has(role);
|
|
532
538
|
}
|
|
533
|
-
function
|
|
534
|
-
|
|
535
|
-
return STANDALONE_ROLES_SET.has(
|
|
539
|
+
function hasStandaloneRole(tag) {
|
|
540
|
+
const role = lookupImplicitRole(tag);
|
|
541
|
+
return !isNullish(role) && STANDALONE_ROLES_SET.has(role);
|
|
536
542
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
return
|
|
543
|
+
var LIST_ELIGIBLE_INPUT_TYPES = /* @__PURE__ */ new Set(["text", "search", "tel", "url", "email"]);
|
|
544
|
+
function getInputImplicitRole(type, list) {
|
|
545
|
+
if (!isString(type)) return void 0;
|
|
546
|
+
const role = INPUT_TYPE_ROLE_MAP[type];
|
|
547
|
+
if (!role) return void 0;
|
|
548
|
+
if (!isNullish(list) && LIST_ELIGIBLE_INPUT_TYPES.has(type)) {
|
|
549
|
+
return "combobox";
|
|
550
|
+
}
|
|
551
|
+
return role;
|
|
540
552
|
}
|
|
541
553
|
function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
|
|
542
|
-
const isNamed = isString(ariaLabel) || isString(ariaLabelledBy);
|
|
554
|
+
const isNamed = isString(ariaLabel) && ariaLabel.trim().length > 0 || isString(ariaLabelledBy) && ariaLabelledBy.trim().length > 0;
|
|
543
555
|
if (!isNamed) return void 0;
|
|
544
556
|
if (tag === "section") return "region";
|
|
545
557
|
if (tag === "form") return "form";
|
|
@@ -585,7 +597,7 @@ function isTag(...args) {
|
|
|
585
597
|
// ../../lib/contract/src/aria/aria-role-policy.ts
|
|
586
598
|
function getImplicitRole(tag, props) {
|
|
587
599
|
if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
|
|
588
|
-
if (tag === "input") return getInputImplicitRole(props?.type);
|
|
600
|
+
if (tag === "input") return getInputImplicitRole(props?.type, props?.list);
|
|
589
601
|
if (tag === "img") return props?.alt === "" ? "none" : "img";
|
|
590
602
|
if (tag === "section" || tag === "form") {
|
|
591
603
|
return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
|
|
@@ -868,7 +880,11 @@ var ATTRIBUTE_IGNORED_CODES = {
|
|
|
868
880
|
max: DiagnosticCode3.HtmlInputMaxIgnoredForType,
|
|
869
881
|
step: DiagnosticCode3.HtmlInputStepIgnoredForType,
|
|
870
882
|
accept: DiagnosticCode3.HtmlInputAcceptIgnoredForType,
|
|
871
|
-
capture: DiagnosticCode3.HtmlInputCaptureIgnoredForType
|
|
883
|
+
capture: DiagnosticCode3.HtmlInputCaptureIgnoredForType,
|
|
884
|
+
size: DiagnosticCode3.HtmlInputSizeIgnoredForType,
|
|
885
|
+
alt: DiagnosticCode3.HtmlInputAltIgnoredForType,
|
|
886
|
+
height: DiagnosticCode3.HtmlInputHeightIgnoredForType,
|
|
887
|
+
width: DiagnosticCode3.HtmlInputWidthIgnoredForType
|
|
872
888
|
};
|
|
873
889
|
var HtmlDiagnostics = {
|
|
874
890
|
emptyRole(tag) {
|
|
@@ -1056,8 +1072,132 @@ var InvariantBase = class {
|
|
|
1056
1072
|
}
|
|
1057
1073
|
};
|
|
1058
1074
|
|
|
1059
|
-
// ../../lib/contract/src/aria/
|
|
1075
|
+
// ../../lib/contract/src/aria/spec/roles/required-properties.ts
|
|
1076
|
+
var REQUIRED_ARIA_PROPERTIES = {
|
|
1077
|
+
combobox: ["aria-expanded"],
|
|
1078
|
+
option: ["aria-selected"],
|
|
1079
|
+
slider: ["aria-valuenow"],
|
|
1080
|
+
scrollbar: ["aria-controls", "aria-valuenow"],
|
|
1081
|
+
spinbutton: ["aria-valuenow"]
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
// ../../lib/contract/src/aria/spec/roles/name-required.ts
|
|
1085
|
+
var NAME_REQUIRED_ROLES = /* @__PURE__ */ new Set(["img"]);
|
|
1086
|
+
|
|
1087
|
+
// ../../lib/contract/src/aria/spec/validators/required-properties-validator.ts
|
|
1060
1088
|
var NO_VIOLATIONS = [{ valid: true }];
|
|
1089
|
+
function requiredAttributeByRole(roles, attribute) {
|
|
1090
|
+
return Object.fromEntries([...roles].map((role) => [role, [attribute]]));
|
|
1091
|
+
}
|
|
1092
|
+
function checkRequiredAttributes(requirement, { props, effectiveRole }) {
|
|
1093
|
+
if (!effectiveRole) return NO_VIOLATIONS;
|
|
1094
|
+
const requiredAttributes = requirement.attributesByRole[effectiveRole];
|
|
1095
|
+
if (!requiredAttributes) return NO_VIOLATIONS;
|
|
1096
|
+
const results = [];
|
|
1097
|
+
for (const attribute of requiredAttributes) {
|
|
1098
|
+
if (attribute in props) continue;
|
|
1099
|
+
results.push({
|
|
1100
|
+
valid: false,
|
|
1101
|
+
fixable: false,
|
|
1102
|
+
severity: "warning",
|
|
1103
|
+
attribute,
|
|
1104
|
+
diagnostic: requirement.diagnosticFor(attribute, effectiveRole)
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
return results;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// ../../lib/contract/src/aria/spec/roles/live-region.ts
|
|
1111
|
+
var LIVE_REGION_ROLES = /* @__PURE__ */ new Map([
|
|
1112
|
+
["alert", "assertive"],
|
|
1113
|
+
["status", "polite"],
|
|
1114
|
+
["log", "polite"],
|
|
1115
|
+
["timer", "off"]
|
|
1116
|
+
]);
|
|
1117
|
+
var ATOMIC_REQUIREMENTS = requiredAttributeByRole(LIVE_REGION_ROLES.keys(), "aria-atomic");
|
|
1118
|
+
|
|
1119
|
+
// ../../lib/contract/src/aria/spec/attributes/aria-value-types.ts
|
|
1120
|
+
var ARIA_VALUE_TYPES = /* @__PURE__ */ new Map([
|
|
1121
|
+
// Boolean (true | false)
|
|
1122
|
+
["aria-atomic", { kind: "boolean" }],
|
|
1123
|
+
["aria-busy", { kind: "boolean" }],
|
|
1124
|
+
["aria-disabled", { kind: "boolean" }],
|
|
1125
|
+
["aria-expanded", { kind: "boolean" }],
|
|
1126
|
+
["aria-hidden", { kind: "boolean" }],
|
|
1127
|
+
["aria-modal", { kind: "boolean" }],
|
|
1128
|
+
["aria-multiline", { kind: "boolean" }],
|
|
1129
|
+
["aria-multiselectable", { kind: "boolean" }],
|
|
1130
|
+
["aria-readonly", { kind: "boolean" }],
|
|
1131
|
+
["aria-required", { kind: "boolean" }],
|
|
1132
|
+
["aria-selected", { kind: "boolean" }],
|
|
1133
|
+
// Tristate (true | false | mixed)
|
|
1134
|
+
["aria-checked", { kind: "tristate" }],
|
|
1135
|
+
["aria-pressed", { kind: "tristate" }],
|
|
1136
|
+
// Numeric (any finite number)
|
|
1137
|
+
["aria-valuenow", { kind: "number" }],
|
|
1138
|
+
["aria-valuemin", { kind: "number" }],
|
|
1139
|
+
["aria-valuemax", { kind: "number" }],
|
|
1140
|
+
// Integer with optional range
|
|
1141
|
+
["aria-level", { kind: "integer", min: 1, max: 6 }],
|
|
1142
|
+
["aria-posinset", { kind: "integer", min: 1 }],
|
|
1143
|
+
["aria-setsize", { kind: "integer", min: -1 }],
|
|
1144
|
+
["aria-rowcount", { kind: "integer", min: -1 }],
|
|
1145
|
+
["aria-colcount", { kind: "integer", min: -1 }],
|
|
1146
|
+
["aria-rowindex", { kind: "integer", min: 1 }],
|
|
1147
|
+
["aria-colindex", { kind: "integer", min: 1 }],
|
|
1148
|
+
["aria-rowspan", { kind: "integer", min: 0 }],
|
|
1149
|
+
["aria-colspan", { kind: "integer", min: 0 }],
|
|
1150
|
+
// Enum (specific allowed tokens)
|
|
1151
|
+
["aria-autocomplete", { kind: "enum", values: /* @__PURE__ */ new Set(["inline", "list", "both", "none"]) }],
|
|
1152
|
+
[
|
|
1153
|
+
"aria-current",
|
|
1154
|
+
{
|
|
1155
|
+
kind: "enum",
|
|
1156
|
+
values: /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"])
|
|
1157
|
+
}
|
|
1158
|
+
],
|
|
1159
|
+
[
|
|
1160
|
+
"aria-haspopup",
|
|
1161
|
+
{
|
|
1162
|
+
kind: "enum",
|
|
1163
|
+
values: /* @__PURE__ */ new Set(["false", "true", "menu", "listbox", "tree", "grid", "dialog"])
|
|
1164
|
+
}
|
|
1165
|
+
],
|
|
1166
|
+
["aria-invalid", { kind: "enum", values: /* @__PURE__ */ new Set(["grammar", "false", "spelling", "true"]) }],
|
|
1167
|
+
["aria-live", { kind: "enum", values: /* @__PURE__ */ new Set(["assertive", "off", "polite"]) }],
|
|
1168
|
+
["aria-orientation", { kind: "enum", values: /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]) }],
|
|
1169
|
+
["aria-sort", { kind: "enum", values: /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"]) }]
|
|
1170
|
+
]);
|
|
1171
|
+
|
|
1172
|
+
// ../../lib/contract/src/aria/spec/attributes/aria-relevant-tokens.ts
|
|
1173
|
+
var VALID_RELEVANT_TOKENS = /* @__PURE__ */ new Set([
|
|
1174
|
+
"additions",
|
|
1175
|
+
"removals",
|
|
1176
|
+
"text",
|
|
1177
|
+
"all"
|
|
1178
|
+
]);
|
|
1179
|
+
|
|
1180
|
+
// ../../lib/contract/src/aria/spec/elements/heading-implicit-levels.ts
|
|
1181
|
+
var HEADING_IMPLICIT_LEVELS = /* @__PURE__ */ new Map([
|
|
1182
|
+
["h1", 1],
|
|
1183
|
+
["h2", 2],
|
|
1184
|
+
["h3", 3],
|
|
1185
|
+
["h4", 4],
|
|
1186
|
+
["h5", 5],
|
|
1187
|
+
["h6", 6]
|
|
1188
|
+
]);
|
|
1189
|
+
|
|
1190
|
+
// ../../lib/contract/src/aria/spec/elements/interactive-tags.ts
|
|
1191
|
+
var INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
1192
|
+
"a",
|
|
1193
|
+
"button",
|
|
1194
|
+
"input",
|
|
1195
|
+
"select",
|
|
1196
|
+
"textarea"
|
|
1197
|
+
]);
|
|
1198
|
+
|
|
1199
|
+
// ../../lib/contract/src/aria/polymorphic-validator.ts
|
|
1200
|
+
var NO_VIOLATIONS2 = [{ valid: true }];
|
|
1061
1201
|
function isIntrinsicTag(tag) {
|
|
1062
1202
|
return isString(tag);
|
|
1063
1203
|
}
|
|
@@ -1100,7 +1240,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1100
1240
|
if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
|
|
1101
1241
|
const implicitRole = getImplicitRole(tag, props);
|
|
1102
1242
|
const hasRole = isNonNull(implicitRole) || isString(props.role) && props.role.length > 0;
|
|
1103
|
-
if (!hasRole) return { proceed: false, result: { props, violations: [] } };
|
|
1104
1243
|
const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
|
|
1105
1244
|
const workingProps = normalized.normalized ? normalized.result.props : props;
|
|
1106
1245
|
const preExistingViolations = normalized.normalized ? normalized.result.violations : [];
|
|
@@ -1110,6 +1249,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1110
1249
|
tag,
|
|
1111
1250
|
implicitRole,
|
|
1112
1251
|
effectiveRole,
|
|
1252
|
+
hasRole,
|
|
1113
1253
|
props: workingProps,
|
|
1114
1254
|
preExistingViolations,
|
|
1115
1255
|
context: { tag, props: workingProps, implicitRole, effectiveRole }
|
|
@@ -1119,6 +1259,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1119
1259
|
const violations = [];
|
|
1120
1260
|
const fixes = [];
|
|
1121
1261
|
iterate.forEach(rules, (rule) => {
|
|
1262
|
+
if (isNonNull(rule.tags) && !rule.tags.includes(context.tag)) return;
|
|
1122
1263
|
iterate.forEach(rule(context), (result) => {
|
|
1123
1264
|
if (result.valid) return;
|
|
1124
1265
|
const {
|
|
@@ -1144,7 +1285,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1144
1285
|
return { violations, fixes };
|
|
1145
1286
|
}
|
|
1146
1287
|
static #getRules(context) {
|
|
1147
|
-
if (_AriaPolicyEngine.#hasRole(context.props) || isNonNull(context.effectiveRole) &&
|
|
1288
|
+
if (_AriaPolicyEngine.#hasRole(context.props) || isNonNull(context.effectiveRole) && LIVE_REGION_ROLES.has(context.effectiveRole)) {
|
|
1148
1289
|
return _AriaPolicyEngine.#pipeline;
|
|
1149
1290
|
}
|
|
1150
1291
|
return _AriaPolicyEngine.#implicitOnlyRules;
|
|
@@ -1152,6 +1293,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1152
1293
|
static evaluate(tag, props) {
|
|
1153
1294
|
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
1154
1295
|
if (!derived.proceed) return derived.result;
|
|
1296
|
+
if (!derived.hasRole)
|
|
1297
|
+
return { props: derived.props, violations: [...derived.preExistingViolations] };
|
|
1155
1298
|
const {
|
|
1156
1299
|
tag: narrowedTag,
|
|
1157
1300
|
implicitRole,
|
|
@@ -1176,10 +1319,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1176
1319
|
props: workingProps,
|
|
1177
1320
|
preExistingViolations
|
|
1178
1321
|
} = derived;
|
|
1179
|
-
const
|
|
1180
|
-
|
|
1181
|
-
context
|
|
1182
|
-
);
|
|
1322
|
+
const rules = derived.hasRole ? [..._AriaPolicyEngine.#getRules(context), ...extraRules] : extraRules;
|
|
1323
|
+
const { violations, fixes } = _AriaPolicyEngine.#runRules(rules, context);
|
|
1183
1324
|
const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
|
|
1184
1325
|
return { props: next, violations: [...preExistingViolations, ...violations] };
|
|
1185
1326
|
}
|
|
@@ -1346,7 +1487,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1346
1487
|
implicitRole
|
|
1347
1488
|
}) {
|
|
1348
1489
|
const role = props.role;
|
|
1349
|
-
if (!implicitRole || !role || role === implicitRole) return
|
|
1490
|
+
if (!implicitRole || !role || role === implicitRole) return NO_VIOLATIONS2;
|
|
1350
1491
|
if (isStrongImplicitRole(tag) && role === "region") {
|
|
1351
1492
|
const diagnostic = HtmlDiagnostics.implicitRoleOverride(tag, implicitRole, role);
|
|
1352
1493
|
return [
|
|
@@ -1359,11 +1500,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1359
1500
|
}
|
|
1360
1501
|
];
|
|
1361
1502
|
}
|
|
1362
|
-
return
|
|
1503
|
+
return NO_VIOLATIONS2;
|
|
1363
1504
|
}
|
|
1364
1505
|
static #checkRedundantRole({ tag, props, implicitRole }) {
|
|
1365
1506
|
const role = props.role;
|
|
1366
|
-
if (!implicitRole || !role || role !== implicitRole) return
|
|
1507
|
+
if (!implicitRole || !role || role !== implicitRole) return NO_VIOLATIONS2;
|
|
1367
1508
|
const diagnostic = HtmlDiagnostics.implicitRoleRedundant(tag, implicitRole);
|
|
1368
1509
|
return [
|
|
1369
1510
|
{
|
|
@@ -1377,8 +1518,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1377
1518
|
}
|
|
1378
1519
|
static #checkStandaloneRegion({ tag, props, implicitRole }) {
|
|
1379
1520
|
const role = props.role;
|
|
1380
|
-
if (role !== "region") return
|
|
1381
|
-
if (!
|
|
1521
|
+
if (role !== "region") return NO_VIOLATIONS2;
|
|
1522
|
+
if (!hasStandaloneRole(tag)) return NO_VIOLATIONS2;
|
|
1382
1523
|
const diagnostic = HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag);
|
|
1383
1524
|
return [
|
|
1384
1525
|
{
|
|
@@ -1395,7 +1536,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1395
1536
|
props,
|
|
1396
1537
|
effectiveRole
|
|
1397
1538
|
}) {
|
|
1398
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1539
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS2;
|
|
1399
1540
|
const results = [];
|
|
1400
1541
|
iterate.forEachEntry(props, (key) => {
|
|
1401
1542
|
if (!key.startsWith("aria-")) return;
|
|
@@ -1413,62 +1554,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1413
1554
|
return results;
|
|
1414
1555
|
}
|
|
1415
1556
|
// ─── ARIA attribute value validation ──────────────────────────────────────
|
|
1416
|
-
// Accepted value shapes for typed ARIA attributes.
|
|
1417
|
-
// Attributes not in this map are unconstrained (arbitrary string values permitted).
|
|
1418
|
-
static #ARIA_VALUE_TYPES = /* @__PURE__ */ new Map([
|
|
1419
|
-
// Boolean (true | false)
|
|
1420
|
-
["aria-atomic", { kind: "boolean" }],
|
|
1421
|
-
["aria-busy", { kind: "boolean" }],
|
|
1422
|
-
["aria-disabled", { kind: "boolean" }],
|
|
1423
|
-
["aria-expanded", { kind: "boolean" }],
|
|
1424
|
-
["aria-hidden", { kind: "boolean" }],
|
|
1425
|
-
["aria-modal", { kind: "boolean" }],
|
|
1426
|
-
["aria-multiline", { kind: "boolean" }],
|
|
1427
|
-
["aria-multiselectable", { kind: "boolean" }],
|
|
1428
|
-
["aria-readonly", { kind: "boolean" }],
|
|
1429
|
-
["aria-required", { kind: "boolean" }],
|
|
1430
|
-
["aria-selected", { kind: "boolean" }],
|
|
1431
|
-
// Tristate (true | false | mixed)
|
|
1432
|
-
["aria-checked", { kind: "tristate" }],
|
|
1433
|
-
["aria-pressed", { kind: "tristate" }],
|
|
1434
|
-
// Numeric (any finite number)
|
|
1435
|
-
["aria-valuenow", { kind: "number" }],
|
|
1436
|
-
["aria-valuemin", { kind: "number" }],
|
|
1437
|
-
["aria-valuemax", { kind: "number" }],
|
|
1438
|
-
// Integer with optional range
|
|
1439
|
-
["aria-level", { kind: "integer", min: 1, max: 6 }],
|
|
1440
|
-
["aria-posinset", { kind: "integer", min: 1 }],
|
|
1441
|
-
["aria-setsize", { kind: "integer", min: -1 }],
|
|
1442
|
-
["aria-rowcount", { kind: "integer", min: -1 }],
|
|
1443
|
-
["aria-colcount", { kind: "integer", min: -1 }],
|
|
1444
|
-
["aria-rowindex", { kind: "integer", min: 1 }],
|
|
1445
|
-
["aria-colindex", { kind: "integer", min: 1 }],
|
|
1446
|
-
["aria-rowspan", { kind: "integer", min: 0 }],
|
|
1447
|
-
["aria-colspan", { kind: "integer", min: 0 }],
|
|
1448
|
-
// Enum (specific allowed tokens)
|
|
1449
|
-
["aria-autocomplete", { kind: "enum", values: /* @__PURE__ */ new Set(["inline", "list", "both", "none"]) }],
|
|
1450
|
-
[
|
|
1451
|
-
"aria-current",
|
|
1452
|
-
{
|
|
1453
|
-
kind: "enum",
|
|
1454
|
-
values: /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"])
|
|
1455
|
-
}
|
|
1456
|
-
],
|
|
1457
|
-
[
|
|
1458
|
-
"aria-haspopup",
|
|
1459
|
-
{
|
|
1460
|
-
kind: "enum",
|
|
1461
|
-
values: /* @__PURE__ */ new Set(["false", "true", "menu", "listbox", "tree", "grid", "dialog"])
|
|
1462
|
-
}
|
|
1463
|
-
],
|
|
1464
|
-
["aria-invalid", { kind: "enum", values: /* @__PURE__ */ new Set(["grammar", "false", "spelling", "true"]) }],
|
|
1465
|
-
["aria-live", { kind: "enum", values: /* @__PURE__ */ new Set(["assertive", "off", "polite"]) }],
|
|
1466
|
-
[
|
|
1467
|
-
"aria-orientation",
|
|
1468
|
-
{ kind: "enum", values: /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]) }
|
|
1469
|
-
],
|
|
1470
|
-
["aria-sort", { kind: "enum", values: /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"]) }]
|
|
1471
|
-
]);
|
|
1472
1557
|
static #isValidAriaValue(value, type) {
|
|
1473
1558
|
switch (type.kind) {
|
|
1474
1559
|
case "boolean":
|
|
@@ -1513,11 +1598,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1513
1598
|
}
|
|
1514
1599
|
}
|
|
1515
1600
|
static #checkAriaAttributeValues({ props, effectiveRole }) {
|
|
1516
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1601
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS2;
|
|
1517
1602
|
const results = [];
|
|
1518
1603
|
iterate.forEachEntry(props, (key, value) => {
|
|
1519
1604
|
if (!key.startsWith("aria-")) return;
|
|
1520
|
-
const type =
|
|
1605
|
+
const type = ARIA_VALUE_TYPES.get(key);
|
|
1521
1606
|
if (!isNonNull(type)) return;
|
|
1522
1607
|
if (_AriaPolicyEngine.#isValidAriaValue(value, type)) return;
|
|
1523
1608
|
results.push({
|
|
@@ -1536,26 +1621,18 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1536
1621
|
return results;
|
|
1537
1622
|
}
|
|
1538
1623
|
// ─── Heading implicit level ────────────────────────────────────────────────
|
|
1539
|
-
static #HEADING_IMPLICIT_LEVELS = /* @__PURE__ */ new Map([
|
|
1540
|
-
["h1", 1],
|
|
1541
|
-
["h2", 2],
|
|
1542
|
-
["h3", 3],
|
|
1543
|
-
["h4", 4],
|
|
1544
|
-
["h5", 5],
|
|
1545
|
-
["h6", 6]
|
|
1546
|
-
]);
|
|
1547
1624
|
static #checkRedundantAriaLevel({
|
|
1548
1625
|
tag,
|
|
1549
1626
|
props,
|
|
1550
1627
|
effectiveRole
|
|
1551
1628
|
}) {
|
|
1552
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1553
|
-
const implicitLevel =
|
|
1554
|
-
if (!isNonNull(implicitLevel)) return
|
|
1629
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS2;
|
|
1630
|
+
const implicitLevel = HEADING_IMPLICIT_LEVELS.get(tag);
|
|
1631
|
+
if (!isNonNull(implicitLevel)) return NO_VIOLATIONS2;
|
|
1555
1632
|
const raw = props["aria-level"];
|
|
1556
|
-
if (!isNonNull(raw)) return
|
|
1633
|
+
if (!isNonNull(raw)) return NO_VIOLATIONS2;
|
|
1557
1634
|
const n = typeof raw === "number" ? raw : typeof raw === "string" ? parseInt(raw, 10) : NaN;
|
|
1558
|
-
if (!Number.isFinite(n) || n !== implicitLevel) return
|
|
1635
|
+
if (!Number.isFinite(n) || n !== implicitLevel) return NO_VIOLATIONS2;
|
|
1559
1636
|
return [
|
|
1560
1637
|
{
|
|
1561
1638
|
valid: false,
|
|
@@ -1568,20 +1645,14 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1568
1645
|
];
|
|
1569
1646
|
}
|
|
1570
1647
|
// ─── Name-required roles ───────────────────────────────────────────────────
|
|
1571
|
-
// Roles that always require an accessible name per WAI-ARIA APG.
|
|
1572
|
-
// Dialog and landmark names are enforced via contracts (ariaContract) rather than
|
|
1573
|
-
// the built-in pipeline so consumers can opt in; img is built in because role=img
|
|
1574
|
-
// on any element (including bare <img>) is definitionally useless without a name.
|
|
1575
|
-
static #NAME_REQUIRED_ROLES = /* @__PURE__ */ new Set(["img"]);
|
|
1576
1648
|
static #checkNameRequiredRoles({
|
|
1577
1649
|
tag,
|
|
1578
1650
|
props,
|
|
1579
1651
|
effectiveRole
|
|
1580
1652
|
}) {
|
|
1581
|
-
if (!effectiveRole || !
|
|
1582
|
-
|
|
1583
|
-
if ("
|
|
1584
|
-
if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return NO_VIOLATIONS;
|
|
1653
|
+
if (!effectiveRole || !NAME_REQUIRED_ROLES.has(effectiveRole)) return NO_VIOLATIONS2;
|
|
1654
|
+
if ("aria-label" in props || "aria-labelledby" in props) return NO_VIOLATIONS2;
|
|
1655
|
+
if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return NO_VIOLATIONS2;
|
|
1585
1656
|
return [
|
|
1586
1657
|
{
|
|
1587
1658
|
valid: false,
|
|
@@ -1591,51 +1662,21 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1591
1662
|
}
|
|
1592
1663
|
];
|
|
1593
1664
|
}
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
["scrollbar", ["aria-controls", "aria-valuenow"]],
|
|
1601
|
-
["spinbutton", ["aria-valuenow"]]
|
|
1602
|
-
]);
|
|
1603
|
-
static #checkRequiredAriaProperties({
|
|
1604
|
-
props,
|
|
1605
|
-
effectiveRole
|
|
1606
|
-
}) {
|
|
1607
|
-
if (!effectiveRole) return NO_VIOLATIONS;
|
|
1608
|
-
const required = _AriaPolicyEngine.#REQUIRED_PROPERTIES.get(effectiveRole);
|
|
1609
|
-
if (!isNonNull(required)) return NO_VIOLATIONS;
|
|
1610
|
-
const results = [];
|
|
1611
|
-
iterate.forEach(required, (attr) => {
|
|
1612
|
-
if (attr in props) return;
|
|
1613
|
-
results.push({
|
|
1614
|
-
valid: false,
|
|
1615
|
-
fixable: false,
|
|
1616
|
-
severity: "warning",
|
|
1617
|
-
attribute: attr,
|
|
1618
|
-
diagnostic: AriaDiagnostics.requiredProperty(attr, effectiveRole)
|
|
1619
|
-
});
|
|
1620
|
-
});
|
|
1621
|
-
return results;
|
|
1665
|
+
static #requiredAriaPropertiesRule = {
|
|
1666
|
+
attributesByRole: REQUIRED_ARIA_PROPERTIES,
|
|
1667
|
+
diagnosticFor: (attribute, role) => AriaDiagnostics.requiredProperty(attribute, role)
|
|
1668
|
+
};
|
|
1669
|
+
static #checkRequiredAriaProperties(context) {
|
|
1670
|
+
return checkRequiredAttributes(_AriaPolicyEngine.#requiredAriaPropertiesRule, context);
|
|
1622
1671
|
}
|
|
1623
|
-
// Natively interactive HTML elements — always keyboard-reachable unless explicitly disabled.
|
|
1624
|
-
static #INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
1625
|
-
"a",
|
|
1626
|
-
"button",
|
|
1627
|
-
"input",
|
|
1628
|
-
"select",
|
|
1629
|
-
"textarea"
|
|
1630
|
-
]);
|
|
1631
1672
|
// WAI-ARIA 1.2 §6.6: aria-hidden="true" must not be placed on focusable elements.
|
|
1632
1673
|
static #checkAriaHiddenOnFocusable({ tag, props }) {
|
|
1633
|
-
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return
|
|
1634
|
-
const isInteractive =
|
|
1674
|
+
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return NO_VIOLATIONS2;
|
|
1675
|
+
const isInteractive = INTERACTIVE_TAGS.has(tag);
|
|
1635
1676
|
if (!isInteractive) {
|
|
1636
1677
|
const tabindex = props.tabindex;
|
|
1637
1678
|
const n = typeof tabindex === "number" ? tabindex : typeof tabindex === "string" ? parseInt(tabindex, 10) : NaN;
|
|
1638
|
-
if (!Number.isFinite(n) || n < 0) return
|
|
1679
|
+
if (!Number.isFinite(n) || n < 0) return NO_VIOLATIONS2;
|
|
1639
1680
|
}
|
|
1640
1681
|
return [
|
|
1641
1682
|
{
|
|
@@ -1654,7 +1695,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1654
1695
|
props,
|
|
1655
1696
|
effectiveRole
|
|
1656
1697
|
}) {
|
|
1657
|
-
if (effectiveRole !== "none" && effectiveRole !== "presentation") return
|
|
1698
|
+
if (effectiveRole !== "none" && effectiveRole !== "presentation") return NO_VIOLATIONS2;
|
|
1658
1699
|
const results = [];
|
|
1659
1700
|
iterate.forEachEntry(props, (key) => {
|
|
1660
1701
|
if (!key.startsWith("aria-")) return;
|
|
@@ -1670,18 +1711,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1670
1711
|
});
|
|
1671
1712
|
return results;
|
|
1672
1713
|
}
|
|
1673
|
-
// WAI-ARIA live region roles and their implied aria-live politeness values.
|
|
1674
|
-
static #LIVE_REGION_ROLES = /* @__PURE__ */ new Map([
|
|
1675
|
-
["alert", "assertive"],
|
|
1676
|
-
["status", "polite"],
|
|
1677
|
-
["log", "polite"],
|
|
1678
|
-
["timer", "off"]
|
|
1679
|
-
]);
|
|
1680
1714
|
static #checkMissingLiveRegion({ effectiveRole, props }) {
|
|
1681
|
-
if (!effectiveRole) return
|
|
1682
|
-
const impliedLive =
|
|
1683
|
-
if (!impliedLive) return
|
|
1684
|
-
if ("aria-live" in props) return
|
|
1715
|
+
if (!effectiveRole) return NO_VIOLATIONS2;
|
|
1716
|
+
const impliedLive = LIVE_REGION_ROLES.get(effectiveRole);
|
|
1717
|
+
if (!impliedLive) return NO_VIOLATIONS2;
|
|
1718
|
+
if ("aria-live" in props) return NO_VIOLATIONS2;
|
|
1685
1719
|
const injectLive = {
|
|
1686
1720
|
kind: `injectLive:${effectiveRole}`,
|
|
1687
1721
|
apply: (ctx) => ({
|
|
@@ -1700,20 +1734,13 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1700
1734
|
}
|
|
1701
1735
|
];
|
|
1702
1736
|
}
|
|
1703
|
-
static #
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
valid: false,
|
|
1710
|
-
fixable: false,
|
|
1711
|
-
severity: "warning",
|
|
1712
|
-
diagnostic: AriaDiagnostics.missingAtomic(effectiveRole)
|
|
1713
|
-
}
|
|
1714
|
-
];
|
|
1737
|
+
static #missingAtomicRule = {
|
|
1738
|
+
attributesByRole: ATOMIC_REQUIREMENTS,
|
|
1739
|
+
diagnosticFor: (_attribute, role) => AriaDiagnostics.missingAtomic(role)
|
|
1740
|
+
};
|
|
1741
|
+
static #checkMissingAtomic(context) {
|
|
1742
|
+
return checkRequiredAttributes(_AriaPolicyEngine.#missingAtomicRule, context);
|
|
1715
1743
|
}
|
|
1716
|
-
static #VALID_RELEVANT_TOKENS = /* @__PURE__ */ new Set(["additions", "removals", "text", "all"]);
|
|
1717
1744
|
// Custom fix rules passed via `options.rules` must be pure functions of (tag, props) — the cache
|
|
1718
1745
|
// replays stored fixes against new prop objects, so fixes that close over external state will
|
|
1719
1746
|
// produce inconsistent results on cache hits.
|
|
@@ -1727,10 +1754,10 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1727
1754
|
};
|
|
1728
1755
|
static #checkInvalidAriaRelevant({ props }) {
|
|
1729
1756
|
const relevant = props["aria-relevant"];
|
|
1730
|
-
if (relevant === void 0) return
|
|
1731
|
-
if (typeof relevant !== "string") return
|
|
1757
|
+
if (relevant === void 0) return NO_VIOLATIONS2;
|
|
1758
|
+
if (typeof relevant !== "string") return NO_VIOLATIONS2;
|
|
1732
1759
|
const tokens = relevant.trim().split(/\s+/);
|
|
1733
|
-
const invalid = tokens.filter((t) => !
|
|
1760
|
+
const invalid = tokens.filter((t) => !VALID_RELEVANT_TOKENS.has(t));
|
|
1734
1761
|
if (invalid.length > 0) {
|
|
1735
1762
|
return [
|
|
1736
1763
|
{
|
|
@@ -1755,7 +1782,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1755
1782
|
}
|
|
1756
1783
|
];
|
|
1757
1784
|
}
|
|
1758
|
-
return
|
|
1785
|
+
return NO_VIOLATIONS2;
|
|
1759
1786
|
}
|
|
1760
1787
|
};
|
|
1761
1788
|
|
|
@@ -2075,7 +2102,59 @@ var readonlyProps = ({
|
|
|
2075
2102
|
// ../core/src/html/evaluators.ts
|
|
2076
2103
|
import { warnDiagnostics as warnDiagnostics2 } from "../_shared/diagnostics.js";
|
|
2077
2104
|
|
|
2078
|
-
// ../core/src/html/input
|
|
2105
|
+
// ../core/src/html/spec/vocabulary/input.ts
|
|
2106
|
+
var TEXT_INPUT_TYPES = ["text", "search", "url", "tel", "email", "password"];
|
|
2107
|
+
var NUMERIC_INPUT_TYPES = [
|
|
2108
|
+
"number",
|
|
2109
|
+
"range",
|
|
2110
|
+
"date",
|
|
2111
|
+
"month",
|
|
2112
|
+
"week",
|
|
2113
|
+
"time",
|
|
2114
|
+
"datetime-local"
|
|
2115
|
+
];
|
|
2116
|
+
var HTML_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
2117
|
+
...TEXT_INPUT_TYPES,
|
|
2118
|
+
...NUMERIC_INPUT_TYPES,
|
|
2119
|
+
"checkbox",
|
|
2120
|
+
"radio",
|
|
2121
|
+
"file",
|
|
2122
|
+
"color",
|
|
2123
|
+
"hidden",
|
|
2124
|
+
"button",
|
|
2125
|
+
"submit",
|
|
2126
|
+
"reset",
|
|
2127
|
+
"image"
|
|
2128
|
+
]);
|
|
2129
|
+
|
|
2130
|
+
// ../core/src/html/spec/attributes/input.ts
|
|
2131
|
+
var INPUT_ATTRIBUTE_TYPE_POLICIES = [
|
|
2132
|
+
{ attribute: "checked", allowedTypes: ["checkbox", "radio"] },
|
|
2133
|
+
{ attribute: "multiple", allowedTypes: ["email", "file"] },
|
|
2134
|
+
{ attribute: "maxLength", allowedTypes: TEXT_INPUT_TYPES },
|
|
2135
|
+
{ attribute: "minLength", allowedTypes: TEXT_INPUT_TYPES },
|
|
2136
|
+
{ attribute: "pattern", allowedTypes: TEXT_INPUT_TYPES },
|
|
2137
|
+
{ attribute: "min", allowedTypes: NUMERIC_INPUT_TYPES },
|
|
2138
|
+
{ attribute: "max", allowedTypes: NUMERIC_INPUT_TYPES },
|
|
2139
|
+
{ attribute: "step", allowedTypes: NUMERIC_INPUT_TYPES },
|
|
2140
|
+
{ attribute: "accept", allowedTypes: ["file"] },
|
|
2141
|
+
{ attribute: "capture", allowedTypes: ["file"] },
|
|
2142
|
+
{ attribute: "size", allowedTypes: TEXT_INPUT_TYPES },
|
|
2143
|
+
{ attribute: "alt", allowedTypes: ["image"] },
|
|
2144
|
+
{ attribute: "height", allowedTypes: ["image"] },
|
|
2145
|
+
{ attribute: "width", allowedTypes: ["image"] }
|
|
2146
|
+
];
|
|
2147
|
+
|
|
2148
|
+
// ../core/src/html/spec/constraints/input.ts
|
|
2149
|
+
var REQUIRED_READONLY_CONFLICT = {
|
|
2150
|
+
props: ["required", "readOnly"],
|
|
2151
|
+
diagnostic: () => InputAccessibilityDiagnostics.requiredReadOnlyConflict()
|
|
2152
|
+
};
|
|
2153
|
+
var INPUT_MUTUALLY_EXCLUSIVE_POLICIES = [
|
|
2154
|
+
REQUIRED_READONLY_CONFLICT
|
|
2155
|
+
];
|
|
2156
|
+
|
|
2157
|
+
// ../core/src/html/spec/validators/attribute-type-validator.ts
|
|
2079
2158
|
var DEFAULT_INPUT_TYPE = "text";
|
|
2080
2159
|
function omit(props, key) {
|
|
2081
2160
|
const next = { ...props };
|
|
@@ -2091,7 +2170,10 @@ function removeAttributeFix(attribute) {
|
|
|
2091
2170
|
}
|
|
2092
2171
|
};
|
|
2093
2172
|
}
|
|
2094
|
-
function
|
|
2173
|
+
function createInputAttributeTypeRule({
|
|
2174
|
+
attribute,
|
|
2175
|
+
allowedTypes
|
|
2176
|
+
}) {
|
|
2095
2177
|
const rule = ({ tag, props }) => {
|
|
2096
2178
|
if (tag !== "input" || !(attribute in props)) return [];
|
|
2097
2179
|
const type = typeof props.type === "string" ? props.type : DEFAULT_INPUT_TYPE;
|
|
@@ -2107,31 +2189,30 @@ function inputAttributeRequiresType(attribute, allowedTypes) {
|
|
|
2107
2189
|
}
|
|
2108
2190
|
];
|
|
2109
2191
|
};
|
|
2110
|
-
return Object.assign(rule, { readsProps: ["type", attribute] });
|
|
2192
|
+
return Object.assign(rule, { readsProps: ["type", attribute], tags: ["input"] });
|
|
2193
|
+
}
|
|
2194
|
+
|
|
2195
|
+
// ../core/src/html/spec/validators/mutually-exclusive-validator.ts
|
|
2196
|
+
function createMutuallyExclusiveRule({
|
|
2197
|
+
props: conflictingProps,
|
|
2198
|
+
diagnostic: createDiagnostic
|
|
2199
|
+
}) {
|
|
2200
|
+
const [first, second] = conflictingProps;
|
|
2201
|
+
const rule = ({ tag, props }) => {
|
|
2202
|
+
if (tag !== "input" || !props[first] || !props[second]) return [];
|
|
2203
|
+
const diagnostic = createDiagnostic();
|
|
2204
|
+
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2205
|
+
};
|
|
2206
|
+
return Object.assign(rule, { readsProps: conflictingProps, tags: ["input"] });
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
// ../core/src/html/input-rules.ts
|
|
2210
|
+
var policyByAttribute = Object.fromEntries(
|
|
2211
|
+
INPUT_ATTRIBUTE_TYPE_POLICIES.map((policy) => [policy.attribute, policy])
|
|
2212
|
+
);
|
|
2213
|
+
function policyFor(attribute) {
|
|
2214
|
+
return policyByAttribute[attribute];
|
|
2111
2215
|
}
|
|
2112
|
-
var TEXT_INPUT_TYPES = ["text", "search", "url", "tel", "email", "password"];
|
|
2113
|
-
var NUMERIC_INPUT_TYPES = [
|
|
2114
|
-
"number",
|
|
2115
|
-
"range",
|
|
2116
|
-
"date",
|
|
2117
|
-
"month",
|
|
2118
|
-
"week",
|
|
2119
|
-
"time",
|
|
2120
|
-
"datetime-local"
|
|
2121
|
-
];
|
|
2122
|
-
var HTML_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
2123
|
-
...TEXT_INPUT_TYPES,
|
|
2124
|
-
...NUMERIC_INPUT_TYPES,
|
|
2125
|
-
"checkbox",
|
|
2126
|
-
"radio",
|
|
2127
|
-
"file",
|
|
2128
|
-
"color",
|
|
2129
|
-
"hidden",
|
|
2130
|
-
"button",
|
|
2131
|
-
"submit",
|
|
2132
|
-
"reset",
|
|
2133
|
-
"image"
|
|
2134
|
-
]);
|
|
2135
2216
|
var supportedInputTypeRule = Object.assign(
|
|
2136
2217
|
({ tag, props }) => {
|
|
2137
2218
|
if (tag !== "input" || typeof props.type !== "string") return [];
|
|
@@ -2147,30 +2228,22 @@ var supportedInputTypeRule = Object.assign(
|
|
|
2147
2228
|
}
|
|
2148
2229
|
];
|
|
2149
2230
|
},
|
|
2150
|
-
{ readsProps: ["type"] }
|
|
2151
|
-
);
|
|
2152
|
-
var checkedRequiresCheckableTypeRule = inputAttributeRequiresType("checked", [
|
|
2153
|
-
"checkbox",
|
|
2154
|
-
"radio"
|
|
2155
|
-
]);
|
|
2156
|
-
var multipleRequiresSupportedTypeRule = inputAttributeRequiresType("multiple", [
|
|
2157
|
-
"email",
|
|
2158
|
-
"file"
|
|
2159
|
-
]);
|
|
2160
|
-
var maxLengthRequiresTextTypeRule = inputAttributeRequiresType(
|
|
2161
|
-
"maxLength",
|
|
2162
|
-
TEXT_INPUT_TYPES
|
|
2163
|
-
);
|
|
2164
|
-
var minLengthRequiresTextTypeRule = inputAttributeRequiresType(
|
|
2165
|
-
"minLength",
|
|
2166
|
-
TEXT_INPUT_TYPES
|
|
2231
|
+
{ readsProps: ["type"], tags: ["input"] }
|
|
2167
2232
|
);
|
|
2168
|
-
var
|
|
2169
|
-
var
|
|
2170
|
-
var
|
|
2171
|
-
var
|
|
2172
|
-
var
|
|
2173
|
-
var
|
|
2233
|
+
var checkedRequiresCheckableTypeRule = createInputAttributeTypeRule(policyFor("checked"));
|
|
2234
|
+
var multipleRequiresSupportedTypeRule = createInputAttributeTypeRule(policyFor("multiple"));
|
|
2235
|
+
var maxLengthRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("maxLength"));
|
|
2236
|
+
var minLengthRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("minLength"));
|
|
2237
|
+
var patternRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("pattern"));
|
|
2238
|
+
var minRequiresNumericTypeRule = createInputAttributeTypeRule(policyFor("min"));
|
|
2239
|
+
var maxRequiresNumericTypeRule = createInputAttributeTypeRule(policyFor("max"));
|
|
2240
|
+
var stepRequiresNumericTypeRule = createInputAttributeTypeRule(policyFor("step"));
|
|
2241
|
+
var acceptRequiresFileTypeRule = createInputAttributeTypeRule(policyFor("accept"));
|
|
2242
|
+
var captureRequiresFileTypeRule = createInputAttributeTypeRule(policyFor("capture"));
|
|
2243
|
+
var sizeRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("size"));
|
|
2244
|
+
var altRequiresImageTypeRule = createInputAttributeTypeRule(policyFor("alt"));
|
|
2245
|
+
var heightRequiresImageTypeRule = createInputAttributeTypeRule(policyFor("height"));
|
|
2246
|
+
var widthRequiresImageTypeRule = createInputAttributeTypeRule(policyFor("width"));
|
|
2174
2247
|
var inputAccessibleNameRule = Object.assign(
|
|
2175
2248
|
({ tag, props }) => {
|
|
2176
2249
|
if (tag !== "input" || props.type === "hidden") return [];
|
|
@@ -2179,7 +2252,10 @@ var inputAccessibleNameRule = Object.assign(
|
|
|
2179
2252
|
const diagnostic = hasPlaceholder ? InputAccessibilityDiagnostics.placeholderIsNotLabel() : InputAccessibilityDiagnostics.missingAccessibleName();
|
|
2180
2253
|
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2181
2254
|
},
|
|
2182
|
-
{
|
|
2255
|
+
{
|
|
2256
|
+
readsProps: ["type", "aria-label", "aria-labelledby", "placeholder"],
|
|
2257
|
+
tags: ["input"]
|
|
2258
|
+
}
|
|
2183
2259
|
);
|
|
2184
2260
|
var PASSWORD_AUTOCOMPLETE_VALUES = ["current-password", "new-password"];
|
|
2185
2261
|
var passwordAutocompleteRule = Object.assign(
|
|
@@ -2191,16 +2267,9 @@ var passwordAutocompleteRule = Object.assign(
|
|
|
2191
2267
|
const diagnostic = InputAccessibilityDiagnostics.passwordMissingAutocomplete();
|
|
2192
2268
|
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2193
2269
|
},
|
|
2194
|
-
{ readsProps: ["type", "autoComplete"] }
|
|
2195
|
-
);
|
|
2196
|
-
var requiredReadOnlyConflictRule = Object.assign(
|
|
2197
|
-
({ tag, props }) => {
|
|
2198
|
-
if (tag !== "input" || !props.required || !props.readOnly) return [];
|
|
2199
|
-
const diagnostic = InputAccessibilityDiagnostics.requiredReadOnlyConflict();
|
|
2200
|
-
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2201
|
-
},
|
|
2202
|
-
{ readsProps: ["required", "readOnly"] }
|
|
2270
|
+
{ readsProps: ["type", "autoComplete"], tags: ["input"] }
|
|
2203
2271
|
);
|
|
2272
|
+
var requiredReadOnlyConflictRule = createMutuallyExclusiveRule(REQUIRED_READONLY_CONFLICT);
|
|
2204
2273
|
var INPUT_RULES = [
|
|
2205
2274
|
supportedInputTypeRule,
|
|
2206
2275
|
checkedRequiresCheckableTypeRule,
|
|
@@ -2213,11 +2282,132 @@ var INPUT_RULES = [
|
|
|
2213
2282
|
stepRequiresNumericTypeRule,
|
|
2214
2283
|
acceptRequiresFileTypeRule,
|
|
2215
2284
|
captureRequiresFileTypeRule,
|
|
2285
|
+
sizeRequiresTextTypeRule,
|
|
2286
|
+
altRequiresImageTypeRule,
|
|
2287
|
+
heightRequiresImageTypeRule,
|
|
2288
|
+
widthRequiresImageTypeRule,
|
|
2216
2289
|
inputAccessibleNameRule,
|
|
2217
2290
|
passwordAutocompleteRule,
|
|
2218
2291
|
requiredReadOnlyConflictRule
|
|
2219
2292
|
];
|
|
2220
2293
|
|
|
2294
|
+
// ../core/src/html/spec/types.ts
|
|
2295
|
+
function definePropRolePolicy(prop, map2, fallback) {
|
|
2296
|
+
return { kind: "byProp", prop, map: map2, fallback };
|
|
2297
|
+
}
|
|
2298
|
+
function resolveAllowedRoles(spec, props) {
|
|
2299
|
+
const policy = spec.allowedRoles;
|
|
2300
|
+
if (!policy) return void 0;
|
|
2301
|
+
switch (policy.kind) {
|
|
2302
|
+
case "fixed":
|
|
2303
|
+
return policy.roles;
|
|
2304
|
+
case "byProp": {
|
|
2305
|
+
const value = typeof props[policy.prop] === "string" ? props[policy.prop] : policy.fallback;
|
|
2306
|
+
return policy.map[value];
|
|
2307
|
+
}
|
|
2308
|
+
case "dynamic":
|
|
2309
|
+
return policy.resolve({ props });
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
// ../core/src/html/spec/roles/input.ts
|
|
2314
|
+
var ALLOWED_INPUT_ROLES = {
|
|
2315
|
+
checkbox: ["menuitemcheckbox", "option", "switch", "button"],
|
|
2316
|
+
radio: ["menuitemradio"],
|
|
2317
|
+
range: [],
|
|
2318
|
+
number: [],
|
|
2319
|
+
search: ["combobox"],
|
|
2320
|
+
text: ["combobox", "searchbox", "spinbutton"],
|
|
2321
|
+
email: ["combobox"],
|
|
2322
|
+
tel: ["combobox"],
|
|
2323
|
+
url: ["combobox"],
|
|
2324
|
+
button: [
|
|
2325
|
+
"link",
|
|
2326
|
+
"menuitem",
|
|
2327
|
+
"menuitemcheckbox",
|
|
2328
|
+
"menuitemradio",
|
|
2329
|
+
"option",
|
|
2330
|
+
"radio",
|
|
2331
|
+
"switch",
|
|
2332
|
+
"tab"
|
|
2333
|
+
],
|
|
2334
|
+
submit: [
|
|
2335
|
+
"link",
|
|
2336
|
+
"menuitem",
|
|
2337
|
+
"menuitemcheckbox",
|
|
2338
|
+
"menuitemradio",
|
|
2339
|
+
"option",
|
|
2340
|
+
"radio",
|
|
2341
|
+
"switch",
|
|
2342
|
+
"tab"
|
|
2343
|
+
],
|
|
2344
|
+
reset: [
|
|
2345
|
+
"link",
|
|
2346
|
+
"menuitem",
|
|
2347
|
+
"menuitemcheckbox",
|
|
2348
|
+
"menuitemradio",
|
|
2349
|
+
"option",
|
|
2350
|
+
"radio",
|
|
2351
|
+
"switch",
|
|
2352
|
+
"tab"
|
|
2353
|
+
],
|
|
2354
|
+
image: [
|
|
2355
|
+
"link",
|
|
2356
|
+
"menuitem",
|
|
2357
|
+
"menuitemcheckbox",
|
|
2358
|
+
"menuitemradio",
|
|
2359
|
+
"option",
|
|
2360
|
+
"radio",
|
|
2361
|
+
"switch",
|
|
2362
|
+
"tab"
|
|
2363
|
+
],
|
|
2364
|
+
hidden: []
|
|
2365
|
+
};
|
|
2366
|
+
|
|
2367
|
+
// ../core/src/html/spec/elements/input.ts
|
|
2368
|
+
var inputElementSpec = {
|
|
2369
|
+
tag: "input",
|
|
2370
|
+
allowedRoles: definePropRolePolicy("type", ALLOWED_INPUT_ROLES, "text"),
|
|
2371
|
+
attributes: INPUT_ATTRIBUTE_TYPE_POLICIES,
|
|
2372
|
+
mutuallyExclusive: INPUT_MUTUALLY_EXCLUSIVE_POLICIES
|
|
2373
|
+
};
|
|
2374
|
+
|
|
2375
|
+
// ../core/src/html/spec/roles/img.ts
|
|
2376
|
+
var IMG_NAMED_ROLES = [
|
|
2377
|
+
"button",
|
|
2378
|
+
"checkbox",
|
|
2379
|
+
"link",
|
|
2380
|
+
"menuitem",
|
|
2381
|
+
"menuitemcheckbox",
|
|
2382
|
+
"menuitemradio",
|
|
2383
|
+
"option",
|
|
2384
|
+
"progressbar",
|
|
2385
|
+
"scrollbar",
|
|
2386
|
+
"separator",
|
|
2387
|
+
"slider",
|
|
2388
|
+
"switch",
|
|
2389
|
+
"tab",
|
|
2390
|
+
"treeitem"
|
|
2391
|
+
];
|
|
2392
|
+
|
|
2393
|
+
// ../core/src/html/spec/elements/img.ts
|
|
2394
|
+
var imgElementSpec = {
|
|
2395
|
+
tag: "img",
|
|
2396
|
+
allowedRoles: {
|
|
2397
|
+
kind: "dynamic",
|
|
2398
|
+
resolve: ({ props }) => props.alt === "" ? [] : IMG_NAMED_ROLES
|
|
2399
|
+
}
|
|
2400
|
+
};
|
|
2401
|
+
|
|
2402
|
+
// ../core/src/html/spec/roles/table.ts
|
|
2403
|
+
var ALLOWED_TABLE_ROLES = ["grid", "treegrid"];
|
|
2404
|
+
|
|
2405
|
+
// ../core/src/html/spec/elements/table.ts
|
|
2406
|
+
var tableElementSpec = {
|
|
2407
|
+
tag: "table",
|
|
2408
|
+
allowedRoles: { kind: "fixed", roles: ALLOWED_TABLE_ROLES }
|
|
2409
|
+
};
|
|
2410
|
+
|
|
2221
2411
|
// ../core/src/html/role-restrictions.ts
|
|
2222
2412
|
var ALLOWED_ROLES = {
|
|
2223
2413
|
article: ["application", "document", "feed", "main", "none", "presentation", "region"],
|
|
@@ -2290,86 +2480,17 @@ var ALLOWED_ROLES = {
|
|
|
2290
2480
|
"tab",
|
|
2291
2481
|
"treeitem"
|
|
2292
2482
|
],
|
|
2293
|
-
table: ["grid", "treegrid"],
|
|
2294
2483
|
dialog: ["alertdialog"],
|
|
2295
2484
|
fieldset: ["none", "presentation", "radiogroup"]
|
|
2296
2485
|
};
|
|
2297
|
-
var
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
"menuitem",
|
|
2302
|
-
"menuitemcheckbox",
|
|
2303
|
-
"menuitemradio",
|
|
2304
|
-
"option",
|
|
2305
|
-
"progressbar",
|
|
2306
|
-
"scrollbar",
|
|
2307
|
-
"separator",
|
|
2308
|
-
"slider",
|
|
2309
|
-
"switch",
|
|
2310
|
-
"tab",
|
|
2311
|
-
"treeitem"
|
|
2312
|
-
];
|
|
2313
|
-
var ALLOWED_INPUT_ROLES = {
|
|
2314
|
-
checkbox: ["menuitemcheckbox", "option", "switch", "button"],
|
|
2315
|
-
radio: ["menuitemradio"],
|
|
2316
|
-
range: [],
|
|
2317
|
-
number: [],
|
|
2318
|
-
search: ["combobox"],
|
|
2319
|
-
text: ["combobox", "searchbox", "spinbutton"],
|
|
2320
|
-
email: ["combobox"],
|
|
2321
|
-
tel: ["combobox"],
|
|
2322
|
-
url: ["combobox"],
|
|
2323
|
-
button: [
|
|
2324
|
-
"link",
|
|
2325
|
-
"menuitem",
|
|
2326
|
-
"menuitemcheckbox",
|
|
2327
|
-
"menuitemradio",
|
|
2328
|
-
"option",
|
|
2329
|
-
"radio",
|
|
2330
|
-
"switch",
|
|
2331
|
-
"tab"
|
|
2332
|
-
],
|
|
2333
|
-
submit: [
|
|
2334
|
-
"link",
|
|
2335
|
-
"menuitem",
|
|
2336
|
-
"menuitemcheckbox",
|
|
2337
|
-
"menuitemradio",
|
|
2338
|
-
"option",
|
|
2339
|
-
"radio",
|
|
2340
|
-
"switch",
|
|
2341
|
-
"tab"
|
|
2342
|
-
],
|
|
2343
|
-
reset: [
|
|
2344
|
-
"link",
|
|
2345
|
-
"menuitem",
|
|
2346
|
-
"menuitemcheckbox",
|
|
2347
|
-
"menuitemradio",
|
|
2348
|
-
"option",
|
|
2349
|
-
"radio",
|
|
2350
|
-
"switch",
|
|
2351
|
-
"tab"
|
|
2352
|
-
],
|
|
2353
|
-
image: [
|
|
2354
|
-
"link",
|
|
2355
|
-
"menuitem",
|
|
2356
|
-
"menuitemcheckbox",
|
|
2357
|
-
"menuitemradio",
|
|
2358
|
-
"option",
|
|
2359
|
-
"radio",
|
|
2360
|
-
"switch",
|
|
2361
|
-
"tab"
|
|
2362
|
-
],
|
|
2363
|
-
hidden: []
|
|
2486
|
+
var ELEMENT_SPECS = {
|
|
2487
|
+
input: inputElementSpec,
|
|
2488
|
+
img: imgElementSpec,
|
|
2489
|
+
table: tableElementSpec
|
|
2364
2490
|
};
|
|
2365
2491
|
function getAllowedRoles(tag, props) {
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
return ALLOWED_INPUT_ROLES[type];
|
|
2369
|
-
}
|
|
2370
|
-
if (tag === "img") {
|
|
2371
|
-
return props.alt === "" ? [] : IMG_NAMED_ROLES;
|
|
2372
|
-
}
|
|
2492
|
+
const spec = ELEMENT_SPECS[tag];
|
|
2493
|
+
if (spec) return resolveAllowedRoles(spec, props);
|
|
2373
2494
|
return ALLOWED_ROLES[tag];
|
|
2374
2495
|
}
|
|
2375
2496
|
var removeRoleFix = {
|
|
@@ -2410,21 +2531,24 @@ var removeLandmarkRoleOverride = {
|
|
|
2410
2531
|
return { applied: true, next: rest, previous: props };
|
|
2411
2532
|
}
|
|
2412
2533
|
};
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2534
|
+
var landmarkRoleRule = Object.assign(
|
|
2535
|
+
({ tag, props, implicitRole }) => {
|
|
2536
|
+
if (!LANDMARK_TAG_SET.has(tag) || !implicitRole) return [];
|
|
2537
|
+
const role = props.role;
|
|
2538
|
+
if (!role || role === implicitRole) return [];
|
|
2539
|
+
const diagnostic = HtmlDiagnostics.landmarkRoleOverride(tag, implicitRole, role);
|
|
2540
|
+
return [
|
|
2541
|
+
{
|
|
2542
|
+
valid: false,
|
|
2543
|
+
fixable: true,
|
|
2544
|
+
severity: diagnostic.severity,
|
|
2545
|
+
fix: removeLandmarkRoleOverride,
|
|
2546
|
+
diagnostic
|
|
2547
|
+
}
|
|
2548
|
+
];
|
|
2549
|
+
},
|
|
2550
|
+
{ tags: [...LANDMARK_TAG_SET] }
|
|
2551
|
+
);
|
|
2428
2552
|
function requireAccessibleName({ tag, props }) {
|
|
2429
2553
|
if ("aria-label" in props || "aria-labelledby" in props) return [];
|
|
2430
2554
|
return [
|
|
@@ -2437,10 +2561,13 @@ function requireAccessibleName({ tag, props }) {
|
|
|
2437
2561
|
];
|
|
2438
2562
|
}
|
|
2439
2563
|
var NAMED_LANDMARK_TAGS = /* @__PURE__ */ new Set(["nav", "aside"]);
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2564
|
+
var landmarkNameAdvisory = Object.assign(
|
|
2565
|
+
(ctx) => {
|
|
2566
|
+
if (!ctx.implicitRole || !NAMED_LANDMARK_TAGS.has(ctx.tag)) return [];
|
|
2567
|
+
return requireAccessibleName(ctx);
|
|
2568
|
+
},
|
|
2569
|
+
{ tags: [...NAMED_LANDMARK_TAGS] }
|
|
2570
|
+
);
|
|
2444
2571
|
var HTML_ARIA_RULES = [
|
|
2445
2572
|
landmarkRoleRule,
|
|
2446
2573
|
landmarkNameAdvisory,
|
|
@@ -2541,6 +2668,62 @@ var figureContract = contract([
|
|
|
2541
2668
|
]);
|
|
2542
2669
|
var detailsContract = firstChildContract("summary", "summary");
|
|
2543
2670
|
var fieldsetContract = firstChildContract("legend", "legend");
|
|
2671
|
+
var objectContract = contract([
|
|
2672
|
+
{ name: "param", match: isTag("param") },
|
|
2673
|
+
{ name: "content", match: isOpenContent("param") }
|
|
2674
|
+
]);
|
|
2675
|
+
var INTERACTIVE_CONTENT_TAGS = ["a", "button", "input", "select", "textarea", "label"];
|
|
2676
|
+
var buttonContract = closedContract([
|
|
2677
|
+
{ name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
|
|
2678
|
+
]);
|
|
2679
|
+
var anchorContract = closedContract([
|
|
2680
|
+
{ name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
|
|
2681
|
+
]);
|
|
2682
|
+
var LABELABLE_TAGS = [
|
|
2683
|
+
"button",
|
|
2684
|
+
"input",
|
|
2685
|
+
"meter",
|
|
2686
|
+
"output",
|
|
2687
|
+
"progress",
|
|
2688
|
+
"select",
|
|
2689
|
+
"textarea"
|
|
2690
|
+
];
|
|
2691
|
+
var labelContract = contract([
|
|
2692
|
+
{ name: "control", match: isTag(...LABELABLE_TAGS), cardinality: { max: 1 } }
|
|
2693
|
+
]);
|
|
2694
|
+
var P_BLOCKED_TAGS = [
|
|
2695
|
+
"address",
|
|
2696
|
+
"article",
|
|
2697
|
+
"aside",
|
|
2698
|
+
"blockquote",
|
|
2699
|
+
"details",
|
|
2700
|
+
"dialog",
|
|
2701
|
+
"div",
|
|
2702
|
+
"dl",
|
|
2703
|
+
"fieldset",
|
|
2704
|
+
"figure",
|
|
2705
|
+
"footer",
|
|
2706
|
+
"form",
|
|
2707
|
+
"h1",
|
|
2708
|
+
"h2",
|
|
2709
|
+
"h3",
|
|
2710
|
+
"h4",
|
|
2711
|
+
"h5",
|
|
2712
|
+
"h6",
|
|
2713
|
+
"header",
|
|
2714
|
+
"hr",
|
|
2715
|
+
"main",
|
|
2716
|
+
"nav",
|
|
2717
|
+
"ol",
|
|
2718
|
+
"p",
|
|
2719
|
+
"pre",
|
|
2720
|
+
"section",
|
|
2721
|
+
"table",
|
|
2722
|
+
"ul"
|
|
2723
|
+
];
|
|
2724
|
+
var pContract = closedContract([
|
|
2725
|
+
{ name: "content", match: isOpenContent(...P_BLOCKED_TAGS) }
|
|
2726
|
+
]);
|
|
2544
2727
|
var mediaContract = contract([
|
|
2545
2728
|
{ name: "source", match: isTag("source") },
|
|
2546
2729
|
{ name: "track", match: isTag("track") },
|
|
@@ -2595,6 +2778,11 @@ var htmlContracts = {
|
|
|
2595
2778
|
details: detailsContract,
|
|
2596
2779
|
fieldset: fieldsetContract,
|
|
2597
2780
|
dialog: dialogContract,
|
|
2781
|
+
object: objectContract,
|
|
2782
|
+
button: buttonContract,
|
|
2783
|
+
a: anchorContract,
|
|
2784
|
+
label: labelContract,
|
|
2785
|
+
p: pContract,
|
|
2598
2786
|
head: headContract,
|
|
2599
2787
|
html: htmlContract
|
|
2600
2788
|
};
|
|
@@ -2821,6 +3009,11 @@ function composeNormalizers(normalizers, fn) {
|
|
|
2821
3009
|
function whenDefined(key, value) {
|
|
2822
3010
|
return value === void 0 ? {} : { [key]: value };
|
|
2823
3011
|
}
|
|
3012
|
+
function mergeAriaRules(aria, rules) {
|
|
3013
|
+
if (!aria?.length) return rules;
|
|
3014
|
+
if (!rules?.length) return aria;
|
|
3015
|
+
return [...aria, ...rules];
|
|
3016
|
+
}
|
|
2824
3017
|
function resolveFactoryOptions(options = {}) {
|
|
2825
3018
|
const { styling, enforcement } = options;
|
|
2826
3019
|
const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
|
|
@@ -2841,7 +3034,7 @@ function resolveFactoryOptions(options = {}) {
|
|
|
2841
3034
|
...whenDefined("defaultVariants", styling?.defaults),
|
|
2842
3035
|
...whenDefined("compoundVariants", styling?.compounds),
|
|
2843
3036
|
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
2844
|
-
...whenDefined("ariaRules", enforcement?.aria),
|
|
3037
|
+
...whenDefined("ariaRules", mergeAriaRules(enforcement?.aria, enforcement?.rules)),
|
|
2845
3038
|
...whenDefined("childRules", enforcement?.children),
|
|
2846
3039
|
...whenDefined("exclusiveChildren", enforcement?.exclusiveChildren),
|
|
2847
3040
|
...whenDefined("allowText", enforcement?.allowText),
|