praxis-kit 7.4.0 → 7.8.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 +3 -0
- package/dist/_shared/diagnostics.js +3 -0
- package/dist/{chunk-EIKPSL26.js → chunk-QYP7KLRE.js} +316 -154
- package/dist/contract/index.d.ts +27 -4
- package/dist/eslint/index.js +227 -187
- package/dist/html/index.d.ts +6 -1
- package/dist/html/index.js +234 -68
- package/dist/lit/index.d.ts +27 -4
- package/dist/lit/index.js +305 -141
- package/dist/preact/index.d.ts +114 -6
- package/dist/preact/index.js +321 -153
- package/dist/react/index.d.ts +3 -2
- package/dist/react/index.js +7 -2
- package/dist/react/legacy.d.ts +8 -5
- package/dist/react/legacy.js +13 -9
- package/dist/{react-options-BnjZpdVh.d.ts → react-options-DU3EdFOv.d.ts} +126 -7
- package/dist/solid/index.d.ts +127 -8
- package/dist/solid/index.js +320 -153
- package/dist/svelte/Polymorphic.svelte +8 -0
- package/dist/svelte/index.d.ts +224 -13
- package/dist/svelte/index.js +319 -152
- package/dist/tailwind/index.d.ts +1 -1
- package/dist/vite-plugin/index.d.ts +6 -3
- package/dist/vue/index.d.ts +94 -6
- package/dist/vue/index.js +320 -153
- package/dist/web/index.d.ts +27 -4
- package/dist/web/index.js +305 -141
- package/package.json +9 -9
package/dist/solid/index.js
CHANGED
|
@@ -38,6 +38,9 @@ function dynamic(resolve) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
// ../../lib/primitive/src/guards/foundational/is-defined.ts
|
|
41
|
+
function isDefined(value) {
|
|
42
|
+
return value !== void 0;
|
|
43
|
+
}
|
|
41
44
|
function isUndefined(value) {
|
|
42
45
|
return value === void 0;
|
|
43
46
|
}
|
|
@@ -771,21 +774,65 @@ function getImplicitRole(tag, props) {
|
|
|
771
774
|
return void 0;
|
|
772
775
|
}
|
|
773
776
|
|
|
774
|
-
// ../../lib/contract/src/diagnostics/
|
|
777
|
+
// ../../lib/contract/src/diagnostics/anchor-accessibility.ts
|
|
775
778
|
import { DiagnosticCategory, DiagnosticCode } from "../_shared/diagnostics.js";
|
|
779
|
+
function createDiagnostic(input) {
|
|
780
|
+
return { category: DiagnosticCategory.Accessibility, ...input };
|
|
781
|
+
}
|
|
782
|
+
var AnchorAccessibilityDiagnostics = {
|
|
783
|
+
roleButtonWithHref() {
|
|
784
|
+
return createDiagnostic({
|
|
785
|
+
code: DiagnosticCode.A11yAnchorRoleButtonWithHref,
|
|
786
|
+
severity: "warning",
|
|
787
|
+
message: 'role="button" on an <a> with an href overrides its navigation semantics for assistive technology; use a real <button> element, or remove href, if this element should not navigate.',
|
|
788
|
+
rationale: 'Assistive technology announces role="button" as a button, not a link \u2014 but the element still follows the link when activated by mouse or keyboard, which is confusing and inconsistent with how a button is expected to behave.',
|
|
789
|
+
suggestions: [
|
|
790
|
+
{
|
|
791
|
+
title: "Use a real <button>",
|
|
792
|
+
description: "If this element should not navigate, render a <button> instead of an <a>."
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
title: 'Remove role="button"',
|
|
796
|
+
description: "If this element should navigate, keep the default link role."
|
|
797
|
+
}
|
|
798
|
+
]
|
|
799
|
+
});
|
|
800
|
+
},
|
|
801
|
+
ariaDisabledInert() {
|
|
802
|
+
return createDiagnostic({
|
|
803
|
+
code: DiagnosticCode.A11yAnchorAriaDisabledInert,
|
|
804
|
+
severity: "warning",
|
|
805
|
+
message: "aria-disabled does not prevent an <a> from being focused, clicked, or navigated via keyboard; remove href, or prevent navigation yourself, if this link should be inert.",
|
|
806
|
+
rationale: "Unlike a native form control, an <a> has no disabled state the browser enforces \u2014 aria-disabled only changes what assistive technology announces, not what actually happens when the link is activated by mouse or keyboard.",
|
|
807
|
+
suggestions: [
|
|
808
|
+
{
|
|
809
|
+
title: "Remove href",
|
|
810
|
+
description: "If this element is temporarily unavailable, remove href until it can be activated."
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
title: "Prevent navigation when disabled",
|
|
814
|
+
description: "Prevent the click and keyboard activation when the link is disabled so it behaves consistently for all users."
|
|
815
|
+
}
|
|
816
|
+
]
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
// ../../lib/contract/src/diagnostics/aria.ts
|
|
822
|
+
import { DiagnosticCategory as DiagnosticCategory2, DiagnosticCode as DiagnosticCode2 } from "../_shared/diagnostics.js";
|
|
776
823
|
var AriaDiagnostics = {
|
|
777
824
|
/** Generic bridge for violations produced by external AriaRule functions. */
|
|
778
825
|
fromViolation(v) {
|
|
779
826
|
return {
|
|
780
|
-
code:
|
|
781
|
-
category:
|
|
827
|
+
code: DiagnosticCode2.AriaViolation,
|
|
828
|
+
category: DiagnosticCategory2.ARIA,
|
|
782
829
|
message: v.message
|
|
783
830
|
};
|
|
784
831
|
},
|
|
785
832
|
attributeInvalid(key, role) {
|
|
786
833
|
return {
|
|
787
|
-
code:
|
|
788
|
-
category:
|
|
834
|
+
code: DiagnosticCode2.AriaAttributeInvalid,
|
|
835
|
+
category: DiagnosticCategory2.ARIA,
|
|
789
836
|
message: `"${key}" is not valid on role="${role}". It will be removed.`,
|
|
790
837
|
rationale: "Invalid ARIA attributes are ignored by assistive technology and may trigger accessibility-tree warnings in browser devtools.",
|
|
791
838
|
suggestions: [
|
|
@@ -798,8 +845,8 @@ var AriaDiagnostics = {
|
|
|
798
845
|
},
|
|
799
846
|
missingLiveRegion(role, impliedLive) {
|
|
800
847
|
return {
|
|
801
|
-
code:
|
|
802
|
-
category:
|
|
848
|
+
code: DiagnosticCode2.AriaMissingLiveRegion,
|
|
849
|
+
category: DiagnosticCategory2.ARIA,
|
|
803
850
|
message: `role="${role}" implies aria-live="${impliedLive}" but it is missing. It has been injected.`,
|
|
804
851
|
rationale: "Live-region roles announce dynamic content changes to screen readers. Without aria-live the politeness level is unspecified and announcements may be silent.",
|
|
805
852
|
suggestions: [
|
|
@@ -813,8 +860,8 @@ var AriaDiagnostics = {
|
|
|
813
860
|
},
|
|
814
861
|
missingAtomic(role) {
|
|
815
862
|
return {
|
|
816
|
-
code:
|
|
817
|
-
category:
|
|
863
|
+
code: DiagnosticCode2.AriaMissingAtomic,
|
|
864
|
+
category: DiagnosticCategory2.ARIA,
|
|
818
865
|
message: `role="${role}" is a live region. Consider setting aria-atomic="true" if the full region should be announced as a unit, or aria-atomic="false" if only changed nodes should be read.`,
|
|
819
866
|
rationale: "aria-atomic controls whether assistive technology announces the entire live region or only the changed nodes. Omitting it leaves the behaviour browser-defined."
|
|
820
867
|
};
|
|
@@ -822,8 +869,8 @@ var AriaDiagnostics = {
|
|
|
822
869
|
relevantInvalidTokens(invalid) {
|
|
823
870
|
const quoted = invalid.map((t) => `"${t}"`).join(", ");
|
|
824
871
|
return {
|
|
825
|
-
code:
|
|
826
|
-
category:
|
|
872
|
+
code: DiagnosticCode2.AriaRelevantInvalidToken,
|
|
873
|
+
category: DiagnosticCategory2.ARIA,
|
|
827
874
|
message: `aria-relevant contains invalid token(s): ${quoted}. Valid tokens are: additions, removals, text, all.`,
|
|
828
875
|
rationale: "aria-relevant accepts a space-separated list of change types. Unrecognised tokens are silently ignored by assistive technology, making the attribute ineffective.",
|
|
829
876
|
suggestions: [
|
|
@@ -836,8 +883,8 @@ var AriaDiagnostics = {
|
|
|
836
883
|
},
|
|
837
884
|
relevantSuperseded() {
|
|
838
885
|
return {
|
|
839
|
-
code:
|
|
840
|
-
category:
|
|
886
|
+
code: DiagnosticCode2.AriaRelevantSuperseded,
|
|
887
|
+
category: DiagnosticCategory2.ARIA,
|
|
841
888
|
message: 'aria-relevant includes "all" alongside other tokens. "all" supersedes additions, removals, and text \u2014 use aria-relevant="all" alone.',
|
|
842
889
|
rationale: '"all" is equivalent to "additions removals text". Combining it with other tokens is redundant and may confuse readers of the markup.',
|
|
843
890
|
suggestions: [
|
|
@@ -850,8 +897,8 @@ var AriaDiagnostics = {
|
|
|
850
897
|
},
|
|
851
898
|
missingAccessibleName(tag) {
|
|
852
899
|
return {
|
|
853
|
-
code:
|
|
854
|
-
category:
|
|
900
|
+
code: DiagnosticCode2.AriaMissingAccessibleName,
|
|
901
|
+
category: DiagnosticCategory2.ARIA,
|
|
855
902
|
message: `<${tag}> has no accessible name. Add aria-label or aria-labelledby.`,
|
|
856
903
|
rationale: "Elements with a landmark or interactive role must have an accessible name so that assistive technology can identify them when presenting the page outline.",
|
|
857
904
|
suggestions: [
|
|
@@ -868,8 +915,8 @@ var AriaDiagnostics = {
|
|
|
868
915
|
},
|
|
869
916
|
attributeOnPresentational(attr, tag) {
|
|
870
917
|
return {
|
|
871
|
-
code:
|
|
872
|
-
category:
|
|
918
|
+
code: DiagnosticCode2.AriaAttributeOnPresentational,
|
|
919
|
+
category: DiagnosticCategory2.ARIA,
|
|
873
920
|
message: `"${attr}" is not allowed on a presentational <${tag}>. Presentational elements are invisible to assistive technology.`,
|
|
874
921
|
rationale: 'role="none" and role="presentation" (including <img alt="">) remove an element from the accessibility tree. ARIA attributes on such elements are ignored by assistive technology.',
|
|
875
922
|
suggestions: [
|
|
@@ -882,8 +929,8 @@ var AriaDiagnostics = {
|
|
|
882
929
|
},
|
|
883
930
|
ariaHiddenOnFocusable(tag) {
|
|
884
931
|
return {
|
|
885
|
-
code:
|
|
886
|
-
category:
|
|
932
|
+
code: DiagnosticCode2.AriaHiddenOnFocusable,
|
|
933
|
+
category: DiagnosticCategory2.ARIA,
|
|
887
934
|
message: `aria-hidden="true" must not be used on focusable <${tag}> elements. Screen reader users who navigate by keyboard will encounter the element but receive no information about it.`,
|
|
888
935
|
rationale: 'aria-hidden removes an element from the accessibility tree while leaving it keyboard-reachable. This creates a "ghost" \u2014 a focusable element assistive technology cannot describe.',
|
|
889
936
|
suggestions: [
|
|
@@ -901,8 +948,8 @@ var AriaDiagnostics = {
|
|
|
901
948
|
invalidAttributeValue(attr, value, expected) {
|
|
902
949
|
const got = value === null ? "null" : value === void 0 ? "undefined" : typeof value === "string" ? `"${value}"` : String(value);
|
|
903
950
|
return {
|
|
904
|
-
code:
|
|
905
|
-
category:
|
|
951
|
+
code: DiagnosticCode2.AriaInvalidAttributeValue,
|
|
952
|
+
category: DiagnosticCategory2.ARIA,
|
|
906
953
|
message: `"${attr}" has an invalid value (${got}). Expected: ${expected}.`,
|
|
907
954
|
rationale: "ARIA attributes with invalid values are silently ignored by assistive technology, making the markup semantically inert.",
|
|
908
955
|
suggestions: [
|
|
@@ -915,8 +962,8 @@ var AriaDiagnostics = {
|
|
|
915
962
|
},
|
|
916
963
|
redundantAriaLevel(tag, level) {
|
|
917
964
|
return {
|
|
918
|
-
code:
|
|
919
|
-
category:
|
|
965
|
+
code: DiagnosticCode2.AriaRedundantLevelAttribute,
|
|
966
|
+
category: DiagnosticCategory2.ARIA,
|
|
920
967
|
message: `aria-level="${level}" is redundant on <${tag}>: the element already has an implicit heading level of ${level}. Remove the attribute.`,
|
|
921
968
|
rationale: 'Restating the implicit aria-level adds noise without semantic value. Use aria-level only to override the native heading level (e.g. aria-level="3" on <h2>).',
|
|
922
969
|
suggestions: [
|
|
@@ -929,8 +976,8 @@ var AriaDiagnostics = {
|
|
|
929
976
|
},
|
|
930
977
|
requiredProperty(attr, role) {
|
|
931
978
|
return {
|
|
932
|
-
code:
|
|
933
|
-
category:
|
|
979
|
+
code: DiagnosticCode2.AriaRequiredProperty,
|
|
980
|
+
category: DiagnosticCategory2.ARIA,
|
|
934
981
|
message: `"${attr}" is required for role="${role}" but is missing.`,
|
|
935
982
|
rationale: `WAI-ARIA 1.2 specifies required states and properties for certain roles. Without "${attr}", assistive technology cannot correctly communicate the element's state to users.`,
|
|
936
983
|
suggestions: [
|
|
@@ -943,8 +990,8 @@ var AriaDiagnostics = {
|
|
|
943
990
|
},
|
|
944
991
|
invalidRole(role, tag) {
|
|
945
992
|
return {
|
|
946
|
-
code:
|
|
947
|
-
category:
|
|
993
|
+
code: DiagnosticCode2.AriaInvalidRole,
|
|
994
|
+
category: DiagnosticCategory2.ARIA,
|
|
948
995
|
message: `Invalid role "${role ?? ""}" on <${tag}>.`,
|
|
949
996
|
rationale: "An unrecognised or misapplied ARIA role is ignored by assistive technology and may degrade the accessibility of the element."
|
|
950
997
|
};
|
|
@@ -952,12 +999,12 @@ var AriaDiagnostics = {
|
|
|
952
999
|
};
|
|
953
1000
|
|
|
954
1001
|
// ../../lib/contract/src/diagnostics/contract.ts
|
|
955
|
-
import { DiagnosticCategory as
|
|
1002
|
+
import { DiagnosticCategory as DiagnosticCategory3, DiagnosticCode as DiagnosticCode3 } from "../_shared/diagnostics.js";
|
|
956
1003
|
var ContractDiagnostics = {
|
|
957
1004
|
unexpectedChild(typeName, index, context) {
|
|
958
1005
|
return {
|
|
959
|
-
code:
|
|
960
|
-
category:
|
|
1006
|
+
code: DiagnosticCode3.UnexpectedChild,
|
|
1007
|
+
category: DiagnosticCategory3.Contract,
|
|
961
1008
|
component: context,
|
|
962
1009
|
message: `${context}: unexpected child "${typeName}" at index ${index}.`
|
|
963
1010
|
};
|
|
@@ -965,69 +1012,69 @@ var ContractDiagnostics = {
|
|
|
965
1012
|
ambiguousChild(typeName, index, ruleNames, context) {
|
|
966
1013
|
const quoted = ruleNames.map((n) => `"${n}"`).join(" and ");
|
|
967
1014
|
return {
|
|
968
|
-
code:
|
|
969
|
-
category:
|
|
1015
|
+
code: DiagnosticCode3.AmbiguousChild,
|
|
1016
|
+
category: DiagnosticCategory3.Contract,
|
|
970
1017
|
component: context,
|
|
971
1018
|
message: `${context}: child "${typeName}" at index ${index} matches multiple child rules: ${quoted}.`
|
|
972
1019
|
};
|
|
973
1020
|
},
|
|
974
1021
|
cardinalityMin(ruleName, min, context) {
|
|
975
1022
|
return {
|
|
976
|
-
code:
|
|
977
|
-
category:
|
|
1023
|
+
code: DiagnosticCode3.CardinalityMin,
|
|
1024
|
+
category: DiagnosticCategory3.Contract,
|
|
978
1025
|
component: context,
|
|
979
1026
|
message: `${context}: "${ruleName}" requires at least ${min}.`
|
|
980
1027
|
};
|
|
981
1028
|
},
|
|
982
1029
|
cardinalityMax(ruleName, max, context) {
|
|
983
1030
|
return {
|
|
984
|
-
code:
|
|
985
|
-
category:
|
|
1031
|
+
code: DiagnosticCode3.CardinalityMax,
|
|
1032
|
+
category: DiagnosticCategory3.Contract,
|
|
986
1033
|
component: context,
|
|
987
1034
|
message: `${context}: "${ruleName}" allows at most ${max}.`
|
|
988
1035
|
};
|
|
989
1036
|
},
|
|
990
1037
|
positionViolation(ruleName, position, index, context) {
|
|
991
1038
|
return {
|
|
992
|
-
code:
|
|
993
|
-
category:
|
|
1039
|
+
code: DiagnosticCode3.PositionViolation,
|
|
1040
|
+
category: DiagnosticCategory3.Contract,
|
|
994
1041
|
component: context,
|
|
995
1042
|
message: `${context}: "${ruleName}" must be ${position}, got index ${index}`
|
|
996
1043
|
};
|
|
997
1044
|
},
|
|
998
1045
|
unknownVariantDim(component, label2, dim) {
|
|
999
1046
|
return {
|
|
1000
|
-
code:
|
|
1001
|
-
category:
|
|
1047
|
+
code: DiagnosticCode3.ContractUnknownVariantDim,
|
|
1048
|
+
category: DiagnosticCategory3.Contract,
|
|
1002
1049
|
message: `${component}: ${label2} references unknown variant "${dim}".`
|
|
1003
1050
|
};
|
|
1004
1051
|
},
|
|
1005
1052
|
unknownVariantValue(component, label2, dim, value, valid) {
|
|
1006
1053
|
return {
|
|
1007
|
-
code:
|
|
1008
|
-
category:
|
|
1054
|
+
code: DiagnosticCode3.ContractUnknownVariantValue,
|
|
1055
|
+
category: DiagnosticCategory3.Contract,
|
|
1009
1056
|
message: `${component}: ${label2} sets "${dim}" to unknown value "${value}" (valid: ${valid.join(", ")}).`
|
|
1010
1057
|
};
|
|
1011
1058
|
},
|
|
1012
1059
|
unknownRecipeKey(component, key) {
|
|
1013
1060
|
return {
|
|
1014
|
-
code:
|
|
1015
|
-
category:
|
|
1061
|
+
code: DiagnosticCode3.ContractUnknownRecipeKey,
|
|
1062
|
+
category: DiagnosticCategory3.Contract,
|
|
1016
1063
|
message: `${component} Unknown recipeKey "${key}" \u2014 no preset with that name exists.`
|
|
1017
1064
|
};
|
|
1018
1065
|
},
|
|
1019
1066
|
invalidVariantValue(component, key, value) {
|
|
1020
1067
|
return {
|
|
1021
|
-
code:
|
|
1022
|
-
category:
|
|
1068
|
+
code: DiagnosticCode3.ContractInvalidVariantValue,
|
|
1069
|
+
category: DiagnosticCategory3.Contract,
|
|
1023
1070
|
message: `${component} Variant "${key}=${value}" is not a defined value for the "${key}" dimension.`
|
|
1024
1071
|
};
|
|
1025
1072
|
},
|
|
1026
1073
|
allowedAsViolation(tag, allowedAs, component) {
|
|
1027
1074
|
const allowed = allowedAs.map((t) => `"${String(t)}"`).join(", ");
|
|
1028
1075
|
return {
|
|
1029
|
-
code:
|
|
1030
|
-
category:
|
|
1076
|
+
code: DiagnosticCode3.AllowedAsViolation,
|
|
1077
|
+
category: DiagnosticCategory3.Contract,
|
|
1031
1078
|
component,
|
|
1032
1079
|
message: `<${component}>: "as" prop received "${tag}" but only [${allowed}] are allowed.`
|
|
1033
1080
|
};
|
|
@@ -1035,68 +1082,68 @@ var ContractDiagnostics = {
|
|
|
1035
1082
|
};
|
|
1036
1083
|
|
|
1037
1084
|
// ../../lib/contract/src/diagnostics/html.ts
|
|
1038
|
-
import { DiagnosticCategory as
|
|
1085
|
+
import { DiagnosticCategory as DiagnosticCategory4, DiagnosticCode as DiagnosticCode4 } from "../_shared/diagnostics.js";
|
|
1039
1086
|
var ATTRIBUTE_IGNORED_CODES = {
|
|
1040
|
-
checked:
|
|
1041
|
-
multiple:
|
|
1042
|
-
maxLength:
|
|
1043
|
-
minLength:
|
|
1044
|
-
pattern:
|
|
1045
|
-
min:
|
|
1046
|
-
max:
|
|
1047
|
-
step:
|
|
1048
|
-
accept:
|
|
1049
|
-
capture:
|
|
1050
|
-
size:
|
|
1051
|
-
alt:
|
|
1052
|
-
height:
|
|
1053
|
-
width:
|
|
1087
|
+
checked: DiagnosticCode4.HtmlInputCheckedIgnoredForType,
|
|
1088
|
+
multiple: DiagnosticCode4.HtmlInputMultipleIgnoredForType,
|
|
1089
|
+
maxLength: DiagnosticCode4.HtmlInputMaxLengthIgnoredForType,
|
|
1090
|
+
minLength: DiagnosticCode4.HtmlInputMinLengthIgnoredForType,
|
|
1091
|
+
pattern: DiagnosticCode4.HtmlInputPatternIgnoredForType,
|
|
1092
|
+
min: DiagnosticCode4.HtmlInputMinIgnoredForType,
|
|
1093
|
+
max: DiagnosticCode4.HtmlInputMaxIgnoredForType,
|
|
1094
|
+
step: DiagnosticCode4.HtmlInputStepIgnoredForType,
|
|
1095
|
+
accept: DiagnosticCode4.HtmlInputAcceptIgnoredForType,
|
|
1096
|
+
capture: DiagnosticCode4.HtmlInputCaptureIgnoredForType,
|
|
1097
|
+
size: DiagnosticCode4.HtmlInputSizeIgnoredForType,
|
|
1098
|
+
alt: DiagnosticCode4.HtmlInputAltIgnoredForType,
|
|
1099
|
+
height: DiagnosticCode4.HtmlInputHeightIgnoredForType,
|
|
1100
|
+
width: DiagnosticCode4.HtmlInputWidthIgnoredForType
|
|
1054
1101
|
};
|
|
1055
1102
|
var HtmlDiagnostics = {
|
|
1056
1103
|
emptyRole(tag) {
|
|
1057
1104
|
return {
|
|
1058
|
-
code:
|
|
1059
|
-
category:
|
|
1105
|
+
code: DiagnosticCode4.HtmlEmptyRole,
|
|
1106
|
+
category: DiagnosticCategory4.HTML,
|
|
1060
1107
|
severity: "warning",
|
|
1061
1108
|
message: `<${tag}> has an explicit empty role="". Omit the attribute instead.`
|
|
1062
1109
|
};
|
|
1063
1110
|
},
|
|
1064
1111
|
implicitRoleRedundant(tag, implicitRole) {
|
|
1065
1112
|
return {
|
|
1066
|
-
code:
|
|
1067
|
-
category:
|
|
1113
|
+
code: DiagnosticCode4.HtmlImplicitRoleRedundant,
|
|
1114
|
+
category: DiagnosticCategory4.HTML,
|
|
1068
1115
|
severity: "warning",
|
|
1069
1116
|
message: `<${tag}> already has implicit role="${implicitRole}". Avoid redundant role assignment.`
|
|
1070
1117
|
};
|
|
1071
1118
|
},
|
|
1072
1119
|
implicitRoleOverride(tag, implicitRole, role) {
|
|
1073
1120
|
return {
|
|
1074
|
-
code:
|
|
1075
|
-
category:
|
|
1121
|
+
code: DiagnosticCode4.HtmlImplicitRoleOverride,
|
|
1122
|
+
category: DiagnosticCategory4.HTML,
|
|
1076
1123
|
severity: "error",
|
|
1077
1124
|
message: `<${tag}> should not override its implicit role="${implicitRole}" with role="${role}".`
|
|
1078
1125
|
};
|
|
1079
1126
|
},
|
|
1080
1127
|
standaloneRegionOverride(tag, implicitRole) {
|
|
1081
1128
|
return {
|
|
1082
|
-
code:
|
|
1083
|
-
category:
|
|
1129
|
+
code: DiagnosticCode4.HtmlStandaloneRegionOverride,
|
|
1130
|
+
category: DiagnosticCategory4.HTML,
|
|
1084
1131
|
severity: "error",
|
|
1085
1132
|
message: `<${tag}> is a self-contained element with implicit role="${implicitRole}". Assigning role="region" has been removed.`
|
|
1086
1133
|
};
|
|
1087
1134
|
},
|
|
1088
1135
|
landmarkRoleOverride(tag, implicitRole, role) {
|
|
1089
1136
|
return {
|
|
1090
|
-
code:
|
|
1091
|
-
category:
|
|
1137
|
+
code: DiagnosticCode4.HtmlLandmarkRoleOverride,
|
|
1138
|
+
category: DiagnosticCategory4.HTML,
|
|
1092
1139
|
severity: "error",
|
|
1093
1140
|
message: `<${tag}> has a fixed landmark role="${implicitRole}". role="${role}" overrides it and confuses assistive technology. The override has been removed.`
|
|
1094
1141
|
};
|
|
1095
1142
|
},
|
|
1096
1143
|
invalidChild(child, parent, allowed) {
|
|
1097
1144
|
return {
|
|
1098
|
-
code:
|
|
1099
|
-
category:
|
|
1145
|
+
code: DiagnosticCode4.HtmlInvalidChild,
|
|
1146
|
+
category: DiagnosticCategory4.HTML,
|
|
1100
1147
|
severity: "error",
|
|
1101
1148
|
message: `<${child}> is not a valid direct child of <${parent}>. Allowed: ${allowed}.`
|
|
1102
1149
|
};
|
|
@@ -1104,8 +1151,8 @@ var HtmlDiagnostics = {
|
|
|
1104
1151
|
roleNotPermitted(tag, role, allowedRoles) {
|
|
1105
1152
|
const allowed = allowedRoles.length > 0 ? allowedRoles.map((r) => `"${r}"`).join(", ") : "none \u2014 no explicit role is permitted on this element";
|
|
1106
1153
|
return {
|
|
1107
|
-
code:
|
|
1108
|
-
category:
|
|
1154
|
+
code: DiagnosticCode4.HtmlRoleNotPermitted,
|
|
1155
|
+
category: DiagnosticCategory4.HTML,
|
|
1109
1156
|
severity: "error",
|
|
1110
1157
|
message: `role="${role}" is not permitted on <${tag}>. Allowed alternate role(s): ${allowed}.`,
|
|
1111
1158
|
rationale: 'The WAI-ARIA "ARIA in HTML" specification restricts which explicit roles a native element may take. A role outside that set is ignored or produces undefined behavior in assistive technology.'
|
|
@@ -1116,8 +1163,8 @@ var HtmlDiagnostics = {
|
|
|
1116
1163
|
input: {
|
|
1117
1164
|
unsupportedType(type) {
|
|
1118
1165
|
return {
|
|
1119
|
-
code:
|
|
1120
|
-
category:
|
|
1166
|
+
code: DiagnosticCode4.HtmlInputUnsupportedType,
|
|
1167
|
+
category: DiagnosticCategory4.HTML,
|
|
1121
1168
|
severity: "warning",
|
|
1122
1169
|
message: `type="${type}" is not a value defined by the HTML specification. Browsers silently fall back to type="text".`,
|
|
1123
1170
|
rationale: 'An unrecognized input type is not invalid markup \u2014 the spec requires the "text" fallback \u2014 but it usually means a typo, since the input keeps working while silently losing the intended type-specific behavior (validation, virtual keyboard, picker UI).',
|
|
@@ -1137,7 +1184,7 @@ var HtmlDiagnostics = {
|
|
|
1137
1184
|
if (!code) throw new Error(`No DiagnosticCode registered for input attribute "${attribute}"`);
|
|
1138
1185
|
return {
|
|
1139
1186
|
code,
|
|
1140
|
-
category:
|
|
1187
|
+
category: DiagnosticCategory4.HTML,
|
|
1141
1188
|
severity: "warning",
|
|
1142
1189
|
message: `"${attribute}" is ignored on <input type="${type}">.`,
|
|
1143
1190
|
rationale: `"${attribute}" only has an effect when type is one of: ${allowed}. Browsers silently ignore it on other input types.`,
|
|
@@ -1149,18 +1196,30 @@ var HtmlDiagnostics = {
|
|
|
1149
1196
|
]
|
|
1150
1197
|
};
|
|
1151
1198
|
}
|
|
1199
|
+
},
|
|
1200
|
+
// Reserved for <a>-specific facts (HTML3201–3299, see codes.ts).
|
|
1201
|
+
anchor: {
|
|
1202
|
+
dangerousHref(href) {
|
|
1203
|
+
return {
|
|
1204
|
+
code: DiagnosticCode4.HtmlAnchorDangerousHref,
|
|
1205
|
+
category: DiagnosticCategory4.HTML,
|
|
1206
|
+
severity: "warning",
|
|
1207
|
+
message: `href="${href}" uses a scheme that executes attacker-controlled content when navigated to. It has been removed.`,
|
|
1208
|
+
rationale: '"javascript:", "data:", and "vbscript:" URLs are a common XSS vector when href comes from untrusted input \u2014 none of the three are needed for legitimate navigation.'
|
|
1209
|
+
};
|
|
1210
|
+
}
|
|
1152
1211
|
}
|
|
1153
1212
|
};
|
|
1154
1213
|
|
|
1155
1214
|
// ../../lib/contract/src/diagnostics/input-accessibility.ts
|
|
1156
|
-
import { DiagnosticCategory as
|
|
1215
|
+
import { DiagnosticCategory as DiagnosticCategory5, DiagnosticCode as DiagnosticCode5 } from "../_shared/diagnostics.js";
|
|
1157
1216
|
function accessibilityFact(input) {
|
|
1158
|
-
return { category:
|
|
1217
|
+
return { category: DiagnosticCategory5.Accessibility, ...input };
|
|
1159
1218
|
}
|
|
1160
1219
|
var InputAccessibilityDiagnostics = {
|
|
1161
1220
|
missingAccessibleName() {
|
|
1162
1221
|
return accessibilityFact({
|
|
1163
|
-
code:
|
|
1222
|
+
code: DiagnosticCode5.A11yInputMissingAccessibleName,
|
|
1164
1223
|
severity: "warning",
|
|
1165
1224
|
message: "This input has no accessible name. Add an associated <label>, aria-label, or aria-labelledby.",
|
|
1166
1225
|
rationale: "Assistive technology announces a form field by its accessible name; without one, users of screen readers cannot tell what the field is for.",
|
|
@@ -1175,7 +1234,7 @@ var InputAccessibilityDiagnostics = {
|
|
|
1175
1234
|
},
|
|
1176
1235
|
placeholderIsNotLabel() {
|
|
1177
1236
|
return accessibilityFact({
|
|
1178
|
-
code:
|
|
1237
|
+
code: DiagnosticCode5.A11yInputPlaceholderNotLabel,
|
|
1179
1238
|
severity: "warning",
|
|
1180
1239
|
message: "Placeholder text does not provide an accessible name. Add an associated <label>, aria-label, or aria-labelledby.",
|
|
1181
1240
|
rationale: "Placeholder text disappears as users interact with the field and is not treated as the control's accessible name by many assistive technologies.",
|
|
@@ -1190,7 +1249,7 @@ var InputAccessibilityDiagnostics = {
|
|
|
1190
1249
|
},
|
|
1191
1250
|
passwordMissingAutocomplete() {
|
|
1192
1251
|
return accessibilityFact({
|
|
1193
|
-
code:
|
|
1252
|
+
code: DiagnosticCode5.A11yInputPasswordAutocomplete,
|
|
1194
1253
|
severity: "warning",
|
|
1195
1254
|
message: "Password inputs should specify an autoComplete value.",
|
|
1196
1255
|
rationale: "Without an explicit autocomplete hint, password managers and browsers cannot reliably tell a sign-in field apart from a password-creation field.",
|
|
@@ -1208,7 +1267,7 @@ var InputAccessibilityDiagnostics = {
|
|
|
1208
1267
|
},
|
|
1209
1268
|
requiredReadOnlyConflict() {
|
|
1210
1269
|
return accessibilityFact({
|
|
1211
|
-
code:
|
|
1270
|
+
code: DiagnosticCode5.A11yInputRequiredReadOnlyConflict,
|
|
1212
1271
|
severity: "warning",
|
|
1213
1272
|
message: "The required and readOnly attributes are both present. A read-only field cannot satisfy required validation through user interaction.",
|
|
1214
1273
|
rationale: "This combination is valid HTML but usually indicates an unintended state. Consider using disabled instead of readOnly, or only applying required when the field is editable."
|
|
@@ -1217,28 +1276,28 @@ var InputAccessibilityDiagnostics = {
|
|
|
1217
1276
|
};
|
|
1218
1277
|
|
|
1219
1278
|
// ../../lib/contract/src/diagnostics/slot.ts
|
|
1220
|
-
import { DiagnosticCategory as
|
|
1279
|
+
import { DiagnosticCategory as DiagnosticCategory6, DiagnosticCode as DiagnosticCode6 } from "../_shared/diagnostics.js";
|
|
1221
1280
|
var SlotDiagnostics = {
|
|
1222
1281
|
exclusive(name) {
|
|
1223
1282
|
return {
|
|
1224
|
-
code:
|
|
1225
|
-
category:
|
|
1283
|
+
code: DiagnosticCode6.SlotExclusive,
|
|
1284
|
+
category: DiagnosticCategory6.Contract,
|
|
1226
1285
|
component: name,
|
|
1227
1286
|
message: `${name}: "as" and "asChild" are mutually exclusive`
|
|
1228
1287
|
};
|
|
1229
1288
|
},
|
|
1230
1289
|
singleChildRequired(name, elementTerm) {
|
|
1231
1290
|
return {
|
|
1232
|
-
code:
|
|
1233
|
-
category:
|
|
1291
|
+
code: DiagnosticCode6.SlotSingleChild,
|
|
1292
|
+
category: DiagnosticCategory6.Contract,
|
|
1234
1293
|
component: name,
|
|
1235
1294
|
message: `${name}: asChild requires a ${elementTerm} child`
|
|
1236
1295
|
};
|
|
1237
1296
|
},
|
|
1238
1297
|
singleChildExceeded(name, elementTerm, count) {
|
|
1239
1298
|
return {
|
|
1240
|
-
code:
|
|
1241
|
-
category:
|
|
1299
|
+
code: DiagnosticCode6.SlotSingleChild,
|
|
1300
|
+
category: DiagnosticCategory6.Contract,
|
|
1242
1301
|
component: name,
|
|
1243
1302
|
message: `${name}: asChild requires exactly one ${elementTerm} child, got ${count}`
|
|
1244
1303
|
};
|
|
@@ -1246,16 +1305,16 @@ var SlotDiagnostics = {
|
|
|
1246
1305
|
discardedChildren(name, elementTerm, count) {
|
|
1247
1306
|
const suffix = count === 1 ? "" : "ren";
|
|
1248
1307
|
return {
|
|
1249
|
-
code:
|
|
1250
|
-
category:
|
|
1308
|
+
code: DiagnosticCode6.SlotDiscardedChildren,
|
|
1309
|
+
category: DiagnosticCategory6.Contract,
|
|
1251
1310
|
component: name,
|
|
1252
1311
|
message: `${name}: asChild discarded ${count} non-element child${suffix} \u2014 only ${elementTerm}s are valid asChild children.`
|
|
1253
1312
|
};
|
|
1254
1313
|
},
|
|
1255
1314
|
renderFnRequired(name, received) {
|
|
1256
1315
|
return {
|
|
1257
|
-
code:
|
|
1258
|
-
category:
|
|
1316
|
+
code: DiagnosticCode6.SlotRenderFn,
|
|
1317
|
+
category: DiagnosticCategory6.Contract,
|
|
1259
1318
|
component: name,
|
|
1260
1319
|
message: `${name}: asChild requires a render function as children, got ${received}`
|
|
1261
1320
|
};
|
|
@@ -2001,6 +2060,27 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
2001
2060
|
};
|
|
2002
2061
|
|
|
2003
2062
|
// ../../lib/contract/src/aria/factories.ts
|
|
2063
|
+
function invalidWithoutFix(input) {
|
|
2064
|
+
return {
|
|
2065
|
+
valid: false,
|
|
2066
|
+
fixable: false,
|
|
2067
|
+
severity: input.severity,
|
|
2068
|
+
...isDefined(input.attribute) && { attribute: input.attribute },
|
|
2069
|
+
...isDefined(input.message) && { message: input.message },
|
|
2070
|
+
...isDefined(input.diagnostic) && { diagnostic: input.diagnostic }
|
|
2071
|
+
};
|
|
2072
|
+
}
|
|
2073
|
+
function invalidWithFix(input) {
|
|
2074
|
+
return {
|
|
2075
|
+
valid: false,
|
|
2076
|
+
fixable: true,
|
|
2077
|
+
severity: input.severity,
|
|
2078
|
+
...isDefined(input.attribute) && { attribute: input.attribute },
|
|
2079
|
+
...isDefined(input.message) && { message: input.message },
|
|
2080
|
+
...isDefined(input.diagnostic) && { diagnostic: input.diagnostic },
|
|
2081
|
+
fix: input.fix
|
|
2082
|
+
};
|
|
2083
|
+
}
|
|
2004
2084
|
function removeProp(props, key) {
|
|
2005
2085
|
const next = { ...props };
|
|
2006
2086
|
delete next[key];
|
|
@@ -2016,6 +2096,34 @@ function removeAttributeFix(attribute) {
|
|
|
2016
2096
|
}
|
|
2017
2097
|
});
|
|
2018
2098
|
}
|
|
2099
|
+
function defineRuleMetadata(rule, metadata2) {
|
|
2100
|
+
const descriptors = {};
|
|
2101
|
+
for (const key of Object.keys(metadata2)) {
|
|
2102
|
+
descriptors[key] = { value: metadata2[key], enumerable: false };
|
|
2103
|
+
}
|
|
2104
|
+
Object.defineProperties(rule, descriptors);
|
|
2105
|
+
return rule;
|
|
2106
|
+
}
|
|
2107
|
+
function createRemoveAttributeRule(attribute, options) {
|
|
2108
|
+
const { when, severity = "warning", message, diagnostic, readsProps, tags } = options;
|
|
2109
|
+
const fix = removeAttributeFix(attribute);
|
|
2110
|
+
const rule = (context) => {
|
|
2111
|
+
if (!when(context)) return [];
|
|
2112
|
+
return [
|
|
2113
|
+
invalidWithFix({
|
|
2114
|
+
severity,
|
|
2115
|
+
attribute,
|
|
2116
|
+
...isDefined(message) && { message },
|
|
2117
|
+
...isDefined(diagnostic) && { diagnostic: diagnostic(context) },
|
|
2118
|
+
fix
|
|
2119
|
+
})
|
|
2120
|
+
];
|
|
2121
|
+
};
|
|
2122
|
+
return defineRuleMetadata(rule, {
|
|
2123
|
+
...isDefined(readsProps) && { readsProps },
|
|
2124
|
+
...isDefined(tags) && { tags }
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
2019
2127
|
|
|
2020
2128
|
// ../../lib/contract/src/children/get-type-name.ts
|
|
2021
2129
|
function getTypeName(value) {
|
|
@@ -2404,6 +2512,52 @@ var P_BLOCKED_TAGS = [
|
|
|
2404
2512
|
"ul"
|
|
2405
2513
|
];
|
|
2406
2514
|
|
|
2515
|
+
// ../core/src/html/anchor-rules.ts
|
|
2516
|
+
var DANGEROUS_URL_SCHEMES = ["javascript:", "data:", "vbscript:"];
|
|
2517
|
+
function normalizeForSchemeCheck(href) {
|
|
2518
|
+
return href.replace(/[\x00-\x20]/g, "").toLowerCase();
|
|
2519
|
+
}
|
|
2520
|
+
function isDangerousUrl(href) {
|
|
2521
|
+
if (!isString(href)) return false;
|
|
2522
|
+
const normalized = normalizeForSchemeCheck(href);
|
|
2523
|
+
return DANGEROUS_URL_SCHEMES.some((scheme) => normalized.startsWith(scheme));
|
|
2524
|
+
}
|
|
2525
|
+
var dangerousHrefRule = createRemoveAttributeRule("href", {
|
|
2526
|
+
when: ({ props }) => isDangerousUrl(props.href),
|
|
2527
|
+
severity: "warning",
|
|
2528
|
+
diagnostic: ({ props }) => HtmlDiagnostics.anchor.dangerousHref(props.href),
|
|
2529
|
+
readsProps: ["href"],
|
|
2530
|
+
tags: ["a"]
|
|
2531
|
+
});
|
|
2532
|
+
var roleButtonWithHrefRule = Object.assign(
|
|
2533
|
+
({ props }) => {
|
|
2534
|
+
if (props.role !== "button" || !isString(props.href) || props.href.length === 0) {
|
|
2535
|
+
return [];
|
|
2536
|
+
}
|
|
2537
|
+
const diagnostic = AnchorAccessibilityDiagnostics.roleButtonWithHref();
|
|
2538
|
+
return [invalidWithoutFix({ severity: diagnostic.severity, attribute: "role", diagnostic })];
|
|
2539
|
+
},
|
|
2540
|
+
{ readsProps: ["role", "href"], tags: ["a"] }
|
|
2541
|
+
);
|
|
2542
|
+
var ariaDisabledInertRule = Object.assign(
|
|
2543
|
+
({ props }) => {
|
|
2544
|
+
const ariaDisabled = props["aria-disabled"];
|
|
2545
|
+
const isDisabled = ariaDisabled === true || ariaDisabled === "true";
|
|
2546
|
+
const hasHref = isString(props.href) && props.href.length > 0;
|
|
2547
|
+
if (!isDisabled || !hasHref) return [];
|
|
2548
|
+
const diagnostic = AnchorAccessibilityDiagnostics.ariaDisabledInert();
|
|
2549
|
+
return [
|
|
2550
|
+
invalidWithoutFix({ severity: diagnostic.severity, attribute: "aria-disabled", diagnostic })
|
|
2551
|
+
];
|
|
2552
|
+
},
|
|
2553
|
+
{ readsProps: ["aria-disabled", "href"], tags: ["a"] }
|
|
2554
|
+
);
|
|
2555
|
+
var ANCHOR_RULES = [
|
|
2556
|
+
dangerousHrefRule,
|
|
2557
|
+
roleButtonWithHrefRule,
|
|
2558
|
+
ariaDisabledInertRule
|
|
2559
|
+
];
|
|
2560
|
+
|
|
2407
2561
|
// ../core/src/html/spec/vocabulary/input.ts
|
|
2408
2562
|
var TEXT_INPUT_TYPES = ["text", "search", "url", "tel", "email", "password"];
|
|
2409
2563
|
var NUMERIC_INPUT_TYPES = [
|
|
@@ -2483,12 +2637,12 @@ function createInputAttributeTypeRule({
|
|
|
2483
2637
|
// ../core/src/html/spec/validators/mutually-exclusive-validator.ts
|
|
2484
2638
|
function createMutuallyExclusiveRule({
|
|
2485
2639
|
props: conflictingProps,
|
|
2486
|
-
diagnostic:
|
|
2640
|
+
diagnostic: createDiagnostic2
|
|
2487
2641
|
}) {
|
|
2488
2642
|
const [first, second] = conflictingProps;
|
|
2489
2643
|
const rule = ({ tag, props }) => {
|
|
2490
2644
|
if (tag !== "input" || !props[first] || !props[second]) return [];
|
|
2491
|
-
const diagnostic =
|
|
2645
|
+
const diagnostic = createDiagnostic2();
|
|
2492
2646
|
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2493
2647
|
};
|
|
2494
2648
|
return Object.assign(rule, { readsProps: conflictingProps, tags: ["input"] });
|
|
@@ -2868,7 +3022,8 @@ var HTML_ARIA_RULES = [
|
|
|
2868
3022
|
landmarkRoleRule,
|
|
2869
3023
|
landmarkAccessibleNameRule,
|
|
2870
3024
|
roleNotPermittedRule,
|
|
2871
|
-
...INPUT_RULES
|
|
3025
|
+
...INPUT_RULES,
|
|
3026
|
+
...ANCHOR_RULES
|
|
2872
3027
|
];
|
|
2873
3028
|
|
|
2874
3029
|
// ../core/src/html/contracts/helpers.ts
|
|
@@ -3278,19 +3433,6 @@ function createClassPipeline(resolved) {
|
|
|
3278
3433
|
};
|
|
3279
3434
|
}
|
|
3280
3435
|
|
|
3281
|
-
// ../../lib/pipeline-kit/src/factory/define-pipeline.ts
|
|
3282
|
-
function definePipeline(factory) {
|
|
3283
|
-
const cache = /* @__PURE__ */ new WeakMap();
|
|
3284
|
-
return (resolved) => {
|
|
3285
|
-
let pipeline = cache.get(resolved);
|
|
3286
|
-
if (!pipeline) {
|
|
3287
|
-
pipeline = factory(resolved);
|
|
3288
|
-
cache.set(resolved, pipeline);
|
|
3289
|
-
}
|
|
3290
|
-
return pipeline;
|
|
3291
|
-
};
|
|
3292
|
-
}
|
|
3293
|
-
|
|
3294
3436
|
// ../core/src/options/resolve-factory-options.ts
|
|
3295
3437
|
import { resolveDiagnostics, silentDiagnostics } from "../_shared/diagnostics.js";
|
|
3296
3438
|
var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
|
|
@@ -3394,25 +3536,66 @@ function validateRenderProps(diagnostics, options, props, recipeKey) {
|
|
|
3394
3536
|
}
|
|
3395
3537
|
}
|
|
3396
3538
|
|
|
3539
|
+
// ../../lib/pipeline-kit/src/factory/define-pipeline.ts
|
|
3540
|
+
function definePipeline(factory) {
|
|
3541
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
3542
|
+
return (resolved) => {
|
|
3543
|
+
let pipeline = cache.get(resolved);
|
|
3544
|
+
if (!pipeline) {
|
|
3545
|
+
pipeline = factory(resolved);
|
|
3546
|
+
cache.set(resolved, pipeline);
|
|
3547
|
+
}
|
|
3548
|
+
return pipeline;
|
|
3549
|
+
};
|
|
3550
|
+
}
|
|
3551
|
+
|
|
3552
|
+
// ../core/src/factory/pipelines/generic.ts
|
|
3553
|
+
var createTagPipeline = (resolved) => makeResolveTag(resolved.defaultTag);
|
|
3554
|
+
var createPropsPipeline = (resolved) => (props) => mergeProps(resolved.defaultProps, props);
|
|
3555
|
+
var createHtmlPropNormalizersPipeline = () => getHtmlPropNormalizers;
|
|
3556
|
+
var createHtmlChildrenEvaluatorPipeline = () => getHtmlChildrenEvaluator;
|
|
3557
|
+
var createStylingClassPipeline = (resolved) => createClassPipeline(resolved);
|
|
3558
|
+
var memoizedTagPipeline = definePipeline(createTagPipeline);
|
|
3559
|
+
var memoizedPropsPipeline = definePipeline(createPropsPipeline);
|
|
3560
|
+
var memoizedHtmlPropNormalizersPipeline = definePipeline(createHtmlPropNormalizersPipeline);
|
|
3561
|
+
var memoizedHtmlChildrenEvaluatorPipeline = definePipeline(
|
|
3562
|
+
createHtmlChildrenEvaluatorPipeline
|
|
3563
|
+
);
|
|
3564
|
+
var memoizedClassPipeline = definePipeline(createStylingClassPipeline);
|
|
3565
|
+
|
|
3566
|
+
// ../core/src/factory/pipelines/aria.ts
|
|
3567
|
+
function resolveAriaRules(resolved) {
|
|
3568
|
+
return [.../* @__PURE__ */ new Set([...HTML_ARIA_RULES, ...resolved.ariaRules ?? []])];
|
|
3569
|
+
}
|
|
3570
|
+
var createAriaPipeline = (resolved) => {
|
|
3571
|
+
const rules = resolveAriaRules(resolved);
|
|
3572
|
+
const engine = new AriaPolicyEngine(resolved.diagnostics, rules.length ? { rules } : void 0);
|
|
3573
|
+
return (tag, props) => engine.validate(tag, props);
|
|
3574
|
+
};
|
|
3575
|
+
var memoizedAriaPipeline = definePipeline(createAriaPipeline);
|
|
3576
|
+
function resolveAriaPassthrough(_tag, props) {
|
|
3577
|
+
return { props };
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3397
3580
|
// ../core/src/factory/plugin-invariants.ts
|
|
3398
3581
|
import { throwDiagnostics } from "../_shared/diagnostics.js";
|
|
3399
3582
|
|
|
3400
3583
|
// ../core/src/factory/plugin-diagnostics.ts
|
|
3401
|
-
import { DiagnosticCategory as
|
|
3584
|
+
import { DiagnosticCategory as DiagnosticCategory7, DiagnosticCode as DiagnosticCode7 } from "../_shared/diagnostics.js";
|
|
3402
3585
|
var PluginDiagnostics = {
|
|
3403
3586
|
invalidShape(received) {
|
|
3404
|
-
const got = received
|
|
3587
|
+
const got = isNull(received) ? "null" : typeof received;
|
|
3405
3588
|
return {
|
|
3406
|
-
code:
|
|
3407
|
-
category:
|
|
3589
|
+
code: DiagnosticCode7.PluginInvalidShape,
|
|
3590
|
+
category: DiagnosticCategory7.Internal,
|
|
3408
3591
|
message: `[praxis-kit] Plugin factory must return an object with a 'pipeline' function. Got: ${got}.`
|
|
3409
3592
|
};
|
|
3410
3593
|
},
|
|
3411
3594
|
pipelineReturnType(received) {
|
|
3412
|
-
const got = received
|
|
3595
|
+
const got = isNull(received) ? "null" : Array.isArray(received) ? "array" : typeof received;
|
|
3413
3596
|
return {
|
|
3414
|
-
code:
|
|
3415
|
-
category:
|
|
3597
|
+
code: DiagnosticCode7.PluginPipelineReturnType,
|
|
3598
|
+
category: DiagnosticCategory7.Internal,
|
|
3416
3599
|
message: `[praxis-kit] Plugin pipeline must return a string. Got: ${got}.`
|
|
3417
3600
|
};
|
|
3418
3601
|
}
|
|
@@ -3420,60 +3603,41 @@ var PluginDiagnostics = {
|
|
|
3420
3603
|
|
|
3421
3604
|
// ../core/src/factory/plugin-invariants.ts
|
|
3422
3605
|
function assertPluginShape(result) {
|
|
3423
|
-
if (result
|
|
3606
|
+
if (isNull(result) || !isObject(result))
|
|
3424
3607
|
throwDiagnostics.error(PluginDiagnostics.invalidShape(result));
|
|
3425
3608
|
const plugin = result;
|
|
3426
|
-
if (
|
|
3427
|
-
throwDiagnostics.error(PluginDiagnostics.invalidShape(result));
|
|
3609
|
+
if (!isFunction(plugin.pipeline)) throwDiagnostics.error(PluginDiagnostics.invalidShape(result));
|
|
3428
3610
|
}
|
|
3429
3611
|
function guardPipeline(pipeline) {
|
|
3430
3612
|
if (process.env.NODE_ENV === "production") return pipeline;
|
|
3431
3613
|
return function guardedPipeline(tag, props, className, recipe) {
|
|
3432
3614
|
const result = pipeline(tag, props, className, recipe);
|
|
3433
|
-
if (
|
|
3434
|
-
throwDiagnostics.error(PluginDiagnostics.pipelineReturnType(result));
|
|
3615
|
+
if (!isString(result)) throwDiagnostics.error(PluginDiagnostics.pipelineReturnType(result));
|
|
3435
3616
|
return result;
|
|
3436
3617
|
};
|
|
3437
3618
|
}
|
|
3438
3619
|
|
|
3439
|
-
// ../core/src/factory/
|
|
3440
|
-
var createTagPipeline = (resolved) => makeResolveTag(resolved.defaultTag);
|
|
3441
|
-
var createPropsPipeline = (resolved) => (props) => mergeProps(resolved.defaultProps, props);
|
|
3442
|
-
var createHtmlPropNormalizersPipeline = () => getHtmlPropNormalizers;
|
|
3443
|
-
var createHtmlChildrenEvaluatorPipeline = () => getHtmlChildrenEvaluator;
|
|
3444
|
-
var createStylingClassPipeline = (resolved) => createClassPipeline(resolved);
|
|
3445
|
-
function resolveAriaRules(resolved) {
|
|
3446
|
-
return [.../* @__PURE__ */ new Set([...HTML_ARIA_RULES, ...resolved.ariaRules ?? []])];
|
|
3447
|
-
}
|
|
3448
|
-
var createAriaPipeline = (resolved) => {
|
|
3449
|
-
const rules = resolveAriaRules(resolved);
|
|
3450
|
-
const engine = new AriaPolicyEngine(resolved.diagnostics, rules.length ? { rules } : void 0);
|
|
3451
|
-
return (tag, props) => engine.validate(tag, props);
|
|
3452
|
-
};
|
|
3453
|
-
var memoizedTagPipeline = definePipeline(createTagPipeline);
|
|
3454
|
-
var memoizedPropsPipeline = definePipeline(createPropsPipeline);
|
|
3455
|
-
var memoizedHtmlPropNormalizersPipeline = definePipeline(createHtmlPropNormalizersPipeline);
|
|
3456
|
-
var memoizedHtmlChildrenEvaluatorPipeline = definePipeline(createHtmlChildrenEvaluatorPipeline);
|
|
3457
|
-
var memoizedClassPipeline = definePipeline(createStylingClassPipeline);
|
|
3458
|
-
var memoizedAriaPipeline = definePipeline(createAriaPipeline);
|
|
3459
|
-
function resolveAriaPassthrough(_tag, props) {
|
|
3460
|
-
return { props };
|
|
3461
|
-
}
|
|
3620
|
+
// ../core/src/factory/pipelines/styling.ts
|
|
3462
3621
|
function resolveClassPlugin(factory, resolved, diagnostics) {
|
|
3463
3622
|
if (!factory) return { pluginResult: void 0, classPipeline: memoizedClassPipeline(resolved) };
|
|
3464
3623
|
const pluginResult = factory(resolved, diagnostics);
|
|
3465
3624
|
assertPluginShape(pluginResult);
|
|
3466
3625
|
return { pluginResult, classPipeline: guardPipeline(pluginResult.pipeline) };
|
|
3467
3626
|
}
|
|
3468
|
-
|
|
3627
|
+
|
|
3628
|
+
// ../core/src/factory/create-polymorphic.ts
|
|
3629
|
+
function eraseResolvedShape(resolved) {
|
|
3630
|
+
return resolved;
|
|
3631
|
+
}
|
|
3632
|
+
function createPolymorphic(options = {}) {
|
|
3469
3633
|
const baseResolved = resolveFactoryOptions(options);
|
|
3470
|
-
const anyBaseResolved = baseResolved;
|
|
3634
|
+
const anyBaseResolved = eraseResolvedShape(baseResolved);
|
|
3471
3635
|
const resolved = Object.freeze({
|
|
3472
3636
|
...baseResolved,
|
|
3473
3637
|
htmlPropNormalizersFn: memoizedHtmlPropNormalizersPipeline(anyBaseResolved),
|
|
3474
3638
|
htmlChildrenEvaluatorFn: memoizedHtmlChildrenEvaluatorPipeline(anyBaseResolved)
|
|
3475
3639
|
});
|
|
3476
|
-
const anyResolved = resolved;
|
|
3640
|
+
const anyResolved = eraseResolvedShape(resolved);
|
|
3477
3641
|
if (process.env.NODE_ENV !== "production") {
|
|
3478
3642
|
validateFactoryOptions(resolved, resolved.diagnostics);
|
|
3479
3643
|
}
|
|
@@ -3514,7 +3678,7 @@ function enforceAllowedAs(tag, allowedAs, diagnostics, displayName) {
|
|
|
3514
3678
|
// ../../lib/adapter-utils/src/runtime/build-core-runtime.ts
|
|
3515
3679
|
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
3516
3680
|
function buildCoreRuntime(normalized) {
|
|
3517
|
-
const runtime =
|
|
3681
|
+
const runtime = createPolymorphic(normalized);
|
|
3518
3682
|
const ownedKeys = "classPlugin" in runtime ? runtime.classPlugin.ownedKeys ?? EMPTY_SET : EMPTY_SET;
|
|
3519
3683
|
return { runtime, ownedKeys };
|
|
3520
3684
|
}
|
|
@@ -3749,7 +3913,10 @@ function createContractComponent(options) {
|
|
|
3749
3913
|
const consumerRef = props.ref;
|
|
3750
3914
|
return (el) => {
|
|
3751
3915
|
if (typeof consumerRef === "function") consumerRef(el);
|
|
3752
|
-
const cleanup = onElement(
|
|
3916
|
+
const cleanup = onElement(
|
|
3917
|
+
el,
|
|
3918
|
+
() => props
|
|
3919
|
+
);
|
|
3753
3920
|
if (cleanup) onCleanup(cleanup);
|
|
3754
3921
|
};
|
|
3755
3922
|
}
|