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
|
@@ -28,6 +28,9 @@ function isNull(value) {
|
|
|
28
28
|
function isNonNull(value) {
|
|
29
29
|
return value != null;
|
|
30
30
|
}
|
|
31
|
+
function isNullish(value) {
|
|
32
|
+
return isNull(value) || value === void 0;
|
|
33
|
+
}
|
|
31
34
|
|
|
32
35
|
// ../../lib/primitive/src/utils/type-guards.ts
|
|
33
36
|
function isObject(value, excludeArrays = false) {
|
|
@@ -655,20 +658,29 @@ function isAriaAttributeValidForRole(attr, role) {
|
|
|
655
658
|
}
|
|
656
659
|
|
|
657
660
|
// ../../lib/primitive/src/guards/aria/is-aria-role.ts
|
|
661
|
+
function lookupImplicitRole(tag) {
|
|
662
|
+
return IMPLICIT_ROLE_RECORD[tag];
|
|
663
|
+
}
|
|
658
664
|
function isStrongImplicitRole(tag) {
|
|
659
|
-
|
|
660
|
-
return STRONG_ROLES_SET.has(
|
|
665
|
+
const role = lookupImplicitRole(tag);
|
|
666
|
+
return !isNullish(role) && STRONG_ROLES_SET.has(role);
|
|
661
667
|
}
|
|
662
|
-
function
|
|
663
|
-
|
|
664
|
-
return STANDALONE_ROLES_SET.has(
|
|
668
|
+
function hasStandaloneRole(tag) {
|
|
669
|
+
const role = lookupImplicitRole(tag);
|
|
670
|
+
return !isNullish(role) && STANDALONE_ROLES_SET.has(role);
|
|
665
671
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
return
|
|
672
|
+
var LIST_ELIGIBLE_INPUT_TYPES = /* @__PURE__ */ new Set(["text", "search", "tel", "url", "email"]);
|
|
673
|
+
function getInputImplicitRole(type, list) {
|
|
674
|
+
if (!isString(type)) return void 0;
|
|
675
|
+
const role = INPUT_TYPE_ROLE_MAP[type];
|
|
676
|
+
if (!role) return void 0;
|
|
677
|
+
if (!isNullish(list) && LIST_ELIGIBLE_INPUT_TYPES.has(type)) {
|
|
678
|
+
return "combobox";
|
|
679
|
+
}
|
|
680
|
+
return role;
|
|
669
681
|
}
|
|
670
682
|
function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
|
|
671
|
-
const isNamed = isString(ariaLabel) || isString(ariaLabelledBy);
|
|
683
|
+
const isNamed = isString(ariaLabel) && ariaLabel.trim().length > 0 || isString(ariaLabelledBy) && ariaLabelledBy.trim().length > 0;
|
|
672
684
|
if (!isNamed) return void 0;
|
|
673
685
|
if (tag === "section") return "region";
|
|
674
686
|
if (tag === "form") return "form";
|
|
@@ -720,7 +732,7 @@ function isTag(...args) {
|
|
|
720
732
|
// ../../lib/contract/src/aria/aria-role-policy.ts
|
|
721
733
|
function getImplicitRole(tag, props) {
|
|
722
734
|
if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
|
|
723
|
-
if (tag === "input") return getInputImplicitRole(props?.type);
|
|
735
|
+
if (tag === "input") return getInputImplicitRole(props?.type, props?.list);
|
|
724
736
|
if (tag === "img") return props?.alt === "" ? "none" : "img";
|
|
725
737
|
if (tag === "section" || tag === "form") {
|
|
726
738
|
return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
|
|
@@ -1003,7 +1015,11 @@ var ATTRIBUTE_IGNORED_CODES = {
|
|
|
1003
1015
|
max: DiagnosticCode3.HtmlInputMaxIgnoredForType,
|
|
1004
1016
|
step: DiagnosticCode3.HtmlInputStepIgnoredForType,
|
|
1005
1017
|
accept: DiagnosticCode3.HtmlInputAcceptIgnoredForType,
|
|
1006
|
-
capture: DiagnosticCode3.HtmlInputCaptureIgnoredForType
|
|
1018
|
+
capture: DiagnosticCode3.HtmlInputCaptureIgnoredForType,
|
|
1019
|
+
size: DiagnosticCode3.HtmlInputSizeIgnoredForType,
|
|
1020
|
+
alt: DiagnosticCode3.HtmlInputAltIgnoredForType,
|
|
1021
|
+
height: DiagnosticCode3.HtmlInputHeightIgnoredForType,
|
|
1022
|
+
width: DiagnosticCode3.HtmlInputWidthIgnoredForType
|
|
1007
1023
|
};
|
|
1008
1024
|
var HtmlDiagnostics = {
|
|
1009
1025
|
emptyRole(tag) {
|
|
@@ -1237,8 +1253,132 @@ var InvariantBase = class {
|
|
|
1237
1253
|
}
|
|
1238
1254
|
};
|
|
1239
1255
|
|
|
1240
|
-
// ../../lib/contract/src/aria/
|
|
1256
|
+
// ../../lib/contract/src/aria/spec/roles/required-properties.ts
|
|
1257
|
+
var REQUIRED_ARIA_PROPERTIES = {
|
|
1258
|
+
combobox: ["aria-expanded"],
|
|
1259
|
+
option: ["aria-selected"],
|
|
1260
|
+
slider: ["aria-valuenow"],
|
|
1261
|
+
scrollbar: ["aria-controls", "aria-valuenow"],
|
|
1262
|
+
spinbutton: ["aria-valuenow"]
|
|
1263
|
+
};
|
|
1264
|
+
|
|
1265
|
+
// ../../lib/contract/src/aria/spec/roles/name-required.ts
|
|
1266
|
+
var NAME_REQUIRED_ROLES = /* @__PURE__ */ new Set(["img"]);
|
|
1267
|
+
|
|
1268
|
+
// ../../lib/contract/src/aria/spec/validators/required-properties-validator.ts
|
|
1241
1269
|
var NO_VIOLATIONS = [{ valid: true }];
|
|
1270
|
+
function requiredAttributeByRole(roles, attribute) {
|
|
1271
|
+
return Object.fromEntries([...roles].map((role) => [role, [attribute]]));
|
|
1272
|
+
}
|
|
1273
|
+
function checkRequiredAttributes(requirement, { props, effectiveRole }) {
|
|
1274
|
+
if (!effectiveRole) return NO_VIOLATIONS;
|
|
1275
|
+
const requiredAttributes = requirement.attributesByRole[effectiveRole];
|
|
1276
|
+
if (!requiredAttributes) return NO_VIOLATIONS;
|
|
1277
|
+
const results = [];
|
|
1278
|
+
for (const attribute of requiredAttributes) {
|
|
1279
|
+
if (attribute in props) continue;
|
|
1280
|
+
results.push({
|
|
1281
|
+
valid: false,
|
|
1282
|
+
fixable: false,
|
|
1283
|
+
severity: "warning",
|
|
1284
|
+
attribute,
|
|
1285
|
+
diagnostic: requirement.diagnosticFor(attribute, effectiveRole)
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
return results;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
// ../../lib/contract/src/aria/spec/roles/live-region.ts
|
|
1292
|
+
var LIVE_REGION_ROLES = /* @__PURE__ */ new Map([
|
|
1293
|
+
["alert", "assertive"],
|
|
1294
|
+
["status", "polite"],
|
|
1295
|
+
["log", "polite"],
|
|
1296
|
+
["timer", "off"]
|
|
1297
|
+
]);
|
|
1298
|
+
var ATOMIC_REQUIREMENTS = requiredAttributeByRole(LIVE_REGION_ROLES.keys(), "aria-atomic");
|
|
1299
|
+
|
|
1300
|
+
// ../../lib/contract/src/aria/spec/attributes/aria-value-types.ts
|
|
1301
|
+
var ARIA_VALUE_TYPES = /* @__PURE__ */ new Map([
|
|
1302
|
+
// Boolean (true | false)
|
|
1303
|
+
["aria-atomic", { kind: "boolean" }],
|
|
1304
|
+
["aria-busy", { kind: "boolean" }],
|
|
1305
|
+
["aria-disabled", { kind: "boolean" }],
|
|
1306
|
+
["aria-expanded", { kind: "boolean" }],
|
|
1307
|
+
["aria-hidden", { kind: "boolean" }],
|
|
1308
|
+
["aria-modal", { kind: "boolean" }],
|
|
1309
|
+
["aria-multiline", { kind: "boolean" }],
|
|
1310
|
+
["aria-multiselectable", { kind: "boolean" }],
|
|
1311
|
+
["aria-readonly", { kind: "boolean" }],
|
|
1312
|
+
["aria-required", { kind: "boolean" }],
|
|
1313
|
+
["aria-selected", { kind: "boolean" }],
|
|
1314
|
+
// Tristate (true | false | mixed)
|
|
1315
|
+
["aria-checked", { kind: "tristate" }],
|
|
1316
|
+
["aria-pressed", { kind: "tristate" }],
|
|
1317
|
+
// Numeric (any finite number)
|
|
1318
|
+
["aria-valuenow", { kind: "number" }],
|
|
1319
|
+
["aria-valuemin", { kind: "number" }],
|
|
1320
|
+
["aria-valuemax", { kind: "number" }],
|
|
1321
|
+
// Integer with optional range
|
|
1322
|
+
["aria-level", { kind: "integer", min: 1, max: 6 }],
|
|
1323
|
+
["aria-posinset", { kind: "integer", min: 1 }],
|
|
1324
|
+
["aria-setsize", { kind: "integer", min: -1 }],
|
|
1325
|
+
["aria-rowcount", { kind: "integer", min: -1 }],
|
|
1326
|
+
["aria-colcount", { kind: "integer", min: -1 }],
|
|
1327
|
+
["aria-rowindex", { kind: "integer", min: 1 }],
|
|
1328
|
+
["aria-colindex", { kind: "integer", min: 1 }],
|
|
1329
|
+
["aria-rowspan", { kind: "integer", min: 0 }],
|
|
1330
|
+
["aria-colspan", { kind: "integer", min: 0 }],
|
|
1331
|
+
// Enum (specific allowed tokens)
|
|
1332
|
+
["aria-autocomplete", { kind: "enum", values: /* @__PURE__ */ new Set(["inline", "list", "both", "none"]) }],
|
|
1333
|
+
[
|
|
1334
|
+
"aria-current",
|
|
1335
|
+
{
|
|
1336
|
+
kind: "enum",
|
|
1337
|
+
values: /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"])
|
|
1338
|
+
}
|
|
1339
|
+
],
|
|
1340
|
+
[
|
|
1341
|
+
"aria-haspopup",
|
|
1342
|
+
{
|
|
1343
|
+
kind: "enum",
|
|
1344
|
+
values: /* @__PURE__ */ new Set(["false", "true", "menu", "listbox", "tree", "grid", "dialog"])
|
|
1345
|
+
}
|
|
1346
|
+
],
|
|
1347
|
+
["aria-invalid", { kind: "enum", values: /* @__PURE__ */ new Set(["grammar", "false", "spelling", "true"]) }],
|
|
1348
|
+
["aria-live", { kind: "enum", values: /* @__PURE__ */ new Set(["assertive", "off", "polite"]) }],
|
|
1349
|
+
["aria-orientation", { kind: "enum", values: /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]) }],
|
|
1350
|
+
["aria-sort", { kind: "enum", values: /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"]) }]
|
|
1351
|
+
]);
|
|
1352
|
+
|
|
1353
|
+
// ../../lib/contract/src/aria/spec/attributes/aria-relevant-tokens.ts
|
|
1354
|
+
var VALID_RELEVANT_TOKENS = /* @__PURE__ */ new Set([
|
|
1355
|
+
"additions",
|
|
1356
|
+
"removals",
|
|
1357
|
+
"text",
|
|
1358
|
+
"all"
|
|
1359
|
+
]);
|
|
1360
|
+
|
|
1361
|
+
// ../../lib/contract/src/aria/spec/elements/heading-implicit-levels.ts
|
|
1362
|
+
var HEADING_IMPLICIT_LEVELS = /* @__PURE__ */ new Map([
|
|
1363
|
+
["h1", 1],
|
|
1364
|
+
["h2", 2],
|
|
1365
|
+
["h3", 3],
|
|
1366
|
+
["h4", 4],
|
|
1367
|
+
["h5", 5],
|
|
1368
|
+
["h6", 6]
|
|
1369
|
+
]);
|
|
1370
|
+
|
|
1371
|
+
// ../../lib/contract/src/aria/spec/elements/interactive-tags.ts
|
|
1372
|
+
var INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
1373
|
+
"a",
|
|
1374
|
+
"button",
|
|
1375
|
+
"input",
|
|
1376
|
+
"select",
|
|
1377
|
+
"textarea"
|
|
1378
|
+
]);
|
|
1379
|
+
|
|
1380
|
+
// ../../lib/contract/src/aria/polymorphic-validator.ts
|
|
1381
|
+
var NO_VIOLATIONS2 = [{ valid: true }];
|
|
1242
1382
|
function isIntrinsicTag(tag) {
|
|
1243
1383
|
return isString(tag);
|
|
1244
1384
|
}
|
|
@@ -1281,7 +1421,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1281
1421
|
if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
|
|
1282
1422
|
const implicitRole = getImplicitRole(tag, props);
|
|
1283
1423
|
const hasRole2 = isNonNull(implicitRole) || isString(props.role) && props.role.length > 0;
|
|
1284
|
-
if (!hasRole2) return { proceed: false, result: { props, violations: [] } };
|
|
1285
1424
|
const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
|
|
1286
1425
|
const workingProps = normalized.normalized ? normalized.result.props : props;
|
|
1287
1426
|
const preExistingViolations = normalized.normalized ? normalized.result.violations : [];
|
|
@@ -1291,6 +1430,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1291
1430
|
tag,
|
|
1292
1431
|
implicitRole,
|
|
1293
1432
|
effectiveRole,
|
|
1433
|
+
hasRole: hasRole2,
|
|
1294
1434
|
props: workingProps,
|
|
1295
1435
|
preExistingViolations,
|
|
1296
1436
|
context: { tag, props: workingProps, implicitRole, effectiveRole }
|
|
@@ -1300,6 +1440,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1300
1440
|
const violations = [];
|
|
1301
1441
|
const fixes = [];
|
|
1302
1442
|
iterate.forEach(rules, (rule) => {
|
|
1443
|
+
if (isNonNull(rule.tags) && !rule.tags.includes(context.tag)) return;
|
|
1303
1444
|
iterate.forEach(rule(context), (result) => {
|
|
1304
1445
|
if (result.valid) return;
|
|
1305
1446
|
const {
|
|
@@ -1325,7 +1466,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1325
1466
|
return { violations, fixes };
|
|
1326
1467
|
}
|
|
1327
1468
|
static #getRules(context) {
|
|
1328
|
-
if (_AriaPolicyEngine.#hasRole(context.props) || isNonNull(context.effectiveRole) &&
|
|
1469
|
+
if (_AriaPolicyEngine.#hasRole(context.props) || isNonNull(context.effectiveRole) && LIVE_REGION_ROLES.has(context.effectiveRole)) {
|
|
1329
1470
|
return _AriaPolicyEngine.#pipeline;
|
|
1330
1471
|
}
|
|
1331
1472
|
return _AriaPolicyEngine.#implicitOnlyRules;
|
|
@@ -1333,6 +1474,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1333
1474
|
static evaluate(tag, props) {
|
|
1334
1475
|
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
1335
1476
|
if (!derived.proceed) return derived.result;
|
|
1477
|
+
if (!derived.hasRole)
|
|
1478
|
+
return { props: derived.props, violations: [...derived.preExistingViolations] };
|
|
1336
1479
|
const {
|
|
1337
1480
|
tag: narrowedTag,
|
|
1338
1481
|
implicitRole,
|
|
@@ -1357,10 +1500,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1357
1500
|
props: workingProps,
|
|
1358
1501
|
preExistingViolations
|
|
1359
1502
|
} = derived;
|
|
1360
|
-
const
|
|
1361
|
-
|
|
1362
|
-
context
|
|
1363
|
-
);
|
|
1503
|
+
const rules = derived.hasRole ? [..._AriaPolicyEngine.#getRules(context), ...extraRules] : extraRules;
|
|
1504
|
+
const { violations, fixes } = _AriaPolicyEngine.#runRules(rules, context);
|
|
1364
1505
|
const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
|
|
1365
1506
|
return { props: next, violations: [...preExistingViolations, ...violations] };
|
|
1366
1507
|
}
|
|
@@ -1527,7 +1668,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1527
1668
|
implicitRole
|
|
1528
1669
|
}) {
|
|
1529
1670
|
const role = props.role;
|
|
1530
|
-
if (!implicitRole || !role || role === implicitRole) return
|
|
1671
|
+
if (!implicitRole || !role || role === implicitRole) return NO_VIOLATIONS2;
|
|
1531
1672
|
if (isStrongImplicitRole(tag) && role === "region") {
|
|
1532
1673
|
const diagnostic = HtmlDiagnostics.implicitRoleOverride(tag, implicitRole, role);
|
|
1533
1674
|
return [
|
|
@@ -1540,11 +1681,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1540
1681
|
}
|
|
1541
1682
|
];
|
|
1542
1683
|
}
|
|
1543
|
-
return
|
|
1684
|
+
return NO_VIOLATIONS2;
|
|
1544
1685
|
}
|
|
1545
1686
|
static #checkRedundantRole({ tag, props, implicitRole }) {
|
|
1546
1687
|
const role = props.role;
|
|
1547
|
-
if (!implicitRole || !role || role !== implicitRole) return
|
|
1688
|
+
if (!implicitRole || !role || role !== implicitRole) return NO_VIOLATIONS2;
|
|
1548
1689
|
const diagnostic = HtmlDiagnostics.implicitRoleRedundant(tag, implicitRole);
|
|
1549
1690
|
return [
|
|
1550
1691
|
{
|
|
@@ -1558,8 +1699,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1558
1699
|
}
|
|
1559
1700
|
static #checkStandaloneRegion({ tag, props, implicitRole }) {
|
|
1560
1701
|
const role = props.role;
|
|
1561
|
-
if (role !== "region") return
|
|
1562
|
-
if (!
|
|
1702
|
+
if (role !== "region") return NO_VIOLATIONS2;
|
|
1703
|
+
if (!hasStandaloneRole(tag)) return NO_VIOLATIONS2;
|
|
1563
1704
|
const diagnostic = HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag);
|
|
1564
1705
|
return [
|
|
1565
1706
|
{
|
|
@@ -1576,7 +1717,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1576
1717
|
props,
|
|
1577
1718
|
effectiveRole
|
|
1578
1719
|
}) {
|
|
1579
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1720
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS2;
|
|
1580
1721
|
const results = [];
|
|
1581
1722
|
iterate.forEachEntry(props, (key) => {
|
|
1582
1723
|
if (!key.startsWith("aria-")) return;
|
|
@@ -1594,62 +1735,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1594
1735
|
return results;
|
|
1595
1736
|
}
|
|
1596
1737
|
// ─── ARIA attribute value validation ──────────────────────────────────────
|
|
1597
|
-
// Accepted value shapes for typed ARIA attributes.
|
|
1598
|
-
// Attributes not in this map are unconstrained (arbitrary string values permitted).
|
|
1599
|
-
static #ARIA_VALUE_TYPES = /* @__PURE__ */ new Map([
|
|
1600
|
-
// Boolean (true | false)
|
|
1601
|
-
["aria-atomic", { kind: "boolean" }],
|
|
1602
|
-
["aria-busy", { kind: "boolean" }],
|
|
1603
|
-
["aria-disabled", { kind: "boolean" }],
|
|
1604
|
-
["aria-expanded", { kind: "boolean" }],
|
|
1605
|
-
["aria-hidden", { kind: "boolean" }],
|
|
1606
|
-
["aria-modal", { kind: "boolean" }],
|
|
1607
|
-
["aria-multiline", { kind: "boolean" }],
|
|
1608
|
-
["aria-multiselectable", { kind: "boolean" }],
|
|
1609
|
-
["aria-readonly", { kind: "boolean" }],
|
|
1610
|
-
["aria-required", { kind: "boolean" }],
|
|
1611
|
-
["aria-selected", { kind: "boolean" }],
|
|
1612
|
-
// Tristate (true | false | mixed)
|
|
1613
|
-
["aria-checked", { kind: "tristate" }],
|
|
1614
|
-
["aria-pressed", { kind: "tristate" }],
|
|
1615
|
-
// Numeric (any finite number)
|
|
1616
|
-
["aria-valuenow", { kind: "number" }],
|
|
1617
|
-
["aria-valuemin", { kind: "number" }],
|
|
1618
|
-
["aria-valuemax", { kind: "number" }],
|
|
1619
|
-
// Integer with optional range
|
|
1620
|
-
["aria-level", { kind: "integer", min: 1, max: 6 }],
|
|
1621
|
-
["aria-posinset", { kind: "integer", min: 1 }],
|
|
1622
|
-
["aria-setsize", { kind: "integer", min: -1 }],
|
|
1623
|
-
["aria-rowcount", { kind: "integer", min: -1 }],
|
|
1624
|
-
["aria-colcount", { kind: "integer", min: -1 }],
|
|
1625
|
-
["aria-rowindex", { kind: "integer", min: 1 }],
|
|
1626
|
-
["aria-colindex", { kind: "integer", min: 1 }],
|
|
1627
|
-
["aria-rowspan", { kind: "integer", min: 0 }],
|
|
1628
|
-
["aria-colspan", { kind: "integer", min: 0 }],
|
|
1629
|
-
// Enum (specific allowed tokens)
|
|
1630
|
-
["aria-autocomplete", { kind: "enum", values: /* @__PURE__ */ new Set(["inline", "list", "both", "none"]) }],
|
|
1631
|
-
[
|
|
1632
|
-
"aria-current",
|
|
1633
|
-
{
|
|
1634
|
-
kind: "enum",
|
|
1635
|
-
values: /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"])
|
|
1636
|
-
}
|
|
1637
|
-
],
|
|
1638
|
-
[
|
|
1639
|
-
"aria-haspopup",
|
|
1640
|
-
{
|
|
1641
|
-
kind: "enum",
|
|
1642
|
-
values: /* @__PURE__ */ new Set(["false", "true", "menu", "listbox", "tree", "grid", "dialog"])
|
|
1643
|
-
}
|
|
1644
|
-
],
|
|
1645
|
-
["aria-invalid", { kind: "enum", values: /* @__PURE__ */ new Set(["grammar", "false", "spelling", "true"]) }],
|
|
1646
|
-
["aria-live", { kind: "enum", values: /* @__PURE__ */ new Set(["assertive", "off", "polite"]) }],
|
|
1647
|
-
[
|
|
1648
|
-
"aria-orientation",
|
|
1649
|
-
{ kind: "enum", values: /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]) }
|
|
1650
|
-
],
|
|
1651
|
-
["aria-sort", { kind: "enum", values: /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"]) }]
|
|
1652
|
-
]);
|
|
1653
1738
|
static #isValidAriaValue(value, type) {
|
|
1654
1739
|
switch (type.kind) {
|
|
1655
1740
|
case "boolean":
|
|
@@ -1694,11 +1779,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1694
1779
|
}
|
|
1695
1780
|
}
|
|
1696
1781
|
static #checkAriaAttributeValues({ props, effectiveRole }) {
|
|
1697
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1782
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS2;
|
|
1698
1783
|
const results = [];
|
|
1699
1784
|
iterate.forEachEntry(props, (key, value) => {
|
|
1700
1785
|
if (!key.startsWith("aria-")) return;
|
|
1701
|
-
const type =
|
|
1786
|
+
const type = ARIA_VALUE_TYPES.get(key);
|
|
1702
1787
|
if (!isNonNull(type)) return;
|
|
1703
1788
|
if (_AriaPolicyEngine.#isValidAriaValue(value, type)) return;
|
|
1704
1789
|
results.push({
|
|
@@ -1717,26 +1802,18 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1717
1802
|
return results;
|
|
1718
1803
|
}
|
|
1719
1804
|
// ─── Heading implicit level ────────────────────────────────────────────────
|
|
1720
|
-
static #HEADING_IMPLICIT_LEVELS = /* @__PURE__ */ new Map([
|
|
1721
|
-
["h1", 1],
|
|
1722
|
-
["h2", 2],
|
|
1723
|
-
["h3", 3],
|
|
1724
|
-
["h4", 4],
|
|
1725
|
-
["h5", 5],
|
|
1726
|
-
["h6", 6]
|
|
1727
|
-
]);
|
|
1728
1805
|
static #checkRedundantAriaLevel({
|
|
1729
1806
|
tag,
|
|
1730
1807
|
props,
|
|
1731
1808
|
effectiveRole
|
|
1732
1809
|
}) {
|
|
1733
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1734
|
-
const implicitLevel =
|
|
1735
|
-
if (!isNonNull(implicitLevel)) return
|
|
1810
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS2;
|
|
1811
|
+
const implicitLevel = HEADING_IMPLICIT_LEVELS.get(tag);
|
|
1812
|
+
if (!isNonNull(implicitLevel)) return NO_VIOLATIONS2;
|
|
1736
1813
|
const raw = props["aria-level"];
|
|
1737
|
-
if (!isNonNull(raw)) return
|
|
1814
|
+
if (!isNonNull(raw)) return NO_VIOLATIONS2;
|
|
1738
1815
|
const n = typeof raw === "number" ? raw : typeof raw === "string" ? parseInt(raw, 10) : NaN;
|
|
1739
|
-
if (!Number.isFinite(n) || n !== implicitLevel) return
|
|
1816
|
+
if (!Number.isFinite(n) || n !== implicitLevel) return NO_VIOLATIONS2;
|
|
1740
1817
|
return [
|
|
1741
1818
|
{
|
|
1742
1819
|
valid: false,
|
|
@@ -1749,20 +1826,14 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1749
1826
|
];
|
|
1750
1827
|
}
|
|
1751
1828
|
// ─── Name-required roles ───────────────────────────────────────────────────
|
|
1752
|
-
// Roles that always require an accessible name per WAI-ARIA APG.
|
|
1753
|
-
// Dialog and landmark names are enforced via contracts (ariaContract) rather than
|
|
1754
|
-
// the built-in pipeline so consumers can opt in; img is built in because role=img
|
|
1755
|
-
// on any element (including bare <img>) is definitionally useless without a name.
|
|
1756
|
-
static #NAME_REQUIRED_ROLES = /* @__PURE__ */ new Set(["img"]);
|
|
1757
1829
|
static #checkNameRequiredRoles({
|
|
1758
1830
|
tag,
|
|
1759
1831
|
props,
|
|
1760
1832
|
effectiveRole
|
|
1761
1833
|
}) {
|
|
1762
|
-
if (!effectiveRole || !
|
|
1763
|
-
|
|
1764
|
-
if ("
|
|
1765
|
-
if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return NO_VIOLATIONS;
|
|
1834
|
+
if (!effectiveRole || !NAME_REQUIRED_ROLES.has(effectiveRole)) return NO_VIOLATIONS2;
|
|
1835
|
+
if ("aria-label" in props || "aria-labelledby" in props) return NO_VIOLATIONS2;
|
|
1836
|
+
if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return NO_VIOLATIONS2;
|
|
1766
1837
|
return [
|
|
1767
1838
|
{
|
|
1768
1839
|
valid: false,
|
|
@@ -1772,51 +1843,21 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1772
1843
|
}
|
|
1773
1844
|
];
|
|
1774
1845
|
}
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
["scrollbar", ["aria-controls", "aria-valuenow"]],
|
|
1782
|
-
["spinbutton", ["aria-valuenow"]]
|
|
1783
|
-
]);
|
|
1784
|
-
static #checkRequiredAriaProperties({
|
|
1785
|
-
props,
|
|
1786
|
-
effectiveRole
|
|
1787
|
-
}) {
|
|
1788
|
-
if (!effectiveRole) return NO_VIOLATIONS;
|
|
1789
|
-
const required = _AriaPolicyEngine.#REQUIRED_PROPERTIES.get(effectiveRole);
|
|
1790
|
-
if (!isNonNull(required)) return NO_VIOLATIONS;
|
|
1791
|
-
const results = [];
|
|
1792
|
-
iterate.forEach(required, (attr) => {
|
|
1793
|
-
if (attr in props) return;
|
|
1794
|
-
results.push({
|
|
1795
|
-
valid: false,
|
|
1796
|
-
fixable: false,
|
|
1797
|
-
severity: "warning",
|
|
1798
|
-
attribute: attr,
|
|
1799
|
-
diagnostic: AriaDiagnostics.requiredProperty(attr, effectiveRole)
|
|
1800
|
-
});
|
|
1801
|
-
});
|
|
1802
|
-
return results;
|
|
1846
|
+
static #requiredAriaPropertiesRule = {
|
|
1847
|
+
attributesByRole: REQUIRED_ARIA_PROPERTIES,
|
|
1848
|
+
diagnosticFor: (attribute, role) => AriaDiagnostics.requiredProperty(attribute, role)
|
|
1849
|
+
};
|
|
1850
|
+
static #checkRequiredAriaProperties(context) {
|
|
1851
|
+
return checkRequiredAttributes(_AriaPolicyEngine.#requiredAriaPropertiesRule, context);
|
|
1803
1852
|
}
|
|
1804
|
-
// Natively interactive HTML elements — always keyboard-reachable unless explicitly disabled.
|
|
1805
|
-
static #INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
1806
|
-
"a",
|
|
1807
|
-
"button",
|
|
1808
|
-
"input",
|
|
1809
|
-
"select",
|
|
1810
|
-
"textarea"
|
|
1811
|
-
]);
|
|
1812
1853
|
// WAI-ARIA 1.2 §6.6: aria-hidden="true" must not be placed on focusable elements.
|
|
1813
1854
|
static #checkAriaHiddenOnFocusable({ tag, props }) {
|
|
1814
|
-
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return
|
|
1815
|
-
const isInteractive =
|
|
1855
|
+
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return NO_VIOLATIONS2;
|
|
1856
|
+
const isInteractive = INTERACTIVE_TAGS.has(tag);
|
|
1816
1857
|
if (!isInteractive) {
|
|
1817
1858
|
const tabindex = props.tabindex;
|
|
1818
1859
|
const n = typeof tabindex === "number" ? tabindex : typeof tabindex === "string" ? parseInt(tabindex, 10) : NaN;
|
|
1819
|
-
if (!Number.isFinite(n) || n < 0) return
|
|
1860
|
+
if (!Number.isFinite(n) || n < 0) return NO_VIOLATIONS2;
|
|
1820
1861
|
}
|
|
1821
1862
|
return [
|
|
1822
1863
|
{
|
|
@@ -1835,7 +1876,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1835
1876
|
props,
|
|
1836
1877
|
effectiveRole
|
|
1837
1878
|
}) {
|
|
1838
|
-
if (effectiveRole !== "none" && effectiveRole !== "presentation") return
|
|
1879
|
+
if (effectiveRole !== "none" && effectiveRole !== "presentation") return NO_VIOLATIONS2;
|
|
1839
1880
|
const results = [];
|
|
1840
1881
|
iterate.forEachEntry(props, (key) => {
|
|
1841
1882
|
if (!key.startsWith("aria-")) return;
|
|
@@ -1851,18 +1892,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1851
1892
|
});
|
|
1852
1893
|
return results;
|
|
1853
1894
|
}
|
|
1854
|
-
// WAI-ARIA live region roles and their implied aria-live politeness values.
|
|
1855
|
-
static #LIVE_REGION_ROLES = /* @__PURE__ */ new Map([
|
|
1856
|
-
["alert", "assertive"],
|
|
1857
|
-
["status", "polite"],
|
|
1858
|
-
["log", "polite"],
|
|
1859
|
-
["timer", "off"]
|
|
1860
|
-
]);
|
|
1861
1895
|
static #checkMissingLiveRegion({ effectiveRole, props }) {
|
|
1862
|
-
if (!effectiveRole) return
|
|
1863
|
-
const impliedLive =
|
|
1864
|
-
if (!impliedLive) return
|
|
1865
|
-
if ("aria-live" in props) return
|
|
1896
|
+
if (!effectiveRole) return NO_VIOLATIONS2;
|
|
1897
|
+
const impliedLive = LIVE_REGION_ROLES.get(effectiveRole);
|
|
1898
|
+
if (!impliedLive) return NO_VIOLATIONS2;
|
|
1899
|
+
if ("aria-live" in props) return NO_VIOLATIONS2;
|
|
1866
1900
|
const injectLive = {
|
|
1867
1901
|
kind: `injectLive:${effectiveRole}`,
|
|
1868
1902
|
apply: (ctx) => ({
|
|
@@ -1881,20 +1915,13 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1881
1915
|
}
|
|
1882
1916
|
];
|
|
1883
1917
|
}
|
|
1884
|
-
static #
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
valid: false,
|
|
1891
|
-
fixable: false,
|
|
1892
|
-
severity: "warning",
|
|
1893
|
-
diagnostic: AriaDiagnostics.missingAtomic(effectiveRole)
|
|
1894
|
-
}
|
|
1895
|
-
];
|
|
1918
|
+
static #missingAtomicRule = {
|
|
1919
|
+
attributesByRole: ATOMIC_REQUIREMENTS,
|
|
1920
|
+
diagnosticFor: (_attribute, role) => AriaDiagnostics.missingAtomic(role)
|
|
1921
|
+
};
|
|
1922
|
+
static #checkMissingAtomic(context) {
|
|
1923
|
+
return checkRequiredAttributes(_AriaPolicyEngine.#missingAtomicRule, context);
|
|
1896
1924
|
}
|
|
1897
|
-
static #VALID_RELEVANT_TOKENS = /* @__PURE__ */ new Set(["additions", "removals", "text", "all"]);
|
|
1898
1925
|
// Custom fix rules passed via `options.rules` must be pure functions of (tag, props) — the cache
|
|
1899
1926
|
// replays stored fixes against new prop objects, so fixes that close over external state will
|
|
1900
1927
|
// produce inconsistent results on cache hits.
|
|
@@ -1908,10 +1935,10 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1908
1935
|
};
|
|
1909
1936
|
static #checkInvalidAriaRelevant({ props }) {
|
|
1910
1937
|
const relevant = props["aria-relevant"];
|
|
1911
|
-
if (relevant === void 0) return
|
|
1912
|
-
if (typeof relevant !== "string") return
|
|
1938
|
+
if (relevant === void 0) return NO_VIOLATIONS2;
|
|
1939
|
+
if (typeof relevant !== "string") return NO_VIOLATIONS2;
|
|
1913
1940
|
const tokens = relevant.trim().split(/\s+/);
|
|
1914
|
-
const invalid = tokens.filter((t) => !
|
|
1941
|
+
const invalid = tokens.filter((t) => !VALID_RELEVANT_TOKENS.has(t));
|
|
1915
1942
|
if (invalid.length > 0) {
|
|
1916
1943
|
return [
|
|
1917
1944
|
{
|
|
@@ -1936,7 +1963,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1936
1963
|
}
|
|
1937
1964
|
];
|
|
1938
1965
|
}
|
|
1939
|
-
return
|
|
1966
|
+
return NO_VIOLATIONS2;
|
|
1940
1967
|
}
|
|
1941
1968
|
};
|
|
1942
1969
|
|
|
@@ -2256,7 +2283,59 @@ var readonlyProps = ({
|
|
|
2256
2283
|
// ../core/src/html/evaluators.ts
|
|
2257
2284
|
import { warnDiagnostics as warnDiagnostics2 } from "./_shared/diagnostics.js";
|
|
2258
2285
|
|
|
2259
|
-
// ../core/src/html/input
|
|
2286
|
+
// ../core/src/html/spec/vocabulary/input.ts
|
|
2287
|
+
var TEXT_INPUT_TYPES = ["text", "search", "url", "tel", "email", "password"];
|
|
2288
|
+
var NUMERIC_INPUT_TYPES = [
|
|
2289
|
+
"number",
|
|
2290
|
+
"range",
|
|
2291
|
+
"date",
|
|
2292
|
+
"month",
|
|
2293
|
+
"week",
|
|
2294
|
+
"time",
|
|
2295
|
+
"datetime-local"
|
|
2296
|
+
];
|
|
2297
|
+
var HTML_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
2298
|
+
...TEXT_INPUT_TYPES,
|
|
2299
|
+
...NUMERIC_INPUT_TYPES,
|
|
2300
|
+
"checkbox",
|
|
2301
|
+
"radio",
|
|
2302
|
+
"file",
|
|
2303
|
+
"color",
|
|
2304
|
+
"hidden",
|
|
2305
|
+
"button",
|
|
2306
|
+
"submit",
|
|
2307
|
+
"reset",
|
|
2308
|
+
"image"
|
|
2309
|
+
]);
|
|
2310
|
+
|
|
2311
|
+
// ../core/src/html/spec/attributes/input.ts
|
|
2312
|
+
var INPUT_ATTRIBUTE_TYPE_POLICIES = [
|
|
2313
|
+
{ attribute: "checked", allowedTypes: ["checkbox", "radio"] },
|
|
2314
|
+
{ attribute: "multiple", allowedTypes: ["email", "file"] },
|
|
2315
|
+
{ attribute: "maxLength", allowedTypes: TEXT_INPUT_TYPES },
|
|
2316
|
+
{ attribute: "minLength", allowedTypes: TEXT_INPUT_TYPES },
|
|
2317
|
+
{ attribute: "pattern", allowedTypes: TEXT_INPUT_TYPES },
|
|
2318
|
+
{ attribute: "min", allowedTypes: NUMERIC_INPUT_TYPES },
|
|
2319
|
+
{ attribute: "max", allowedTypes: NUMERIC_INPUT_TYPES },
|
|
2320
|
+
{ attribute: "step", allowedTypes: NUMERIC_INPUT_TYPES },
|
|
2321
|
+
{ attribute: "accept", allowedTypes: ["file"] },
|
|
2322
|
+
{ attribute: "capture", allowedTypes: ["file"] },
|
|
2323
|
+
{ attribute: "size", allowedTypes: TEXT_INPUT_TYPES },
|
|
2324
|
+
{ attribute: "alt", allowedTypes: ["image"] },
|
|
2325
|
+
{ attribute: "height", allowedTypes: ["image"] },
|
|
2326
|
+
{ attribute: "width", allowedTypes: ["image"] }
|
|
2327
|
+
];
|
|
2328
|
+
|
|
2329
|
+
// ../core/src/html/spec/constraints/input.ts
|
|
2330
|
+
var REQUIRED_READONLY_CONFLICT = {
|
|
2331
|
+
props: ["required", "readOnly"],
|
|
2332
|
+
diagnostic: () => InputAccessibilityDiagnostics.requiredReadOnlyConflict()
|
|
2333
|
+
};
|
|
2334
|
+
var INPUT_MUTUALLY_EXCLUSIVE_POLICIES = [
|
|
2335
|
+
REQUIRED_READONLY_CONFLICT
|
|
2336
|
+
];
|
|
2337
|
+
|
|
2338
|
+
// ../core/src/html/spec/validators/attribute-type-validator.ts
|
|
2260
2339
|
var DEFAULT_INPUT_TYPE = "text";
|
|
2261
2340
|
function omit(props, key) {
|
|
2262
2341
|
const next = { ...props };
|
|
@@ -2272,7 +2351,10 @@ function removeAttributeFix(attribute) {
|
|
|
2272
2351
|
}
|
|
2273
2352
|
};
|
|
2274
2353
|
}
|
|
2275
|
-
function
|
|
2354
|
+
function createInputAttributeTypeRule({
|
|
2355
|
+
attribute,
|
|
2356
|
+
allowedTypes
|
|
2357
|
+
}) {
|
|
2276
2358
|
const rule = ({ tag, props }) => {
|
|
2277
2359
|
if (tag !== "input" || !(attribute in props)) return [];
|
|
2278
2360
|
const type = typeof props.type === "string" ? props.type : DEFAULT_INPUT_TYPE;
|
|
@@ -2288,31 +2370,30 @@ function inputAttributeRequiresType(attribute, allowedTypes) {
|
|
|
2288
2370
|
}
|
|
2289
2371
|
];
|
|
2290
2372
|
};
|
|
2291
|
-
return Object.assign(rule, { readsProps: ["type", attribute] });
|
|
2373
|
+
return Object.assign(rule, { readsProps: ["type", attribute], tags: ["input"] });
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
// ../core/src/html/spec/validators/mutually-exclusive-validator.ts
|
|
2377
|
+
function createMutuallyExclusiveRule({
|
|
2378
|
+
props: conflictingProps,
|
|
2379
|
+
diagnostic: createDiagnostic
|
|
2380
|
+
}) {
|
|
2381
|
+
const [first, second] = conflictingProps;
|
|
2382
|
+
const rule = ({ tag, props }) => {
|
|
2383
|
+
if (tag !== "input" || !props[first] || !props[second]) return [];
|
|
2384
|
+
const diagnostic = createDiagnostic();
|
|
2385
|
+
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2386
|
+
};
|
|
2387
|
+
return Object.assign(rule, { readsProps: conflictingProps, tags: ["input"] });
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
// ../core/src/html/input-rules.ts
|
|
2391
|
+
var policyByAttribute = Object.fromEntries(
|
|
2392
|
+
INPUT_ATTRIBUTE_TYPE_POLICIES.map((policy) => [policy.attribute, policy])
|
|
2393
|
+
);
|
|
2394
|
+
function policyFor(attribute) {
|
|
2395
|
+
return policyByAttribute[attribute];
|
|
2292
2396
|
}
|
|
2293
|
-
var TEXT_INPUT_TYPES = ["text", "search", "url", "tel", "email", "password"];
|
|
2294
|
-
var NUMERIC_INPUT_TYPES = [
|
|
2295
|
-
"number",
|
|
2296
|
-
"range",
|
|
2297
|
-
"date",
|
|
2298
|
-
"month",
|
|
2299
|
-
"week",
|
|
2300
|
-
"time",
|
|
2301
|
-
"datetime-local"
|
|
2302
|
-
];
|
|
2303
|
-
var HTML_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
2304
|
-
...TEXT_INPUT_TYPES,
|
|
2305
|
-
...NUMERIC_INPUT_TYPES,
|
|
2306
|
-
"checkbox",
|
|
2307
|
-
"radio",
|
|
2308
|
-
"file",
|
|
2309
|
-
"color",
|
|
2310
|
-
"hidden",
|
|
2311
|
-
"button",
|
|
2312
|
-
"submit",
|
|
2313
|
-
"reset",
|
|
2314
|
-
"image"
|
|
2315
|
-
]);
|
|
2316
2397
|
var supportedInputTypeRule = Object.assign(
|
|
2317
2398
|
({ tag, props }) => {
|
|
2318
2399
|
if (tag !== "input" || typeof props.type !== "string") return [];
|
|
@@ -2328,30 +2409,22 @@ var supportedInputTypeRule = Object.assign(
|
|
|
2328
2409
|
}
|
|
2329
2410
|
];
|
|
2330
2411
|
},
|
|
2331
|
-
{ readsProps: ["type"] }
|
|
2412
|
+
{ readsProps: ["type"], tags: ["input"] }
|
|
2332
2413
|
);
|
|
2333
|
-
var checkedRequiresCheckableTypeRule =
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
var
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
var
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
);
|
|
2345
|
-
var
|
|
2346
|
-
|
|
2347
|
-
TEXT_INPUT_TYPES
|
|
2348
|
-
);
|
|
2349
|
-
var patternRequiresTextTypeRule = inputAttributeRequiresType("pattern", TEXT_INPUT_TYPES);
|
|
2350
|
-
var minRequiresNumericTypeRule = inputAttributeRequiresType("min", NUMERIC_INPUT_TYPES);
|
|
2351
|
-
var maxRequiresNumericTypeRule = inputAttributeRequiresType("max", NUMERIC_INPUT_TYPES);
|
|
2352
|
-
var stepRequiresNumericTypeRule = inputAttributeRequiresType("step", NUMERIC_INPUT_TYPES);
|
|
2353
|
-
var acceptRequiresFileTypeRule = inputAttributeRequiresType("accept", ["file"]);
|
|
2354
|
-
var captureRequiresFileTypeRule = inputAttributeRequiresType("capture", ["file"]);
|
|
2414
|
+
var checkedRequiresCheckableTypeRule = createInputAttributeTypeRule(policyFor("checked"));
|
|
2415
|
+
var multipleRequiresSupportedTypeRule = createInputAttributeTypeRule(policyFor("multiple"));
|
|
2416
|
+
var maxLengthRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("maxLength"));
|
|
2417
|
+
var minLengthRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("minLength"));
|
|
2418
|
+
var patternRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("pattern"));
|
|
2419
|
+
var minRequiresNumericTypeRule = createInputAttributeTypeRule(policyFor("min"));
|
|
2420
|
+
var maxRequiresNumericTypeRule = createInputAttributeTypeRule(policyFor("max"));
|
|
2421
|
+
var stepRequiresNumericTypeRule = createInputAttributeTypeRule(policyFor("step"));
|
|
2422
|
+
var acceptRequiresFileTypeRule = createInputAttributeTypeRule(policyFor("accept"));
|
|
2423
|
+
var captureRequiresFileTypeRule = createInputAttributeTypeRule(policyFor("capture"));
|
|
2424
|
+
var sizeRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("size"));
|
|
2425
|
+
var altRequiresImageTypeRule = createInputAttributeTypeRule(policyFor("alt"));
|
|
2426
|
+
var heightRequiresImageTypeRule = createInputAttributeTypeRule(policyFor("height"));
|
|
2427
|
+
var widthRequiresImageTypeRule = createInputAttributeTypeRule(policyFor("width"));
|
|
2355
2428
|
var inputAccessibleNameRule = Object.assign(
|
|
2356
2429
|
({ tag, props }) => {
|
|
2357
2430
|
if (tag !== "input" || props.type === "hidden") return [];
|
|
@@ -2360,7 +2433,10 @@ var inputAccessibleNameRule = Object.assign(
|
|
|
2360
2433
|
const diagnostic = hasPlaceholder ? InputAccessibilityDiagnostics.placeholderIsNotLabel() : InputAccessibilityDiagnostics.missingAccessibleName();
|
|
2361
2434
|
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2362
2435
|
},
|
|
2363
|
-
{
|
|
2436
|
+
{
|
|
2437
|
+
readsProps: ["type", "aria-label", "aria-labelledby", "placeholder"],
|
|
2438
|
+
tags: ["input"]
|
|
2439
|
+
}
|
|
2364
2440
|
);
|
|
2365
2441
|
var PASSWORD_AUTOCOMPLETE_VALUES = ["current-password", "new-password"];
|
|
2366
2442
|
var passwordAutocompleteRule = Object.assign(
|
|
@@ -2372,16 +2448,9 @@ var passwordAutocompleteRule = Object.assign(
|
|
|
2372
2448
|
const diagnostic = InputAccessibilityDiagnostics.passwordMissingAutocomplete();
|
|
2373
2449
|
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2374
2450
|
},
|
|
2375
|
-
{ readsProps: ["type", "autoComplete"] }
|
|
2376
|
-
);
|
|
2377
|
-
var requiredReadOnlyConflictRule = Object.assign(
|
|
2378
|
-
({ tag, props }) => {
|
|
2379
|
-
if (tag !== "input" || !props.required || !props.readOnly) return [];
|
|
2380
|
-
const diagnostic = InputAccessibilityDiagnostics.requiredReadOnlyConflict();
|
|
2381
|
-
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2382
|
-
},
|
|
2383
|
-
{ readsProps: ["required", "readOnly"] }
|
|
2451
|
+
{ readsProps: ["type", "autoComplete"], tags: ["input"] }
|
|
2384
2452
|
);
|
|
2453
|
+
var requiredReadOnlyConflictRule = createMutuallyExclusiveRule(REQUIRED_READONLY_CONFLICT);
|
|
2385
2454
|
var INPUT_RULES = [
|
|
2386
2455
|
supportedInputTypeRule,
|
|
2387
2456
|
checkedRequiresCheckableTypeRule,
|
|
@@ -2394,11 +2463,132 @@ var INPUT_RULES = [
|
|
|
2394
2463
|
stepRequiresNumericTypeRule,
|
|
2395
2464
|
acceptRequiresFileTypeRule,
|
|
2396
2465
|
captureRequiresFileTypeRule,
|
|
2466
|
+
sizeRequiresTextTypeRule,
|
|
2467
|
+
altRequiresImageTypeRule,
|
|
2468
|
+
heightRequiresImageTypeRule,
|
|
2469
|
+
widthRequiresImageTypeRule,
|
|
2397
2470
|
inputAccessibleNameRule,
|
|
2398
2471
|
passwordAutocompleteRule,
|
|
2399
2472
|
requiredReadOnlyConflictRule
|
|
2400
2473
|
];
|
|
2401
2474
|
|
|
2475
|
+
// ../core/src/html/spec/types.ts
|
|
2476
|
+
function definePropRolePolicy(prop, map2, fallback) {
|
|
2477
|
+
return { kind: "byProp", prop, map: map2, fallback };
|
|
2478
|
+
}
|
|
2479
|
+
function resolveAllowedRoles(spec, props) {
|
|
2480
|
+
const policy = spec.allowedRoles;
|
|
2481
|
+
if (!policy) return void 0;
|
|
2482
|
+
switch (policy.kind) {
|
|
2483
|
+
case "fixed":
|
|
2484
|
+
return policy.roles;
|
|
2485
|
+
case "byProp": {
|
|
2486
|
+
const value = typeof props[policy.prop] === "string" ? props[policy.prop] : policy.fallback;
|
|
2487
|
+
return policy.map[value];
|
|
2488
|
+
}
|
|
2489
|
+
case "dynamic":
|
|
2490
|
+
return policy.resolve({ props });
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
// ../core/src/html/spec/roles/input.ts
|
|
2495
|
+
var ALLOWED_INPUT_ROLES = {
|
|
2496
|
+
checkbox: ["menuitemcheckbox", "option", "switch", "button"],
|
|
2497
|
+
radio: ["menuitemradio"],
|
|
2498
|
+
range: [],
|
|
2499
|
+
number: [],
|
|
2500
|
+
search: ["combobox"],
|
|
2501
|
+
text: ["combobox", "searchbox", "spinbutton"],
|
|
2502
|
+
email: ["combobox"],
|
|
2503
|
+
tel: ["combobox"],
|
|
2504
|
+
url: ["combobox"],
|
|
2505
|
+
button: [
|
|
2506
|
+
"link",
|
|
2507
|
+
"menuitem",
|
|
2508
|
+
"menuitemcheckbox",
|
|
2509
|
+
"menuitemradio",
|
|
2510
|
+
"option",
|
|
2511
|
+
"radio",
|
|
2512
|
+
"switch",
|
|
2513
|
+
"tab"
|
|
2514
|
+
],
|
|
2515
|
+
submit: [
|
|
2516
|
+
"link",
|
|
2517
|
+
"menuitem",
|
|
2518
|
+
"menuitemcheckbox",
|
|
2519
|
+
"menuitemradio",
|
|
2520
|
+
"option",
|
|
2521
|
+
"radio",
|
|
2522
|
+
"switch",
|
|
2523
|
+
"tab"
|
|
2524
|
+
],
|
|
2525
|
+
reset: [
|
|
2526
|
+
"link",
|
|
2527
|
+
"menuitem",
|
|
2528
|
+
"menuitemcheckbox",
|
|
2529
|
+
"menuitemradio",
|
|
2530
|
+
"option",
|
|
2531
|
+
"radio",
|
|
2532
|
+
"switch",
|
|
2533
|
+
"tab"
|
|
2534
|
+
],
|
|
2535
|
+
image: [
|
|
2536
|
+
"link",
|
|
2537
|
+
"menuitem",
|
|
2538
|
+
"menuitemcheckbox",
|
|
2539
|
+
"menuitemradio",
|
|
2540
|
+
"option",
|
|
2541
|
+
"radio",
|
|
2542
|
+
"switch",
|
|
2543
|
+
"tab"
|
|
2544
|
+
],
|
|
2545
|
+
hidden: []
|
|
2546
|
+
};
|
|
2547
|
+
|
|
2548
|
+
// ../core/src/html/spec/elements/input.ts
|
|
2549
|
+
var inputElementSpec = {
|
|
2550
|
+
tag: "input",
|
|
2551
|
+
allowedRoles: definePropRolePolicy("type", ALLOWED_INPUT_ROLES, "text"),
|
|
2552
|
+
attributes: INPUT_ATTRIBUTE_TYPE_POLICIES,
|
|
2553
|
+
mutuallyExclusive: INPUT_MUTUALLY_EXCLUSIVE_POLICIES
|
|
2554
|
+
};
|
|
2555
|
+
|
|
2556
|
+
// ../core/src/html/spec/roles/img.ts
|
|
2557
|
+
var IMG_NAMED_ROLES = [
|
|
2558
|
+
"button",
|
|
2559
|
+
"checkbox",
|
|
2560
|
+
"link",
|
|
2561
|
+
"menuitem",
|
|
2562
|
+
"menuitemcheckbox",
|
|
2563
|
+
"menuitemradio",
|
|
2564
|
+
"option",
|
|
2565
|
+
"progressbar",
|
|
2566
|
+
"scrollbar",
|
|
2567
|
+
"separator",
|
|
2568
|
+
"slider",
|
|
2569
|
+
"switch",
|
|
2570
|
+
"tab",
|
|
2571
|
+
"treeitem"
|
|
2572
|
+
];
|
|
2573
|
+
|
|
2574
|
+
// ../core/src/html/spec/elements/img.ts
|
|
2575
|
+
var imgElementSpec = {
|
|
2576
|
+
tag: "img",
|
|
2577
|
+
allowedRoles: {
|
|
2578
|
+
kind: "dynamic",
|
|
2579
|
+
resolve: ({ props }) => props.alt === "" ? [] : IMG_NAMED_ROLES
|
|
2580
|
+
}
|
|
2581
|
+
};
|
|
2582
|
+
|
|
2583
|
+
// ../core/src/html/spec/roles/table.ts
|
|
2584
|
+
var ALLOWED_TABLE_ROLES = ["grid", "treegrid"];
|
|
2585
|
+
|
|
2586
|
+
// ../core/src/html/spec/elements/table.ts
|
|
2587
|
+
var tableElementSpec = {
|
|
2588
|
+
tag: "table",
|
|
2589
|
+
allowedRoles: { kind: "fixed", roles: ALLOWED_TABLE_ROLES }
|
|
2590
|
+
};
|
|
2591
|
+
|
|
2402
2592
|
// ../core/src/html/role-restrictions.ts
|
|
2403
2593
|
var ALLOWED_ROLES = {
|
|
2404
2594
|
article: ["application", "document", "feed", "main", "none", "presentation", "region"],
|
|
@@ -2471,86 +2661,17 @@ var ALLOWED_ROLES = {
|
|
|
2471
2661
|
"tab",
|
|
2472
2662
|
"treeitem"
|
|
2473
2663
|
],
|
|
2474
|
-
table: ["grid", "treegrid"],
|
|
2475
2664
|
dialog: ["alertdialog"],
|
|
2476
2665
|
fieldset: ["none", "presentation", "radiogroup"]
|
|
2477
2666
|
};
|
|
2478
|
-
var
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
"menuitem",
|
|
2483
|
-
"menuitemcheckbox",
|
|
2484
|
-
"menuitemradio",
|
|
2485
|
-
"option",
|
|
2486
|
-
"progressbar",
|
|
2487
|
-
"scrollbar",
|
|
2488
|
-
"separator",
|
|
2489
|
-
"slider",
|
|
2490
|
-
"switch",
|
|
2491
|
-
"tab",
|
|
2492
|
-
"treeitem"
|
|
2493
|
-
];
|
|
2494
|
-
var ALLOWED_INPUT_ROLES = {
|
|
2495
|
-
checkbox: ["menuitemcheckbox", "option", "switch", "button"],
|
|
2496
|
-
radio: ["menuitemradio"],
|
|
2497
|
-
range: [],
|
|
2498
|
-
number: [],
|
|
2499
|
-
search: ["combobox"],
|
|
2500
|
-
text: ["combobox", "searchbox", "spinbutton"],
|
|
2501
|
-
email: ["combobox"],
|
|
2502
|
-
tel: ["combobox"],
|
|
2503
|
-
url: ["combobox"],
|
|
2504
|
-
button: [
|
|
2505
|
-
"link",
|
|
2506
|
-
"menuitem",
|
|
2507
|
-
"menuitemcheckbox",
|
|
2508
|
-
"menuitemradio",
|
|
2509
|
-
"option",
|
|
2510
|
-
"radio",
|
|
2511
|
-
"switch",
|
|
2512
|
-
"tab"
|
|
2513
|
-
],
|
|
2514
|
-
submit: [
|
|
2515
|
-
"link",
|
|
2516
|
-
"menuitem",
|
|
2517
|
-
"menuitemcheckbox",
|
|
2518
|
-
"menuitemradio",
|
|
2519
|
-
"option",
|
|
2520
|
-
"radio",
|
|
2521
|
-
"switch",
|
|
2522
|
-
"tab"
|
|
2523
|
-
],
|
|
2524
|
-
reset: [
|
|
2525
|
-
"link",
|
|
2526
|
-
"menuitem",
|
|
2527
|
-
"menuitemcheckbox",
|
|
2528
|
-
"menuitemradio",
|
|
2529
|
-
"option",
|
|
2530
|
-
"radio",
|
|
2531
|
-
"switch",
|
|
2532
|
-
"tab"
|
|
2533
|
-
],
|
|
2534
|
-
image: [
|
|
2535
|
-
"link",
|
|
2536
|
-
"menuitem",
|
|
2537
|
-
"menuitemcheckbox",
|
|
2538
|
-
"menuitemradio",
|
|
2539
|
-
"option",
|
|
2540
|
-
"radio",
|
|
2541
|
-
"switch",
|
|
2542
|
-
"tab"
|
|
2543
|
-
],
|
|
2544
|
-
hidden: []
|
|
2667
|
+
var ELEMENT_SPECS = {
|
|
2668
|
+
input: inputElementSpec,
|
|
2669
|
+
img: imgElementSpec,
|
|
2670
|
+
table: tableElementSpec
|
|
2545
2671
|
};
|
|
2546
2672
|
function getAllowedRoles(tag, props) {
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
return ALLOWED_INPUT_ROLES[type];
|
|
2550
|
-
}
|
|
2551
|
-
if (tag === "img") {
|
|
2552
|
-
return props.alt === "" ? [] : IMG_NAMED_ROLES;
|
|
2553
|
-
}
|
|
2673
|
+
const spec = ELEMENT_SPECS[tag];
|
|
2674
|
+
if (spec) return resolveAllowedRoles(spec, props);
|
|
2554
2675
|
return ALLOWED_ROLES[tag];
|
|
2555
2676
|
}
|
|
2556
2677
|
var removeRoleFix = {
|
|
@@ -2591,21 +2712,24 @@ var removeLandmarkRoleOverride = {
|
|
|
2591
2712
|
return { applied: true, next: rest, previous: props };
|
|
2592
2713
|
}
|
|
2593
2714
|
};
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2715
|
+
var landmarkRoleRule = Object.assign(
|
|
2716
|
+
({ tag, props, implicitRole }) => {
|
|
2717
|
+
if (!LANDMARK_TAG_SET.has(tag) || !implicitRole) return [];
|
|
2718
|
+
const role = props.role;
|
|
2719
|
+
if (!role || role === implicitRole) return [];
|
|
2720
|
+
const diagnostic = HtmlDiagnostics.landmarkRoleOverride(tag, implicitRole, role);
|
|
2721
|
+
return [
|
|
2722
|
+
{
|
|
2723
|
+
valid: false,
|
|
2724
|
+
fixable: true,
|
|
2725
|
+
severity: diagnostic.severity,
|
|
2726
|
+
fix: removeLandmarkRoleOverride,
|
|
2727
|
+
diagnostic
|
|
2728
|
+
}
|
|
2729
|
+
];
|
|
2730
|
+
},
|
|
2731
|
+
{ tags: [...LANDMARK_TAG_SET] }
|
|
2732
|
+
);
|
|
2609
2733
|
function requireAccessibleName({ tag, props }) {
|
|
2610
2734
|
if ("aria-label" in props || "aria-labelledby" in props) return [];
|
|
2611
2735
|
return [
|
|
@@ -2618,10 +2742,13 @@ function requireAccessibleName({ tag, props }) {
|
|
|
2618
2742
|
];
|
|
2619
2743
|
}
|
|
2620
2744
|
var NAMED_LANDMARK_TAGS = /* @__PURE__ */ new Set(["nav", "aside"]);
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2745
|
+
var landmarkNameAdvisory = Object.assign(
|
|
2746
|
+
(ctx) => {
|
|
2747
|
+
if (!ctx.implicitRole || !NAMED_LANDMARK_TAGS.has(ctx.tag)) return [];
|
|
2748
|
+
return requireAccessibleName(ctx);
|
|
2749
|
+
},
|
|
2750
|
+
{ tags: [...NAMED_LANDMARK_TAGS] }
|
|
2751
|
+
);
|
|
2625
2752
|
var HTML_ARIA_RULES = [
|
|
2626
2753
|
landmarkRoleRule,
|
|
2627
2754
|
landmarkNameAdvisory,
|
|
@@ -2722,6 +2849,62 @@ var figureContract = contract([
|
|
|
2722
2849
|
]);
|
|
2723
2850
|
var detailsContract = firstChildContract("summary", "summary");
|
|
2724
2851
|
var fieldsetContract = firstChildContract("legend", "legend");
|
|
2852
|
+
var objectContract = contract([
|
|
2853
|
+
{ name: "param", match: isTag("param") },
|
|
2854
|
+
{ name: "content", match: isOpenContent("param") }
|
|
2855
|
+
]);
|
|
2856
|
+
var INTERACTIVE_CONTENT_TAGS = ["a", "button", "input", "select", "textarea", "label"];
|
|
2857
|
+
var buttonContract = closedContract([
|
|
2858
|
+
{ name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
|
|
2859
|
+
]);
|
|
2860
|
+
var anchorContract = closedContract([
|
|
2861
|
+
{ name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
|
|
2862
|
+
]);
|
|
2863
|
+
var LABELABLE_TAGS = [
|
|
2864
|
+
"button",
|
|
2865
|
+
"input",
|
|
2866
|
+
"meter",
|
|
2867
|
+
"output",
|
|
2868
|
+
"progress",
|
|
2869
|
+
"select",
|
|
2870
|
+
"textarea"
|
|
2871
|
+
];
|
|
2872
|
+
var labelContract = contract([
|
|
2873
|
+
{ name: "control", match: isTag(...LABELABLE_TAGS), cardinality: { max: 1 } }
|
|
2874
|
+
]);
|
|
2875
|
+
var P_BLOCKED_TAGS = [
|
|
2876
|
+
"address",
|
|
2877
|
+
"article",
|
|
2878
|
+
"aside",
|
|
2879
|
+
"blockquote",
|
|
2880
|
+
"details",
|
|
2881
|
+
"dialog",
|
|
2882
|
+
"div",
|
|
2883
|
+
"dl",
|
|
2884
|
+
"fieldset",
|
|
2885
|
+
"figure",
|
|
2886
|
+
"footer",
|
|
2887
|
+
"form",
|
|
2888
|
+
"h1",
|
|
2889
|
+
"h2",
|
|
2890
|
+
"h3",
|
|
2891
|
+
"h4",
|
|
2892
|
+
"h5",
|
|
2893
|
+
"h6",
|
|
2894
|
+
"header",
|
|
2895
|
+
"hr",
|
|
2896
|
+
"main",
|
|
2897
|
+
"nav",
|
|
2898
|
+
"ol",
|
|
2899
|
+
"p",
|
|
2900
|
+
"pre",
|
|
2901
|
+
"section",
|
|
2902
|
+
"table",
|
|
2903
|
+
"ul"
|
|
2904
|
+
];
|
|
2905
|
+
var pContract = closedContract([
|
|
2906
|
+
{ name: "content", match: isOpenContent(...P_BLOCKED_TAGS) }
|
|
2907
|
+
]);
|
|
2725
2908
|
var mediaContract = contract([
|
|
2726
2909
|
{ name: "source", match: isTag("source") },
|
|
2727
2910
|
{ name: "track", match: isTag("track") },
|
|
@@ -2776,6 +2959,11 @@ var htmlContracts = {
|
|
|
2776
2959
|
details: detailsContract,
|
|
2777
2960
|
fieldset: fieldsetContract,
|
|
2778
2961
|
dialog: dialogContract,
|
|
2962
|
+
object: objectContract,
|
|
2963
|
+
button: buttonContract,
|
|
2964
|
+
a: anchorContract,
|
|
2965
|
+
label: labelContract,
|
|
2966
|
+
p: pContract,
|
|
2779
2967
|
head: headContract,
|
|
2780
2968
|
html: htmlContract
|
|
2781
2969
|
};
|
|
@@ -3002,6 +3190,11 @@ function composeNormalizers(normalizers, fn) {
|
|
|
3002
3190
|
function whenDefined(key, value) {
|
|
3003
3191
|
return value === void 0 ? {} : { [key]: value };
|
|
3004
3192
|
}
|
|
3193
|
+
function mergeAriaRules(aria, rules) {
|
|
3194
|
+
if (!aria?.length) return rules;
|
|
3195
|
+
if (!rules?.length) return aria;
|
|
3196
|
+
return [...aria, ...rules];
|
|
3197
|
+
}
|
|
3005
3198
|
function resolveFactoryOptions(options = {}) {
|
|
3006
3199
|
const { styling, enforcement } = options;
|
|
3007
3200
|
const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
|
|
@@ -3022,7 +3215,7 @@ function resolveFactoryOptions(options = {}) {
|
|
|
3022
3215
|
...whenDefined("defaultVariants", styling?.defaults),
|
|
3023
3216
|
...whenDefined("compoundVariants", styling?.compounds),
|
|
3024
3217
|
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
3025
|
-
...whenDefined("ariaRules", enforcement?.aria),
|
|
3218
|
+
...whenDefined("ariaRules", mergeAriaRules(enforcement?.aria, enforcement?.rules)),
|
|
3026
3219
|
...whenDefined("childRules", enforcement?.children),
|
|
3027
3220
|
...whenDefined("exclusiveChildren", enforcement?.exclusiveChildren),
|
|
3028
3221
|
...whenDefined("allowText", enforcement?.allowText),
|