@tamagui/style-grammar 0.0.0-bootstrap.0 → 3.0.0-beta.643.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/LICENSE +21 -0
- package/README.md +33 -1
- package/dist/cjs/backgroundFamily.cjs +176 -0
- package/dist/cjs/backgroundFamily.native.cjs +195 -0
- package/dist/cjs/backgroundFamily.native.js +197 -0
- package/dist/cjs/backgroundFamily.native.js.map +1 -0
- package/dist/cjs/borderFamily.cjs +169 -0
- package/dist/cjs/borderFamily.native.cjs +247 -0
- package/dist/cjs/borderFamily.native.js +249 -0
- package/dist/cjs/borderFamily.native.js.map +1 -0
- package/dist/cjs/candidate.cjs +608 -0
- package/dist/cjs/candidate.native.cjs +821 -0
- package/dist/cjs/candidate.native.js +823 -0
- package/dist/cjs/candidate.native.js.map +1 -0
- package/dist/cjs/candidateTarget.cjs +50 -0
- package/dist/cjs/candidateTarget.native.cjs +88 -0
- package/dist/cjs/candidateTarget.native.js +90 -0
- package/dist/cjs/candidateTarget.native.js.map +1 -0
- package/dist/cjs/clauseCapability.cjs +130 -0
- package/dist/cjs/clauseCapability.native.cjs +152 -0
- package/dist/cjs/clauseCapability.native.js +154 -0
- package/dist/cjs/clauseCapability.native.js.map +1 -0
- package/dist/cjs/clausePrecedence.cjs +153 -0
- package/dist/cjs/clausePrecedence.native.cjs +204 -0
- package/dist/cjs/clausePrecedence.native.js +206 -0
- package/dist/cjs/clausePrecedence.native.js.map +1 -0
- package/dist/cjs/clauseSources.cjs +47 -0
- package/dist/cjs/clauseSources.native.cjs +49 -0
- package/dist/cjs/clauseSources.native.js +51 -0
- package/dist/cjs/clauseSources.native.js.map +1 -0
- package/dist/cjs/config.cjs +130 -0
- package/dist/cjs/config.native.cjs +185 -0
- package/dist/cjs/config.native.js +187 -0
- package/dist/cjs/config.native.js.map +1 -0
- package/dist/cjs/evaluateProgram.cjs +65 -0
- package/dist/cjs/evaluateProgram.native.cjs +70 -0
- package/dist/cjs/evaluateProgram.native.js +72 -0
- package/dist/cjs/evaluateProgram.native.js.map +1 -0
- package/dist/cjs/fontShorthand.cjs +207 -0
- package/dist/cjs/fontShorthand.native.cjs +260 -0
- package/dist/cjs/fontShorthand.native.js +262 -0
- package/dist/cjs/fontShorthand.native.js.map +1 -0
- package/dist/cjs/geometricShorthand.cjs +122 -0
- package/dist/cjs/geometricShorthand.native.cjs +128 -0
- package/dist/cjs/geometricShorthand.native.js +130 -0
- package/dist/cjs/geometricShorthand.native.js.map +1 -0
- package/dist/cjs/index.cjs +19 -0
- package/dist/cjs/index.native.cjs +21 -0
- package/dist/cjs/index.native.js +23 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/cjs/lowerProgram.cjs +205 -0
- package/dist/cjs/lowerProgram.native.cjs +257 -0
- package/dist/cjs/lowerProgram.native.js +259 -0
- package/dist/cjs/lowerProgram.native.js.map +1 -0
- package/dist/cjs/mergeFlatValues.cjs +50 -0
- package/dist/cjs/mergeFlatValues.native.cjs +71 -0
- package/dist/cjs/mergeFlatValues.native.js +73 -0
- package/dist/cjs/mergeFlatValues.native.js.map +1 -0
- package/dist/cjs/modifierRegistry.cjs +246 -0
- package/dist/cjs/modifierRegistry.native.cjs +426 -0
- package/dist/cjs/modifierRegistry.native.js +428 -0
- package/dist/cjs/modifierRegistry.native.js.map +1 -0
- package/dist/cjs/payloadShape.cjs +69 -0
- package/dist/cjs/payloadShape.native.cjs +71 -0
- package/dist/cjs/payloadShape.native.js +73 -0
- package/dist/cjs/payloadShape.native.js.map +1 -0
- package/dist/cjs/programEligibility.cjs +46 -0
- package/dist/cjs/programEligibility.native.cjs +48 -0
- package/dist/cjs/programEligibility.native.js +50 -0
- package/dist/cjs/programEligibility.native.js.map +1 -0
- package/dist/cjs/programHash.cjs +86 -0
- package/dist/cjs/programHash.native.cjs +106 -0
- package/dist/cjs/programHash.native.js +108 -0
- package/dist/cjs/programHash.native.js.map +1 -0
- package/dist/cjs/programs.cjs +128 -0
- package/dist/cjs/programs.native.cjs +220 -0
- package/dist/cjs/programs.native.js +222 -0
- package/dist/cjs/programs.native.js.map +1 -0
- package/dist/cjs/registry.cjs +629 -0
- package/dist/cjs/registry.native.cjs +635 -0
- package/dist/cjs/registry.native.js +637 -0
- package/dist/cjs/registry.native.js.map +1 -0
- package/dist/cjs/resolvePayload.cjs +296 -0
- package/dist/cjs/resolvePayload.native.cjs +302 -0
- package/dist/cjs/resolvePayload.native.js +304 -0
- package/dist/cjs/resolvePayload.native.js.map +1 -0
- package/dist/cjs/runtime.cjs +50 -0
- package/dist/cjs/runtime.native.cjs +52 -0
- package/dist/cjs/runtime.native.js +54 -0
- package/dist/cjs/runtime.native.js.map +1 -0
- package/dist/cjs/safeAreaVariables.cjs +42 -0
- package/dist/cjs/safeAreaVariables.native.cjs +44 -0
- package/dist/cjs/safeAreaVariables.native.js +46 -0
- package/dist/cjs/safeAreaVariables.native.js.map +1 -0
- package/dist/cjs/scanFlatValue.cjs +181 -0
- package/dist/cjs/scanFlatValue.native.cjs +183 -0
- package/dist/cjs/scanFlatValue.native.js +185 -0
- package/dist/cjs/scanFlatValue.native.js.map +1 -0
- package/dist/cjs/serializePayload.cjs +149 -0
- package/dist/cjs/serializePayload.native.cjs +187 -0
- package/dist/cjs/serializePayload.native.js +189 -0
- package/dist/cjs/serializePayload.native.js.map +1 -0
- package/dist/cjs/stateModifiers.cjs +43 -0
- package/dist/cjs/stateModifiers.native.cjs +45 -0
- package/dist/cjs/stateModifiers.native.js +47 -0
- package/dist/cjs/stateModifiers.native.js.map +1 -0
- package/dist/cjs/states.cjs +97 -0
- package/dist/cjs/states.native.cjs +131 -0
- package/dist/cjs/states.native.js +133 -0
- package/dist/cjs/states.native.js.map +1 -0
- package/dist/cjs/table.cjs +54 -0
- package/dist/cjs/table.native.cjs +135 -0
- package/dist/cjs/table.native.js +137 -0
- package/dist/cjs/table.native.js.map +1 -0
- package/dist/cjs/textDecorationFamily.cjs +129 -0
- package/dist/cjs/textDecorationFamily.native.cjs +199 -0
- package/dist/cjs/textDecorationFamily.native.js +201 -0
- package/dist/cjs/textDecorationFamily.native.js.map +1 -0
- package/dist/cjs/tooling.cjs +26 -0
- package/dist/cjs/tooling.native.cjs +28 -0
- package/dist/cjs/tooling.native.js +30 -0
- package/dist/cjs/tooling.native.js.map +1 -0
- package/dist/cjs/toolingAnnotations.cjs +105 -0
- package/dist/cjs/toolingAnnotations.native.cjs +133 -0
- package/dist/cjs/toolingAnnotations.native.js +135 -0
- package/dist/cjs/toolingAnnotations.native.js.map +1 -0
- package/dist/cjs/toolingDiagnostics.cjs +459 -0
- package/dist/cjs/toolingDiagnostics.native.cjs +788 -0
- package/dist/cjs/toolingDiagnostics.native.js +790 -0
- package/dist/cjs/toolingDiagnostics.native.js.map +1 -0
- package/dist/cjs/toolingRegistry.cjs +159 -0
- package/dist/cjs/toolingRegistry.native.cjs +164 -0
- package/dist/cjs/toolingRegistry.native.js +166 -0
- package/dist/cjs/toolingRegistry.native.js.map +1 -0
- package/dist/cjs/transformFamily.cjs +425 -0
- package/dist/cjs/transformFamily.native.cjs +517 -0
- package/dist/cjs/transformFamily.native.js +519 -0
- package/dist/cjs/transformFamily.native.js.map +1 -0
- package/dist/cjs/transition.cjs +459 -0
- package/dist/cjs/transition.native.cjs +499 -0
- package/dist/cjs/transition.native.js +501 -0
- package/dist/cjs/transition.native.js.map +1 -0
- package/dist/cjs/transitionAlign.cjs +115 -0
- package/dist/cjs/transitionAlign.native.cjs +154 -0
- package/dist/cjs/transitionAlign.native.js +156 -0
- package/dist/cjs/transitionAlign.native.js.map +1 -0
- package/dist/cjs/transitionLegacy.cjs +217 -0
- package/dist/cjs/transitionLegacy.native.cjs +260 -0
- package/dist/cjs/transitionLegacy.native.js +262 -0
- package/dist/cjs/transitionLegacy.native.js.map +1 -0
- package/dist/cjs/transitionNative.cjs +281 -0
- package/dist/cjs/transitionNative.native.cjs +285 -0
- package/dist/cjs/transitionNative.native.js +287 -0
- package/dist/cjs/transitionNative.native.js.map +1 -0
- package/dist/cjs/unitlessNumbers.cjs +86 -0
- package/dist/cjs/unitlessNumbers.native.cjs +106 -0
- package/dist/cjs/unitlessNumbers.native.js +108 -0
- package/dist/cjs/unitlessNumbers.native.js.map +1 -0
- package/dist/cjs/v6ThemeNames.cjs +47 -0
- package/dist/cjs/v6ThemeNames.native.cjs +53 -0
- package/dist/cjs/v6ThemeNames.native.js +55 -0
- package/dist/cjs/v6ThemeNames.native.js.map +1 -0
- package/dist/cjs/valueParser.cjs +148 -0
- package/dist/cjs/valueParser.native.cjs +150 -0
- package/dist/cjs/valueParser.native.js +152 -0
- package/dist/cjs/valueParser.native.js.map +1 -0
- package/dist/cjs/valueTypes.cjs +38 -0
- package/dist/cjs/valueTypes.native.cjs +40 -0
- package/dist/cjs/valueTypes.native.js +42 -0
- package/dist/cjs/valueTypes.native.js.map +1 -0
- package/dist/esm/backgroundFamily.mjs +150 -0
- package/dist/esm/backgroundFamily.mjs.map +1 -0
- package/dist/esm/backgroundFamily.native.js +167 -0
- package/dist/esm/backgroundFamily.native.js.map +1 -0
- package/dist/esm/borderFamily.mjs +146 -0
- package/dist/esm/borderFamily.mjs.map +1 -0
- package/dist/esm/borderFamily.native.js +222 -0
- package/dist/esm/borderFamily.native.js.map +1 -0
- package/dist/esm/candidate.mjs +581 -0
- package/dist/esm/candidate.mjs.map +1 -0
- package/dist/esm/candidate.native.js +792 -0
- package/dist/esm/candidate.native.js.map +1 -0
- package/dist/esm/candidateTarget.mjs +29 -0
- package/dist/esm/candidateTarget.mjs.map +1 -0
- package/dist/esm/candidateTarget.native.js +65 -0
- package/dist/esm/candidateTarget.native.js.map +1 -0
- package/dist/esm/clauseCapability.mjs +107 -0
- package/dist/esm/clauseCapability.mjs.map +1 -0
- package/dist/esm/clauseCapability.native.js +127 -0
- package/dist/esm/clauseCapability.native.js.map +1 -0
- package/dist/esm/clausePrecedence.mjs +121 -0
- package/dist/esm/clausePrecedence.mjs.map +1 -0
- package/dist/esm/clausePrecedence.native.js +170 -0
- package/dist/esm/clausePrecedence.native.js.map +1 -0
- package/dist/esm/clauseSources.mjs +23 -0
- package/dist/esm/clauseSources.mjs.map +1 -0
- package/dist/esm/clauseSources.native.js +23 -0
- package/dist/esm/clauseSources.native.js.map +1 -0
- package/dist/esm/config.mjs +103 -0
- package/dist/esm/config.mjs.map +1 -0
- package/dist/esm/config.native.js +156 -0
- package/dist/esm/config.native.js.map +1 -0
- package/dist/esm/evaluateProgram.mjs +45 -0
- package/dist/esm/evaluateProgram.mjs.map +1 -0
- package/dist/esm/evaluateProgram.native.js +48 -0
- package/dist/esm/evaluateProgram.native.js.map +1 -0
- package/dist/esm/fontShorthand.mjs +184 -0
- package/dist/esm/fontShorthand.mjs.map +1 -0
- package/dist/esm/fontShorthand.native.js +235 -0
- package/dist/esm/fontShorthand.native.js.map +1 -0
- package/dist/esm/geometricShorthand.mjs +102 -0
- package/dist/esm/geometricShorthand.mjs.map +1 -0
- package/dist/esm/geometricShorthand.native.js +106 -0
- package/dist/esm/geometricShorthand.native.js.map +1 -0
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/index.native.js +1 -0
- package/dist/esm/lowerProgram.mjs +182 -0
- package/dist/esm/lowerProgram.mjs.map +1 -0
- package/dist/esm/lowerProgram.native.js +232 -0
- package/dist/esm/lowerProgram.native.js.map +1 -0
- package/dist/esm/mergeFlatValues.mjs +27 -0
- package/dist/esm/mergeFlatValues.mjs.map +1 -0
- package/dist/esm/mergeFlatValues.native.js +46 -0
- package/dist/esm/mergeFlatValues.native.js.map +1 -0
- package/dist/esm/modifierRegistry.mjs +219 -0
- package/dist/esm/modifierRegistry.mjs.map +1 -0
- package/dist/esm/modifierRegistry.native.js +397 -0
- package/dist/esm/modifierRegistry.native.js.map +1 -0
- package/dist/esm/payloadShape.mjs +49 -0
- package/dist/esm/payloadShape.mjs.map +1 -0
- package/dist/esm/payloadShape.native.js +49 -0
- package/dist/esm/payloadShape.native.js.map +1 -0
- package/dist/esm/programEligibility.mjs +22 -0
- package/dist/esm/programEligibility.mjs.map +1 -0
- package/dist/esm/programEligibility.native.js +22 -0
- package/dist/esm/programEligibility.native.js.map +1 -0
- package/dist/esm/programHash.mjs +62 -0
- package/dist/esm/programHash.mjs.map +1 -0
- package/dist/esm/programHash.native.js +80 -0
- package/dist/esm/programHash.native.js.map +1 -0
- package/dist/esm/programs.mjs +103 -0
- package/dist/esm/programs.mjs.map +1 -0
- package/dist/esm/programs.native.js +193 -0
- package/dist/esm/programs.native.js.map +1 -0
- package/dist/esm/registry.mjs +595 -0
- package/dist/esm/registry.mjs.map +1 -0
- package/dist/esm/registry.native.js +599 -0
- package/dist/esm/registry.native.js.map +1 -0
- package/dist/esm/resolvePayload.mjs +273 -0
- package/dist/esm/resolvePayload.mjs.map +1 -0
- package/dist/esm/resolvePayload.native.js +277 -0
- package/dist/esm/resolvePayload.native.js.map +1 -0
- package/dist/esm/runtime.mjs +63 -0
- package/dist/esm/runtime.native.js +63 -0
- package/dist/esm/safeAreaVariables.mjs +18 -0
- package/dist/esm/safeAreaVariables.mjs.map +1 -0
- package/dist/esm/safeAreaVariables.native.js +18 -0
- package/dist/esm/safeAreaVariables.native.js.map +1 -0
- package/dist/esm/scanFlatValue.mjs +160 -0
- package/dist/esm/scanFlatValue.mjs.map +1 -0
- package/dist/esm/scanFlatValue.native.js +160 -0
- package/dist/esm/scanFlatValue.native.js.map +1 -0
- package/dist/esm/serializePayload.mjs +125 -0
- package/dist/esm/serializePayload.mjs.map +1 -0
- package/dist/esm/serializePayload.native.js +161 -0
- package/dist/esm/serializePayload.native.js.map +1 -0
- package/dist/esm/stateModifiers.mjs +19 -0
- package/dist/esm/stateModifiers.mjs.map +1 -0
- package/dist/esm/stateModifiers.native.js +19 -0
- package/dist/esm/stateModifiers.native.js.map +1 -0
- package/dist/esm/states.mjs +69 -0
- package/dist/esm/states.mjs.map +1 -0
- package/dist/esm/states.native.js +101 -0
- package/dist/esm/states.native.js.map +1 -0
- package/dist/esm/table.mjs +31 -0
- package/dist/esm/table.mjs.map +1 -0
- package/dist/esm/table.native.js +110 -0
- package/dist/esm/table.native.js.map +1 -0
- package/dist/esm/textDecorationFamily.mjs +106 -0
- package/dist/esm/textDecorationFamily.mjs.map +1 -0
- package/dist/esm/textDecorationFamily.native.js +174 -0
- package/dist/esm/textDecorationFamily.native.js.map +1 -0
- package/dist/esm/tooling.mjs +15 -0
- package/dist/esm/tooling.native.js +15 -0
- package/dist/esm/toolingAnnotations.mjs +85 -0
- package/dist/esm/toolingAnnotations.mjs.map +1 -0
- package/dist/esm/toolingAnnotations.native.js +111 -0
- package/dist/esm/toolingAnnotations.native.js.map +1 -0
- package/dist/esm/toolingDiagnostics.mjs +428 -0
- package/dist/esm/toolingDiagnostics.mjs.map +1 -0
- package/dist/esm/toolingDiagnostics.native.js +755 -0
- package/dist/esm/toolingDiagnostics.native.js.map +1 -0
- package/dist/esm/toolingRegistry.mjs +135 -0
- package/dist/esm/toolingRegistry.mjs.map +1 -0
- package/dist/esm/toolingRegistry.native.js +138 -0
- package/dist/esm/toolingRegistry.native.js.map +1 -0
- package/dist/esm/transformFamily.mjs +392 -0
- package/dist/esm/transformFamily.mjs.map +1 -0
- package/dist/esm/transformFamily.native.js +482 -0
- package/dist/esm/transformFamily.native.js.map +1 -0
- package/dist/esm/transition.mjs +434 -0
- package/dist/esm/transition.mjs.map +1 -0
- package/dist/esm/transition.native.js +472 -0
- package/dist/esm/transition.native.js.map +1 -0
- package/dist/esm/transitionAlign.mjs +95 -0
- package/dist/esm/transitionAlign.mjs.map +1 -0
- package/dist/esm/transitionAlign.native.js +132 -0
- package/dist/esm/transitionAlign.native.js.map +1 -0
- package/dist/esm/transitionLegacy.mjs +197 -0
- package/dist/esm/transitionLegacy.mjs.map +1 -0
- package/dist/esm/transitionLegacy.native.js +238 -0
- package/dist/esm/transitionLegacy.native.js.map +1 -0
- package/dist/esm/transitionNative.mjs +257 -0
- package/dist/esm/transitionNative.mjs.map +1 -0
- package/dist/esm/transitionNative.native.js +259 -0
- package/dist/esm/transitionNative.native.js.map +1 -0
- package/dist/esm/unitlessNumbers.mjs +65 -0
- package/dist/esm/unitlessNumbers.mjs.map +1 -0
- package/dist/esm/unitlessNumbers.native.js +83 -0
- package/dist/esm/unitlessNumbers.native.js.map +1 -0
- package/dist/esm/v6ThemeNames.mjs +23 -0
- package/dist/esm/v6ThemeNames.mjs.map +1 -0
- package/dist/esm/v6ThemeNames.native.js +27 -0
- package/dist/esm/v6ThemeNames.native.js.map +1 -0
- package/dist/esm/valueParser.mjs +125 -0
- package/dist/esm/valueParser.mjs.map +1 -0
- package/dist/esm/valueParser.native.js +125 -0
- package/dist/esm/valueParser.native.js.map +1 -0
- package/dist/esm/valueTypes.mjs +14 -0
- package/dist/esm/valueTypes.mjs.map +1 -0
- package/dist/esm/valueTypes.native.js +14 -0
- package/dist/esm/valueTypes.native.js.map +1 -0
- package/package.json +98 -4
- package/src/backgroundFamily.ts +182 -0
- package/src/borderFamily.ts +172 -0
- package/src/candidate.ts +691 -0
- package/src/candidateTarget.ts +67 -0
- package/src/clauseCapability.ts +209 -0
- package/src/clausePrecedence.ts +198 -0
- package/src/clauseSources.ts +29 -0
- package/src/config.ts +169 -0
- package/src/evaluateProgram.ts +91 -0
- package/src/fontShorthand.ts +177 -0
- package/src/geometricShorthand.ts +105 -0
- package/src/index.ts +1 -0
- package/src/lowerProgram.ts +398 -0
- package/src/modifierRegistry.ts +340 -0
- package/src/payloadShape.ts +92 -0
- package/src/programEligibility.ts +46 -0
- package/src/programHash.ts +128 -0
- package/src/programs.ts +95 -0
- package/src/registry.ts +367 -0
- package/src/resolvePayload.ts +480 -0
- package/src/runtime.ts +32 -0
- package/src/safeAreaVariables.ts +19 -0
- package/src/scanFlatValue.ts +327 -0
- package/src/serializePayload.ts +199 -0
- package/src/stateModifiers.ts +36 -0
- package/src/states.ts +128 -0
- package/src/table.ts +47 -0
- package/src/textDecorationFamily.ts +119 -0
- package/src/tooling.ts +8 -0
- package/src/toolingAnnotations.ts +151 -0
- package/src/toolingDiagnostics.ts +735 -0
- package/src/toolingRegistry.ts +130 -0
- package/src/transformFamily.ts +590 -0
- package/src/transition.ts +553 -0
- package/src/transitionAlign.ts +165 -0
- package/src/transitionLegacy.ts +237 -0
- package/src/transitionNative.ts +357 -0
- package/src/unitlessNumbers.ts +61 -0
- package/src/v6ThemeNames.ts +40 -0
- package/src/valueParser.ts +193 -0
- package/src/valueTypes.ts +136 -0
- package/types/backgroundFamily.d.ts +17 -0
- package/types/backgroundFamily.d.ts.map +11 -0
- package/types/borderFamily.d.ts +23 -0
- package/types/borderFamily.d.ts.map +11 -0
- package/types/candidate.d.ts +52 -0
- package/types/candidate.d.ts.map +11 -0
- package/types/candidateTarget.d.ts +32 -0
- package/types/candidateTarget.d.ts.map +11 -0
- package/types/clauseCapability.d.ts +69 -0
- package/types/clauseCapability.d.ts.map +11 -0
- package/types/clausePrecedence.d.ts +30 -0
- package/types/clausePrecedence.d.ts.map +11 -0
- package/types/clauseSources.d.ts +12 -0
- package/types/clauseSources.d.ts.map +11 -0
- package/types/config.d.ts +44 -0
- package/types/config.d.ts.map +11 -0
- package/types/evaluateProgram.d.ts +27 -0
- package/types/evaluateProgram.d.ts.map +11 -0
- package/types/fontShorthand.d.ts +25 -0
- package/types/fontShorthand.d.ts.map +11 -0
- package/types/geometricShorthand.d.ts +21 -0
- package/types/geometricShorthand.d.ts.map +11 -0
- package/types/index.d.ts +3 -0
- package/types/index.d.ts.map +11 -0
- package/types/lowerProgram.d.ts +73 -0
- package/types/lowerProgram.d.ts.map +11 -0
- package/types/mergeFlatValues.d.ts +14 -0
- package/types/mergeFlatValues.d.ts.map +11 -0
- package/types/modifierRegistry.d.ts +70 -0
- package/types/modifierRegistry.d.ts.map +11 -0
- package/types/payloadShape.d.ts +15 -0
- package/types/payloadShape.d.ts.map +11 -0
- package/types/programEligibility.d.ts +23 -0
- package/types/programEligibility.d.ts.map +11 -0
- package/types/programHash.d.ts +20 -0
- package/types/programHash.d.ts.map +11 -0
- package/types/programs.d.ts +18 -0
- package/types/programs.d.ts.map +11 -0
- package/types/registry.d.ts +24 -0
- package/types/registry.d.ts.map +11 -0
- package/types/resolvePayload.d.ts +75 -0
- package/types/resolvePayload.d.ts.map +11 -0
- package/types/runtime.d.ts +34 -0
- package/types/runtime.d.ts.map +11 -0
- package/types/safeAreaVariables.d.ts +5 -0
- package/types/safeAreaVariables.d.ts.map +11 -0
- package/types/scanFlatValue.d.ts +29 -0
- package/types/scanFlatValue.d.ts.map +11 -0
- package/types/serializePayload.d.ts +13 -0
- package/types/serializePayload.d.ts.map +11 -0
- package/types/stateModifiers.d.ts +14 -0
- package/types/stateModifiers.d.ts.map +11 -0
- package/types/states.d.ts +22 -0
- package/types/states.d.ts.map +11 -0
- package/types/table.d.ts +4 -0
- package/types/table.d.ts.map +11 -0
- package/types/textDecorationFamily.d.ts +23 -0
- package/types/textDecorationFamily.d.ts.map +11 -0
- package/types/tooling.d.ts +10 -0
- package/types/tooling.d.ts.map +11 -0
- package/types/toolingAnnotations.d.ts +29 -0
- package/types/toolingAnnotations.d.ts.map +11 -0
- package/types/toolingDiagnostics.d.ts +114 -0
- package/types/toolingDiagnostics.d.ts.map +11 -0
- package/types/toolingRegistry.d.ts +10 -0
- package/types/toolingRegistry.d.ts.map +11 -0
- package/types/transformFamily.d.ts +83 -0
- package/types/transformFamily.d.ts.map +11 -0
- package/types/transition.d.ts +65 -0
- package/types/transition.d.ts.map +11 -0
- package/types/transitionAlign.d.ts +15 -0
- package/types/transitionAlign.d.ts.map +11 -0
- package/types/transitionLegacy.d.ts +9 -0
- package/types/transitionLegacy.d.ts.map +11 -0
- package/types/transitionNative.d.ts +41 -0
- package/types/transitionNative.d.ts.map +11 -0
- package/types/unitlessNumbers.d.ts +3 -0
- package/types/unitlessNumbers.d.ts.map +11 -0
- package/types/v6ThemeNames.d.ts +7 -0
- package/types/v6ThemeNames.d.ts.map +11 -0
- package/types/valueParser.d.ts +36 -0
- package/types/valueParser.d.ts.map +11 -0
- package/types/valueTypes.d.ts +66 -0
- package/types/valueTypes.d.ts.map +11 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
// The one global modifier namespace the flat value grammar parses against.
|
|
2
|
+
//
|
|
3
|
+
// Built from the existing built-in state vocabulary plus the config's media
|
|
4
|
+
// keys, platform names, and root theme names, with parameterized group
|
|
5
|
+
// modifiers resolved on lookup. There is a single namespace on purpose: a name
|
|
6
|
+
// may mean exactly one thing, so a config whose media key collides with a state
|
|
7
|
+
// or theme name gets a diagnostic instead of a silent choice. Registration order
|
|
8
|
+
// is state, media, platform, theme, and first registration wins.
|
|
9
|
+
//
|
|
10
|
+
// See plans/dom-tailwind-flat-values.md — "Conditions".
|
|
11
|
+
|
|
12
|
+
import type { GrammarConfigView } from './candidate'
|
|
13
|
+
import { grammarPlatformNames } from './config'
|
|
14
|
+
import { coreStateModifierNames, modifierAliases } from './stateModifiers'
|
|
15
|
+
import { componentStateNames } from './states'
|
|
16
|
+
import {
|
|
17
|
+
grammarMaxNonPlatformDepth,
|
|
18
|
+
type ModifierKind,
|
|
19
|
+
type ModifierRegistryView,
|
|
20
|
+
} from './valueTypes'
|
|
21
|
+
|
|
22
|
+
type Names = readonly string[] | ReadonlySet<string> | Readonly<Record<string, unknown>>
|
|
23
|
+
|
|
24
|
+
export interface ModifierRegistryResult {
|
|
25
|
+
registry: ModifierRegistryView
|
|
26
|
+
/** one human-readable line per name collision, in registration order */
|
|
27
|
+
diagnostics: string[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CreateModifierRegistryOptions {
|
|
31
|
+
/**
|
|
32
|
+
* The media keys that measure a size, so `@key` is a meaningful container
|
|
33
|
+
* query. A `hover` or `pointer` media key measures nothing a container has, and
|
|
34
|
+
* `@container (hover: none)` is valid syntax with no meaning, so those keys have
|
|
35
|
+
* no `@` form.
|
|
36
|
+
*
|
|
37
|
+
* Overrides the view's derived `containerSizeNames`. When NEITHER is
|
|
38
|
+
* supplied the sizes are unknown: no container modifier registers and a
|
|
39
|
+
* diagnostic says so — an unknowable set refuses rather than over-claims.
|
|
40
|
+
* A caller with genuinely no container concept passes `[]` explicitly.
|
|
41
|
+
*/
|
|
42
|
+
containerSizeNames?: Names
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Every built-in interaction/state modifier spelling: the modifiers of the core
|
|
47
|
+
* pseudo-style props, their aliases, and the component-tier state words the
|
|
48
|
+
* behavior packages expose through DOM attributes.
|
|
49
|
+
*/
|
|
50
|
+
export const stateModifierNames: readonly string[] = Object.freeze([
|
|
51
|
+
...coreStateModifierNames,
|
|
52
|
+
...Object.keys(modifierAliases),
|
|
53
|
+
...componentStateNames,
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
const stateModifierSet: ReadonlySet<string> = new Set(stateModifierNames)
|
|
57
|
+
|
|
58
|
+
const groupPrefixLength = 'group-'.length
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Theme conditions name a root theme. Nested themes still inherit from that
|
|
62
|
+
* root, so `dark:` applies within `dark_blue`, but `dark_blue:` is not a
|
|
63
|
+
* condition of its own.
|
|
64
|
+
*/
|
|
65
|
+
export function isRootThemeName(name: string): boolean {
|
|
66
|
+
return name.length > 0 && !name.includes('_')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface GroupModifier {
|
|
70
|
+
/** the state the parent group must be in, always a built-in state modifier */
|
|
71
|
+
state: string
|
|
72
|
+
/** the group name, or null for the nearest unnamed group */
|
|
73
|
+
group: string | null
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Canonical spelling used by slot identity, precedence, hashing, and matching. */
|
|
77
|
+
export function canonicalClauseModifier(name: string): string {
|
|
78
|
+
const direct = modifierAliases[name]
|
|
79
|
+
if (direct) return direct
|
|
80
|
+
if (name.startsWith('group-')) {
|
|
81
|
+
const group = parseGroupModifier(name)
|
|
82
|
+
if (group) {
|
|
83
|
+
const state = modifierAliases[group.state] ?? group.state
|
|
84
|
+
if (state !== group.state) {
|
|
85
|
+
return group.group === null ? `group-${state}` : `group-${state}/${group.group}`
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return name
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Parameterized group modifiers use Tailwind's spelling: `group-hover` for the
|
|
94
|
+
* nearest unnamed group and `group-hover/card` for a named one. The state part
|
|
95
|
+
* must be a built-in state modifier; the name part is an identifier. Returns
|
|
96
|
+
* null for anything else, which is what makes the spelling a single source of
|
|
97
|
+
* truth for both registration and lowering.
|
|
98
|
+
*/
|
|
99
|
+
export function parseGroupModifier(name: string): GroupModifier | null {
|
|
100
|
+
if (!name.startsWith('group-')) return null
|
|
101
|
+
const slash = name.indexOf('/')
|
|
102
|
+
if (slash === -1) {
|
|
103
|
+
const state = name.slice(groupPrefixLength)
|
|
104
|
+
return stateModifierSet.has(state) ? { state, group: null } : null
|
|
105
|
+
}
|
|
106
|
+
if (!isModifierName(name, slash + 1, name.length)) return null
|
|
107
|
+
const state = name.slice(groupPrefixLength, slash)
|
|
108
|
+
return stateModifierSet.has(state) ? { state, group: name.slice(slash + 1) } : null
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface ContainerModifier {
|
|
112
|
+
/** the size condition; the registry only accepts a registered media name here */
|
|
113
|
+
size: string
|
|
114
|
+
/** the container name, or null for the nearest container */
|
|
115
|
+
container: string | null
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface ModifierTrieNode {
|
|
119
|
+
modifiers: readonly string[]
|
|
120
|
+
children: Map<string, ModifierTrieNode>
|
|
121
|
+
next?: readonly string[]
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Container query modifiers own the `@` prefix: `@sm` targets the nearest
|
|
126
|
+
* container and `@sm/card` a named one (plan decisions 17-18). Plain `sm:` stays
|
|
127
|
+
* a viewport media query, which is why the prefix is reserved.
|
|
128
|
+
*
|
|
129
|
+
* This parses the spelling only. Whether `size` names a registered media key is
|
|
130
|
+
* config-dependent, so the registry checks that on lookup and lowering resolves
|
|
131
|
+
* the query text — the same split groups use for their state part.
|
|
132
|
+
*/
|
|
133
|
+
export function parseContainerModifier(name: string): ContainerModifier | null {
|
|
134
|
+
if (name.charCodeAt(0) !== 64 /* @ */) return null
|
|
135
|
+
const slash = name.indexOf('/')
|
|
136
|
+
if (slash === -1) {
|
|
137
|
+
return isModifierName(name, 1, name.length)
|
|
138
|
+
? { size: name.slice(1), container: null }
|
|
139
|
+
: null
|
|
140
|
+
}
|
|
141
|
+
if (!isModifierName(name, 1, slash) || !isModifierName(name, slash + 1, name.length)) {
|
|
142
|
+
return null
|
|
143
|
+
}
|
|
144
|
+
return { size: name.slice(1, slash), container: name.slice(slash + 1) }
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** the shared identifier rule for the parameterized parts of a modifier */
|
|
148
|
+
function isModifierName(text: string, start: number, end: number): boolean {
|
|
149
|
+
if (start >= end) return false
|
|
150
|
+
for (let index = start; index < end; index++) {
|
|
151
|
+
const code = text.charCodeAt(index)
|
|
152
|
+
if (
|
|
153
|
+
!(code >= 97 && code <= 122) && // a-z
|
|
154
|
+
!(code >= 65 && code <= 90) && // A-Z
|
|
155
|
+
!(code >= 48 && code <= 57) && // 0-9
|
|
156
|
+
code !== 45 && // -
|
|
157
|
+
code !== 95 // _
|
|
158
|
+
) {
|
|
159
|
+
return false
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return true
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function forEachName(source: Names | undefined, visit: (name: string) => void): void {
|
|
166
|
+
if (!source) return
|
|
167
|
+
if (Array.isArray(source)) {
|
|
168
|
+
for (const name of source) visit(name)
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
if (source instanceof Set) {
|
|
172
|
+
for (const name of source) visit(name)
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
for (const name in source as Readonly<Record<string, unknown>>) visit(name)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function createModifierRegistry(
|
|
179
|
+
view: GrammarConfigView,
|
|
180
|
+
options: CreateModifierRegistryOptions = {}
|
|
181
|
+
): ModifierRegistryResult {
|
|
182
|
+
const names = new Map<string, ModifierKind>()
|
|
183
|
+
const diagnostics: string[] = []
|
|
184
|
+
const completionNames: string[] = []
|
|
185
|
+
|
|
186
|
+
// options override the view's derived set. an undefined BOTH falls back to
|
|
187
|
+
// every-media-name for now — that over-claim is scheduled for removal with
|
|
188
|
+
// its own caller sweep; views built from media records already carry the
|
|
189
|
+
// correct derived subset
|
|
190
|
+
const sizeSource = options.containerSizeNames ?? view.containerSizeNames
|
|
191
|
+
let containerSizes: Set<string> | null = null
|
|
192
|
+
if (sizeSource !== undefined) {
|
|
193
|
+
containerSizes = new Set()
|
|
194
|
+
forEachName(sizeSource, (name) => containerSizes!.add(name))
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const register = (name: string, kind: ModifierKind): void => {
|
|
198
|
+
if (name.charCodeAt(0) === 64 /* @ */) {
|
|
199
|
+
// the `@` prefix belongs to container queries, so no configured name may
|
|
200
|
+
// take it; otherwise `@sm:` would mean two things
|
|
201
|
+
diagnostics.push(
|
|
202
|
+
`modifier "${name}" is not registered: the "@" prefix is reserved for container query modifiers, so it cannot be a ${kind} name`
|
|
203
|
+
)
|
|
204
|
+
return
|
|
205
|
+
}
|
|
206
|
+
const existing = names.get(name)
|
|
207
|
+
if (existing !== undefined) {
|
|
208
|
+
if (existing !== kind) {
|
|
209
|
+
diagnostics.push(
|
|
210
|
+
`modifier "${name}" is already registered as a ${existing} modifier, so the ${kind} name is ignored`
|
|
211
|
+
)
|
|
212
|
+
}
|
|
213
|
+
return
|
|
214
|
+
}
|
|
215
|
+
if (parseGroupModifier(name) !== null) {
|
|
216
|
+
diagnostics.push(
|
|
217
|
+
`modifier "${name}" shadows the group modifier of the same spelling, which can no longer be used as a ${kind} name`
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
names.set(name, kind)
|
|
221
|
+
completionNames.push(name)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// when the caller or the view declares which sizes a container can measure,
|
|
225
|
+
// that list is the whole rule. Otherwise any registered media name works
|
|
226
|
+
// (legacy fallback, removal pending its caller sweep)
|
|
227
|
+
const isContainerSize = (size: string): boolean =>
|
|
228
|
+
containerSizes ? containerSizes.has(size) : names.get(size) === 'media'
|
|
229
|
+
|
|
230
|
+
for (const name of stateModifierNames) register(name, 'state')
|
|
231
|
+
forEachName(view.mediaNames, (name) => register(name, 'media'))
|
|
232
|
+
forEachName(view.platformNames ?? grammarPlatformNames, (name) =>
|
|
233
|
+
register(name, 'platform')
|
|
234
|
+
)
|
|
235
|
+
forEachName(view.themeNames, (name) => {
|
|
236
|
+
if (isRootThemeName(name)) register(name, 'theme')
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
for (const name of stateModifierNames) {
|
|
240
|
+
const group = `group-${name}`
|
|
241
|
+
if (names.get(group) === undefined) completionNames.push(group)
|
|
242
|
+
}
|
|
243
|
+
if (containerSizes) {
|
|
244
|
+
for (const size of containerSizes) {
|
|
245
|
+
if (isContainerSize(size)) completionNames.push(`@${size}`)
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
for (const name of completionNames.slice()) {
|
|
249
|
+
if (names.get(name) === 'media') completionNames.push(`@${name}`)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const kindOrder: Readonly<Record<ModifierKind, number>> = {
|
|
254
|
+
platform: 0,
|
|
255
|
+
theme: 1,
|
|
256
|
+
container: 2,
|
|
257
|
+
media: 3,
|
|
258
|
+
group: 4,
|
|
259
|
+
state: 5,
|
|
260
|
+
}
|
|
261
|
+
const modifierTrie: ModifierTrieNode = {
|
|
262
|
+
modifiers: [],
|
|
263
|
+
children: new Map(),
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const get = (name: string): ModifierKind | undefined => {
|
|
267
|
+
const kind = names.get(name)
|
|
268
|
+
if (kind !== undefined) return kind
|
|
269
|
+
if (parseGroupModifier(name) !== null) return 'group'
|
|
270
|
+
const container = parseContainerModifier(name)
|
|
271
|
+
if (container !== null && isContainerSize(container.size)) return 'container'
|
|
272
|
+
return undefined
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
registry: {
|
|
277
|
+
get,
|
|
278
|
+
next(modifiers: readonly string[]): readonly string[] {
|
|
279
|
+
let node = modifierTrie
|
|
280
|
+
for (const authored of modifiers) {
|
|
281
|
+
const canonical = canonicalClauseModifier(authored)
|
|
282
|
+
let child = node.children.get(canonical)
|
|
283
|
+
if (!child) {
|
|
284
|
+
child = {
|
|
285
|
+
modifiers: [...node.modifiers, canonical],
|
|
286
|
+
children: new Map(),
|
|
287
|
+
}
|
|
288
|
+
node.children.set(canonical, child)
|
|
289
|
+
}
|
|
290
|
+
node = child
|
|
291
|
+
}
|
|
292
|
+
if (node.next) return node.next
|
|
293
|
+
|
|
294
|
+
const used = new Set<string>()
|
|
295
|
+
const usedKinds = new Set<ModifierKind>()
|
|
296
|
+
let highestOrder = -1
|
|
297
|
+
let nonPlatformDepth = 0
|
|
298
|
+
|
|
299
|
+
for (const canonical of node.modifiers) {
|
|
300
|
+
if (used.has(canonical)) {
|
|
301
|
+
node.next = []
|
|
302
|
+
return node.next
|
|
303
|
+
}
|
|
304
|
+
used.add(canonical)
|
|
305
|
+
const kind = get(canonical)
|
|
306
|
+
if (!kind || usedKinds.has(kind) || kindOrder[kind] < highestOrder) {
|
|
307
|
+
node.next = []
|
|
308
|
+
return node.next
|
|
309
|
+
}
|
|
310
|
+
usedKinds.add(kind)
|
|
311
|
+
highestOrder = kindOrder[kind]
|
|
312
|
+
if (kind !== 'platform') {
|
|
313
|
+
nonPlatformDepth++
|
|
314
|
+
if (nonPlatformDepth > grammarMaxNonPlatformDepth) {
|
|
315
|
+
node.next = []
|
|
316
|
+
return node.next
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const next: string[] = []
|
|
322
|
+
for (const name of completionNames) {
|
|
323
|
+
const canonical = canonicalClauseModifier(name)
|
|
324
|
+
if (canonical !== name) continue
|
|
325
|
+
if (used.has(canonical)) continue
|
|
326
|
+
const kind = get(name)
|
|
327
|
+
if (!kind || kindOrder[kind] < highestOrder) continue
|
|
328
|
+
if (usedKinds.has(kind)) continue
|
|
329
|
+
if (kind !== 'platform' && nonPlatformDepth >= grammarMaxNonPlatformDepth) {
|
|
330
|
+
continue
|
|
331
|
+
}
|
|
332
|
+
next.push(name)
|
|
333
|
+
}
|
|
334
|
+
node.next = next
|
|
335
|
+
return node.next
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
diagnostics,
|
|
339
|
+
}
|
|
340
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Value-level payload-shape validation, owned by the resolution layer per the
|
|
2
|
+
// design record ("Value-level validation of resolved payloads has exactly one
|
|
3
|
+
// owner, the resolution step"). One source of truth for the runtime, the
|
|
4
|
+
// compiler, and the ESLint rule — none of them may grow a second opinion
|
|
5
|
+
// about what a suspicious payload looks like.
|
|
6
|
+
//
|
|
7
|
+
// The clause grammar is space-greedy by design: a payload extends until the
|
|
8
|
+
// next `modifier:` clause, because many longhands legitimately take
|
|
9
|
+
// space-separated component lists (`boxShadow="inset 0 2px red"`). The
|
|
10
|
+
// consequence is that a base written AFTER a conditional is absorbed into
|
|
11
|
+
// that conditional's payload — `backgroundColor="sm:green red"` parses as one
|
|
12
|
+
// clause with payload "green red" and NO base, the browser then drops the
|
|
13
|
+
// invalid declaration, and the element renders with nothing at every
|
|
14
|
+
// viewport. The absorption stays (changing it would break legitimate
|
|
15
|
+
// multi-component payloads); the silence goes: a multi-component payload on a
|
|
16
|
+
// longhand that takes exactly one component value is a diagnostic.
|
|
17
|
+
|
|
18
|
+
import { splitTopLevelComponents } from './backgroundFamily'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Longhands whose value is a component LIST, where a multi-component payload
|
|
22
|
+
* is ordinary CSS. Everything else that this validator is asked about is
|
|
23
|
+
* treated as single-component. Family shorthands (`border`, `background`,
|
|
24
|
+
* `textDecoration`, `font`) never reach payload validation — they split into
|
|
25
|
+
* per-longhand programs first.
|
|
26
|
+
*/
|
|
27
|
+
const listValuedLonghands: ReadonlySet<string> = new Set([
|
|
28
|
+
'boxShadow',
|
|
29
|
+
'textShadow',
|
|
30
|
+
'transform',
|
|
31
|
+
'transition',
|
|
32
|
+
'transitionProperty',
|
|
33
|
+
'animation',
|
|
34
|
+
'animationName',
|
|
35
|
+
'backgroundImage',
|
|
36
|
+
'backgroundPosition',
|
|
37
|
+
'backgroundSize',
|
|
38
|
+
'backgroundRepeat',
|
|
39
|
+
'fontFamily',
|
|
40
|
+
'fontVariant',
|
|
41
|
+
'filter',
|
|
42
|
+
'backdropFilter',
|
|
43
|
+
'willChange',
|
|
44
|
+
'quotes',
|
|
45
|
+
'textDecorationLine',
|
|
46
|
+
'containIntrinsicSize',
|
|
47
|
+
'strokeDasharray',
|
|
48
|
+
'gridTemplateColumns',
|
|
49
|
+
'gridTemplateRows',
|
|
50
|
+
'gridTemplateAreas',
|
|
51
|
+
'gridArea',
|
|
52
|
+
'gridColumn',
|
|
53
|
+
'gridRow',
|
|
54
|
+
'inset',
|
|
55
|
+
'mask',
|
|
56
|
+
'maskImage',
|
|
57
|
+
'maskPosition',
|
|
58
|
+
'maskSize',
|
|
59
|
+
])
|
|
60
|
+
|
|
61
|
+
export interface PayloadShapeDiagnostic {
|
|
62
|
+
code: 'multi-component-single-value'
|
|
63
|
+
property: string
|
|
64
|
+
payload: string
|
|
65
|
+
message: string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Returns a diagnostic when `payload` holds more than one top-level component
|
|
70
|
+
* for a longhand that takes exactly one. `hasBase` sharpens the message: with
|
|
71
|
+
* no base in the program, the most likely cause is a base written after a
|
|
72
|
+
* conditional and swallowed by its space-greedy payload.
|
|
73
|
+
*/
|
|
74
|
+
export function validatePayloadShape(
|
|
75
|
+
property: string,
|
|
76
|
+
payload: string,
|
|
77
|
+
hasBase: boolean
|
|
78
|
+
): PayloadShapeDiagnostic | null {
|
|
79
|
+
if (listValuedLonghands.has(property)) return null
|
|
80
|
+
const components = splitTopLevelComponents(payload)
|
|
81
|
+
if (components.length <= 1) return null
|
|
82
|
+
return {
|
|
83
|
+
code: 'multi-component-single-value',
|
|
84
|
+
property,
|
|
85
|
+
payload,
|
|
86
|
+
message:
|
|
87
|
+
`"${payload}" holds ${components.length} values but "${property}" takes one.` +
|
|
88
|
+
(hasBase
|
|
89
|
+
? ''
|
|
90
|
+
: ` A value written after a conditional joins that conditional's payload — write the base value before the first conditional.`),
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// One owner for "does a flat clause value on this prop evaluate through the
|
|
2
|
+
// program engine". The runtime consults it before contributing, the codemod
|
|
3
|
+
// consults it before converting a condition object, and the ESLint rule
|
|
4
|
+
// consults it before blessing a clause spelling — so a migration can never
|
|
5
|
+
// produce source the runtime will not evaluate (review P0-2).
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Props with no per-part flat clause spelling BY DESIGN, mapped to the
|
|
9
|
+
* composite property that owns their clause spelling.
|
|
10
|
+
*
|
|
11
|
+
* - RN shadow parts are not CSS longhands: plain values compose into
|
|
12
|
+
* boxShadow/textShadow (web `styleToCSS`) or pass straight to the RN host,
|
|
13
|
+
* and the composite property carries any conditional.
|
|
14
|
+
* - Transform parts outside the flat family (skews, 3D rotations,
|
|
15
|
+
* perspective, matrix) have no per-part spelling; the raw `transform`
|
|
16
|
+
* property is one ordinary program and owns their clauses (design record,
|
|
17
|
+
* "The transform family").
|
|
18
|
+
*/
|
|
19
|
+
export const legacyPartComposite: Readonly<Record<string, string>> = Object.freeze({
|
|
20
|
+
shadowColor: 'boxShadow',
|
|
21
|
+
shadowOffset: 'boxShadow',
|
|
22
|
+
shadowOpacity: 'boxShadow',
|
|
23
|
+
shadowRadius: 'boxShadow',
|
|
24
|
+
textShadowColor: 'textShadow',
|
|
25
|
+
textShadowOffset: 'textShadow',
|
|
26
|
+
textShadowRadius: 'textShadow',
|
|
27
|
+
perspective: 'transform',
|
|
28
|
+
skewX: 'transform',
|
|
29
|
+
skewY: 'transform',
|
|
30
|
+
matrix: 'transform',
|
|
31
|
+
rotateX: 'transform',
|
|
32
|
+
rotateY: 'transform',
|
|
33
|
+
rotateZ: 'transform',
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
export type ProgramEligibility = 'program' | 'legacy-part'
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 'program': a clause-bearing flat value on this prop evaluates through the
|
|
40
|
+
* program engine. 'legacy-part': plain values keep their legacy pipeline and
|
|
41
|
+
* a clause-bearing value is a diagnostic naming the composite — never a
|
|
42
|
+
* silent forward, never a codemod conversion.
|
|
43
|
+
*/
|
|
44
|
+
export function programEligibility(prop: string): ProgramEligibility {
|
|
45
|
+
return prop in legacyPartComposite ? 'legacy-part' : 'program'
|
|
46
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Deterministic identity for one lowered program.
|
|
2
|
+
//
|
|
3
|
+
// A (longhand property, program, config revision) triple hashes to one class
|
|
4
|
+
// name, which is the whole dedup mechanism for the program block encoding: a
|
|
5
|
+
// class name fully determines its block, so duplicate arrival is idempotent and
|
|
6
|
+
// dedup is a name check. See plans/dom-tailwind-flat-values.md — "The program
|
|
7
|
+
// block encoding".
|
|
8
|
+
//
|
|
9
|
+
// Server and client must agree, so nothing here may depend on iteration order,
|
|
10
|
+
// config object identity, or insertion history. The config revision is the
|
|
11
|
+
// caller's opaque stamp for "the resolved config that produced these payloads".
|
|
12
|
+
|
|
13
|
+
import { canonicalClauseModifier } from './clausePrecedence'
|
|
14
|
+
import type { ParsedValue } from './valueTypes'
|
|
15
|
+
|
|
16
|
+
// The hash is the algorithm from @tamagui/simple-hash
|
|
17
|
+
// (code/core/simple-hash/src/index.ts), copied rather than imported because this
|
|
18
|
+
// package stays dependency-free. Same accumulator, same CSS-safe character
|
|
19
|
+
// rules, so identifiers behave like the ones core already generates. Keep in
|
|
20
|
+
// sync if that file changes. Two deliberate differences: no memo cache (callers
|
|
21
|
+
// own caching, and a shared module-level cache in the grammar package would
|
|
22
|
+
// outlive every config), and `strict` mode at the call site below.
|
|
23
|
+
function hashChar(hash: number, char: string): number {
|
|
24
|
+
return (Math.imul(31, hash) + char.charCodeAt(0)) | 0
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function isValidCssCharCode(code: number): boolean {
|
|
28
|
+
return (
|
|
29
|
+
(code >= 65 && code <= 90) || // A-Z
|
|
30
|
+
(code >= 97 && code <= 122) || // a-z
|
|
31
|
+
code === 95 || // _
|
|
32
|
+
code === 45 || // -
|
|
33
|
+
(code >= 48 && code <= 57) // 0-9
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function simpleHash(input: string, hashMin: number | 'strict' = 10): string {
|
|
38
|
+
let str = input
|
|
39
|
+
|
|
40
|
+
// remove var()
|
|
41
|
+
if (str[0] === 'v' && str.startsWith('var(')) {
|
|
42
|
+
str = str.slice(6, str.length - 1)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let hash = 0
|
|
46
|
+
let valids = ''
|
|
47
|
+
let added = 0
|
|
48
|
+
const len = str.length
|
|
49
|
+
|
|
50
|
+
for (let i = 0; i < len; i++) {
|
|
51
|
+
if (hashMin !== 'strict' && added <= hashMin) {
|
|
52
|
+
const char = str.charCodeAt(i)
|
|
53
|
+
if (char === 46) {
|
|
54
|
+
valids += '--'
|
|
55
|
+
continue
|
|
56
|
+
}
|
|
57
|
+
if (isValidCssCharCode(char)) {
|
|
58
|
+
added++
|
|
59
|
+
valids += str[i]
|
|
60
|
+
continue
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
hash = hashChar(hash, str[i])
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return valids + (hash ? Math.abs(hash) : '')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The exact string that identifies a program. Every variable-length part is
|
|
71
|
+
* length-prefixed, so no payload can forge a boundary and two different
|
|
72
|
+
* programs cannot normalize to the same key. Also usable as the upstream
|
|
73
|
+
* parse/lower cache key.
|
|
74
|
+
*/
|
|
75
|
+
export function normalizeProgramKey(
|
|
76
|
+
property: string,
|
|
77
|
+
value: ParsedValue,
|
|
78
|
+
configRevision: string
|
|
79
|
+
): string {
|
|
80
|
+
let key = `${configRevision.length}:${configRevision}${property.length}:${property}`
|
|
81
|
+
key += value.base === null ? 'n' : `b${value.base.length}:${value.base}`
|
|
82
|
+
for (const clause of value.clauses) {
|
|
83
|
+
// condition sets are conjunctions: `dark:hover:` and `hover:dark:` are one
|
|
84
|
+
// clause, so the hash sorts a copy to agree with the merge rule and dedup;
|
|
85
|
+
// alias spellings canonicalize first so `active:` and `press:` are one name
|
|
86
|
+
const canonical = clause.modifiers.map(canonicalClauseModifier)
|
|
87
|
+
const modifiers =
|
|
88
|
+
canonical.length > 1 ? canonical.sort().join(',') : canonical.join(',')
|
|
89
|
+
key += `c${modifiers.length}:${modifiers}${clause.payload.length}:${clause.payload}`
|
|
90
|
+
}
|
|
91
|
+
return key
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Short per-property prefix for readability in devtools: the first letter of
|
|
96
|
+
* each camelCase word, so `backgroundColor` is `bc` and `borderTopLeftRadius`
|
|
97
|
+
* is `btlr`. Abbreviations may collide (`backgroundColor` and `backgroundClip`
|
|
98
|
+
* are both `bc`); the hash carries the property name, so the full class name
|
|
99
|
+
* still differs. This is a label, not identity.
|
|
100
|
+
*/
|
|
101
|
+
export function propertyAbbreviation(property: string): string {
|
|
102
|
+
let out = ''
|
|
103
|
+
for (let index = 0; index < property.length; index++) {
|
|
104
|
+
const code = property.charCodeAt(index)
|
|
105
|
+
const isWordStart =
|
|
106
|
+
index === 0 ||
|
|
107
|
+
(code >= 65 && code <= 90) ||
|
|
108
|
+
// a dash also starts a word, so the transform family's custom properties
|
|
109
|
+
// read as `--t-x` -> `tx` rather than collapsing to the fallback
|
|
110
|
+
property.charCodeAt(index - 1) === 45
|
|
111
|
+
if (isWordStart && ((code >= 65 && code <= 90) || (code >= 97 && code <= 122))) {
|
|
112
|
+
out += property[index].toLowerCase()
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return out || 'x'
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** the css-safe class name that owns this program's block, eg `_bc-1076745300` */
|
|
119
|
+
export function programClassName(
|
|
120
|
+
property: string,
|
|
121
|
+
value: ParsedValue,
|
|
122
|
+
configRevision: string
|
|
123
|
+
): string {
|
|
124
|
+
const hash = simpleHash(normalizeProgramKey(property, value, configRevision), 'strict')
|
|
125
|
+
// `strict` returns '' when the accumulator lands on 0, which would make every
|
|
126
|
+
// such program share one name
|
|
127
|
+
return `_${propertyAbbreviation(property)}-${hash || '0'}`
|
|
128
|
+
}
|