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/preact/index.js
CHANGED
|
@@ -41,6 +41,9 @@ function dynamic(resolve) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
// ../../lib/primitive/src/guards/foundational/is-defined.ts
|
|
44
|
+
function isDefined(value) {
|
|
45
|
+
return value !== void 0;
|
|
46
|
+
}
|
|
44
47
|
function isUndefined(value) {
|
|
45
48
|
return value === void 0;
|
|
46
49
|
}
|
|
@@ -798,21 +801,65 @@ function getImplicitRole(tag, props) {
|
|
|
798
801
|
return void 0;
|
|
799
802
|
}
|
|
800
803
|
|
|
801
|
-
// ../../lib/contract/src/diagnostics/
|
|
804
|
+
// ../../lib/contract/src/diagnostics/anchor-accessibility.ts
|
|
802
805
|
import { DiagnosticCategory, DiagnosticCode } from "../_shared/diagnostics.js";
|
|
806
|
+
function createDiagnostic(input) {
|
|
807
|
+
return { category: DiagnosticCategory.Accessibility, ...input };
|
|
808
|
+
}
|
|
809
|
+
var AnchorAccessibilityDiagnostics = {
|
|
810
|
+
roleButtonWithHref() {
|
|
811
|
+
return createDiagnostic({
|
|
812
|
+
code: DiagnosticCode.A11yAnchorRoleButtonWithHref,
|
|
813
|
+
severity: "warning",
|
|
814
|
+
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.',
|
|
815
|
+
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.',
|
|
816
|
+
suggestions: [
|
|
817
|
+
{
|
|
818
|
+
title: "Use a real <button>",
|
|
819
|
+
description: "If this element should not navigate, render a <button> instead of an <a>."
|
|
820
|
+
},
|
|
821
|
+
{
|
|
822
|
+
title: 'Remove role="button"',
|
|
823
|
+
description: "If this element should navigate, keep the default link role."
|
|
824
|
+
}
|
|
825
|
+
]
|
|
826
|
+
});
|
|
827
|
+
},
|
|
828
|
+
ariaDisabledInert() {
|
|
829
|
+
return createDiagnostic({
|
|
830
|
+
code: DiagnosticCode.A11yAnchorAriaDisabledInert,
|
|
831
|
+
severity: "warning",
|
|
832
|
+
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.",
|
|
833
|
+
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.",
|
|
834
|
+
suggestions: [
|
|
835
|
+
{
|
|
836
|
+
title: "Remove href",
|
|
837
|
+
description: "If this element is temporarily unavailable, remove href until it can be activated."
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
title: "Prevent navigation when disabled",
|
|
841
|
+
description: "Prevent the click and keyboard activation when the link is disabled so it behaves consistently for all users."
|
|
842
|
+
}
|
|
843
|
+
]
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
// ../../lib/contract/src/diagnostics/aria.ts
|
|
849
|
+
import { DiagnosticCategory as DiagnosticCategory2, DiagnosticCode as DiagnosticCode2 } from "../_shared/diagnostics.js";
|
|
803
850
|
var AriaDiagnostics = {
|
|
804
851
|
/** Generic bridge for violations produced by external AriaRule functions. */
|
|
805
852
|
fromViolation(v) {
|
|
806
853
|
return {
|
|
807
|
-
code:
|
|
808
|
-
category:
|
|
854
|
+
code: DiagnosticCode2.AriaViolation,
|
|
855
|
+
category: DiagnosticCategory2.ARIA,
|
|
809
856
|
message: v.message
|
|
810
857
|
};
|
|
811
858
|
},
|
|
812
859
|
attributeInvalid(key, role) {
|
|
813
860
|
return {
|
|
814
|
-
code:
|
|
815
|
-
category:
|
|
861
|
+
code: DiagnosticCode2.AriaAttributeInvalid,
|
|
862
|
+
category: DiagnosticCategory2.ARIA,
|
|
816
863
|
message: `"${key}" is not valid on role="${role}". It will be removed.`,
|
|
817
864
|
rationale: "Invalid ARIA attributes are ignored by assistive technology and may trigger accessibility-tree warnings in browser devtools.",
|
|
818
865
|
suggestions: [
|
|
@@ -825,8 +872,8 @@ var AriaDiagnostics = {
|
|
|
825
872
|
},
|
|
826
873
|
missingLiveRegion(role, impliedLive) {
|
|
827
874
|
return {
|
|
828
|
-
code:
|
|
829
|
-
category:
|
|
875
|
+
code: DiagnosticCode2.AriaMissingLiveRegion,
|
|
876
|
+
category: DiagnosticCategory2.ARIA,
|
|
830
877
|
message: `role="${role}" implies aria-live="${impliedLive}" but it is missing. It has been injected.`,
|
|
831
878
|
rationale: "Live-region roles announce dynamic content changes to screen readers. Without aria-live the politeness level is unspecified and announcements may be silent.",
|
|
832
879
|
suggestions: [
|
|
@@ -840,8 +887,8 @@ var AriaDiagnostics = {
|
|
|
840
887
|
},
|
|
841
888
|
missingAtomic(role) {
|
|
842
889
|
return {
|
|
843
|
-
code:
|
|
844
|
-
category:
|
|
890
|
+
code: DiagnosticCode2.AriaMissingAtomic,
|
|
891
|
+
category: DiagnosticCategory2.ARIA,
|
|
845
892
|
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.`,
|
|
846
893
|
rationale: "aria-atomic controls whether assistive technology announces the entire live region or only the changed nodes. Omitting it leaves the behaviour browser-defined."
|
|
847
894
|
};
|
|
@@ -849,8 +896,8 @@ var AriaDiagnostics = {
|
|
|
849
896
|
relevantInvalidTokens(invalid) {
|
|
850
897
|
const quoted = invalid.map((t) => `"${t}"`).join(", ");
|
|
851
898
|
return {
|
|
852
|
-
code:
|
|
853
|
-
category:
|
|
899
|
+
code: DiagnosticCode2.AriaRelevantInvalidToken,
|
|
900
|
+
category: DiagnosticCategory2.ARIA,
|
|
854
901
|
message: `aria-relevant contains invalid token(s): ${quoted}. Valid tokens are: additions, removals, text, all.`,
|
|
855
902
|
rationale: "aria-relevant accepts a space-separated list of change types. Unrecognised tokens are silently ignored by assistive technology, making the attribute ineffective.",
|
|
856
903
|
suggestions: [
|
|
@@ -863,8 +910,8 @@ var AriaDiagnostics = {
|
|
|
863
910
|
},
|
|
864
911
|
relevantSuperseded() {
|
|
865
912
|
return {
|
|
866
|
-
code:
|
|
867
|
-
category:
|
|
913
|
+
code: DiagnosticCode2.AriaRelevantSuperseded,
|
|
914
|
+
category: DiagnosticCategory2.ARIA,
|
|
868
915
|
message: 'aria-relevant includes "all" alongside other tokens. "all" supersedes additions, removals, and text \u2014 use aria-relevant="all" alone.',
|
|
869
916
|
rationale: '"all" is equivalent to "additions removals text". Combining it with other tokens is redundant and may confuse readers of the markup.',
|
|
870
917
|
suggestions: [
|
|
@@ -877,8 +924,8 @@ var AriaDiagnostics = {
|
|
|
877
924
|
},
|
|
878
925
|
missingAccessibleName(tag) {
|
|
879
926
|
return {
|
|
880
|
-
code:
|
|
881
|
-
category:
|
|
927
|
+
code: DiagnosticCode2.AriaMissingAccessibleName,
|
|
928
|
+
category: DiagnosticCategory2.ARIA,
|
|
882
929
|
message: `<${tag}> has no accessible name. Add aria-label or aria-labelledby.`,
|
|
883
930
|
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.",
|
|
884
931
|
suggestions: [
|
|
@@ -895,8 +942,8 @@ var AriaDiagnostics = {
|
|
|
895
942
|
},
|
|
896
943
|
attributeOnPresentational(attr, tag) {
|
|
897
944
|
return {
|
|
898
|
-
code:
|
|
899
|
-
category:
|
|
945
|
+
code: DiagnosticCode2.AriaAttributeOnPresentational,
|
|
946
|
+
category: DiagnosticCategory2.ARIA,
|
|
900
947
|
message: `"${attr}" is not allowed on a presentational <${tag}>. Presentational elements are invisible to assistive technology.`,
|
|
901
948
|
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.',
|
|
902
949
|
suggestions: [
|
|
@@ -909,8 +956,8 @@ var AriaDiagnostics = {
|
|
|
909
956
|
},
|
|
910
957
|
ariaHiddenOnFocusable(tag) {
|
|
911
958
|
return {
|
|
912
|
-
code:
|
|
913
|
-
category:
|
|
959
|
+
code: DiagnosticCode2.AriaHiddenOnFocusable,
|
|
960
|
+
category: DiagnosticCategory2.ARIA,
|
|
914
961
|
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.`,
|
|
915
962
|
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.',
|
|
916
963
|
suggestions: [
|
|
@@ -928,8 +975,8 @@ var AriaDiagnostics = {
|
|
|
928
975
|
invalidAttributeValue(attr, value, expected) {
|
|
929
976
|
const got = value === null ? "null" : value === void 0 ? "undefined" : typeof value === "string" ? `"${value}"` : String(value);
|
|
930
977
|
return {
|
|
931
|
-
code:
|
|
932
|
-
category:
|
|
978
|
+
code: DiagnosticCode2.AriaInvalidAttributeValue,
|
|
979
|
+
category: DiagnosticCategory2.ARIA,
|
|
933
980
|
message: `"${attr}" has an invalid value (${got}). Expected: ${expected}.`,
|
|
934
981
|
rationale: "ARIA attributes with invalid values are silently ignored by assistive technology, making the markup semantically inert.",
|
|
935
982
|
suggestions: [
|
|
@@ -942,8 +989,8 @@ var AriaDiagnostics = {
|
|
|
942
989
|
},
|
|
943
990
|
redundantAriaLevel(tag, level) {
|
|
944
991
|
return {
|
|
945
|
-
code:
|
|
946
|
-
category:
|
|
992
|
+
code: DiagnosticCode2.AriaRedundantLevelAttribute,
|
|
993
|
+
category: DiagnosticCategory2.ARIA,
|
|
947
994
|
message: `aria-level="${level}" is redundant on <${tag}>: the element already has an implicit heading level of ${level}. Remove the attribute.`,
|
|
948
995
|
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>).',
|
|
949
996
|
suggestions: [
|
|
@@ -956,8 +1003,8 @@ var AriaDiagnostics = {
|
|
|
956
1003
|
},
|
|
957
1004
|
requiredProperty(attr, role) {
|
|
958
1005
|
return {
|
|
959
|
-
code:
|
|
960
|
-
category:
|
|
1006
|
+
code: DiagnosticCode2.AriaRequiredProperty,
|
|
1007
|
+
category: DiagnosticCategory2.ARIA,
|
|
961
1008
|
message: `"${attr}" is required for role="${role}" but is missing.`,
|
|
962
1009
|
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.`,
|
|
963
1010
|
suggestions: [
|
|
@@ -970,8 +1017,8 @@ var AriaDiagnostics = {
|
|
|
970
1017
|
},
|
|
971
1018
|
invalidRole(role, tag) {
|
|
972
1019
|
return {
|
|
973
|
-
code:
|
|
974
|
-
category:
|
|
1020
|
+
code: DiagnosticCode2.AriaInvalidRole,
|
|
1021
|
+
category: DiagnosticCategory2.ARIA,
|
|
975
1022
|
message: `Invalid role "${role ?? ""}" on <${tag}>.`,
|
|
976
1023
|
rationale: "An unrecognised or misapplied ARIA role is ignored by assistive technology and may degrade the accessibility of the element."
|
|
977
1024
|
};
|
|
@@ -979,12 +1026,12 @@ var AriaDiagnostics = {
|
|
|
979
1026
|
};
|
|
980
1027
|
|
|
981
1028
|
// ../../lib/contract/src/diagnostics/contract.ts
|
|
982
|
-
import { DiagnosticCategory as
|
|
1029
|
+
import { DiagnosticCategory as DiagnosticCategory3, DiagnosticCode as DiagnosticCode3 } from "../_shared/diagnostics.js";
|
|
983
1030
|
var ContractDiagnostics = {
|
|
984
1031
|
unexpectedChild(typeName, index, context) {
|
|
985
1032
|
return {
|
|
986
|
-
code:
|
|
987
|
-
category:
|
|
1033
|
+
code: DiagnosticCode3.UnexpectedChild,
|
|
1034
|
+
category: DiagnosticCategory3.Contract,
|
|
988
1035
|
component: context,
|
|
989
1036
|
message: `${context}: unexpected child "${typeName}" at index ${index}.`
|
|
990
1037
|
};
|
|
@@ -992,69 +1039,69 @@ var ContractDiagnostics = {
|
|
|
992
1039
|
ambiguousChild(typeName, index, ruleNames, context) {
|
|
993
1040
|
const quoted = ruleNames.map((n) => `"${n}"`).join(" and ");
|
|
994
1041
|
return {
|
|
995
|
-
code:
|
|
996
|
-
category:
|
|
1042
|
+
code: DiagnosticCode3.AmbiguousChild,
|
|
1043
|
+
category: DiagnosticCategory3.Contract,
|
|
997
1044
|
component: context,
|
|
998
1045
|
message: `${context}: child "${typeName}" at index ${index} matches multiple child rules: ${quoted}.`
|
|
999
1046
|
};
|
|
1000
1047
|
},
|
|
1001
1048
|
cardinalityMin(ruleName, min, context) {
|
|
1002
1049
|
return {
|
|
1003
|
-
code:
|
|
1004
|
-
category:
|
|
1050
|
+
code: DiagnosticCode3.CardinalityMin,
|
|
1051
|
+
category: DiagnosticCategory3.Contract,
|
|
1005
1052
|
component: context,
|
|
1006
1053
|
message: `${context}: "${ruleName}" requires at least ${min}.`
|
|
1007
1054
|
};
|
|
1008
1055
|
},
|
|
1009
1056
|
cardinalityMax(ruleName, max, context) {
|
|
1010
1057
|
return {
|
|
1011
|
-
code:
|
|
1012
|
-
category:
|
|
1058
|
+
code: DiagnosticCode3.CardinalityMax,
|
|
1059
|
+
category: DiagnosticCategory3.Contract,
|
|
1013
1060
|
component: context,
|
|
1014
1061
|
message: `${context}: "${ruleName}" allows at most ${max}.`
|
|
1015
1062
|
};
|
|
1016
1063
|
},
|
|
1017
1064
|
positionViolation(ruleName, position, index, context) {
|
|
1018
1065
|
return {
|
|
1019
|
-
code:
|
|
1020
|
-
category:
|
|
1066
|
+
code: DiagnosticCode3.PositionViolation,
|
|
1067
|
+
category: DiagnosticCategory3.Contract,
|
|
1021
1068
|
component: context,
|
|
1022
1069
|
message: `${context}: "${ruleName}" must be ${position}, got index ${index}`
|
|
1023
1070
|
};
|
|
1024
1071
|
},
|
|
1025
1072
|
unknownVariantDim(component, label2, dim) {
|
|
1026
1073
|
return {
|
|
1027
|
-
code:
|
|
1028
|
-
category:
|
|
1074
|
+
code: DiagnosticCode3.ContractUnknownVariantDim,
|
|
1075
|
+
category: DiagnosticCategory3.Contract,
|
|
1029
1076
|
message: `${component}: ${label2} references unknown variant "${dim}".`
|
|
1030
1077
|
};
|
|
1031
1078
|
},
|
|
1032
1079
|
unknownVariantValue(component, label2, dim, value, valid) {
|
|
1033
1080
|
return {
|
|
1034
|
-
code:
|
|
1035
|
-
category:
|
|
1081
|
+
code: DiagnosticCode3.ContractUnknownVariantValue,
|
|
1082
|
+
category: DiagnosticCategory3.Contract,
|
|
1036
1083
|
message: `${component}: ${label2} sets "${dim}" to unknown value "${value}" (valid: ${valid.join(", ")}).`
|
|
1037
1084
|
};
|
|
1038
1085
|
},
|
|
1039
1086
|
unknownRecipeKey(component, key) {
|
|
1040
1087
|
return {
|
|
1041
|
-
code:
|
|
1042
|
-
category:
|
|
1088
|
+
code: DiagnosticCode3.ContractUnknownRecipeKey,
|
|
1089
|
+
category: DiagnosticCategory3.Contract,
|
|
1043
1090
|
message: `${component} Unknown recipeKey "${key}" \u2014 no preset with that name exists.`
|
|
1044
1091
|
};
|
|
1045
1092
|
},
|
|
1046
1093
|
invalidVariantValue(component, key, value) {
|
|
1047
1094
|
return {
|
|
1048
|
-
code:
|
|
1049
|
-
category:
|
|
1095
|
+
code: DiagnosticCode3.ContractInvalidVariantValue,
|
|
1096
|
+
category: DiagnosticCategory3.Contract,
|
|
1050
1097
|
message: `${component} Variant "${key}=${value}" is not a defined value for the "${key}" dimension.`
|
|
1051
1098
|
};
|
|
1052
1099
|
},
|
|
1053
1100
|
allowedAsViolation(tag, allowedAs, component) {
|
|
1054
1101
|
const allowed = allowedAs.map((t) => `"${String(t)}"`).join(", ");
|
|
1055
1102
|
return {
|
|
1056
|
-
code:
|
|
1057
|
-
category:
|
|
1103
|
+
code: DiagnosticCode3.AllowedAsViolation,
|
|
1104
|
+
category: DiagnosticCategory3.Contract,
|
|
1058
1105
|
component,
|
|
1059
1106
|
message: `<${component}>: "as" prop received "${tag}" but only [${allowed}] are allowed.`
|
|
1060
1107
|
};
|
|
@@ -1062,68 +1109,68 @@ var ContractDiagnostics = {
|
|
|
1062
1109
|
};
|
|
1063
1110
|
|
|
1064
1111
|
// ../../lib/contract/src/diagnostics/html.ts
|
|
1065
|
-
import { DiagnosticCategory as
|
|
1112
|
+
import { DiagnosticCategory as DiagnosticCategory4, DiagnosticCode as DiagnosticCode4 } from "../_shared/diagnostics.js";
|
|
1066
1113
|
var ATTRIBUTE_IGNORED_CODES = {
|
|
1067
|
-
checked:
|
|
1068
|
-
multiple:
|
|
1069
|
-
maxLength:
|
|
1070
|
-
minLength:
|
|
1071
|
-
pattern:
|
|
1072
|
-
min:
|
|
1073
|
-
max:
|
|
1074
|
-
step:
|
|
1075
|
-
accept:
|
|
1076
|
-
capture:
|
|
1077
|
-
size:
|
|
1078
|
-
alt:
|
|
1079
|
-
height:
|
|
1080
|
-
width:
|
|
1114
|
+
checked: DiagnosticCode4.HtmlInputCheckedIgnoredForType,
|
|
1115
|
+
multiple: DiagnosticCode4.HtmlInputMultipleIgnoredForType,
|
|
1116
|
+
maxLength: DiagnosticCode4.HtmlInputMaxLengthIgnoredForType,
|
|
1117
|
+
minLength: DiagnosticCode4.HtmlInputMinLengthIgnoredForType,
|
|
1118
|
+
pattern: DiagnosticCode4.HtmlInputPatternIgnoredForType,
|
|
1119
|
+
min: DiagnosticCode4.HtmlInputMinIgnoredForType,
|
|
1120
|
+
max: DiagnosticCode4.HtmlInputMaxIgnoredForType,
|
|
1121
|
+
step: DiagnosticCode4.HtmlInputStepIgnoredForType,
|
|
1122
|
+
accept: DiagnosticCode4.HtmlInputAcceptIgnoredForType,
|
|
1123
|
+
capture: DiagnosticCode4.HtmlInputCaptureIgnoredForType,
|
|
1124
|
+
size: DiagnosticCode4.HtmlInputSizeIgnoredForType,
|
|
1125
|
+
alt: DiagnosticCode4.HtmlInputAltIgnoredForType,
|
|
1126
|
+
height: DiagnosticCode4.HtmlInputHeightIgnoredForType,
|
|
1127
|
+
width: DiagnosticCode4.HtmlInputWidthIgnoredForType
|
|
1081
1128
|
};
|
|
1082
1129
|
var HtmlDiagnostics = {
|
|
1083
1130
|
emptyRole(tag) {
|
|
1084
1131
|
return {
|
|
1085
|
-
code:
|
|
1086
|
-
category:
|
|
1132
|
+
code: DiagnosticCode4.HtmlEmptyRole,
|
|
1133
|
+
category: DiagnosticCategory4.HTML,
|
|
1087
1134
|
severity: "warning",
|
|
1088
1135
|
message: `<${tag}> has an explicit empty role="". Omit the attribute instead.`
|
|
1089
1136
|
};
|
|
1090
1137
|
},
|
|
1091
1138
|
implicitRoleRedundant(tag, implicitRole) {
|
|
1092
1139
|
return {
|
|
1093
|
-
code:
|
|
1094
|
-
category:
|
|
1140
|
+
code: DiagnosticCode4.HtmlImplicitRoleRedundant,
|
|
1141
|
+
category: DiagnosticCategory4.HTML,
|
|
1095
1142
|
severity: "warning",
|
|
1096
1143
|
message: `<${tag}> already has implicit role="${implicitRole}". Avoid redundant role assignment.`
|
|
1097
1144
|
};
|
|
1098
1145
|
},
|
|
1099
1146
|
implicitRoleOverride(tag, implicitRole, role) {
|
|
1100
1147
|
return {
|
|
1101
|
-
code:
|
|
1102
|
-
category:
|
|
1148
|
+
code: DiagnosticCode4.HtmlImplicitRoleOverride,
|
|
1149
|
+
category: DiagnosticCategory4.HTML,
|
|
1103
1150
|
severity: "error",
|
|
1104
1151
|
message: `<${tag}> should not override its implicit role="${implicitRole}" with role="${role}".`
|
|
1105
1152
|
};
|
|
1106
1153
|
},
|
|
1107
1154
|
standaloneRegionOverride(tag, implicitRole) {
|
|
1108
1155
|
return {
|
|
1109
|
-
code:
|
|
1110
|
-
category:
|
|
1156
|
+
code: DiagnosticCode4.HtmlStandaloneRegionOverride,
|
|
1157
|
+
category: DiagnosticCategory4.HTML,
|
|
1111
1158
|
severity: "error",
|
|
1112
1159
|
message: `<${tag}> is a self-contained element with implicit role="${implicitRole}". Assigning role="region" has been removed.`
|
|
1113
1160
|
};
|
|
1114
1161
|
},
|
|
1115
1162
|
landmarkRoleOverride(tag, implicitRole, role) {
|
|
1116
1163
|
return {
|
|
1117
|
-
code:
|
|
1118
|
-
category:
|
|
1164
|
+
code: DiagnosticCode4.HtmlLandmarkRoleOverride,
|
|
1165
|
+
category: DiagnosticCategory4.HTML,
|
|
1119
1166
|
severity: "error",
|
|
1120
1167
|
message: `<${tag}> has a fixed landmark role="${implicitRole}". role="${role}" overrides it and confuses assistive technology. The override has been removed.`
|
|
1121
1168
|
};
|
|
1122
1169
|
},
|
|
1123
1170
|
invalidChild(child, parent, allowed) {
|
|
1124
1171
|
return {
|
|
1125
|
-
code:
|
|
1126
|
-
category:
|
|
1172
|
+
code: DiagnosticCode4.HtmlInvalidChild,
|
|
1173
|
+
category: DiagnosticCategory4.HTML,
|
|
1127
1174
|
severity: "error",
|
|
1128
1175
|
message: `<${child}> is not a valid direct child of <${parent}>. Allowed: ${allowed}.`
|
|
1129
1176
|
};
|
|
@@ -1131,8 +1178,8 @@ var HtmlDiagnostics = {
|
|
|
1131
1178
|
roleNotPermitted(tag, role, allowedRoles) {
|
|
1132
1179
|
const allowed = allowedRoles.length > 0 ? allowedRoles.map((r) => `"${r}"`).join(", ") : "none \u2014 no explicit role is permitted on this element";
|
|
1133
1180
|
return {
|
|
1134
|
-
code:
|
|
1135
|
-
category:
|
|
1181
|
+
code: DiagnosticCode4.HtmlRoleNotPermitted,
|
|
1182
|
+
category: DiagnosticCategory4.HTML,
|
|
1136
1183
|
severity: "error",
|
|
1137
1184
|
message: `role="${role}" is not permitted on <${tag}>. Allowed alternate role(s): ${allowed}.`,
|
|
1138
1185
|
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.'
|
|
@@ -1143,8 +1190,8 @@ var HtmlDiagnostics = {
|
|
|
1143
1190
|
input: {
|
|
1144
1191
|
unsupportedType(type) {
|
|
1145
1192
|
return {
|
|
1146
|
-
code:
|
|
1147
|
-
category:
|
|
1193
|
+
code: DiagnosticCode4.HtmlInputUnsupportedType,
|
|
1194
|
+
category: DiagnosticCategory4.HTML,
|
|
1148
1195
|
severity: "warning",
|
|
1149
1196
|
message: `type="${type}" is not a value defined by the HTML specification. Browsers silently fall back to type="text".`,
|
|
1150
1197
|
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).',
|
|
@@ -1164,7 +1211,7 @@ var HtmlDiagnostics = {
|
|
|
1164
1211
|
if (!code) throw new Error(`No DiagnosticCode registered for input attribute "${attribute}"`);
|
|
1165
1212
|
return {
|
|
1166
1213
|
code,
|
|
1167
|
-
category:
|
|
1214
|
+
category: DiagnosticCategory4.HTML,
|
|
1168
1215
|
severity: "warning",
|
|
1169
1216
|
message: `"${attribute}" is ignored on <input type="${type}">.`,
|
|
1170
1217
|
rationale: `"${attribute}" only has an effect when type is one of: ${allowed}. Browsers silently ignore it on other input types.`,
|
|
@@ -1176,18 +1223,30 @@ var HtmlDiagnostics = {
|
|
|
1176
1223
|
]
|
|
1177
1224
|
};
|
|
1178
1225
|
}
|
|
1226
|
+
},
|
|
1227
|
+
// Reserved for <a>-specific facts (HTML3201–3299, see codes.ts).
|
|
1228
|
+
anchor: {
|
|
1229
|
+
dangerousHref(href) {
|
|
1230
|
+
return {
|
|
1231
|
+
code: DiagnosticCode4.HtmlAnchorDangerousHref,
|
|
1232
|
+
category: DiagnosticCategory4.HTML,
|
|
1233
|
+
severity: "warning",
|
|
1234
|
+
message: `href="${href}" uses a scheme that executes attacker-controlled content when navigated to. It has been removed.`,
|
|
1235
|
+
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.'
|
|
1236
|
+
};
|
|
1237
|
+
}
|
|
1179
1238
|
}
|
|
1180
1239
|
};
|
|
1181
1240
|
|
|
1182
1241
|
// ../../lib/contract/src/diagnostics/input-accessibility.ts
|
|
1183
|
-
import { DiagnosticCategory as
|
|
1242
|
+
import { DiagnosticCategory as DiagnosticCategory5, DiagnosticCode as DiagnosticCode5 } from "../_shared/diagnostics.js";
|
|
1184
1243
|
function accessibilityFact(input) {
|
|
1185
|
-
return { category:
|
|
1244
|
+
return { category: DiagnosticCategory5.Accessibility, ...input };
|
|
1186
1245
|
}
|
|
1187
1246
|
var InputAccessibilityDiagnostics = {
|
|
1188
1247
|
missingAccessibleName() {
|
|
1189
1248
|
return accessibilityFact({
|
|
1190
|
-
code:
|
|
1249
|
+
code: DiagnosticCode5.A11yInputMissingAccessibleName,
|
|
1191
1250
|
severity: "warning",
|
|
1192
1251
|
message: "This input has no accessible name. Add an associated <label>, aria-label, or aria-labelledby.",
|
|
1193
1252
|
rationale: "Assistive technology announces a form field by its accessible name; without one, users of screen readers cannot tell what the field is for.",
|
|
@@ -1202,7 +1261,7 @@ var InputAccessibilityDiagnostics = {
|
|
|
1202
1261
|
},
|
|
1203
1262
|
placeholderIsNotLabel() {
|
|
1204
1263
|
return accessibilityFact({
|
|
1205
|
-
code:
|
|
1264
|
+
code: DiagnosticCode5.A11yInputPlaceholderNotLabel,
|
|
1206
1265
|
severity: "warning",
|
|
1207
1266
|
message: "Placeholder text does not provide an accessible name. Add an associated <label>, aria-label, or aria-labelledby.",
|
|
1208
1267
|
rationale: "Placeholder text disappears as users interact with the field and is not treated as the control's accessible name by many assistive technologies.",
|
|
@@ -1217,7 +1276,7 @@ var InputAccessibilityDiagnostics = {
|
|
|
1217
1276
|
},
|
|
1218
1277
|
passwordMissingAutocomplete() {
|
|
1219
1278
|
return accessibilityFact({
|
|
1220
|
-
code:
|
|
1279
|
+
code: DiagnosticCode5.A11yInputPasswordAutocomplete,
|
|
1221
1280
|
severity: "warning",
|
|
1222
1281
|
message: "Password inputs should specify an autoComplete value.",
|
|
1223
1282
|
rationale: "Without an explicit autocomplete hint, password managers and browsers cannot reliably tell a sign-in field apart from a password-creation field.",
|
|
@@ -1235,7 +1294,7 @@ var InputAccessibilityDiagnostics = {
|
|
|
1235
1294
|
},
|
|
1236
1295
|
requiredReadOnlyConflict() {
|
|
1237
1296
|
return accessibilityFact({
|
|
1238
|
-
code:
|
|
1297
|
+
code: DiagnosticCode5.A11yInputRequiredReadOnlyConflict,
|
|
1239
1298
|
severity: "warning",
|
|
1240
1299
|
message: "The required and readOnly attributes are both present. A read-only field cannot satisfy required validation through user interaction.",
|
|
1241
1300
|
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."
|
|
@@ -1244,28 +1303,28 @@ var InputAccessibilityDiagnostics = {
|
|
|
1244
1303
|
};
|
|
1245
1304
|
|
|
1246
1305
|
// ../../lib/contract/src/diagnostics/slot.ts
|
|
1247
|
-
import { DiagnosticCategory as
|
|
1306
|
+
import { DiagnosticCategory as DiagnosticCategory6, DiagnosticCode as DiagnosticCode6 } from "../_shared/diagnostics.js";
|
|
1248
1307
|
var SlotDiagnostics = {
|
|
1249
1308
|
exclusive(name) {
|
|
1250
1309
|
return {
|
|
1251
|
-
code:
|
|
1252
|
-
category:
|
|
1310
|
+
code: DiagnosticCode6.SlotExclusive,
|
|
1311
|
+
category: DiagnosticCategory6.Contract,
|
|
1253
1312
|
component: name,
|
|
1254
1313
|
message: `${name}: "as" and "asChild" are mutually exclusive`
|
|
1255
1314
|
};
|
|
1256
1315
|
},
|
|
1257
1316
|
singleChildRequired(name, elementTerm) {
|
|
1258
1317
|
return {
|
|
1259
|
-
code:
|
|
1260
|
-
category:
|
|
1318
|
+
code: DiagnosticCode6.SlotSingleChild,
|
|
1319
|
+
category: DiagnosticCategory6.Contract,
|
|
1261
1320
|
component: name,
|
|
1262
1321
|
message: `${name}: asChild requires a ${elementTerm} child`
|
|
1263
1322
|
};
|
|
1264
1323
|
},
|
|
1265
1324
|
singleChildExceeded(name, elementTerm, count) {
|
|
1266
1325
|
return {
|
|
1267
|
-
code:
|
|
1268
|
-
category:
|
|
1326
|
+
code: DiagnosticCode6.SlotSingleChild,
|
|
1327
|
+
category: DiagnosticCategory6.Contract,
|
|
1269
1328
|
component: name,
|
|
1270
1329
|
message: `${name}: asChild requires exactly one ${elementTerm} child, got ${count}`
|
|
1271
1330
|
};
|
|
@@ -1273,16 +1332,16 @@ var SlotDiagnostics = {
|
|
|
1273
1332
|
discardedChildren(name, elementTerm, count) {
|
|
1274
1333
|
const suffix = count === 1 ? "" : "ren";
|
|
1275
1334
|
return {
|
|
1276
|
-
code:
|
|
1277
|
-
category:
|
|
1335
|
+
code: DiagnosticCode6.SlotDiscardedChildren,
|
|
1336
|
+
category: DiagnosticCategory6.Contract,
|
|
1278
1337
|
component: name,
|
|
1279
1338
|
message: `${name}: asChild discarded ${count} non-element child${suffix} \u2014 only ${elementTerm}s are valid asChild children.`
|
|
1280
1339
|
};
|
|
1281
1340
|
},
|
|
1282
1341
|
renderFnRequired(name, received) {
|
|
1283
1342
|
return {
|
|
1284
|
-
code:
|
|
1285
|
-
category:
|
|
1343
|
+
code: DiagnosticCode6.SlotRenderFn,
|
|
1344
|
+
category: DiagnosticCategory6.Contract,
|
|
1286
1345
|
component: name,
|
|
1287
1346
|
message: `${name}: asChild requires a render function as children, got ${received}`
|
|
1288
1347
|
};
|
|
@@ -2028,6 +2087,27 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
2028
2087
|
};
|
|
2029
2088
|
|
|
2030
2089
|
// ../../lib/contract/src/aria/factories.ts
|
|
2090
|
+
function invalidWithoutFix(input) {
|
|
2091
|
+
return {
|
|
2092
|
+
valid: false,
|
|
2093
|
+
fixable: false,
|
|
2094
|
+
severity: input.severity,
|
|
2095
|
+
...isDefined(input.attribute) && { attribute: input.attribute },
|
|
2096
|
+
...isDefined(input.message) && { message: input.message },
|
|
2097
|
+
...isDefined(input.diagnostic) && { diagnostic: input.diagnostic }
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
function invalidWithFix(input) {
|
|
2101
|
+
return {
|
|
2102
|
+
valid: false,
|
|
2103
|
+
fixable: true,
|
|
2104
|
+
severity: input.severity,
|
|
2105
|
+
...isDefined(input.attribute) && { attribute: input.attribute },
|
|
2106
|
+
...isDefined(input.message) && { message: input.message },
|
|
2107
|
+
...isDefined(input.diagnostic) && { diagnostic: input.diagnostic },
|
|
2108
|
+
fix: input.fix
|
|
2109
|
+
};
|
|
2110
|
+
}
|
|
2031
2111
|
function removeProp(props, key) {
|
|
2032
2112
|
const next = { ...props };
|
|
2033
2113
|
delete next[key];
|
|
@@ -2043,6 +2123,34 @@ function removeAttributeFix(attribute) {
|
|
|
2043
2123
|
}
|
|
2044
2124
|
});
|
|
2045
2125
|
}
|
|
2126
|
+
function defineRuleMetadata(rule, metadata2) {
|
|
2127
|
+
const descriptors = {};
|
|
2128
|
+
for (const key of Object.keys(metadata2)) {
|
|
2129
|
+
descriptors[key] = { value: metadata2[key], enumerable: false };
|
|
2130
|
+
}
|
|
2131
|
+
Object.defineProperties(rule, descriptors);
|
|
2132
|
+
return rule;
|
|
2133
|
+
}
|
|
2134
|
+
function createRemoveAttributeRule(attribute, options) {
|
|
2135
|
+
const { when, severity = "warning", message, diagnostic, readsProps, tags } = options;
|
|
2136
|
+
const fix = removeAttributeFix(attribute);
|
|
2137
|
+
const rule = (context) => {
|
|
2138
|
+
if (!when(context)) return [];
|
|
2139
|
+
return [
|
|
2140
|
+
invalidWithFix({
|
|
2141
|
+
severity,
|
|
2142
|
+
attribute,
|
|
2143
|
+
...isDefined(message) && { message },
|
|
2144
|
+
...isDefined(diagnostic) && { diagnostic: diagnostic(context) },
|
|
2145
|
+
fix
|
|
2146
|
+
})
|
|
2147
|
+
];
|
|
2148
|
+
};
|
|
2149
|
+
return defineRuleMetadata(rule, {
|
|
2150
|
+
...isDefined(readsProps) && { readsProps },
|
|
2151
|
+
...isDefined(tags) && { tags }
|
|
2152
|
+
});
|
|
2153
|
+
}
|
|
2046
2154
|
|
|
2047
2155
|
// ../../lib/contract/src/children/get-type-name.ts
|
|
2048
2156
|
function getTypeName(value) {
|
|
@@ -2431,6 +2539,52 @@ var P_BLOCKED_TAGS = [
|
|
|
2431
2539
|
"ul"
|
|
2432
2540
|
];
|
|
2433
2541
|
|
|
2542
|
+
// ../core/src/html/anchor-rules.ts
|
|
2543
|
+
var DANGEROUS_URL_SCHEMES = ["javascript:", "data:", "vbscript:"];
|
|
2544
|
+
function normalizeForSchemeCheck(href) {
|
|
2545
|
+
return href.replace(/[\x00-\x20]/g, "").toLowerCase();
|
|
2546
|
+
}
|
|
2547
|
+
function isDangerousUrl(href) {
|
|
2548
|
+
if (!isString(href)) return false;
|
|
2549
|
+
const normalized = normalizeForSchemeCheck(href);
|
|
2550
|
+
return DANGEROUS_URL_SCHEMES.some((scheme) => normalized.startsWith(scheme));
|
|
2551
|
+
}
|
|
2552
|
+
var dangerousHrefRule = createRemoveAttributeRule("href", {
|
|
2553
|
+
when: ({ props }) => isDangerousUrl(props.href),
|
|
2554
|
+
severity: "warning",
|
|
2555
|
+
diagnostic: ({ props }) => HtmlDiagnostics.anchor.dangerousHref(props.href),
|
|
2556
|
+
readsProps: ["href"],
|
|
2557
|
+
tags: ["a"]
|
|
2558
|
+
});
|
|
2559
|
+
var roleButtonWithHrefRule = Object.assign(
|
|
2560
|
+
({ props }) => {
|
|
2561
|
+
if (props.role !== "button" || !isString(props.href) || props.href.length === 0) {
|
|
2562
|
+
return [];
|
|
2563
|
+
}
|
|
2564
|
+
const diagnostic = AnchorAccessibilityDiagnostics.roleButtonWithHref();
|
|
2565
|
+
return [invalidWithoutFix({ severity: diagnostic.severity, attribute: "role", diagnostic })];
|
|
2566
|
+
},
|
|
2567
|
+
{ readsProps: ["role", "href"], tags: ["a"] }
|
|
2568
|
+
);
|
|
2569
|
+
var ariaDisabledInertRule = Object.assign(
|
|
2570
|
+
({ props }) => {
|
|
2571
|
+
const ariaDisabled = props["aria-disabled"];
|
|
2572
|
+
const isDisabled = ariaDisabled === true || ariaDisabled === "true";
|
|
2573
|
+
const hasHref = isString(props.href) && props.href.length > 0;
|
|
2574
|
+
if (!isDisabled || !hasHref) return [];
|
|
2575
|
+
const diagnostic = AnchorAccessibilityDiagnostics.ariaDisabledInert();
|
|
2576
|
+
return [
|
|
2577
|
+
invalidWithoutFix({ severity: diagnostic.severity, attribute: "aria-disabled", diagnostic })
|
|
2578
|
+
];
|
|
2579
|
+
},
|
|
2580
|
+
{ readsProps: ["aria-disabled", "href"], tags: ["a"] }
|
|
2581
|
+
);
|
|
2582
|
+
var ANCHOR_RULES = [
|
|
2583
|
+
dangerousHrefRule,
|
|
2584
|
+
roleButtonWithHrefRule,
|
|
2585
|
+
ariaDisabledInertRule
|
|
2586
|
+
];
|
|
2587
|
+
|
|
2434
2588
|
// ../core/src/html/spec/vocabulary/input.ts
|
|
2435
2589
|
var TEXT_INPUT_TYPES = ["text", "search", "url", "tel", "email", "password"];
|
|
2436
2590
|
var NUMERIC_INPUT_TYPES = [
|
|
@@ -2510,12 +2664,12 @@ function createInputAttributeTypeRule({
|
|
|
2510
2664
|
// ../core/src/html/spec/validators/mutually-exclusive-validator.ts
|
|
2511
2665
|
function createMutuallyExclusiveRule({
|
|
2512
2666
|
props: conflictingProps,
|
|
2513
|
-
diagnostic:
|
|
2667
|
+
diagnostic: createDiagnostic2
|
|
2514
2668
|
}) {
|
|
2515
2669
|
const [first, second] = conflictingProps;
|
|
2516
2670
|
const rule = ({ tag, props }) => {
|
|
2517
2671
|
if (tag !== "input" || !props[first] || !props[second]) return [];
|
|
2518
|
-
const diagnostic =
|
|
2672
|
+
const diagnostic = createDiagnostic2();
|
|
2519
2673
|
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2520
2674
|
};
|
|
2521
2675
|
return Object.assign(rule, { readsProps: conflictingProps, tags: ["input"] });
|
|
@@ -2895,7 +3049,8 @@ var HTML_ARIA_RULES = [
|
|
|
2895
3049
|
landmarkRoleRule,
|
|
2896
3050
|
landmarkAccessibleNameRule,
|
|
2897
3051
|
roleNotPermittedRule,
|
|
2898
|
-
...INPUT_RULES
|
|
3052
|
+
...INPUT_RULES,
|
|
3053
|
+
...ANCHOR_RULES
|
|
2899
3054
|
];
|
|
2900
3055
|
|
|
2901
3056
|
// ../core/src/html/contracts/helpers.ts
|
|
@@ -3305,19 +3460,6 @@ function createClassPipeline(resolved) {
|
|
|
3305
3460
|
};
|
|
3306
3461
|
}
|
|
3307
3462
|
|
|
3308
|
-
// ../../lib/pipeline-kit/src/factory/define-pipeline.ts
|
|
3309
|
-
function definePipeline(factory) {
|
|
3310
|
-
const cache = /* @__PURE__ */ new WeakMap();
|
|
3311
|
-
return (resolved) => {
|
|
3312
|
-
let pipeline = cache.get(resolved);
|
|
3313
|
-
if (!pipeline) {
|
|
3314
|
-
pipeline = factory(resolved);
|
|
3315
|
-
cache.set(resolved, pipeline);
|
|
3316
|
-
}
|
|
3317
|
-
return pipeline;
|
|
3318
|
-
};
|
|
3319
|
-
}
|
|
3320
|
-
|
|
3321
3463
|
// ../core/src/options/resolve-factory-options.ts
|
|
3322
3464
|
import { resolveDiagnostics, silentDiagnostics } from "../_shared/diagnostics.js";
|
|
3323
3465
|
var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
|
|
@@ -3421,25 +3563,66 @@ function validateRenderProps(diagnostics, options, props, recipeKey) {
|
|
|
3421
3563
|
}
|
|
3422
3564
|
}
|
|
3423
3565
|
|
|
3566
|
+
// ../../lib/pipeline-kit/src/factory/define-pipeline.ts
|
|
3567
|
+
function definePipeline(factory) {
|
|
3568
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
3569
|
+
return (resolved) => {
|
|
3570
|
+
let pipeline = cache.get(resolved);
|
|
3571
|
+
if (!pipeline) {
|
|
3572
|
+
pipeline = factory(resolved);
|
|
3573
|
+
cache.set(resolved, pipeline);
|
|
3574
|
+
}
|
|
3575
|
+
return pipeline;
|
|
3576
|
+
};
|
|
3577
|
+
}
|
|
3578
|
+
|
|
3579
|
+
// ../core/src/factory/pipelines/generic.ts
|
|
3580
|
+
var createTagPipeline = (resolved) => makeResolveTag(resolved.defaultTag);
|
|
3581
|
+
var createPropsPipeline = (resolved) => (props) => mergeProps(resolved.defaultProps, props);
|
|
3582
|
+
var createHtmlPropNormalizersPipeline = () => getHtmlPropNormalizers;
|
|
3583
|
+
var createHtmlChildrenEvaluatorPipeline = () => getHtmlChildrenEvaluator;
|
|
3584
|
+
var createStylingClassPipeline = (resolved) => createClassPipeline(resolved);
|
|
3585
|
+
var memoizedTagPipeline = definePipeline(createTagPipeline);
|
|
3586
|
+
var memoizedPropsPipeline = definePipeline(createPropsPipeline);
|
|
3587
|
+
var memoizedHtmlPropNormalizersPipeline = definePipeline(createHtmlPropNormalizersPipeline);
|
|
3588
|
+
var memoizedHtmlChildrenEvaluatorPipeline = definePipeline(
|
|
3589
|
+
createHtmlChildrenEvaluatorPipeline
|
|
3590
|
+
);
|
|
3591
|
+
var memoizedClassPipeline = definePipeline(createStylingClassPipeline);
|
|
3592
|
+
|
|
3593
|
+
// ../core/src/factory/pipelines/aria.ts
|
|
3594
|
+
function resolveAriaRules(resolved) {
|
|
3595
|
+
return [.../* @__PURE__ */ new Set([...HTML_ARIA_RULES, ...resolved.ariaRules ?? []])];
|
|
3596
|
+
}
|
|
3597
|
+
var createAriaPipeline = (resolved) => {
|
|
3598
|
+
const rules = resolveAriaRules(resolved);
|
|
3599
|
+
const engine = new AriaPolicyEngine(resolved.diagnostics, rules.length ? { rules } : void 0);
|
|
3600
|
+
return (tag, props) => engine.validate(tag, props);
|
|
3601
|
+
};
|
|
3602
|
+
var memoizedAriaPipeline = definePipeline(createAriaPipeline);
|
|
3603
|
+
function resolveAriaPassthrough(_tag, props) {
|
|
3604
|
+
return { props };
|
|
3605
|
+
}
|
|
3606
|
+
|
|
3424
3607
|
// ../core/src/factory/plugin-invariants.ts
|
|
3425
3608
|
import { throwDiagnostics } from "../_shared/diagnostics.js";
|
|
3426
3609
|
|
|
3427
3610
|
// ../core/src/factory/plugin-diagnostics.ts
|
|
3428
|
-
import { DiagnosticCategory as
|
|
3611
|
+
import { DiagnosticCategory as DiagnosticCategory7, DiagnosticCode as DiagnosticCode7 } from "../_shared/diagnostics.js";
|
|
3429
3612
|
var PluginDiagnostics = {
|
|
3430
3613
|
invalidShape(received) {
|
|
3431
|
-
const got = received
|
|
3614
|
+
const got = isNull(received) ? "null" : typeof received;
|
|
3432
3615
|
return {
|
|
3433
|
-
code:
|
|
3434
|
-
category:
|
|
3616
|
+
code: DiagnosticCode7.PluginInvalidShape,
|
|
3617
|
+
category: DiagnosticCategory7.Internal,
|
|
3435
3618
|
message: `[praxis-kit] Plugin factory must return an object with a 'pipeline' function. Got: ${got}.`
|
|
3436
3619
|
};
|
|
3437
3620
|
},
|
|
3438
3621
|
pipelineReturnType(received) {
|
|
3439
|
-
const got = received
|
|
3622
|
+
const got = isNull(received) ? "null" : Array.isArray(received) ? "array" : typeof received;
|
|
3440
3623
|
return {
|
|
3441
|
-
code:
|
|
3442
|
-
category:
|
|
3624
|
+
code: DiagnosticCode7.PluginPipelineReturnType,
|
|
3625
|
+
category: DiagnosticCategory7.Internal,
|
|
3443
3626
|
message: `[praxis-kit] Plugin pipeline must return a string. Got: ${got}.`
|
|
3444
3627
|
};
|
|
3445
3628
|
}
|
|
@@ -3447,60 +3630,41 @@ var PluginDiagnostics = {
|
|
|
3447
3630
|
|
|
3448
3631
|
// ../core/src/factory/plugin-invariants.ts
|
|
3449
3632
|
function assertPluginShape(result) {
|
|
3450
|
-
if (result
|
|
3633
|
+
if (isNull(result) || !isObject(result))
|
|
3451
3634
|
throwDiagnostics.error(PluginDiagnostics.invalidShape(result));
|
|
3452
3635
|
const plugin = result;
|
|
3453
|
-
if (
|
|
3454
|
-
throwDiagnostics.error(PluginDiagnostics.invalidShape(result));
|
|
3636
|
+
if (!isFunction(plugin.pipeline)) throwDiagnostics.error(PluginDiagnostics.invalidShape(result));
|
|
3455
3637
|
}
|
|
3456
3638
|
function guardPipeline(pipeline) {
|
|
3457
3639
|
if (process.env.NODE_ENV === "production") return pipeline;
|
|
3458
3640
|
return function guardedPipeline(tag, props, className, recipe) {
|
|
3459
3641
|
const result = pipeline(tag, props, className, recipe);
|
|
3460
|
-
if (
|
|
3461
|
-
throwDiagnostics.error(PluginDiagnostics.pipelineReturnType(result));
|
|
3642
|
+
if (!isString(result)) throwDiagnostics.error(PluginDiagnostics.pipelineReturnType(result));
|
|
3462
3643
|
return result;
|
|
3463
3644
|
};
|
|
3464
3645
|
}
|
|
3465
3646
|
|
|
3466
|
-
// ../core/src/factory/
|
|
3467
|
-
var createTagPipeline = (resolved) => makeResolveTag(resolved.defaultTag);
|
|
3468
|
-
var createPropsPipeline = (resolved) => (props) => mergeProps(resolved.defaultProps, props);
|
|
3469
|
-
var createHtmlPropNormalizersPipeline = () => getHtmlPropNormalizers;
|
|
3470
|
-
var createHtmlChildrenEvaluatorPipeline = () => getHtmlChildrenEvaluator;
|
|
3471
|
-
var createStylingClassPipeline = (resolved) => createClassPipeline(resolved);
|
|
3472
|
-
function resolveAriaRules(resolved) {
|
|
3473
|
-
return [.../* @__PURE__ */ new Set([...HTML_ARIA_RULES, ...resolved.ariaRules ?? []])];
|
|
3474
|
-
}
|
|
3475
|
-
var createAriaPipeline = (resolved) => {
|
|
3476
|
-
const rules = resolveAriaRules(resolved);
|
|
3477
|
-
const engine = new AriaPolicyEngine(resolved.diagnostics, rules.length ? { rules } : void 0);
|
|
3478
|
-
return (tag, props) => engine.validate(tag, props);
|
|
3479
|
-
};
|
|
3480
|
-
var memoizedTagPipeline = definePipeline(createTagPipeline);
|
|
3481
|
-
var memoizedPropsPipeline = definePipeline(createPropsPipeline);
|
|
3482
|
-
var memoizedHtmlPropNormalizersPipeline = definePipeline(createHtmlPropNormalizersPipeline);
|
|
3483
|
-
var memoizedHtmlChildrenEvaluatorPipeline = definePipeline(createHtmlChildrenEvaluatorPipeline);
|
|
3484
|
-
var memoizedClassPipeline = definePipeline(createStylingClassPipeline);
|
|
3485
|
-
var memoizedAriaPipeline = definePipeline(createAriaPipeline);
|
|
3486
|
-
function resolveAriaPassthrough(_tag, props) {
|
|
3487
|
-
return { props };
|
|
3488
|
-
}
|
|
3647
|
+
// ../core/src/factory/pipelines/styling.ts
|
|
3489
3648
|
function resolveClassPlugin(factory, resolved, diagnostics) {
|
|
3490
3649
|
if (!factory) return { pluginResult: void 0, classPipeline: memoizedClassPipeline(resolved) };
|
|
3491
3650
|
const pluginResult = factory(resolved, diagnostics);
|
|
3492
3651
|
assertPluginShape(pluginResult);
|
|
3493
3652
|
return { pluginResult, classPipeline: guardPipeline(pluginResult.pipeline) };
|
|
3494
3653
|
}
|
|
3495
|
-
|
|
3654
|
+
|
|
3655
|
+
// ../core/src/factory/create-polymorphic.ts
|
|
3656
|
+
function eraseResolvedShape(resolved) {
|
|
3657
|
+
return resolved;
|
|
3658
|
+
}
|
|
3659
|
+
function createPolymorphic(options = {}) {
|
|
3496
3660
|
const baseResolved = resolveFactoryOptions(options);
|
|
3497
|
-
const anyBaseResolved = baseResolved;
|
|
3661
|
+
const anyBaseResolved = eraseResolvedShape(baseResolved);
|
|
3498
3662
|
const resolved = Object.freeze({
|
|
3499
3663
|
...baseResolved,
|
|
3500
3664
|
htmlPropNormalizersFn: memoizedHtmlPropNormalizersPipeline(anyBaseResolved),
|
|
3501
3665
|
htmlChildrenEvaluatorFn: memoizedHtmlChildrenEvaluatorPipeline(anyBaseResolved)
|
|
3502
3666
|
});
|
|
3503
|
-
const anyResolved = resolved;
|
|
3667
|
+
const anyResolved = eraseResolvedShape(resolved);
|
|
3504
3668
|
if (process.env.NODE_ENV !== "production") {
|
|
3505
3669
|
validateFactoryOptions(resolved, resolved.diagnostics);
|
|
3506
3670
|
}
|
|
@@ -3541,7 +3705,7 @@ function enforceAllowedAs(tag, allowedAs, diagnostics, displayName) {
|
|
|
3541
3705
|
// ../../lib/adapter-utils/src/runtime/build-core-runtime.ts
|
|
3542
3706
|
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
3543
3707
|
function buildCoreRuntime(normalized) {
|
|
3544
|
-
const runtime =
|
|
3708
|
+
const runtime = createPolymorphic(normalized);
|
|
3545
3709
|
const ownedKeys = "classPlugin" in runtime ? runtime.classPlugin.ownedKeys ?? EMPTY_SET : EMPTY_SET;
|
|
3546
3710
|
return { runtime, ownedKeys };
|
|
3547
3711
|
}
|
|
@@ -3946,7 +4110,11 @@ function createContractComponent(options) {
|
|
|
3946
4110
|
const onElementRef = useCallback((el) => {
|
|
3947
4111
|
if (!onElement) return;
|
|
3948
4112
|
if (el) {
|
|
3949
|
-
cleanupRef.current
|
|
4113
|
+
cleanupRef.current?.();
|
|
4114
|
+
cleanupRef.current = onElement(
|
|
4115
|
+
el,
|
|
4116
|
+
() => propsRef.current
|
|
4117
|
+
) ?? void 0;
|
|
3950
4118
|
} else {
|
|
3951
4119
|
cleanupRef.current?.();
|
|
3952
4120
|
cleanupRef.current = void 0;
|