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