praxis-kit 6.5.0 → 6.6.1
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/{chunk-AM5J6PY3.js → chunk-6JILZ6GQ.js} +254 -154
- package/dist/contract/index.d.ts +11 -1
- 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 +878 -0
- package/dist/lit/index.d.ts +10 -0
- package/dist/lit/index.js +254 -154
- package/dist/preact/index.d.ts +19 -0
- package/dist/preact/index.js +254 -154
- 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-DoFNqNdY.d.ts → react-options-BUBVohU6.d.ts} +49 -33
- package/dist/solid/index.d.ts +19 -0
- package/dist/solid/index.js +254 -154
- package/dist/svelte/index.d.ts +10 -0
- package/dist/svelte/index.js +254 -154
- package/dist/vue/index.d.ts +10 -0
- package/dist/vue/index.js +254 -154
- package/dist/web/index.d.ts +10 -0
- package/dist/web/index.js +254 -154
- package/package.json +10 -3
|
@@ -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"]);
|
|
@@ -1409,7 +1421,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1409
1421
|
if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
|
|
1410
1422
|
const implicitRole = getImplicitRole(tag, props);
|
|
1411
1423
|
const hasRole2 = isNonNull(implicitRole) || isString(props.role) && props.role.length > 0;
|
|
1412
|
-
if (!hasRole2) return { proceed: false, result: { props, violations: [] } };
|
|
1413
1424
|
const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
|
|
1414
1425
|
const workingProps = normalized.normalized ? normalized.result.props : props;
|
|
1415
1426
|
const preExistingViolations = normalized.normalized ? normalized.result.violations : [];
|
|
@@ -1419,6 +1430,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1419
1430
|
tag,
|
|
1420
1431
|
implicitRole,
|
|
1421
1432
|
effectiveRole,
|
|
1433
|
+
hasRole: hasRole2,
|
|
1422
1434
|
props: workingProps,
|
|
1423
1435
|
preExistingViolations,
|
|
1424
1436
|
context: { tag, props: workingProps, implicitRole, effectiveRole }
|
|
@@ -1462,6 +1474,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1462
1474
|
static evaluate(tag, props) {
|
|
1463
1475
|
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
1464
1476
|
if (!derived.proceed) return derived.result;
|
|
1477
|
+
if (!derived.hasRole)
|
|
1478
|
+
return { props: derived.props, violations: [...derived.preExistingViolations] };
|
|
1465
1479
|
const {
|
|
1466
1480
|
tag: narrowedTag,
|
|
1467
1481
|
implicitRole,
|
|
@@ -1486,10 +1500,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1486
1500
|
props: workingProps,
|
|
1487
1501
|
preExistingViolations
|
|
1488
1502
|
} = derived;
|
|
1489
|
-
const
|
|
1490
|
-
|
|
1491
|
-
context
|
|
1492
|
-
);
|
|
1503
|
+
const rules = derived.hasRole ? [..._AriaPolicyEngine.#getRules(context), ...extraRules] : extraRules;
|
|
1504
|
+
const { violations, fixes } = _AriaPolicyEngine.#runRules(rules, context);
|
|
1493
1505
|
const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
|
|
1494
1506
|
return { props: next, violations: [...preExistingViolations, ...violations] };
|
|
1495
1507
|
}
|
|
@@ -1688,7 +1700,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1688
1700
|
static #checkStandaloneRegion({ tag, props, implicitRole }) {
|
|
1689
1701
|
const role = props.role;
|
|
1690
1702
|
if (role !== "region") return NO_VIOLATIONS2;
|
|
1691
|
-
if (!
|
|
1703
|
+
if (!hasStandaloneRole(tag)) return NO_VIOLATIONS2;
|
|
1692
1704
|
const diagnostic = HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag);
|
|
1693
1705
|
return [
|
|
1694
1706
|
{
|
|
@@ -2271,6 +2283,93 @@ var readonlyProps = ({
|
|
|
2271
2283
|
// ../core/src/html/evaluators.ts
|
|
2272
2284
|
import { warnDiagnostics as warnDiagnostics2 } from "./_shared/diagnostics.js";
|
|
2273
2285
|
|
|
2286
|
+
// ../core/src/html/contracts/categories.ts
|
|
2287
|
+
var METADATA_TAGS = ["script", "template"];
|
|
2288
|
+
var VOID_TAGS = [
|
|
2289
|
+
"area",
|
|
2290
|
+
"base",
|
|
2291
|
+
"br",
|
|
2292
|
+
"col",
|
|
2293
|
+
"embed",
|
|
2294
|
+
"hr",
|
|
2295
|
+
"img",
|
|
2296
|
+
"input",
|
|
2297
|
+
"link",
|
|
2298
|
+
"meta",
|
|
2299
|
+
"param",
|
|
2300
|
+
"source",
|
|
2301
|
+
"track",
|
|
2302
|
+
"wbr"
|
|
2303
|
+
];
|
|
2304
|
+
var TEXT_ONLY_TAGS = [
|
|
2305
|
+
"option",
|
|
2306
|
+
"script",
|
|
2307
|
+
"style",
|
|
2308
|
+
"textarea",
|
|
2309
|
+
"title"
|
|
2310
|
+
];
|
|
2311
|
+
var LANDMARK_TAGS = [
|
|
2312
|
+
"article",
|
|
2313
|
+
"aside",
|
|
2314
|
+
"footer",
|
|
2315
|
+
"header",
|
|
2316
|
+
"main",
|
|
2317
|
+
"nav"
|
|
2318
|
+
];
|
|
2319
|
+
var INTERACTIVE_CONTENT_TAGS = [
|
|
2320
|
+
"a",
|
|
2321
|
+
"button",
|
|
2322
|
+
"input",
|
|
2323
|
+
"select",
|
|
2324
|
+
"textarea",
|
|
2325
|
+
"label"
|
|
2326
|
+
];
|
|
2327
|
+
var LABELABLE_TAGS = [
|
|
2328
|
+
"button",
|
|
2329
|
+
"input",
|
|
2330
|
+
"meter",
|
|
2331
|
+
"output",
|
|
2332
|
+
"progress",
|
|
2333
|
+
"select",
|
|
2334
|
+
"textarea"
|
|
2335
|
+
];
|
|
2336
|
+
var OTHER_INTERACTIVE_TAGS = [
|
|
2337
|
+
"a",
|
|
2338
|
+
"details",
|
|
2339
|
+
"embed",
|
|
2340
|
+
"iframe"
|
|
2341
|
+
];
|
|
2342
|
+
var P_BLOCKED_TAGS = [
|
|
2343
|
+
"address",
|
|
2344
|
+
"article",
|
|
2345
|
+
"aside",
|
|
2346
|
+
"blockquote",
|
|
2347
|
+
"details",
|
|
2348
|
+
"dialog",
|
|
2349
|
+
"div",
|
|
2350
|
+
"dl",
|
|
2351
|
+
"fieldset",
|
|
2352
|
+
"figure",
|
|
2353
|
+
"footer",
|
|
2354
|
+
"form",
|
|
2355
|
+
"h1",
|
|
2356
|
+
"h2",
|
|
2357
|
+
"h3",
|
|
2358
|
+
"h4",
|
|
2359
|
+
"h5",
|
|
2360
|
+
"h6",
|
|
2361
|
+
"header",
|
|
2362
|
+
"hr",
|
|
2363
|
+
"main",
|
|
2364
|
+
"nav",
|
|
2365
|
+
"ol",
|
|
2366
|
+
"p",
|
|
2367
|
+
"pre",
|
|
2368
|
+
"section",
|
|
2369
|
+
"table",
|
|
2370
|
+
"ul"
|
|
2371
|
+
];
|
|
2372
|
+
|
|
2274
2373
|
// ../core/src/html/spec/vocabulary/input.ts
|
|
2275
2374
|
var TEXT_INPUT_TYPES = ["text", "search", "url", "tel", "email", "password"];
|
|
2276
2375
|
var NUMERIC_INPUT_TYPES = [
|
|
@@ -2650,7 +2749,11 @@ var ALLOWED_ROLES = {
|
|
|
2650
2749
|
"treeitem"
|
|
2651
2750
|
],
|
|
2652
2751
|
dialog: ["alertdialog"],
|
|
2653
|
-
fieldset: ["none", "presentation", "radiogroup"]
|
|
2752
|
+
fieldset: ["none", "presentation", "radiogroup"],
|
|
2753
|
+
// `<label>` has no implicit role and no documented alternates — its native labeling
|
|
2754
|
+
// semantics (control association, accessible-name contribution) aren't reproducible via
|
|
2755
|
+
// ARIA, so any explicit `role` should be avoided rather than substituted.
|
|
2756
|
+
label: []
|
|
2654
2757
|
};
|
|
2655
2758
|
var ELEMENT_SPECS = {
|
|
2656
2759
|
input: inputElementSpec,
|
|
@@ -2691,7 +2794,10 @@ var roleNotPermittedRule = Object.assign(
|
|
|
2691
2794
|
);
|
|
2692
2795
|
|
|
2693
2796
|
// ../core/src/html/aria-rules.ts
|
|
2694
|
-
|
|
2797
|
+
function defineAriaRule(tags, rule) {
|
|
2798
|
+
return Object.assign(rule, { tags });
|
|
2799
|
+
}
|
|
2800
|
+
var LANDMARK_TAG_SET = new Set(LANDMARK_TAGS);
|
|
2695
2801
|
var removeLandmarkRoleOverride = {
|
|
2696
2802
|
kind: "removeRole",
|
|
2697
2803
|
apply: ({ props }) => {
|
|
@@ -2700,10 +2806,11 @@ var removeLandmarkRoleOverride = {
|
|
|
2700
2806
|
return { applied: true, next: rest, previous: props };
|
|
2701
2807
|
}
|
|
2702
2808
|
};
|
|
2703
|
-
var landmarkRoleRule =
|
|
2809
|
+
var landmarkRoleRule = defineAriaRule(
|
|
2810
|
+
LANDMARK_TAGS,
|
|
2704
2811
|
({ tag, props, implicitRole }) => {
|
|
2705
2812
|
if (!LANDMARK_TAG_SET.has(tag) || !implicitRole) return [];
|
|
2706
|
-
const role = props
|
|
2813
|
+
const { role } = props;
|
|
2707
2814
|
if (!role || role === implicitRole) return [];
|
|
2708
2815
|
const diagnostic = HtmlDiagnostics.landmarkRoleOverride(tag, implicitRole, role);
|
|
2709
2816
|
return [
|
|
@@ -2715,8 +2822,7 @@ var landmarkRoleRule = Object.assign(
|
|
|
2715
2822
|
diagnostic
|
|
2716
2823
|
}
|
|
2717
2824
|
];
|
|
2718
|
-
}
|
|
2719
|
-
{ tags: [...LANDMARK_TAG_SET] }
|
|
2825
|
+
}
|
|
2720
2826
|
);
|
|
2721
2827
|
function requireAccessibleName({ tag, props }) {
|
|
2722
2828
|
if ("aria-label" in props || "aria-labelledby" in props) return [];
|
|
@@ -2729,38 +2835,44 @@ function requireAccessibleName({ tag, props }) {
|
|
|
2729
2835
|
}
|
|
2730
2836
|
];
|
|
2731
2837
|
}
|
|
2732
|
-
var NAMED_LANDMARK_TAGS =
|
|
2733
|
-
var
|
|
2838
|
+
var NAMED_LANDMARK_TAGS = ["nav", "aside"];
|
|
2839
|
+
var NAMED_LANDMARK_TAG_SET = new Set(NAMED_LANDMARK_TAGS);
|
|
2840
|
+
var landmarkAccessibleNameRule = defineAriaRule(
|
|
2841
|
+
NAMED_LANDMARK_TAGS,
|
|
2734
2842
|
(ctx) => {
|
|
2735
|
-
if (!ctx.implicitRole || !
|
|
2843
|
+
if (!ctx.implicitRole || !NAMED_LANDMARK_TAG_SET.has(ctx.tag)) return [];
|
|
2736
2844
|
return requireAccessibleName(ctx);
|
|
2737
|
-
}
|
|
2738
|
-
{ tags: [...NAMED_LANDMARK_TAGS] }
|
|
2845
|
+
}
|
|
2739
2846
|
);
|
|
2740
2847
|
var HTML_ARIA_RULES = [
|
|
2741
2848
|
landmarkRoleRule,
|
|
2742
|
-
|
|
2849
|
+
landmarkAccessibleNameRule,
|
|
2743
2850
|
roleNotPermittedRule,
|
|
2744
2851
|
...INPUT_RULES
|
|
2745
2852
|
];
|
|
2746
2853
|
|
|
2747
|
-
// ../core/src/html/contracts.ts
|
|
2854
|
+
// ../core/src/html/contracts/helpers.ts
|
|
2748
2855
|
import { warnDiagnostics } from "./_shared/diagnostics.js";
|
|
2856
|
+
function isVNodeLike(child) {
|
|
2857
|
+
return isObject(child) && "type" in child;
|
|
2858
|
+
}
|
|
2749
2859
|
function isOpenContent(...blockedTags) {
|
|
2750
2860
|
const set2 = new Set(blockedTags);
|
|
2751
2861
|
return (child) => {
|
|
2752
|
-
if (!
|
|
2862
|
+
if (!isVNodeLike(child)) return false;
|
|
2753
2863
|
const tag = getTag(child);
|
|
2754
2864
|
return tag === void 0 || !set2.has(tag);
|
|
2755
2865
|
};
|
|
2756
2866
|
}
|
|
2757
|
-
var METADATA_TAGS = ["script", "template"];
|
|
2758
2867
|
var metadataMatch = isTag(...METADATA_TAGS);
|
|
2759
2868
|
function metadata(name = "metadata") {
|
|
2760
2869
|
return { name, match: metadataMatch };
|
|
2761
2870
|
}
|
|
2871
|
+
function optional(name, tag) {
|
|
2872
|
+
return { name, match: isTag(tag), cardinality: { max: 1 } };
|
|
2873
|
+
}
|
|
2762
2874
|
function firstOptional(name, tag) {
|
|
2763
|
-
return { name,
|
|
2875
|
+
return { ...optional(name, tag), position: "first" };
|
|
2764
2876
|
}
|
|
2765
2877
|
function contract(children, options) {
|
|
2766
2878
|
return { diagnostics: warnDiagnostics, children, ...options };
|
|
@@ -2774,50 +2886,41 @@ function ariaContract(aria) {
|
|
|
2774
2886
|
function firstChildContract(name, tag) {
|
|
2775
2887
|
return contract([firstOptional(name, tag), { name: "content", match: isOpenContent(tag) }]);
|
|
2776
2888
|
}
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
];
|
|
2793
|
-
var
|
|
2794
|
-
var
|
|
2795
|
-
var
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
var
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
{ name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
|
|
2804
|
-
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
2805
|
-
]);
|
|
2806
|
-
var tableBodyContract = closedContract([
|
|
2807
|
-
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
2808
|
-
]);
|
|
2809
|
-
var tableRowContract = closedContract([
|
|
2810
|
-
{ name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
|
|
2811
|
-
]);
|
|
2812
|
-
var colgroupContract = closedContract([
|
|
2813
|
-
{ name: "column", match: isTag("col", "template") }
|
|
2889
|
+
function getChildProp(child, key) {
|
|
2890
|
+
if (!isVNodeLike(child)) return void 0;
|
|
2891
|
+
const { props } = child;
|
|
2892
|
+
if (!isObject(props)) return void 0;
|
|
2893
|
+
return props[key];
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
// ../core/src/html/contracts/aria/landmarks.ts
|
|
2897
|
+
var landmarkContract = ariaContract([landmarkRoleRule, landmarkAccessibleNameRule]);
|
|
2898
|
+
|
|
2899
|
+
// ../core/src/html/contracts/aria/widgets.ts
|
|
2900
|
+
var dialogContract = ariaContract([requireAccessibleName]);
|
|
2901
|
+
var menuContract = ariaContract([requireAccessibleName]);
|
|
2902
|
+
var menubarContract = ariaContract([requireAccessibleName]);
|
|
2903
|
+
var treeContract = ariaContract([requireAccessibleName]);
|
|
2904
|
+
var gridContract = ariaContract([requireAccessibleName]);
|
|
2905
|
+
var listboxContract = ariaContract([requireAccessibleName]);
|
|
2906
|
+
var tablistContract = ariaContract([requireAccessibleName]);
|
|
2907
|
+
var radiogroupContract = ariaContract([requireAccessibleName]);
|
|
2908
|
+
|
|
2909
|
+
// ../core/src/html/contracts/html/document.ts
|
|
2910
|
+
var headContract = closedContract([
|
|
2911
|
+
{
|
|
2912
|
+
name: "metadata",
|
|
2913
|
+
match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
|
|
2914
|
+
}
|
|
2814
2915
|
]);
|
|
2815
|
-
var
|
|
2816
|
-
{ name: "
|
|
2817
|
-
{ name: "
|
|
2818
|
-
{ name: "group", match: isTag("div") },
|
|
2819
|
-
metadata()
|
|
2916
|
+
var htmlContract = closedContract([
|
|
2917
|
+
{ name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
|
|
2918
|
+
{ name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
|
|
2820
2919
|
]);
|
|
2920
|
+
var voidContract = contract([], { exclusiveChildren: true, allowText: false });
|
|
2921
|
+
var textOnlyContract = contract([], { exclusiveChildren: true });
|
|
2922
|
+
|
|
2923
|
+
// ../core/src/html/contracts/html/forms.ts
|
|
2821
2924
|
var selectContract = closedContract([
|
|
2822
2925
|
{ name: "option", match: isTag("option", "optgroup", "hr", ...METADATA_TAGS) }
|
|
2823
2926
|
]);
|
|
@@ -2827,6 +2930,45 @@ var optgroupContract = closedContract([
|
|
|
2827
2930
|
var datalistContract = closedContract([
|
|
2828
2931
|
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
2829
2932
|
]);
|
|
2933
|
+
var buttonContract = closedContract([
|
|
2934
|
+
{ name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
|
|
2935
|
+
]);
|
|
2936
|
+
var anchorContract = closedContract([
|
|
2937
|
+
{ name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
|
|
2938
|
+
]);
|
|
2939
|
+
var labelableTagMatch = isTag(...LABELABLE_TAGS);
|
|
2940
|
+
function isLabelableControl(child) {
|
|
2941
|
+
if (!labelableTagMatch(child)) return false;
|
|
2942
|
+
if (getTag(child) !== "input") return true;
|
|
2943
|
+
const type = getChildProp(child, "type");
|
|
2944
|
+
return !isString(type) || type !== "hidden";
|
|
2945
|
+
}
|
|
2946
|
+
var labelContract = contract([
|
|
2947
|
+
{ name: "control", match: isLabelableControl, cardinality: { max: 1 } },
|
|
2948
|
+
{ name: "nested-label", match: isTag("label"), cardinality: { max: 0 } },
|
|
2949
|
+
{
|
|
2950
|
+
name: "other-interactive-content",
|
|
2951
|
+
match: isTag(...OTHER_INTERACTIVE_TAGS),
|
|
2952
|
+
cardinality: { max: 0 }
|
|
2953
|
+
}
|
|
2954
|
+
]);
|
|
2955
|
+
|
|
2956
|
+
// ../core/src/html/contracts/html/grouping.ts
|
|
2957
|
+
var detailsContract = firstChildContract("summary", "summary");
|
|
2958
|
+
var fieldsetContract = firstChildContract("legend", "legend");
|
|
2959
|
+
|
|
2960
|
+
// ../core/src/html/contracts/html/lists.ts
|
|
2961
|
+
var listContract = closedContract([
|
|
2962
|
+
{ name: "list-item", match: isTag("li", ...METADATA_TAGS) }
|
|
2963
|
+
]);
|
|
2964
|
+
var dlContract = closedContract([
|
|
2965
|
+
{ name: "term", match: isTag("dt") },
|
|
2966
|
+
{ name: "description", match: isTag("dd") },
|
|
2967
|
+
{ name: "group", match: isTag("div") },
|
|
2968
|
+
metadata()
|
|
2969
|
+
]);
|
|
2970
|
+
|
|
2971
|
+
// ../core/src/html/contracts/html/media.ts
|
|
2830
2972
|
var pictureContract = closedContract([
|
|
2831
2973
|
{ name: "source", match: isTag("source", ...METADATA_TAGS) },
|
|
2832
2974
|
{ name: "image", match: isTag("img"), cardinality: { min: 1, max: 1 }, position: "last" }
|
|
@@ -2835,91 +2977,49 @@ var figureContract = contract([
|
|
|
2835
2977
|
{ name: "caption", match: isTag("figcaption"), cardinality: { max: 1 } },
|
|
2836
2978
|
{ name: "content", match: isOpenContent("figcaption") }
|
|
2837
2979
|
]);
|
|
2838
|
-
var detailsContract = firstChildContract("summary", "summary");
|
|
2839
|
-
var fieldsetContract = firstChildContract("legend", "legend");
|
|
2840
2980
|
var objectContract = contract([
|
|
2841
2981
|
{ name: "param", match: isTag("param") },
|
|
2842
2982
|
{ name: "content", match: isOpenContent("param") }
|
|
2843
2983
|
]);
|
|
2844
|
-
var INTERACTIVE_CONTENT_TAGS = ["a", "button", "input", "select", "textarea", "label"];
|
|
2845
|
-
var buttonContract = closedContract([
|
|
2846
|
-
{ name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
|
|
2847
|
-
]);
|
|
2848
|
-
var anchorContract = closedContract([
|
|
2849
|
-
{ name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
|
|
2850
|
-
]);
|
|
2851
|
-
var LABELABLE_TAGS = [
|
|
2852
|
-
"button",
|
|
2853
|
-
"input",
|
|
2854
|
-
"meter",
|
|
2855
|
-
"output",
|
|
2856
|
-
"progress",
|
|
2857
|
-
"select",
|
|
2858
|
-
"textarea"
|
|
2859
|
-
];
|
|
2860
|
-
var labelContract = contract([
|
|
2861
|
-
{ name: "control", match: isTag(...LABELABLE_TAGS), cardinality: { max: 1 } }
|
|
2862
|
-
]);
|
|
2863
|
-
var P_BLOCKED_TAGS = [
|
|
2864
|
-
"address",
|
|
2865
|
-
"article",
|
|
2866
|
-
"aside",
|
|
2867
|
-
"blockquote",
|
|
2868
|
-
"details",
|
|
2869
|
-
"dialog",
|
|
2870
|
-
"div",
|
|
2871
|
-
"dl",
|
|
2872
|
-
"fieldset",
|
|
2873
|
-
"figure",
|
|
2874
|
-
"footer",
|
|
2875
|
-
"form",
|
|
2876
|
-
"h1",
|
|
2877
|
-
"h2",
|
|
2878
|
-
"h3",
|
|
2879
|
-
"h4",
|
|
2880
|
-
"h5",
|
|
2881
|
-
"h6",
|
|
2882
|
-
"header",
|
|
2883
|
-
"hr",
|
|
2884
|
-
"main",
|
|
2885
|
-
"nav",
|
|
2886
|
-
"ol",
|
|
2887
|
-
"p",
|
|
2888
|
-
"pre",
|
|
2889
|
-
"section",
|
|
2890
|
-
"table",
|
|
2891
|
-
"ul"
|
|
2892
|
-
];
|
|
2893
|
-
var pContract = closedContract([
|
|
2894
|
-
{ name: "content", match: isOpenContent(...P_BLOCKED_TAGS) }
|
|
2895
|
-
]);
|
|
2896
2984
|
var mediaContract = contract([
|
|
2897
2985
|
{ name: "source", match: isTag("source") },
|
|
2898
2986
|
{ name: "track", match: isTag("track") },
|
|
2899
2987
|
metadata(),
|
|
2900
2988
|
{ name: "content", match: isOpenContent("source", "track", ...METADATA_TAGS) }
|
|
2901
2989
|
]);
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
}
|
|
2990
|
+
|
|
2991
|
+
// ../core/src/html/contracts/html/tables.ts
|
|
2992
|
+
var tableContract = closedContract([
|
|
2993
|
+
firstOptional("caption", "caption"),
|
|
2994
|
+
{ name: "colgroup", match: isTag("colgroup") },
|
|
2995
|
+
{ name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
|
|
2996
|
+
{ name: "tbody", match: isTag("tbody") },
|
|
2997
|
+
{ name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
|
|
2998
|
+
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
2907
2999
|
]);
|
|
2908
|
-
var
|
|
2909
|
-
{ name: "
|
|
2910
|
-
{ name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
|
|
3000
|
+
var tableBodyContract = closedContract([
|
|
3001
|
+
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
2911
3002
|
]);
|
|
2912
|
-
var
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
var
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
var
|
|
2921
|
-
|
|
2922
|
-
|
|
3003
|
+
var tableRowContract = closedContract([
|
|
3004
|
+
{ name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
|
|
3005
|
+
]);
|
|
3006
|
+
var colgroupContract = closedContract([
|
|
3007
|
+
{ name: "column", match: isTag("col", "template") }
|
|
3008
|
+
]);
|
|
3009
|
+
|
|
3010
|
+
// ../core/src/html/contracts/html/text.ts
|
|
3011
|
+
var pContract = closedContract([
|
|
3012
|
+
{ name: "content", match: isOpenContent(...P_BLOCKED_TAGS) }
|
|
3013
|
+
]);
|
|
3014
|
+
|
|
3015
|
+
// ../core/src/html/contracts/build-map.ts
|
|
3016
|
+
function buildMap(groups) {
|
|
3017
|
+
return Object.fromEntries(
|
|
3018
|
+
groups.flatMap(([keys2, value]) => keys2.map((key) => [key, value]))
|
|
3019
|
+
);
|
|
3020
|
+
}
|
|
3021
|
+
|
|
3022
|
+
// ../core/src/html/contracts/maps.ts
|
|
2923
3023
|
var CONTRACT_GROUPS = [
|
|
2924
3024
|
[VOID_TAGS, voidContract],
|
|
2925
3025
|
[TEXT_ONLY_TAGS, textOnlyContract],
|
|
@@ -2928,13 +3028,8 @@ var CONTRACT_GROUPS = [
|
|
|
2928
3028
|
[["audio", "video"], mediaContract],
|
|
2929
3029
|
[["thead", "tbody", "tfoot"], tableBodyContract]
|
|
2930
3030
|
];
|
|
2931
|
-
function contractMap(groups) {
|
|
2932
|
-
return Object.fromEntries(
|
|
2933
|
-
groups.flatMap(([tags, enforcement]) => tags.map((tag) => [tag, enforcement]))
|
|
2934
|
-
);
|
|
2935
|
-
}
|
|
2936
3031
|
var htmlContracts = {
|
|
2937
|
-
...
|
|
3032
|
+
...buildMap(CONTRACT_GROUPS),
|
|
2938
3033
|
table: tableContract,
|
|
2939
3034
|
tr: tableRowContract,
|
|
2940
3035
|
colgroup: colgroupContract,
|
|
@@ -3178,6 +3273,11 @@ function composeNormalizers(normalizers, fn) {
|
|
|
3178
3273
|
function whenDefined(key, value) {
|
|
3179
3274
|
return value === void 0 ? {} : { [key]: value };
|
|
3180
3275
|
}
|
|
3276
|
+
function mergeAriaRules(aria, rules) {
|
|
3277
|
+
if (!aria?.length) return rules;
|
|
3278
|
+
if (!rules?.length) return aria;
|
|
3279
|
+
return [...aria, ...rules];
|
|
3280
|
+
}
|
|
3181
3281
|
function resolveFactoryOptions(options = {}) {
|
|
3182
3282
|
const { styling, enforcement } = options;
|
|
3183
3283
|
const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
|
|
@@ -3198,7 +3298,7 @@ function resolveFactoryOptions(options = {}) {
|
|
|
3198
3298
|
...whenDefined("defaultVariants", styling?.defaults),
|
|
3199
3299
|
...whenDefined("compoundVariants", styling?.compounds),
|
|
3200
3300
|
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
3201
|
-
...whenDefined("ariaRules", enforcement?.aria),
|
|
3301
|
+
...whenDefined("ariaRules", mergeAriaRules(enforcement?.aria, enforcement?.rules)),
|
|
3202
3302
|
...whenDefined("childRules", enforcement?.children),
|
|
3203
3303
|
...whenDefined("exclusiveChildren", enforcement?.exclusiveChildren),
|
|
3204
3304
|
...whenDefined("allowText", enforcement?.allowText),
|
package/dist/contract/index.d.ts
CHANGED
|
@@ -231,6 +231,16 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
231
231
|
*/
|
|
232
232
|
readonly diagnostics?: Diagnostics$1 | DiagnosticsMode;
|
|
233
233
|
readonly aria?: readonly AriaRule[];
|
|
234
|
+
/**
|
|
235
|
+
* Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
|
|
236
|
+
* (`AriaRule`'s `readsProps`, fixable `AriaFix` results) but have no
|
|
237
|
+
* relationship to ARIA semantics — an HTML fact or a security check like a
|
|
238
|
+
* dangerous-URL-scheme guard, for example. Evaluated together with `aria`
|
|
239
|
+
* (both run through the same engine, merged into one rule set) — this is a
|
|
240
|
+
* separate bucket purely so a non-ARIA rule doesn't have to sit under the
|
|
241
|
+
* misleading `aria` name to get the machinery it needs.
|
|
242
|
+
*/
|
|
243
|
+
readonly rules?: readonly AriaRule[];
|
|
234
244
|
readonly children?: readonly ChildRuleInput[];
|
|
235
245
|
/**
|
|
236
246
|
* When true, only children matching a `children` rule (or text, per `allowText`)
|
|
@@ -306,4 +316,4 @@ declare function mergeContracts(...contracts: readonly EnforcementOptions[]): En
|
|
|
306
316
|
|
|
307
317
|
type Diagnostics = Diagnostics$1;
|
|
308
318
|
|
|
309
|
-
export { type AnyFactoryOptions, type AriaContext, type AriaFix, type AriaFixResult, type AriaPhase, type AriaResult, type AriaRule, type Diagnostics, type FixKind, type AriaInvalidResult as InvalidResult, type AriaInvalidWithFix as InvalidWithFix, type AriaInvalidWithoutFix as InvalidWithoutFix, type PropNormalizer, type RemoveAttributeFixKind, type Severity, type ValidResult, activeContract, activeProps, disabledContract, disabledProps, expandedContract, expandedProps, invalidContract, invalidProps, loadingContract, loadingProps, mergeContracts, pressedContract, pressedProps, readonlyContract, readonlyProps, selectedContract, selectedProps };
|
|
319
|
+
export { type AnyFactoryOptions, type AriaContext, type AriaFix, type AriaFixResult, type AriaPhase, type AriaResult, type AriaRule, type Diagnostics, type FixKind, type IntrinsicProps, type AriaInvalidResult as InvalidResult, type AriaInvalidWithFix as InvalidWithFix, type AriaInvalidWithoutFix as InvalidWithoutFix, type NormalizeFn, type PropNormalizer, type RemoveAttributeFixKind, type Severity, type ValidResult, activeContract, activeProps, disabledContract, disabledProps, expandedContract, expandedProps, invalidContract, invalidProps, loadingContract, loadingProps, mergeContracts, pressedContract, pressedProps, readonlyContract, readonlyProps, selectedContract, selectedProps };
|
package/dist/contract/index.js
CHANGED
|
@@ -313,6 +313,7 @@ var selectedContract = stateContract([selectedProps]);
|
|
|
313
313
|
function mergeContracts(...contracts) {
|
|
314
314
|
const props = contracts.flatMap((c) => c.props ?? []);
|
|
315
315
|
const aria = contracts.flatMap((c) => c.aria ?? []);
|
|
316
|
+
const rules = contracts.flatMap((c) => c.rules ?? []);
|
|
316
317
|
const children = contracts.flatMap((c) => c.children ?? []);
|
|
317
318
|
let diagnostics;
|
|
318
319
|
let allowedAs;
|
|
@@ -323,6 +324,7 @@ function mergeContracts(...contracts) {
|
|
|
323
324
|
return {
|
|
324
325
|
...props.length > 0 && { props },
|
|
325
326
|
...aria.length > 0 && { aria },
|
|
327
|
+
...rules.length > 0 && { rules },
|
|
326
328
|
...children.length > 0 && { children },
|
|
327
329
|
...diagnostics !== void 0 && { diagnostics },
|
|
328
330
|
...allowedAs !== void 0 && { allowedAs }
|
package/dist/guards/index.d.ts
CHANGED
|
@@ -22,15 +22,24 @@ type TagChild = {
|
|
|
22
22
|
};
|
|
23
23
|
declare function isTag(tag: string, ...tags: readonly string[]): (child: unknown) => child is TagChild;
|
|
24
24
|
declare function isTag(child: unknown, tag: string, ...tags: readonly string[]): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* A vnode (or text node) that qualifies as flow content: text nodes
|
|
27
|
+
* (string/number) always qualify, and elements/components qualify unless
|
|
28
|
+
* their resolved tag is blocked — see `isFlowContent`.
|
|
29
|
+
*/
|
|
30
|
+
type FlowContentChild = string | number | TagChild;
|
|
25
31
|
/**
|
|
26
32
|
* Checks whether a vnode is flow content per the HTML content model: text nodes
|
|
27
33
|
* (string/number) always qualify, and elements/components qualify unless their
|
|
28
34
|
* resolved tag is in the blocked set.
|
|
35
|
+
*
|
|
36
|
+
* Returns a type guard (not a plain boolean predicate) so it can be used
|
|
37
|
+
* directly as a `ChildRuleInput.match`, which requires the narrowed type.
|
|
29
38
|
*/
|
|
30
|
-
declare function isFlowContent(...blockedTags: readonly string[]): (child: unknown) =>
|
|
39
|
+
declare function isFlowContent(...blockedTags: readonly string[]): (child: unknown) => child is FlowContentChild;
|
|
31
40
|
|
|
32
41
|
declare function isObject(value: unknown, excludeArrays: true): value is AnyRecord;
|
|
33
42
|
declare function isObject(value: unknown, excludeArrays?: false): value is object;
|
|
34
43
|
declare function isString(value: unknown): value is string;
|
|
35
44
|
|
|
36
|
-
export { getTag, isFlowContent, isObject, isString, isTag };
|
|
45
|
+
export { type FlowContentChild, type TagChild, getTag, isFlowContent, isObject, isString, isTag };
|