@tenphi/eslint-plugin-tasty 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/configs.js +2 -1
- package/dist/configs.js.map +1 -1
- package/dist/constants.js +4 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/parsers/value-parser.js +4 -0
- package/dist/parsers/value-parser.js.map +1 -1
- package/dist/rules/no-own-at-root.js +57 -0
- package/dist/rules/no-own-at-root.js.map +1 -0
- package/dist/rules/valid-preset.js +15 -11
- package/dist/rules/valid-preset.js.map +1 -1
- package/dist/rules/valid-state-key.js +0 -5
- package/dist/rules/valid-state-key.js.map +1 -1
- package/package.json +1 -1
package/dist/configs.js
CHANGED
|
@@ -18,7 +18,8 @@ const recommended = {
|
|
|
18
18
|
"tasty/valid-preset": "error",
|
|
19
19
|
"tasty/valid-recipe": "error",
|
|
20
20
|
"tasty/valid-transition": "warn",
|
|
21
|
-
"tasty/require-default-state": "error"
|
|
21
|
+
"tasty/require-default-state": "error",
|
|
22
|
+
"tasty/no-own-at-root": "warn"
|
|
22
23
|
};
|
|
23
24
|
const strict = {
|
|
24
25
|
...recommended,
|
package/dist/configs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configs.js","names":[],"sources":["../src/configs.ts"],"sourcesContent":["import type { TSESLint } from '@typescript-eslint/utils';\n\nexport const recommended: TSESLint.SharedConfig.RulesRecord = {\n 'tasty/known-property': 'warn',\n 'tasty/valid-value': 'error',\n 'tasty/valid-color-token': 'error',\n 'tasty/valid-custom-unit': 'error',\n 'tasty/valid-boolean-property': 'error',\n 'tasty/valid-state-key': 'error',\n 'tasty/valid-styles-structure': 'error',\n 'tasty/no-nested-state-map': 'error',\n 'tasty/no-important': 'error',\n 'tasty/valid-sub-element': 'error',\n 'tasty/valid-directional-modifier': 'error',\n 'tasty/valid-radius-shape': 'error',\n 'tasty/no-nested-selector': 'warn',\n 'tasty/static-no-dynamic-values': 'error',\n 'tasty/static-valid-selector': 'error',\n 'tasty/valid-preset': 'error',\n 'tasty/valid-recipe': 'error',\n 'tasty/valid-transition': 'warn',\n 'tasty/require-default-state': 'error',\n};\n\nexport const strict: TSESLint.SharedConfig.RulesRecord = {\n ...recommended,\n 'tasty/prefer-shorthand-property': 'warn',\n 'tasty/valid-custom-property': 'warn',\n 'tasty/no-unknown-state-alias': 'warn',\n 'tasty/no-styles-prop': 'warn',\n 'tasty/no-raw-color-values': 'warn',\n 'tasty/consistent-token-usage': 'warn',\n 'tasty/no-runtime-styles-mutation': 'warn',\n 'tasty/valid-state-definition': 'warn',\n};\n"],"mappings":";AAEA,MAAa,cAAiD;CAC5D,wBAAwB;CACxB,qBAAqB;CACrB,2BAA2B;CAC3B,2BAA2B;CAC3B,gCAAgC;CAChC,yBAAyB;CACzB,gCAAgC;CAChC,6BAA6B;CAC7B,sBAAsB;CACtB,2BAA2B;CAC3B,oCAAoC;CACpC,4BAA4B;CAC5B,4BAA4B;CAC5B,kCAAkC;CAClC,+BAA+B;CAC/B,sBAAsB;CACtB,sBAAsB;CACtB,0BAA0B;CAC1B,+BAA+B;
|
|
1
|
+
{"version":3,"file":"configs.js","names":[],"sources":["../src/configs.ts"],"sourcesContent":["import type { TSESLint } from '@typescript-eslint/utils';\n\nexport const recommended: TSESLint.SharedConfig.RulesRecord = {\n 'tasty/known-property': 'warn',\n 'tasty/valid-value': 'error',\n 'tasty/valid-color-token': 'error',\n 'tasty/valid-custom-unit': 'error',\n 'tasty/valid-boolean-property': 'error',\n 'tasty/valid-state-key': 'error',\n 'tasty/valid-styles-structure': 'error',\n 'tasty/no-nested-state-map': 'error',\n 'tasty/no-important': 'error',\n 'tasty/valid-sub-element': 'error',\n 'tasty/valid-directional-modifier': 'error',\n 'tasty/valid-radius-shape': 'error',\n 'tasty/no-nested-selector': 'warn',\n 'tasty/static-no-dynamic-values': 'error',\n 'tasty/static-valid-selector': 'error',\n 'tasty/valid-preset': 'error',\n 'tasty/valid-recipe': 'error',\n 'tasty/valid-transition': 'warn',\n 'tasty/require-default-state': 'error',\n 'tasty/no-own-at-root': 'warn',\n};\n\nexport const strict: TSESLint.SharedConfig.RulesRecord = {\n ...recommended,\n 'tasty/prefer-shorthand-property': 'warn',\n 'tasty/valid-custom-property': 'warn',\n 'tasty/no-unknown-state-alias': 'warn',\n 'tasty/no-styles-prop': 'warn',\n 'tasty/no-raw-color-values': 'warn',\n 'tasty/consistent-token-usage': 'warn',\n 'tasty/no-runtime-styles-mutation': 'warn',\n 'tasty/valid-state-definition': 'warn',\n};\n"],"mappings":";AAEA,MAAa,cAAiD;CAC5D,wBAAwB;CACxB,qBAAqB;CACrB,2BAA2B;CAC3B,2BAA2B;CAC3B,gCAAgC;CAChC,yBAAyB;CACzB,gCAAgC;CAChC,6BAA6B;CAC7B,sBAAsB;CACtB,2BAA2B;CAC3B,oCAAoC;CACpC,4BAA4B;CAC5B,4BAA4B;CAC5B,kCAAkC;CAClC,+BAA+B;CAC/B,sBAAsB;CACtB,sBAAsB;CACtB,0BAA0B;CAC1B,+BAA+B;CAC/B,wBAAwB;CACzB;AAED,MAAa,SAA4C;CACvD,GAAG;CACH,mCAAmC;CACnC,+BAA+B;CAC/B,gCAAgC;CAChC,wBAAwB;CACxB,6BAA6B;CAC7B,gCAAgC;CAChC,oCAAoC;CACpC,gCAAgC;CACjC"}
|
package/dist/constants.js
CHANGED
|
@@ -706,11 +706,11 @@ const SHORTHAND_MAPPING = {
|
|
|
706
706
|
},
|
|
707
707
|
fontWeight: {
|
|
708
708
|
property: "preset",
|
|
709
|
-
hint: "preset: '
|
|
709
|
+
hint: "preset: 'name / strong' (with strong modifier)"
|
|
710
710
|
},
|
|
711
711
|
lineHeight: {
|
|
712
712
|
property: "preset",
|
|
713
|
-
hint: "preset: '
|
|
713
|
+
hint: "preset: 'name / tight' (with tight modifier)"
|
|
714
714
|
},
|
|
715
715
|
boxShadow: {
|
|
716
716
|
property: "shadow",
|
|
@@ -722,7 +722,9 @@ const SHORTHAND_MAPPING = {
|
|
|
722
722
|
*/
|
|
723
723
|
const PRESET_MODIFIERS = new Set([
|
|
724
724
|
"strong",
|
|
725
|
+
"bold",
|
|
725
726
|
"italic",
|
|
727
|
+
"icon",
|
|
726
728
|
"tight"
|
|
727
729
|
]);
|
|
728
730
|
/**
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Built-in tasty style properties that are always valid as style keys.\n */\nexport const KNOWN_TASTY_PROPERTIES = new Set([\n 'display',\n 'font',\n 'preset',\n 'hide',\n 'whiteSpace',\n 'opacity',\n 'transition',\n 'gridArea',\n 'order',\n 'gridColumn',\n 'gridRow',\n 'placeSelf',\n 'alignSelf',\n 'justifySelf',\n 'zIndex',\n 'margin',\n 'inset',\n 'position',\n 'padding',\n 'paddingInline',\n 'paddingBlock',\n 'overflow',\n 'scrollbar',\n 'textAlign',\n 'border',\n 'radius',\n 'shadow',\n 'outline',\n 'color',\n 'fill',\n 'fade',\n 'image',\n 'textTransform',\n 'fontWeight',\n 'fontStyle',\n 'width',\n 'height',\n 'flexBasis',\n 'flexGrow',\n 'flexShrink',\n 'flex',\n 'flow',\n 'placeItems',\n 'placeContent',\n 'alignItems',\n 'alignContent',\n 'justifyItems',\n 'justifyContent',\n 'align',\n 'justify',\n 'gap',\n 'columnGap',\n 'rowGap',\n 'gridColumns',\n 'gridRows',\n 'gridTemplate',\n 'gridAreas',\n 'recipe',\n 'textOverflow',\n 'textDecoration',\n 'animation',\n 'cursor',\n 'pointerEvents',\n 'userSelect',\n 'transform',\n 'transformOrigin',\n 'filter',\n 'backdropFilter',\n 'mixBlendMode',\n 'objectFit',\n 'objectPosition',\n 'resize',\n 'appearance',\n 'listStyle',\n 'listStyleType',\n 'content',\n 'boxSizing',\n 'verticalAlign',\n 'wordBreak',\n 'overflowWrap',\n 'hyphens',\n 'tabSize',\n 'direction',\n 'unicodeBidi',\n 'writingMode',\n 'lineClamp',\n 'aspectRatio',\n 'contain',\n 'container',\n 'containerType',\n 'containerName',\n 'interpolateSize',\n 'willChange',\n 'isolation',\n 'touchAction',\n 'scrollBehavior',\n 'scrollSnapType',\n 'scrollSnapAlign',\n 'caretColor',\n 'accentColor',\n 'colorScheme',\n]);\n\n/**\n * Special top-level keys that are valid but not regular style properties.\n */\nexport const SPECIAL_STYLE_KEYS = new Set([\n '@keyframes',\n '@properties',\n '@fontFace',\n '@counterStyle',\n]);\n\n/**\n * CSS property names (common subset for validation).\n * When a key is camelCase and matches a known CSS property, it's valid.\n */\nexport const KNOWN_CSS_PROPERTIES = new Set([\n 'all',\n 'animation',\n 'animationDelay',\n 'animationDirection',\n 'animationDuration',\n 'animationFillMode',\n 'animationIterationCount',\n 'animationName',\n 'animationPlayState',\n 'animationTimingFunction',\n 'appearance',\n 'aspectRatio',\n 'backdropFilter',\n 'backfaceVisibility',\n 'background',\n 'backgroundAttachment',\n 'backgroundBlendMode',\n 'backgroundClip',\n 'backgroundColor',\n 'backgroundImage',\n 'backgroundOrigin',\n 'backgroundPosition',\n 'backgroundRepeat',\n 'backgroundSize',\n 'blockSize',\n 'border',\n 'borderBlock',\n 'borderBlockColor',\n 'borderBlockEnd',\n 'borderBlockEndColor',\n 'borderBlockEndStyle',\n 'borderBlockEndWidth',\n 'borderBlockStart',\n 'borderBlockStartColor',\n 'borderBlockStartStyle',\n 'borderBlockStartWidth',\n 'borderBlockStyle',\n 'borderBlockWidth',\n 'borderBottom',\n 'borderBottomColor',\n 'borderBottomLeftRadius',\n 'borderBottomRightRadius',\n 'borderBottomStyle',\n 'borderBottomWidth',\n 'borderCollapse',\n 'borderColor',\n 'borderImage',\n 'borderInline',\n 'borderInlineColor',\n 'borderInlineEnd',\n 'borderInlineStart',\n 'borderInlineStyle',\n 'borderInlineWidth',\n 'borderLeft',\n 'borderLeftColor',\n 'borderLeftStyle',\n 'borderLeftWidth',\n 'borderRadius',\n 'borderRight',\n 'borderRightColor',\n 'borderRightStyle',\n 'borderRightWidth',\n 'borderSpacing',\n 'borderStyle',\n 'borderTop',\n 'borderTopColor',\n 'borderTopLeftRadius',\n 'borderTopRightRadius',\n 'borderTopStyle',\n 'borderTopWidth',\n 'borderWidth',\n 'bottom',\n 'boxDecorationBreak',\n 'boxShadow',\n 'boxSizing',\n 'breakAfter',\n 'breakBefore',\n 'breakInside',\n 'captionSide',\n 'caretColor',\n 'clear',\n 'clip',\n 'clipPath',\n 'color',\n 'colorScheme',\n 'columnCount',\n 'columnFill',\n 'columnGap',\n 'columnRule',\n 'columnRuleColor',\n 'columnRuleStyle',\n 'columnRuleWidth',\n 'columnSpan',\n 'columnWidth',\n 'columns',\n 'contain',\n 'containerName',\n 'containerType',\n 'content',\n 'contentVisibility',\n 'counterIncrement',\n 'counterReset',\n 'counterSet',\n 'cursor',\n 'direction',\n 'display',\n 'emptyCells',\n 'filter',\n 'flex',\n 'flexBasis',\n 'flexDirection',\n 'flexFlow',\n 'flexGrow',\n 'flexShrink',\n 'flexWrap',\n 'float',\n 'font',\n 'fontFamily',\n 'fontFeatureSettings',\n 'fontKerning',\n 'fontOpticalSizing',\n 'fontSize',\n 'fontSizeAdjust',\n 'fontStretch',\n 'fontStyle',\n 'fontSynthesis',\n 'fontVariant',\n 'fontVariantAlternates',\n 'fontVariantCaps',\n 'fontVariantEastAsian',\n 'fontVariantLigatures',\n 'fontVariantNumeric',\n 'fontVariantPosition',\n 'fontWeight',\n 'gap',\n 'grid',\n 'gridArea',\n 'gridAutoColumns',\n 'gridAutoFlow',\n 'gridAutoRows',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnStart',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowStart',\n 'gridTemplate',\n 'gridTemplateAreas',\n 'gridTemplateColumns',\n 'gridTemplateRows',\n 'height',\n 'hyphens',\n 'imageRendering',\n 'inlineSize',\n 'inset',\n 'insetBlock',\n 'insetBlockEnd',\n 'insetBlockStart',\n 'insetInline',\n 'insetInlineEnd',\n 'insetInlineStart',\n 'isolation',\n 'justifyContent',\n 'justifyItems',\n 'justifySelf',\n 'left',\n 'letterSpacing',\n 'lineBreak',\n 'lineHeight',\n 'listStyle',\n 'listStyleImage',\n 'listStylePosition',\n 'listStyleType',\n 'margin',\n 'marginBlock',\n 'marginBlockEnd',\n 'marginBlockStart',\n 'marginBottom',\n 'marginInline',\n 'marginInlineEnd',\n 'marginInlineStart',\n 'marginLeft',\n 'marginRight',\n 'marginTop',\n 'maskImage',\n 'maxBlockSize',\n 'maxHeight',\n 'maxInlineSize',\n 'maxWidth',\n 'minBlockSize',\n 'minHeight',\n 'minInlineSize',\n 'minWidth',\n 'mixBlendMode',\n 'objectFit',\n 'objectPosition',\n 'opacity',\n 'order',\n 'orphans',\n 'outline',\n 'outlineColor',\n 'outlineOffset',\n 'outlineStyle',\n 'outlineWidth',\n 'overflow',\n 'overflowAnchor',\n 'overflowWrap',\n 'overflowX',\n 'overflowY',\n 'overscrollBehavior',\n 'padding',\n 'paddingBlock',\n 'paddingBlockEnd',\n 'paddingBlockStart',\n 'paddingBottom',\n 'paddingInline',\n 'paddingInlineEnd',\n 'paddingInlineStart',\n 'paddingLeft',\n 'paddingRight',\n 'paddingTop',\n 'perspective',\n 'perspectiveOrigin',\n 'placeContent',\n 'placeItems',\n 'placeSelf',\n 'pointerEvents',\n 'position',\n 'quotes',\n 'resize',\n 'right',\n 'rotate',\n 'rowGap',\n 'scale',\n 'scrollBehavior',\n 'scrollMargin',\n 'scrollMarginBlock',\n 'scrollMarginBlockEnd',\n 'scrollMarginBlockStart',\n 'scrollMarginBottom',\n 'scrollMarginInline',\n 'scrollMarginInlineEnd',\n 'scrollMarginInlineStart',\n 'scrollMarginLeft',\n 'scrollMarginRight',\n 'scrollMarginTop',\n 'scrollPadding',\n 'scrollPaddingBlock',\n 'scrollPaddingBlockEnd',\n 'scrollPaddingBlockStart',\n 'scrollPaddingBottom',\n 'scrollPaddingInline',\n 'scrollPaddingInlineEnd',\n 'scrollPaddingInlineStart',\n 'scrollPaddingLeft',\n 'scrollPaddingRight',\n 'scrollPaddingTop',\n 'scrollSnapAlign',\n 'scrollSnapStop',\n 'scrollSnapType',\n 'scrollbarColor',\n 'scrollbarGutter',\n 'scrollbarWidth',\n 'shapeOutside',\n 'tabSize',\n 'tableLayout',\n 'textAlign',\n 'textAlignLast',\n 'textCombineUpright',\n 'textDecoration',\n 'textDecorationColor',\n 'textDecorationLine',\n 'textDecorationSkipInk',\n 'textDecorationStyle',\n 'textDecorationThickness',\n 'textEmphasis',\n 'textIndent',\n 'textOrientation',\n 'textOverflow',\n 'textRendering',\n 'textShadow',\n 'textSizeAdjust',\n 'textTransform',\n 'textUnderlineOffset',\n 'textUnderlinePosition',\n 'textWrap',\n 'top',\n 'touchAction',\n 'transform',\n 'transformOrigin',\n 'transformStyle',\n 'transition',\n 'transitionDelay',\n 'transitionDuration',\n 'transitionProperty',\n 'transitionTimingFunction',\n 'translate',\n 'unicodeBidi',\n 'userSelect',\n 'verticalAlign',\n 'visibility',\n 'whiteSpace',\n 'widows',\n 'width',\n 'willChange',\n 'wordBreak',\n 'wordSpacing',\n 'writingMode',\n 'zIndex',\n]);\n\n/**\n * Built-in custom units recognized by the tasty parser.\n */\nexport const BUILT_IN_UNITS = new Set(['x', 'r', 'cr', 'bw', 'ow', 'lh', 'sf']);\n\n/**\n * Standard CSS units (always valid).\n */\nexport const CSS_UNITS = new Set([\n 'px',\n 'em',\n 'rem',\n '%',\n 'vw',\n 'vh',\n 'vmin',\n 'vmax',\n 'ch',\n 'ex',\n 'cm',\n 'mm',\n 'in',\n 'pt',\n 'pc',\n 'fr',\n 'deg',\n 'rad',\n 'turn',\n 'grad',\n 's',\n 'ms',\n 'dpi',\n 'dpcm',\n 'dppx',\n 'svw',\n 'svh',\n 'lvw',\n 'lvh',\n 'dvw',\n 'dvh',\n 'cqw',\n 'cqh',\n 'cqi',\n 'cqb',\n 'cqmin',\n 'cqmax',\n 'cap',\n 'ic',\n 'rlh',\n 'vi',\n 'vb',\n]);\n\n/**\n * Properties that accept `true` as a value (means \"use default\").\n */\nexport const BOOLEAN_TRUE_PROPERTIES = new Set([\n 'border',\n 'radius',\n 'padding',\n 'margin',\n 'gap',\n 'fill',\n 'color',\n 'shadow',\n 'outline',\n 'inset',\n 'width',\n 'height',\n 'hide',\n 'preset',\n 'font',\n 'scrollbar',\n]);\n\n/**\n * Directional modifiers and which properties accept them.\n */\nexport const DIRECTIONAL_MODIFIERS: Record<string, Set<string>> = {\n border: new Set(['top', 'right', 'bottom', 'left']),\n radius: new Set([\n 'top',\n 'right',\n 'bottom',\n 'left',\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n ]),\n padding: new Set(['top', 'right', 'bottom', 'left']),\n margin: new Set(['top', 'right', 'bottom', 'left']),\n fade: new Set(['top', 'right', 'bottom', 'left']),\n inset: new Set(['top', 'right', 'bottom', 'left']),\n};\n\n/**\n * Valid radius shape keywords.\n */\nexport const RADIUS_SHAPES = new Set(['round', 'ellipse', 'leaf', 'backleaf']);\n\n/**\n * Known semantic transition names.\n */\nexport const SEMANTIC_TRANSITIONS = new Set([\n 'fade',\n 'fill',\n 'border',\n 'radius',\n 'shadow',\n 'preset',\n 'gap',\n 'theme',\n 'color',\n 'outline',\n 'dimension',\n 'flow',\n 'inset',\n 'text',\n 'opacity',\n 'translate',\n 'rotate',\n 'scale',\n 'filter',\n 'image',\n 'background',\n 'width',\n 'height',\n 'zIndex',\n]);\n\n/**\n * Mapping of native CSS properties to tasty shorthand alternatives.\n */\nexport const SHORTHAND_MAPPING: Record<\n string,\n { property: string; hint: string }\n> = {\n backgroundColor: { property: 'fill', hint: \"fill: '...'\" },\n borderColor: { property: 'border', hint: \"border: '...'\" },\n borderWidth: { property: 'border', hint: \"border: '...'\" },\n borderStyle: { property: 'border', hint: \"border: '...'\" },\n borderTop: { property: 'border', hint: \"border: '... top'\" },\n borderRight: { property: 'border', hint: \"border: '... right'\" },\n borderBottom: { property: 'border', hint: \"border: '... bottom'\" },\n borderLeft: { property: 'border', hint: \"border: '... left'\" },\n borderRadius: { property: 'radius', hint: \"radius: '...'\" },\n maxWidth: { property: 'width', hint: \"width: 'max ...'\" },\n minWidth: { property: 'width', hint: \"width: 'min ...'\" },\n maxHeight: { property: 'height', hint: \"height: 'max ...'\" },\n minHeight: { property: 'height', hint: \"height: 'min ...'\" },\n flexDirection: { property: 'flow', hint: \"flow: '...'\" },\n flexWrap: { property: 'flow', hint: \"flow: '...'\" },\n flexFlow: { property: 'flow', hint: \"flow: '...'\" },\n gridAutoFlow: { property: 'flow', hint: \"flow: '...'\" },\n outlineOffset: { property: 'outline', hint: \"outline: '... / offset'\" },\n paddingTop: { property: 'padding', hint: \"padding: '... top'\" },\n paddingRight: { property: 'padding', hint: \"padding: '... right'\" },\n paddingBottom: { property: 'padding', hint: \"padding: '... bottom'\" },\n paddingLeft: { property: 'padding', hint: \"padding: '... left'\" },\n marginTop: { property: 'margin', hint: \"margin: '... top'\" },\n marginRight: { property: 'margin', hint: \"margin: '... right'\" },\n marginBottom: { property: 'margin', hint: \"margin: '... bottom'\" },\n marginLeft: { property: 'margin', hint: \"margin: '... left'\" },\n fontSize: { property: 'preset', hint: \"preset: '...'\" },\n fontWeight: {\n property: 'preset',\n hint: \"preset: '... strong' (with strong modifier)\",\n },\n lineHeight: {\n property: 'preset',\n hint: \"preset: '... tight' (with tight modifier)\",\n },\n boxShadow: { property: 'shadow', hint: \"shadow: '...'\" },\n};\n\n/**\n * Known preset modifiers.\n */\nexport const PRESET_MODIFIERS = new Set(['strong', 'italic', 'tight']);\n\n/**\n * Default import sources for tasty.\n */\nexport const DEFAULT_IMPORT_SOURCES = ['@tenphi/tasty', '@tenphi/tasty/static'];\n\n/**\n * Built-in state prefixes that are always valid (not aliases).\n */\nexport const BUILT_IN_STATE_PREFIXES = new Set([\n '@media',\n '@root',\n '@parent',\n '@own',\n '@supports',\n '@starting',\n '@keyframes',\n '@properties',\n '@fontFace',\n '@counterStyle',\n]);\n\n/**\n * Known CSS pseudo-classes.\n */\nexport const KNOWN_PSEUDO_CLASSES = new Set([\n ':hover',\n ':focus',\n ':focus-visible',\n ':focus-within',\n ':active',\n ':visited',\n ':link',\n ':checked',\n ':disabled',\n ':enabled',\n ':empty',\n ':first-child',\n ':last-child',\n ':first-of-type',\n ':last-of-type',\n ':only-child',\n ':only-of-type',\n ':root',\n ':target',\n ':valid',\n ':invalid',\n ':required',\n ':optional',\n ':read-only',\n ':read-write',\n ':placeholder-shown',\n ':autofill',\n ':default',\n ':indeterminate',\n ':in-range',\n ':out-of-range',\n ':any-link',\n ':local-link',\n ':is',\n ':not',\n ':where',\n ':has',\n ':nth-child',\n ':nth-last-child',\n ':nth-of-type',\n ':nth-last-of-type',\n '::before',\n '::after',\n '::placeholder',\n '::selection',\n '::first-line',\n '::first-letter',\n '::marker',\n '::backdrop',\n]);\n"],"mappings":";;;;AAGA,MAAa,yBAAyB,IAAI,IAAI;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,qBAAqB,IAAI,IAAI;CACxC;CACA;CACA;CACA;CACD,CAAC;;;;;AAMF,MAAa,uBAAuB,IAAI,IAAI;CAC1C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,iBAAiB,IAAI,IAAI;CAAC;CAAK;CAAK;CAAM;CAAM;CAAM;CAAM;CAAK,CAAC;;;;AAK/E,MAAa,YAAY,IAAI,IAAI;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,0BAA0B,IAAI,IAAI;CAC7C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,wBAAqD;CAChE,QAAQ,IAAI,IAAI;EAAC;EAAO;EAAS;EAAU;EAAO,CAAC;CACnD,QAAQ,IAAI,IAAI;EACd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CACF,SAAS,IAAI,IAAI;EAAC;EAAO;EAAS;EAAU;EAAO,CAAC;CACpD,QAAQ,IAAI,IAAI;EAAC;EAAO;EAAS;EAAU;EAAO,CAAC;CACnD,MAAM,IAAI,IAAI;EAAC;EAAO;EAAS;EAAU;EAAO,CAAC;CACjD,OAAO,IAAI,IAAI;EAAC;EAAO;EAAS;EAAU;EAAO,CAAC;CACnD;;;;AAKD,MAAa,gBAAgB,IAAI,IAAI;CAAC;CAAS;CAAW;CAAQ;CAAW,CAAC;;;;AAK9E,MAAa,uBAAuB,IAAI,IAAI;CAC1C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,oBAGT;CACF,iBAAiB;EAAE,UAAU;EAAQ,MAAM;EAAe;CAC1D,aAAa;EAAE,UAAU;EAAU,MAAM;EAAiB;CAC1D,aAAa;EAAE,UAAU;EAAU,MAAM;EAAiB;CAC1D,aAAa;EAAE,UAAU;EAAU,MAAM;EAAiB;CAC1D,WAAW;EAAE,UAAU;EAAU,MAAM;EAAqB;CAC5D,aAAa;EAAE,UAAU;EAAU,MAAM;EAAuB;CAChE,cAAc;EAAE,UAAU;EAAU,MAAM;EAAwB;CAClE,YAAY;EAAE,UAAU;EAAU,MAAM;EAAsB;CAC9D,cAAc;EAAE,UAAU;EAAU,MAAM;EAAiB;CAC3D,UAAU;EAAE,UAAU;EAAS,MAAM;EAAoB;CACzD,UAAU;EAAE,UAAU;EAAS,MAAM;EAAoB;CACzD,WAAW;EAAE,UAAU;EAAU,MAAM;EAAqB;CAC5D,WAAW;EAAE,UAAU;EAAU,MAAM;EAAqB;CAC5D,eAAe;EAAE,UAAU;EAAQ,MAAM;EAAe;CACxD,UAAU;EAAE,UAAU;EAAQ,MAAM;EAAe;CACnD,UAAU;EAAE,UAAU;EAAQ,MAAM;EAAe;CACnD,cAAc;EAAE,UAAU;EAAQ,MAAM;EAAe;CACvD,eAAe;EAAE,UAAU;EAAW,MAAM;EAA2B;CACvE,YAAY;EAAE,UAAU;EAAW,MAAM;EAAsB;CAC/D,cAAc;EAAE,UAAU;EAAW,MAAM;EAAwB;CACnE,eAAe;EAAE,UAAU;EAAW,MAAM;EAAyB;CACrE,aAAa;EAAE,UAAU;EAAW,MAAM;EAAuB;CACjE,WAAW;EAAE,UAAU;EAAU,MAAM;EAAqB;CAC5D,aAAa;EAAE,UAAU;EAAU,MAAM;EAAuB;CAChE,cAAc;EAAE,UAAU;EAAU,MAAM;EAAwB;CAClE,YAAY;EAAE,UAAU;EAAU,MAAM;EAAsB;CAC9D,UAAU;EAAE,UAAU;EAAU,MAAM;EAAiB;CACvD,YAAY;EACV,UAAU;EACV,MAAM;EACP;CACD,YAAY;EACV,UAAU;EACV,MAAM;EACP;CACD,WAAW;EAAE,UAAU;EAAU,MAAM;EAAiB;CACzD;;;;AAKD,MAAa,mBAAmB,IAAI,IAAI;CAAC;CAAU;CAAU;CAAQ,CAAC;;;;AAKtE,MAAa,yBAAyB,CAAC,iBAAiB,uBAAuB;;;;AAK/E,MAAa,0BAA0B,IAAI,IAAI;CAC7C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,uBAAuB,IAAI,IAAI;CAC1C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Built-in tasty style properties that are always valid as style keys.\n */\nexport const KNOWN_TASTY_PROPERTIES = new Set([\n 'display',\n 'font',\n 'preset',\n 'hide',\n 'whiteSpace',\n 'opacity',\n 'transition',\n 'gridArea',\n 'order',\n 'gridColumn',\n 'gridRow',\n 'placeSelf',\n 'alignSelf',\n 'justifySelf',\n 'zIndex',\n 'margin',\n 'inset',\n 'position',\n 'padding',\n 'paddingInline',\n 'paddingBlock',\n 'overflow',\n 'scrollbar',\n 'textAlign',\n 'border',\n 'radius',\n 'shadow',\n 'outline',\n 'color',\n 'fill',\n 'fade',\n 'image',\n 'textTransform',\n 'fontWeight',\n 'fontStyle',\n 'width',\n 'height',\n 'flexBasis',\n 'flexGrow',\n 'flexShrink',\n 'flex',\n 'flow',\n 'placeItems',\n 'placeContent',\n 'alignItems',\n 'alignContent',\n 'justifyItems',\n 'justifyContent',\n 'align',\n 'justify',\n 'gap',\n 'columnGap',\n 'rowGap',\n 'gridColumns',\n 'gridRows',\n 'gridTemplate',\n 'gridAreas',\n 'recipe',\n 'textOverflow',\n 'textDecoration',\n 'animation',\n 'cursor',\n 'pointerEvents',\n 'userSelect',\n 'transform',\n 'transformOrigin',\n 'filter',\n 'backdropFilter',\n 'mixBlendMode',\n 'objectFit',\n 'objectPosition',\n 'resize',\n 'appearance',\n 'listStyle',\n 'listStyleType',\n 'content',\n 'boxSizing',\n 'verticalAlign',\n 'wordBreak',\n 'overflowWrap',\n 'hyphens',\n 'tabSize',\n 'direction',\n 'unicodeBidi',\n 'writingMode',\n 'lineClamp',\n 'aspectRatio',\n 'contain',\n 'container',\n 'containerType',\n 'containerName',\n 'interpolateSize',\n 'willChange',\n 'isolation',\n 'touchAction',\n 'scrollBehavior',\n 'scrollSnapType',\n 'scrollSnapAlign',\n 'caretColor',\n 'accentColor',\n 'colorScheme',\n]);\n\n/**\n * Special top-level keys that are valid but not regular style properties.\n */\nexport const SPECIAL_STYLE_KEYS = new Set([\n '@keyframes',\n '@properties',\n '@fontFace',\n '@counterStyle',\n]);\n\n/**\n * CSS property names (common subset for validation).\n * When a key is camelCase and matches a known CSS property, it's valid.\n */\nexport const KNOWN_CSS_PROPERTIES = new Set([\n 'all',\n 'animation',\n 'animationDelay',\n 'animationDirection',\n 'animationDuration',\n 'animationFillMode',\n 'animationIterationCount',\n 'animationName',\n 'animationPlayState',\n 'animationTimingFunction',\n 'appearance',\n 'aspectRatio',\n 'backdropFilter',\n 'backfaceVisibility',\n 'background',\n 'backgroundAttachment',\n 'backgroundBlendMode',\n 'backgroundClip',\n 'backgroundColor',\n 'backgroundImage',\n 'backgroundOrigin',\n 'backgroundPosition',\n 'backgroundRepeat',\n 'backgroundSize',\n 'blockSize',\n 'border',\n 'borderBlock',\n 'borderBlockColor',\n 'borderBlockEnd',\n 'borderBlockEndColor',\n 'borderBlockEndStyle',\n 'borderBlockEndWidth',\n 'borderBlockStart',\n 'borderBlockStartColor',\n 'borderBlockStartStyle',\n 'borderBlockStartWidth',\n 'borderBlockStyle',\n 'borderBlockWidth',\n 'borderBottom',\n 'borderBottomColor',\n 'borderBottomLeftRadius',\n 'borderBottomRightRadius',\n 'borderBottomStyle',\n 'borderBottomWidth',\n 'borderCollapse',\n 'borderColor',\n 'borderImage',\n 'borderInline',\n 'borderInlineColor',\n 'borderInlineEnd',\n 'borderInlineStart',\n 'borderInlineStyle',\n 'borderInlineWidth',\n 'borderLeft',\n 'borderLeftColor',\n 'borderLeftStyle',\n 'borderLeftWidth',\n 'borderRadius',\n 'borderRight',\n 'borderRightColor',\n 'borderRightStyle',\n 'borderRightWidth',\n 'borderSpacing',\n 'borderStyle',\n 'borderTop',\n 'borderTopColor',\n 'borderTopLeftRadius',\n 'borderTopRightRadius',\n 'borderTopStyle',\n 'borderTopWidth',\n 'borderWidth',\n 'bottom',\n 'boxDecorationBreak',\n 'boxShadow',\n 'boxSizing',\n 'breakAfter',\n 'breakBefore',\n 'breakInside',\n 'captionSide',\n 'caretColor',\n 'clear',\n 'clip',\n 'clipPath',\n 'color',\n 'colorScheme',\n 'columnCount',\n 'columnFill',\n 'columnGap',\n 'columnRule',\n 'columnRuleColor',\n 'columnRuleStyle',\n 'columnRuleWidth',\n 'columnSpan',\n 'columnWidth',\n 'columns',\n 'contain',\n 'containerName',\n 'containerType',\n 'content',\n 'contentVisibility',\n 'counterIncrement',\n 'counterReset',\n 'counterSet',\n 'cursor',\n 'direction',\n 'display',\n 'emptyCells',\n 'filter',\n 'flex',\n 'flexBasis',\n 'flexDirection',\n 'flexFlow',\n 'flexGrow',\n 'flexShrink',\n 'flexWrap',\n 'float',\n 'font',\n 'fontFamily',\n 'fontFeatureSettings',\n 'fontKerning',\n 'fontOpticalSizing',\n 'fontSize',\n 'fontSizeAdjust',\n 'fontStretch',\n 'fontStyle',\n 'fontSynthesis',\n 'fontVariant',\n 'fontVariantAlternates',\n 'fontVariantCaps',\n 'fontVariantEastAsian',\n 'fontVariantLigatures',\n 'fontVariantNumeric',\n 'fontVariantPosition',\n 'fontWeight',\n 'gap',\n 'grid',\n 'gridArea',\n 'gridAutoColumns',\n 'gridAutoFlow',\n 'gridAutoRows',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnStart',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowStart',\n 'gridTemplate',\n 'gridTemplateAreas',\n 'gridTemplateColumns',\n 'gridTemplateRows',\n 'height',\n 'hyphens',\n 'imageRendering',\n 'inlineSize',\n 'inset',\n 'insetBlock',\n 'insetBlockEnd',\n 'insetBlockStart',\n 'insetInline',\n 'insetInlineEnd',\n 'insetInlineStart',\n 'isolation',\n 'justifyContent',\n 'justifyItems',\n 'justifySelf',\n 'left',\n 'letterSpacing',\n 'lineBreak',\n 'lineHeight',\n 'listStyle',\n 'listStyleImage',\n 'listStylePosition',\n 'listStyleType',\n 'margin',\n 'marginBlock',\n 'marginBlockEnd',\n 'marginBlockStart',\n 'marginBottom',\n 'marginInline',\n 'marginInlineEnd',\n 'marginInlineStart',\n 'marginLeft',\n 'marginRight',\n 'marginTop',\n 'maskImage',\n 'maxBlockSize',\n 'maxHeight',\n 'maxInlineSize',\n 'maxWidth',\n 'minBlockSize',\n 'minHeight',\n 'minInlineSize',\n 'minWidth',\n 'mixBlendMode',\n 'objectFit',\n 'objectPosition',\n 'opacity',\n 'order',\n 'orphans',\n 'outline',\n 'outlineColor',\n 'outlineOffset',\n 'outlineStyle',\n 'outlineWidth',\n 'overflow',\n 'overflowAnchor',\n 'overflowWrap',\n 'overflowX',\n 'overflowY',\n 'overscrollBehavior',\n 'padding',\n 'paddingBlock',\n 'paddingBlockEnd',\n 'paddingBlockStart',\n 'paddingBottom',\n 'paddingInline',\n 'paddingInlineEnd',\n 'paddingInlineStart',\n 'paddingLeft',\n 'paddingRight',\n 'paddingTop',\n 'perspective',\n 'perspectiveOrigin',\n 'placeContent',\n 'placeItems',\n 'placeSelf',\n 'pointerEvents',\n 'position',\n 'quotes',\n 'resize',\n 'right',\n 'rotate',\n 'rowGap',\n 'scale',\n 'scrollBehavior',\n 'scrollMargin',\n 'scrollMarginBlock',\n 'scrollMarginBlockEnd',\n 'scrollMarginBlockStart',\n 'scrollMarginBottom',\n 'scrollMarginInline',\n 'scrollMarginInlineEnd',\n 'scrollMarginInlineStart',\n 'scrollMarginLeft',\n 'scrollMarginRight',\n 'scrollMarginTop',\n 'scrollPadding',\n 'scrollPaddingBlock',\n 'scrollPaddingBlockEnd',\n 'scrollPaddingBlockStart',\n 'scrollPaddingBottom',\n 'scrollPaddingInline',\n 'scrollPaddingInlineEnd',\n 'scrollPaddingInlineStart',\n 'scrollPaddingLeft',\n 'scrollPaddingRight',\n 'scrollPaddingTop',\n 'scrollSnapAlign',\n 'scrollSnapStop',\n 'scrollSnapType',\n 'scrollbarColor',\n 'scrollbarGutter',\n 'scrollbarWidth',\n 'shapeOutside',\n 'tabSize',\n 'tableLayout',\n 'textAlign',\n 'textAlignLast',\n 'textCombineUpright',\n 'textDecoration',\n 'textDecorationColor',\n 'textDecorationLine',\n 'textDecorationSkipInk',\n 'textDecorationStyle',\n 'textDecorationThickness',\n 'textEmphasis',\n 'textIndent',\n 'textOrientation',\n 'textOverflow',\n 'textRendering',\n 'textShadow',\n 'textSizeAdjust',\n 'textTransform',\n 'textUnderlineOffset',\n 'textUnderlinePosition',\n 'textWrap',\n 'top',\n 'touchAction',\n 'transform',\n 'transformOrigin',\n 'transformStyle',\n 'transition',\n 'transitionDelay',\n 'transitionDuration',\n 'transitionProperty',\n 'transitionTimingFunction',\n 'translate',\n 'unicodeBidi',\n 'userSelect',\n 'verticalAlign',\n 'visibility',\n 'whiteSpace',\n 'widows',\n 'width',\n 'willChange',\n 'wordBreak',\n 'wordSpacing',\n 'writingMode',\n 'zIndex',\n]);\n\n/**\n * Built-in custom units recognized by the tasty parser.\n */\nexport const BUILT_IN_UNITS = new Set(['x', 'r', 'cr', 'bw', 'ow', 'lh', 'sf']);\n\n/**\n * Standard CSS units (always valid).\n */\nexport const CSS_UNITS = new Set([\n 'px',\n 'em',\n 'rem',\n '%',\n 'vw',\n 'vh',\n 'vmin',\n 'vmax',\n 'ch',\n 'ex',\n 'cm',\n 'mm',\n 'in',\n 'pt',\n 'pc',\n 'fr',\n 'deg',\n 'rad',\n 'turn',\n 'grad',\n 's',\n 'ms',\n 'dpi',\n 'dpcm',\n 'dppx',\n 'svw',\n 'svh',\n 'lvw',\n 'lvh',\n 'dvw',\n 'dvh',\n 'cqw',\n 'cqh',\n 'cqi',\n 'cqb',\n 'cqmin',\n 'cqmax',\n 'cap',\n 'ic',\n 'rlh',\n 'vi',\n 'vb',\n]);\n\n/**\n * Properties that accept `true` as a value (means \"use default\").\n */\nexport const BOOLEAN_TRUE_PROPERTIES = new Set([\n 'border',\n 'radius',\n 'padding',\n 'margin',\n 'gap',\n 'fill',\n 'color',\n 'shadow',\n 'outline',\n 'inset',\n 'width',\n 'height',\n 'hide',\n 'preset',\n 'font',\n 'scrollbar',\n]);\n\n/**\n * Directional modifiers and which properties accept them.\n */\nexport const DIRECTIONAL_MODIFIERS: Record<string, Set<string>> = {\n border: new Set(['top', 'right', 'bottom', 'left']),\n radius: new Set([\n 'top',\n 'right',\n 'bottom',\n 'left',\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n ]),\n padding: new Set(['top', 'right', 'bottom', 'left']),\n margin: new Set(['top', 'right', 'bottom', 'left']),\n fade: new Set(['top', 'right', 'bottom', 'left']),\n inset: new Set(['top', 'right', 'bottom', 'left']),\n};\n\n/**\n * Valid radius shape keywords.\n */\nexport const RADIUS_SHAPES = new Set(['round', 'ellipse', 'leaf', 'backleaf']);\n\n/**\n * Known semantic transition names.\n */\nexport const SEMANTIC_TRANSITIONS = new Set([\n 'fade',\n 'fill',\n 'border',\n 'radius',\n 'shadow',\n 'preset',\n 'gap',\n 'theme',\n 'color',\n 'outline',\n 'dimension',\n 'flow',\n 'inset',\n 'text',\n 'opacity',\n 'translate',\n 'rotate',\n 'scale',\n 'filter',\n 'image',\n 'background',\n 'width',\n 'height',\n 'zIndex',\n]);\n\n/**\n * Mapping of native CSS properties to tasty shorthand alternatives.\n */\nexport const SHORTHAND_MAPPING: Record<\n string,\n { property: string; hint: string }\n> = {\n backgroundColor: { property: 'fill', hint: \"fill: '...'\" },\n borderColor: { property: 'border', hint: \"border: '...'\" },\n borderWidth: { property: 'border', hint: \"border: '...'\" },\n borderStyle: { property: 'border', hint: \"border: '...'\" },\n borderTop: { property: 'border', hint: \"border: '... top'\" },\n borderRight: { property: 'border', hint: \"border: '... right'\" },\n borderBottom: { property: 'border', hint: \"border: '... bottom'\" },\n borderLeft: { property: 'border', hint: \"border: '... left'\" },\n borderRadius: { property: 'radius', hint: \"radius: '...'\" },\n maxWidth: { property: 'width', hint: \"width: 'max ...'\" },\n minWidth: { property: 'width', hint: \"width: 'min ...'\" },\n maxHeight: { property: 'height', hint: \"height: 'max ...'\" },\n minHeight: { property: 'height', hint: \"height: 'min ...'\" },\n flexDirection: { property: 'flow', hint: \"flow: '...'\" },\n flexWrap: { property: 'flow', hint: \"flow: '...'\" },\n flexFlow: { property: 'flow', hint: \"flow: '...'\" },\n gridAutoFlow: { property: 'flow', hint: \"flow: '...'\" },\n outlineOffset: { property: 'outline', hint: \"outline: '... / offset'\" },\n paddingTop: { property: 'padding', hint: \"padding: '... top'\" },\n paddingRight: { property: 'padding', hint: \"padding: '... right'\" },\n paddingBottom: { property: 'padding', hint: \"padding: '... bottom'\" },\n paddingLeft: { property: 'padding', hint: \"padding: '... left'\" },\n marginTop: { property: 'margin', hint: \"margin: '... top'\" },\n marginRight: { property: 'margin', hint: \"margin: '... right'\" },\n marginBottom: { property: 'margin', hint: \"margin: '... bottom'\" },\n marginLeft: { property: 'margin', hint: \"margin: '... left'\" },\n fontSize: { property: 'preset', hint: \"preset: '...'\" },\n fontWeight: {\n property: 'preset',\n hint: \"preset: 'name / strong' (with strong modifier)\",\n },\n lineHeight: {\n property: 'preset',\n hint: \"preset: 'name / tight' (with tight modifier)\",\n },\n boxShadow: { property: 'shadow', hint: \"shadow: '...'\" },\n};\n\n/**\n * Known preset modifiers.\n */\nexport const PRESET_MODIFIERS = new Set([\n 'strong',\n 'bold',\n 'italic',\n 'icon',\n 'tight',\n]);\n\n/**\n * Default import sources for tasty.\n */\nexport const DEFAULT_IMPORT_SOURCES = ['@tenphi/tasty', '@tenphi/tasty/static'];\n\n/**\n * Built-in state prefixes that are always valid (not aliases).\n */\nexport const BUILT_IN_STATE_PREFIXES = new Set([\n '@media',\n '@root',\n '@parent',\n '@own',\n '@supports',\n '@starting',\n '@keyframes',\n '@properties',\n '@fontFace',\n '@counterStyle',\n]);\n\n/**\n * Known CSS pseudo-classes.\n */\nexport const KNOWN_PSEUDO_CLASSES = new Set([\n ':hover',\n ':focus',\n ':focus-visible',\n ':focus-within',\n ':active',\n ':visited',\n ':link',\n ':checked',\n ':disabled',\n ':enabled',\n ':empty',\n ':first-child',\n ':last-child',\n ':first-of-type',\n ':last-of-type',\n ':only-child',\n ':only-of-type',\n ':root',\n ':target',\n ':valid',\n ':invalid',\n ':required',\n ':optional',\n ':read-only',\n ':read-write',\n ':placeholder-shown',\n ':autofill',\n ':default',\n ':indeterminate',\n ':in-range',\n ':out-of-range',\n ':any-link',\n ':local-link',\n ':is',\n ':not',\n ':where',\n ':has',\n ':nth-child',\n ':nth-last-child',\n ':nth-of-type',\n ':nth-last-of-type',\n '::before',\n '::after',\n '::placeholder',\n '::selection',\n '::first-line',\n '::first-letter',\n '::marker',\n '::backdrop',\n]);\n"],"mappings":";;;;AAGA,MAAa,yBAAyB,IAAI,IAAI;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,qBAAqB,IAAI,IAAI;CACxC;CACA;CACA;CACA;CACD,CAAC;;;;;AAMF,MAAa,uBAAuB,IAAI,IAAI;CAC1C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,iBAAiB,IAAI,IAAI;CAAC;CAAK;CAAK;CAAM;CAAM;CAAM;CAAM;CAAK,CAAC;;;;AAK/E,MAAa,YAAY,IAAI,IAAI;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;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"}
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ import no_styles_prop_default from "./rules/no-styles-prop.js";
|
|
|
25
25
|
import consistent_token_usage_default from "./rules/consistent-token-usage.js";
|
|
26
26
|
import no_runtime_styles_mutation_default from "./rules/no-runtime-styles-mutation.js";
|
|
27
27
|
import valid_state_definition_default from "./rules/valid-state-definition.js";
|
|
28
|
+
import no_own_at_root_default from "./rules/no-own-at-root.js";
|
|
28
29
|
import { recommended, strict } from "./configs.js";
|
|
29
30
|
|
|
30
31
|
//#region src/index.ts
|
|
@@ -60,7 +61,8 @@ const plugin = {
|
|
|
60
61
|
"no-styles-prop": no_styles_prop_default,
|
|
61
62
|
"consistent-token-usage": consistent_token_usage_default,
|
|
62
63
|
"no-runtime-styles-mutation": no_runtime_styles_mutation_default,
|
|
63
|
-
"valid-state-definition": valid_state_definition_default
|
|
64
|
+
"valid-state-definition": valid_state_definition_default,
|
|
65
|
+
"no-own-at-root": no_own_at_root_default
|
|
64
66
|
},
|
|
65
67
|
configs: {
|
|
66
68
|
recommended: {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["rules.knownProperty","rules.validValue","rules.validColorToken","rules.validCustomUnit","rules.validStateKey","rules.validStylesStructure","rules.noNestedSelector","rules.validCustomProperty","rules.validPreset","rules.validRecipe","rules.validBooleanProperty","rules.validDirectionalModifier","rules.validRadiusShape","rules.noImportant","rules.validSubElement","rules.noNestedStateMap","rules.staticNoDynamicValues","rules.staticValidSelector","rules.preferShorthandProperty","rules.validTransition","rules.requireDefaultState","rules.noUnknownStateAlias","rules.noRawColorValues","rules.noStylesProp","rules.consistentTokenUsage","rules.noRuntimeStylesMutation","rules.validStateDefinition"],"sources":["../src/index.ts"],"sourcesContent":["import type { TSESLint } from '@typescript-eslint/utils';\nimport * as rules from './rules/index.js';\nimport { recommended, strict } from './configs.js';\n\nconst ruleMap: Record<string, TSESLint.RuleModule<string, unknown[]>> = {\n 'known-property': rules.knownProperty,\n 'valid-value': rules.validValue,\n 'valid-color-token': rules.validColorToken,\n 'valid-custom-unit': rules.validCustomUnit,\n 'valid-state-key': rules.validStateKey,\n 'valid-styles-structure': rules.validStylesStructure,\n 'no-nested-selector': rules.noNestedSelector,\n 'valid-custom-property': rules.validCustomProperty,\n 'valid-preset': rules.validPreset,\n 'valid-recipe': rules.validRecipe,\n 'valid-boolean-property': rules.validBooleanProperty,\n 'valid-directional-modifier': rules.validDirectionalModifier,\n 'valid-radius-shape': rules.validRadiusShape,\n 'no-important': rules.noImportant,\n 'valid-sub-element': rules.validSubElement,\n 'no-nested-state-map': rules.noNestedStateMap,\n 'static-no-dynamic-values': rules.staticNoDynamicValues,\n 'static-valid-selector': rules.staticValidSelector,\n 'prefer-shorthand-property': rules.preferShorthandProperty,\n 'valid-transition': rules.validTransition,\n 'require-default-state': rules.requireDefaultState,\n 'no-unknown-state-alias': rules.noUnknownStateAlias,\n 'no-raw-color-values': rules.noRawColorValues,\n 'no-styles-prop': rules.noStylesProp,\n 'consistent-token-usage': rules.consistentTokenUsage,\n 'no-runtime-styles-mutation': rules.noRuntimeStylesMutation,\n 'valid-state-definition': rules.validStateDefinition,\n};\n\nconst plugin = {\n meta: {\n name: '@tenphi/eslint-plugin-tasty',\n version: '0.1.0',\n },\n rules: ruleMap,\n configs: {\n recommended: {\n plugins: {\n get tasty() {\n return plugin;\n },\n },\n rules: recommended,\n },\n strict: {\n plugins: {\n get tasty() {\n return plugin;\n },\n },\n rules: strict,\n },\n },\n} satisfies TSESLint.FlatConfig.Plugin & {\n configs: Record<string, TSESLint.FlatConfig.Config>;\n};\n\nexport default plugin;\n\nexport { recommended, strict } from './configs.js';\nexport type { TastyValidationConfig, ResolvedConfig } from './types.js';\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":["rules.knownProperty","rules.validValue","rules.validColorToken","rules.validCustomUnit","rules.validStateKey","rules.validStylesStructure","rules.noNestedSelector","rules.validCustomProperty","rules.validPreset","rules.validRecipe","rules.validBooleanProperty","rules.validDirectionalModifier","rules.validRadiusShape","rules.noImportant","rules.validSubElement","rules.noNestedStateMap","rules.staticNoDynamicValues","rules.staticValidSelector","rules.preferShorthandProperty","rules.validTransition","rules.requireDefaultState","rules.noUnknownStateAlias","rules.noRawColorValues","rules.noStylesProp","rules.consistentTokenUsage","rules.noRuntimeStylesMutation","rules.validStateDefinition","rules.noOwnAtRoot"],"sources":["../src/index.ts"],"sourcesContent":["import type { TSESLint } from '@typescript-eslint/utils';\nimport * as rules from './rules/index.js';\nimport { recommended, strict } from './configs.js';\n\nconst ruleMap: Record<string, TSESLint.RuleModule<string, unknown[]>> = {\n 'known-property': rules.knownProperty,\n 'valid-value': rules.validValue,\n 'valid-color-token': rules.validColorToken,\n 'valid-custom-unit': rules.validCustomUnit,\n 'valid-state-key': rules.validStateKey,\n 'valid-styles-structure': rules.validStylesStructure,\n 'no-nested-selector': rules.noNestedSelector,\n 'valid-custom-property': rules.validCustomProperty,\n 'valid-preset': rules.validPreset,\n 'valid-recipe': rules.validRecipe,\n 'valid-boolean-property': rules.validBooleanProperty,\n 'valid-directional-modifier': rules.validDirectionalModifier,\n 'valid-radius-shape': rules.validRadiusShape,\n 'no-important': rules.noImportant,\n 'valid-sub-element': rules.validSubElement,\n 'no-nested-state-map': rules.noNestedStateMap,\n 'static-no-dynamic-values': rules.staticNoDynamicValues,\n 'static-valid-selector': rules.staticValidSelector,\n 'prefer-shorthand-property': rules.preferShorthandProperty,\n 'valid-transition': rules.validTransition,\n 'require-default-state': rules.requireDefaultState,\n 'no-unknown-state-alias': rules.noUnknownStateAlias,\n 'no-raw-color-values': rules.noRawColorValues,\n 'no-styles-prop': rules.noStylesProp,\n 'consistent-token-usage': rules.consistentTokenUsage,\n 'no-runtime-styles-mutation': rules.noRuntimeStylesMutation,\n 'valid-state-definition': rules.validStateDefinition,\n 'no-own-at-root': rules.noOwnAtRoot,\n};\n\nconst plugin = {\n meta: {\n name: '@tenphi/eslint-plugin-tasty',\n version: '0.1.0',\n },\n rules: ruleMap,\n configs: {\n recommended: {\n plugins: {\n get tasty() {\n return plugin;\n },\n },\n rules: recommended,\n },\n strict: {\n plugins: {\n get tasty() {\n return plugin;\n },\n },\n rules: strict,\n },\n },\n} satisfies TSESLint.FlatConfig.Plugin & {\n configs: Record<string, TSESLint.FlatConfig.Config>;\n};\n\nexport default plugin;\n\nexport { recommended, strict } from './configs.js';\nexport type { TastyValidationConfig, ResolvedConfig } from './types.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,MAAM,SAAS;CACb,MAAM;EACJ,MAAM;EACN,SAAS;EACV;CACD,OApCsE;EACtE,kBAAkBA;EAClB,eAAeC;EACf,qBAAqBC;EACrB,qBAAqBC;EACrB,mBAAmBC;EACnB,0BAA0BC;EAC1B,sBAAsBC;EACtB,yBAAyBC;EACzB,gBAAgBC;EAChB,gBAAgBC;EAChB,0BAA0BC;EAC1B,8BAA8BC;EAC9B,sBAAsBC;EACtB,gBAAgBC;EAChB,qBAAqBC;EACrB,uBAAuBC;EACvB,4BAA4BC;EAC5B,yBAAyBC;EACzB,6BAA6BC;EAC7B,oBAAoBC;EACpB,yBAAyBC;EACzB,0BAA0BC;EAC1B,uBAAuBC;EACvB,kBAAkBC;EAClB,0BAA0BC;EAC1B,8BAA8BC;EAC9B,0BAA0BC;EAC1B,kBAAkBC;EACnB;CAQC,SAAS;EACP,aAAa;GACX,SAAS,EACP,IAAI,QAAQ;AACV,WAAO;MAEV;GACD,OAAO;GACR;EACD,QAAQ;GACN,SAAS,EACP,IAAI,QAAQ;AACV,WAAO;MAEV;GACD,OAAO;GACR;EACF;CACF"}
|
|
@@ -445,6 +445,10 @@ function classifyToken(raw, offset, errors, opts) {
|
|
|
445
445
|
value: parseFloat(token),
|
|
446
446
|
raw: token
|
|
447
447
|
};
|
|
448
|
+
if (token === "@inherit") return {
|
|
449
|
+
type: "keyword",
|
|
450
|
+
value: token
|
|
451
|
+
};
|
|
448
452
|
if (VALUE_KEYWORDS.has(token) || VALUE_KEYWORDS.has(token.toLowerCase())) return {
|
|
449
453
|
type: "keyword",
|
|
450
454
|
value: token
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value-parser.js","names":[],"sources":["../../src/parsers/value-parser.ts"],"sourcesContent":["import { scanTokens, checkBracketBalance } from './utils.js';\nimport { BUILT_IN_UNITS, CSS_UNITS } from '../constants.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ValueToken =\n | { type: 'color-token'; name: string; opacity?: string; raw: string }\n | { type: 'color-ref'; name: string; raw: string }\n | { type: 'custom-prop'; name: string; raw: string }\n | { type: 'custom-prop-ref'; name: string; raw: string }\n | { type: 'custom-unit'; value: number; unit: string; raw: string }\n | { type: 'css-unit'; value: number; unit: string; raw: string }\n | { type: 'number'; value: number; raw: string }\n | { type: 'keyword'; value: string }\n | { type: 'css-function'; name: string; args: string; raw: string }\n | { type: 'string'; value: string; raw: string }\n | { type: 'important'; raw: string }\n | { type: 'group-expr'; inner: string; raw: string }\n | { type: 'unknown'; raw: string };\n\nexport interface ValueError {\n message: string;\n offset: number;\n length: number;\n raw?: string;\n}\n\nexport interface ValuePart {\n tokens: ValueToken[];\n}\n\nexport interface ValueGroup {\n parts: ValuePart[];\n}\n\nexport interface ValueParseResult {\n groups: ValueGroup[];\n errors: ValueError[];\n}\n\nexport interface ValueParserOptions {\n knownUnits?: Set<string> | string[];\n knownFuncs?: Set<string> | string[];\n skipUnitValidation?: boolean;\n skipFuncValidation?: boolean;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst RE_UNIT_NUM = /^[+-]?(?:\\d*\\.\\d+|\\d+)([a-z][a-z0-9]*)$/;\nconst RE_NUMBER = /^[+-]?(?:\\d*\\.\\d+|\\d+)$/;\nconst RE_CSS_UNIT_NUM = /^[+-]?(?:\\d*\\.\\d+|\\d+)([a-z%]+)$/;\n\nconst COLOR_FUNCS = new Set([\n 'rgb',\n 'rgba',\n 'hsl',\n 'hsla',\n 'hwb',\n 'lab',\n 'lch',\n 'oklab',\n 'oklch',\n 'color',\n 'device-cmyk',\n 'gray',\n 'color-mix',\n 'color-contrast',\n]);\n\nconst CSS_FUNCS = new Set([\n 'calc',\n 'min',\n 'max',\n 'clamp',\n 'var',\n 'env',\n 'attr',\n 'counter',\n 'counters',\n 'image-set',\n 'linear-gradient',\n 'radial-gradient',\n 'conic-gradient',\n 'repeating-linear-gradient',\n 'repeating-radial-gradient',\n 'repeating-conic-gradient',\n 'url',\n 'fit-content',\n 'minmax',\n 'repeat',\n 'cubic-bezier',\n 'steps',\n 'linear',\n 'rotate',\n 'scale',\n 'translate',\n 'skew',\n 'matrix',\n 'perspective',\n 'rotate3d',\n 'rotateX',\n 'rotateY',\n 'rotateZ',\n 'scale3d',\n 'scaleX',\n 'scaleY',\n 'scaleZ',\n 'translate3d',\n 'translateX',\n 'translateY',\n 'translateZ',\n 'skewX',\n 'skewY',\n 'matrix3d',\n 'blur',\n 'brightness',\n 'contrast',\n 'drop-shadow',\n 'grayscale',\n 'hue-rotate',\n 'invert',\n 'opacity',\n 'saturate',\n 'sepia',\n 'polygon',\n 'circle',\n 'ellipse',\n 'inset',\n 'path',\n 'light-dark',\n]);\n\nconst VALUE_KEYWORDS = new Set([\n 'auto',\n 'none',\n 'normal',\n 'inherit',\n 'initial',\n 'unset',\n 'revert',\n 'revert-layer',\n 'max-content',\n 'min-content',\n 'fit-content',\n 'stretch',\n 'transparent',\n 'currentcolor',\n 'currentColor',\n // display\n 'block',\n 'inline',\n 'inline-block',\n 'flex',\n 'inline-flex',\n 'grid',\n 'inline-grid',\n 'contents',\n 'table',\n 'table-row',\n 'table-cell',\n 'list-item',\n 'flow-root',\n // position\n 'static',\n 'relative',\n 'absolute',\n 'fixed',\n 'sticky',\n // overflow\n 'visible',\n 'hidden',\n 'scroll',\n 'clip',\n 'overlay',\n // flex/align\n 'center',\n 'start',\n 'end',\n 'flex-start',\n 'flex-end',\n 'space-between',\n 'space-around',\n 'space-evenly',\n 'baseline',\n // flow\n 'row',\n 'column',\n 'row-reverse',\n 'column-reverse',\n 'wrap',\n 'nowrap',\n 'dense',\n // border\n 'solid',\n 'dashed',\n 'dotted',\n 'double',\n 'groove',\n 'ridge',\n 'outset',\n // directional\n 'top',\n 'right',\n 'bottom',\n 'left',\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n // radius shapes\n 'round',\n 'ellipse',\n 'leaf',\n 'backleaf',\n // dimension modifiers\n 'min',\n 'max',\n // text\n 'bold',\n 'bolder',\n 'lighter',\n 'italic',\n 'oblique',\n 'uppercase',\n 'lowercase',\n 'capitalize',\n 'line-through',\n 'underline',\n 'overline',\n 'wavy',\n // cursor\n 'pointer',\n 'default',\n 'text',\n 'move',\n 'grab',\n 'grabbing',\n 'not-allowed',\n 'crosshair',\n 'wait',\n 'help',\n 'col-resize',\n 'row-resize',\n 'n-resize',\n 's-resize',\n 'e-resize',\n 'w-resize',\n 'ne-resize',\n 'nw-resize',\n 'se-resize',\n 'sw-resize',\n 'ew-resize',\n 'ns-resize',\n 'zoom-in',\n 'zoom-out',\n // misc\n 'cover',\n 'contain',\n 'fill',\n 'no-repeat',\n 'repeat-x',\n 'repeat-y',\n 'border-box',\n 'padding-box',\n 'content-box',\n 'break-word',\n 'break-all',\n 'keep-all',\n 'anywhere',\n 'pre',\n 'pre-wrap',\n 'pre-line',\n 'balance',\n 'smooth',\n 'horizontal',\n 'vertical',\n 'both',\n 'mandatory',\n 'proximity',\n // white-space\n 'collapse',\n 'preserve',\n 'preserve-breaks',\n 'break-spaces',\n // text-wrap\n 'pretty',\n 'stable',\n // will-change\n 'transform',\n 'opacity',\n // animation\n 'infinite',\n 'alternate',\n 'alternate-reverse',\n 'reverse',\n 'forwards',\n 'backwards',\n 'running',\n 'paused',\n 'ease',\n 'ease-in',\n 'ease-out',\n 'ease-in-out',\n 'step-start',\n 'step-end',\n // scrollbar\n 'thin',\n 'always',\n 'both-edges',\n // width/height\n 'fixed',\n // shadow\n 'inset',\n // textOverflow\n 'clip',\n // other\n 'ltr',\n 'rtl',\n 'embed',\n 'isolate',\n 'isolate-override',\n 'plaintext',\n 'horizontal-tb',\n 'vertical-rl',\n 'vertical-lr',\n 'sideways-rl',\n 'sideways-lr',\n 'monospace',\n 'serif',\n 'sans-serif',\n 'cursive',\n 'fantasy',\n 'system-ui',\n 'ui-serif',\n 'ui-sans-serif',\n 'ui-monospace',\n 'ui-rounded',\n 'to',\n // misc\n 'strong',\n 'tight',\n 'icon',\n]);\n\n// ============================================================================\n// Classifier\n// ============================================================================\n\nfunction toSet(input?: Set<string> | string[]): Set<string> {\n if (!input) return new Set();\n return input instanceof Set ? input : new Set(input);\n}\n\nfunction classifyToken(\n raw: string,\n offset: number,\n errors: ValueError[],\n opts: ValueParserOptions,\n): ValueToken {\n const token = raw.trim();\n if (!token) return { type: 'keyword', value: '' };\n\n // Quoted strings\n if (\n (token.startsWith('\"') && token.endsWith('\"')) ||\n (token.startsWith(\"'\") && token.endsWith(\"'\"))\n ) {\n return { type: 'string', value: token.slice(1, -1), raw: token };\n }\n\n // !important\n if (token === '!important') {\n return { type: 'important', raw: token };\n }\n\n // Double prefix: $$name (custom property reference for transitions)\n if (token.startsWith('$$')) {\n const name = token.slice(2);\n if (/^[a-z_][a-z0-9-_]*$/i.test(name)) {\n return { type: 'custom-prop-ref', name, raw: token };\n }\n errors.push({\n message: `Invalid custom property reference '${token}'.`,\n offset,\n length: token.length,\n raw: token,\n });\n return { type: 'unknown', raw: token };\n }\n\n // Double prefix: ##name (color reference for transitions)\n if (token.startsWith('##')) {\n const name = token.slice(2);\n if (/^[a-z_][a-z0-9-_]*$/i.test(name)) {\n return { type: 'color-ref', name, raw: token };\n }\n errors.push({\n message: `Invalid color reference '${token}'.`,\n offset,\n length: token.length,\n raw: token,\n });\n return { type: 'unknown', raw: token };\n }\n\n // Custom property: $name\n if (token.startsWith('$')) {\n const name = token.slice(1);\n if (/^[a-z_][a-z0-9-_]*$/i.test(name)) {\n return { type: 'custom-prop', name, raw: token };\n }\n errors.push({\n message: `Invalid custom property syntax '${token}'.`,\n offset,\n length: token.length,\n raw: token,\n });\n return { type: 'unknown', raw: token };\n }\n\n // Color token: #name, #name.N, #name.$prop, or bare # (error)\n if (token.startsWith('#')) {\n if (token.length === 1) {\n errors.push({\n message: 'Empty color token name.',\n offset,\n length: 1,\n raw: token,\n });\n return { type: 'unknown', raw: token };\n }\n return classifyColorToken(token, offset, errors);\n }\n\n // Parenthesized expression: (expr) — fallback, auto-calc, etc.\n if (token.startsWith('(') && token.endsWith(')')) {\n return { type: 'group-expr', inner: token.slice(1, -1), raw: token };\n }\n\n // Function call: name(...)\n const openIdx = token.indexOf('(');\n if (openIdx > 0 && token.endsWith(')')) {\n const fname = token.slice(0, openIdx);\n const args = token.slice(openIdx + 1, -1);\n\n if (opts.skipFuncValidation) {\n return { type: 'css-function', name: fname, args, raw: token };\n }\n\n const knownFuncs = toSet(opts.knownFuncs);\n\n if (\n COLOR_FUNCS.has(fname) ||\n CSS_FUNCS.has(fname) ||\n knownFuncs.has(fname)\n ) {\n return { type: 'css-function', name: fname, args, raw: token };\n }\n\n // Unknown function — still return as css-function but flag it\n errors.push({\n message: `Unknown function '${fname}()'.`,\n offset,\n length: token.length,\n raw: token,\n });\n return { type: 'css-function', name: fname, args, raw: token };\n }\n\n // Unit number: 2x, 1.5r, 10px, 50%, 1fr\n const unitMatch = token.match(RE_UNIT_NUM);\n if (unitMatch) {\n const unit = unitMatch[1];\n const numVal = parseFloat(token.slice(0, -unit.length));\n\n if (opts.skipUnitValidation) {\n return { type: 'custom-unit', value: numVal, unit, raw: token };\n }\n\n const knownUnits = toSet(opts.knownUnits);\n\n if (BUILT_IN_UNITS.has(unit) || knownUnits.has(unit)) {\n return { type: 'custom-unit', value: numVal, unit, raw: token };\n }\n if (CSS_UNITS.has(unit)) {\n return { type: 'css-unit', value: numVal, unit, raw: token };\n }\n\n errors.push({\n message: `Unknown unit '${unit}' in '${token}'.`,\n offset,\n length: token.length,\n raw: token,\n });\n return { type: 'unknown', raw: token };\n }\n\n // CSS unit with % (RE_UNIT_NUM doesn't match % since it expects alpha)\n const cssUnitMatch = token.match(RE_CSS_UNIT_NUM);\n if (cssUnitMatch) {\n const unit = cssUnitMatch[1];\n const numVal = parseFloat(token.slice(0, -unit.length));\n if (CSS_UNITS.has(unit)) {\n return { type: 'css-unit', value: numVal, unit, raw: token };\n }\n }\n\n // Plain number\n if (RE_NUMBER.test(token)) {\n return { type: 'number', value: parseFloat(token), raw: token };\n }\n\n // Known keyword\n if (VALUE_KEYWORDS.has(token) || VALUE_KEYWORDS.has(token.toLowerCase())) {\n return { type: 'keyword', value: token };\n }\n\n // CSS custom property function var(--name)\n if (token.startsWith('var(') && token.endsWith(')')) {\n return {\n type: 'css-function',\n name: 'var',\n args: token.slice(4, -1),\n raw: token,\n };\n }\n\n // Unknown token\n return { type: 'unknown', raw: token };\n}\n\nfunction classifyColorToken(\n token: string,\n offset: number,\n errors: ValueError[],\n): ValueToken {\n const raw = token;\n\n // Strip leading #\n const name = token.slice(1);\n\n if (name.length === 0) {\n errors.push({\n message: 'Empty color token name.',\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n\n // Check for opacity suffix\n const dotIndex = name.indexOf('.');\n if (dotIndex !== -1) {\n const tokenName = name.slice(0, dotIndex);\n const opacitySuffix = name.slice(dotIndex + 1);\n\n if (tokenName.length === 0) {\n errors.push({\n message: 'Empty color token name before opacity.',\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n\n // Dynamic opacity from CSS custom property\n if (opacitySuffix.startsWith('$')) {\n return {\n type: 'color-token',\n name: tokenName,\n opacity: opacitySuffix,\n raw,\n };\n }\n\n if (opacitySuffix.length === 0) {\n errors.push({\n message: 'Trailing dot with no opacity value.',\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n\n const opacity = Number(opacitySuffix);\n if (isNaN(opacity)) {\n errors.push({\n message: `Invalid opacity value '${opacitySuffix}'.`,\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n if (opacity < 0) {\n errors.push({\n message: 'Opacity cannot be negative.',\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n if (opacity > 100) {\n errors.push({\n message: `Opacity '${opacitySuffix}' exceeds 100.`,\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n\n return {\n type: 'color-token',\n name: tokenName,\n opacity: opacitySuffix,\n raw,\n };\n }\n\n return { type: 'color-token', name, raw };\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Parse a style value string into typed tokens organized by\n * comma-separated groups and slash-separated parts.\n */\nexport function parseValue(\n src: string,\n opts: ValueParserOptions = {},\n): ValueParseResult {\n const errors: ValueError[] = [];\n\n // Check bracket balance first\n const bracketError = checkBracketBalance(src);\n if (bracketError) {\n errors.push({\n message: bracketError.message,\n offset: bracketError.position,\n length: 1,\n });\n return { groups: [], errors };\n }\n\n const scanned = scanTokens(src);\n\n const groups: ValueGroup[] = [];\n let currentParts: ValuePart[] = [];\n let currentTokens: ValueToken[] = [];\n\n const endPart = () => {\n if (currentTokens.length > 0) {\n currentParts.push({ tokens: currentTokens });\n currentTokens = [];\n }\n };\n\n const endGroup = () => {\n endPart();\n if (currentParts.length > 0) {\n groups.push({ parts: currentParts });\n } else {\n groups.push({ parts: [{ tokens: [] }] });\n }\n currentParts = [];\n };\n\n for (const scanned_token of scanned) {\n if (scanned_token.value) {\n const classified = classifyToken(\n scanned_token.value,\n scanned_token.offset,\n errors,\n opts,\n );\n currentTokens.push(classified);\n }\n if (scanned_token.isSlash) endPart();\n if (scanned_token.isComma) endGroup();\n }\n\n // Push final group\n if (\n currentTokens.length > 0 ||\n currentParts.length > 0 ||\n groups.length === 0\n ) {\n endGroup();\n }\n\n return { groups, errors };\n}\n\n/**\n * Extract all tokens of a specific type from a parse result.\n */\nexport function extractTokensByType<T extends ValueToken['type']>(\n result: ValueParseResult,\n type: T,\n): Extract<ValueToken, { type: T }>[] {\n const tokens: Extract<ValueToken, { type: T }>[] = [];\n for (const group of result.groups) {\n for (const part of group.parts) {\n for (const token of part.tokens) {\n if (token.type === type) {\n tokens.push(token as Extract<ValueToken, { type: T }>);\n }\n }\n }\n }\n return tokens;\n}\n\n/**\n * Get a flat list of all tokens from a parse result.\n */\nexport function flattenTokens(result: ValueParseResult): ValueToken[] {\n const tokens: ValueToken[] = [];\n for (const group of result.groups) {\n for (const part of group.parts) {\n tokens.push(...part.tokens);\n }\n }\n return tokens;\n}\n"],"mappings":";;;;AAqDA,MAAM,cAAc;AACpB,MAAM,YAAY;AAClB,MAAM,kBAAkB;AAExB,MAAM,cAAc,IAAI,IAAI;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,YAAY,IAAI,IAAI;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,iBAAiB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CAEA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;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"}
|
|
1
|
+
{"version":3,"file":"value-parser.js","names":[],"sources":["../../src/parsers/value-parser.ts"],"sourcesContent":["import { scanTokens, checkBracketBalance } from './utils.js';\nimport { BUILT_IN_UNITS, CSS_UNITS } from '../constants.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ValueToken =\n | { type: 'color-token'; name: string; opacity?: string; raw: string }\n | { type: 'color-ref'; name: string; raw: string }\n | { type: 'custom-prop'; name: string; raw: string }\n | { type: 'custom-prop-ref'; name: string; raw: string }\n | { type: 'custom-unit'; value: number; unit: string; raw: string }\n | { type: 'css-unit'; value: number; unit: string; raw: string }\n | { type: 'number'; value: number; raw: string }\n | { type: 'keyword'; value: string }\n | { type: 'css-function'; name: string; args: string; raw: string }\n | { type: 'string'; value: string; raw: string }\n | { type: 'important'; raw: string }\n | { type: 'group-expr'; inner: string; raw: string }\n | { type: 'unknown'; raw: string };\n\nexport interface ValueError {\n message: string;\n offset: number;\n length: number;\n raw?: string;\n}\n\nexport interface ValuePart {\n tokens: ValueToken[];\n}\n\nexport interface ValueGroup {\n parts: ValuePart[];\n}\n\nexport interface ValueParseResult {\n groups: ValueGroup[];\n errors: ValueError[];\n}\n\nexport interface ValueParserOptions {\n knownUnits?: Set<string> | string[];\n knownFuncs?: Set<string> | string[];\n skipUnitValidation?: boolean;\n skipFuncValidation?: boolean;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst RE_UNIT_NUM = /^[+-]?(?:\\d*\\.\\d+|\\d+)([a-z][a-z0-9]*)$/;\nconst RE_NUMBER = /^[+-]?(?:\\d*\\.\\d+|\\d+)$/;\nconst RE_CSS_UNIT_NUM = /^[+-]?(?:\\d*\\.\\d+|\\d+)([a-z%]+)$/;\n\nconst COLOR_FUNCS = new Set([\n 'rgb',\n 'rgba',\n 'hsl',\n 'hsla',\n 'hwb',\n 'lab',\n 'lch',\n 'oklab',\n 'oklch',\n 'color',\n 'device-cmyk',\n 'gray',\n 'color-mix',\n 'color-contrast',\n]);\n\nconst CSS_FUNCS = new Set([\n 'calc',\n 'min',\n 'max',\n 'clamp',\n 'var',\n 'env',\n 'attr',\n 'counter',\n 'counters',\n 'image-set',\n 'linear-gradient',\n 'radial-gradient',\n 'conic-gradient',\n 'repeating-linear-gradient',\n 'repeating-radial-gradient',\n 'repeating-conic-gradient',\n 'url',\n 'fit-content',\n 'minmax',\n 'repeat',\n 'cubic-bezier',\n 'steps',\n 'linear',\n 'rotate',\n 'scale',\n 'translate',\n 'skew',\n 'matrix',\n 'perspective',\n 'rotate3d',\n 'rotateX',\n 'rotateY',\n 'rotateZ',\n 'scale3d',\n 'scaleX',\n 'scaleY',\n 'scaleZ',\n 'translate3d',\n 'translateX',\n 'translateY',\n 'translateZ',\n 'skewX',\n 'skewY',\n 'matrix3d',\n 'blur',\n 'brightness',\n 'contrast',\n 'drop-shadow',\n 'grayscale',\n 'hue-rotate',\n 'invert',\n 'opacity',\n 'saturate',\n 'sepia',\n 'polygon',\n 'circle',\n 'ellipse',\n 'inset',\n 'path',\n 'light-dark',\n]);\n\nconst VALUE_KEYWORDS = new Set([\n 'auto',\n 'none',\n 'normal',\n 'inherit',\n 'initial',\n 'unset',\n 'revert',\n 'revert-layer',\n 'max-content',\n 'min-content',\n 'fit-content',\n 'stretch',\n 'transparent',\n 'currentcolor',\n 'currentColor',\n // display\n 'block',\n 'inline',\n 'inline-block',\n 'flex',\n 'inline-flex',\n 'grid',\n 'inline-grid',\n 'contents',\n 'table',\n 'table-row',\n 'table-cell',\n 'list-item',\n 'flow-root',\n // position\n 'static',\n 'relative',\n 'absolute',\n 'fixed',\n 'sticky',\n // overflow\n 'visible',\n 'hidden',\n 'scroll',\n 'clip',\n 'overlay',\n // flex/align\n 'center',\n 'start',\n 'end',\n 'flex-start',\n 'flex-end',\n 'space-between',\n 'space-around',\n 'space-evenly',\n 'baseline',\n // flow\n 'row',\n 'column',\n 'row-reverse',\n 'column-reverse',\n 'wrap',\n 'nowrap',\n 'dense',\n // border\n 'solid',\n 'dashed',\n 'dotted',\n 'double',\n 'groove',\n 'ridge',\n 'outset',\n // directional\n 'top',\n 'right',\n 'bottom',\n 'left',\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n // radius shapes\n 'round',\n 'ellipse',\n 'leaf',\n 'backleaf',\n // dimension modifiers\n 'min',\n 'max',\n // text\n 'bold',\n 'bolder',\n 'lighter',\n 'italic',\n 'oblique',\n 'uppercase',\n 'lowercase',\n 'capitalize',\n 'line-through',\n 'underline',\n 'overline',\n 'wavy',\n // cursor\n 'pointer',\n 'default',\n 'text',\n 'move',\n 'grab',\n 'grabbing',\n 'not-allowed',\n 'crosshair',\n 'wait',\n 'help',\n 'col-resize',\n 'row-resize',\n 'n-resize',\n 's-resize',\n 'e-resize',\n 'w-resize',\n 'ne-resize',\n 'nw-resize',\n 'se-resize',\n 'sw-resize',\n 'ew-resize',\n 'ns-resize',\n 'zoom-in',\n 'zoom-out',\n // misc\n 'cover',\n 'contain',\n 'fill',\n 'no-repeat',\n 'repeat-x',\n 'repeat-y',\n 'border-box',\n 'padding-box',\n 'content-box',\n 'break-word',\n 'break-all',\n 'keep-all',\n 'anywhere',\n 'pre',\n 'pre-wrap',\n 'pre-line',\n 'balance',\n 'smooth',\n 'horizontal',\n 'vertical',\n 'both',\n 'mandatory',\n 'proximity',\n // white-space\n 'collapse',\n 'preserve',\n 'preserve-breaks',\n 'break-spaces',\n // text-wrap\n 'pretty',\n 'stable',\n // will-change\n 'transform',\n 'opacity',\n // animation\n 'infinite',\n 'alternate',\n 'alternate-reverse',\n 'reverse',\n 'forwards',\n 'backwards',\n 'running',\n 'paused',\n 'ease',\n 'ease-in',\n 'ease-out',\n 'ease-in-out',\n 'step-start',\n 'step-end',\n // scrollbar\n 'thin',\n 'always',\n 'both-edges',\n // width/height\n 'fixed',\n // shadow\n 'inset',\n // textOverflow\n 'clip',\n // other\n 'ltr',\n 'rtl',\n 'embed',\n 'isolate',\n 'isolate-override',\n 'plaintext',\n 'horizontal-tb',\n 'vertical-rl',\n 'vertical-lr',\n 'sideways-rl',\n 'sideways-lr',\n 'monospace',\n 'serif',\n 'sans-serif',\n 'cursive',\n 'fantasy',\n 'system-ui',\n 'ui-serif',\n 'ui-sans-serif',\n 'ui-monospace',\n 'ui-rounded',\n 'to',\n // misc\n 'strong',\n 'tight',\n 'icon',\n]);\n\n// ============================================================================\n// Classifier\n// ============================================================================\n\nfunction toSet(input?: Set<string> | string[]): Set<string> {\n if (!input) return new Set();\n return input instanceof Set ? input : new Set(input);\n}\n\nfunction classifyToken(\n raw: string,\n offset: number,\n errors: ValueError[],\n opts: ValueParserOptions,\n): ValueToken {\n const token = raw.trim();\n if (!token) return { type: 'keyword', value: '' };\n\n // Quoted strings\n if (\n (token.startsWith('\"') && token.endsWith('\"')) ||\n (token.startsWith(\"'\") && token.endsWith(\"'\"))\n ) {\n return { type: 'string', value: token.slice(1, -1), raw: token };\n }\n\n // !important\n if (token === '!important') {\n return { type: 'important', raw: token };\n }\n\n // Double prefix: $$name (custom property reference for transitions)\n if (token.startsWith('$$')) {\n const name = token.slice(2);\n if (/^[a-z_][a-z0-9-_]*$/i.test(name)) {\n return { type: 'custom-prop-ref', name, raw: token };\n }\n errors.push({\n message: `Invalid custom property reference '${token}'.`,\n offset,\n length: token.length,\n raw: token,\n });\n return { type: 'unknown', raw: token };\n }\n\n // Double prefix: ##name (color reference for transitions)\n if (token.startsWith('##')) {\n const name = token.slice(2);\n if (/^[a-z_][a-z0-9-_]*$/i.test(name)) {\n return { type: 'color-ref', name, raw: token };\n }\n errors.push({\n message: `Invalid color reference '${token}'.`,\n offset,\n length: token.length,\n raw: token,\n });\n return { type: 'unknown', raw: token };\n }\n\n // Custom property: $name\n if (token.startsWith('$')) {\n const name = token.slice(1);\n if (/^[a-z_][a-z0-9-_]*$/i.test(name)) {\n return { type: 'custom-prop', name, raw: token };\n }\n errors.push({\n message: `Invalid custom property syntax '${token}'.`,\n offset,\n length: token.length,\n raw: token,\n });\n return { type: 'unknown', raw: token };\n }\n\n // Color token: #name, #name.N, #name.$prop, or bare # (error)\n if (token.startsWith('#')) {\n if (token.length === 1) {\n errors.push({\n message: 'Empty color token name.',\n offset,\n length: 1,\n raw: token,\n });\n return { type: 'unknown', raw: token };\n }\n return classifyColorToken(token, offset, errors);\n }\n\n // Parenthesized expression: (expr) — fallback, auto-calc, etc.\n if (token.startsWith('(') && token.endsWith(')')) {\n return { type: 'group-expr', inner: token.slice(1, -1), raw: token };\n }\n\n // Function call: name(...)\n const openIdx = token.indexOf('(');\n if (openIdx > 0 && token.endsWith(')')) {\n const fname = token.slice(0, openIdx);\n const args = token.slice(openIdx + 1, -1);\n\n if (opts.skipFuncValidation) {\n return { type: 'css-function', name: fname, args, raw: token };\n }\n\n const knownFuncs = toSet(opts.knownFuncs);\n\n if (\n COLOR_FUNCS.has(fname) ||\n CSS_FUNCS.has(fname) ||\n knownFuncs.has(fname)\n ) {\n return { type: 'css-function', name: fname, args, raw: token };\n }\n\n // Unknown function — still return as css-function but flag it\n errors.push({\n message: `Unknown function '${fname}()'.`,\n offset,\n length: token.length,\n raw: token,\n });\n return { type: 'css-function', name: fname, args, raw: token };\n }\n\n // Unit number: 2x, 1.5r, 10px, 50%, 1fr\n const unitMatch = token.match(RE_UNIT_NUM);\n if (unitMatch) {\n const unit = unitMatch[1];\n const numVal = parseFloat(token.slice(0, -unit.length));\n\n if (opts.skipUnitValidation) {\n return { type: 'custom-unit', value: numVal, unit, raw: token };\n }\n\n const knownUnits = toSet(opts.knownUnits);\n\n if (BUILT_IN_UNITS.has(unit) || knownUnits.has(unit)) {\n return { type: 'custom-unit', value: numVal, unit, raw: token };\n }\n if (CSS_UNITS.has(unit)) {\n return { type: 'css-unit', value: numVal, unit, raw: token };\n }\n\n errors.push({\n message: `Unknown unit '${unit}' in '${token}'.`,\n offset,\n length: token.length,\n raw: token,\n });\n return { type: 'unknown', raw: token };\n }\n\n // CSS unit with % (RE_UNIT_NUM doesn't match % since it expects alpha)\n const cssUnitMatch = token.match(RE_CSS_UNIT_NUM);\n if (cssUnitMatch) {\n const unit = cssUnitMatch[1];\n const numVal = parseFloat(token.slice(0, -unit.length));\n if (CSS_UNITS.has(unit)) {\n return { type: 'css-unit', value: numVal, unit, raw: token };\n }\n }\n\n // Plain number\n if (RE_NUMBER.test(token)) {\n return { type: 'number', value: parseFloat(token), raw: token };\n }\n\n // Tasty merge directive (@inherit)\n if (token === '@inherit') {\n return { type: 'keyword', value: token };\n }\n\n // Known keyword\n if (VALUE_KEYWORDS.has(token) || VALUE_KEYWORDS.has(token.toLowerCase())) {\n return { type: 'keyword', value: token };\n }\n\n // CSS custom property function var(--name)\n if (token.startsWith('var(') && token.endsWith(')')) {\n return {\n type: 'css-function',\n name: 'var',\n args: token.slice(4, -1),\n raw: token,\n };\n }\n\n // Unknown token\n return { type: 'unknown', raw: token };\n}\n\nfunction classifyColorToken(\n token: string,\n offset: number,\n errors: ValueError[],\n): ValueToken {\n const raw = token;\n\n // Strip leading #\n const name = token.slice(1);\n\n if (name.length === 0) {\n errors.push({\n message: 'Empty color token name.',\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n\n // Check for opacity suffix\n const dotIndex = name.indexOf('.');\n if (dotIndex !== -1) {\n const tokenName = name.slice(0, dotIndex);\n const opacitySuffix = name.slice(dotIndex + 1);\n\n if (tokenName.length === 0) {\n errors.push({\n message: 'Empty color token name before opacity.',\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n\n // Dynamic opacity from CSS custom property\n if (opacitySuffix.startsWith('$')) {\n return {\n type: 'color-token',\n name: tokenName,\n opacity: opacitySuffix,\n raw,\n };\n }\n\n if (opacitySuffix.length === 0) {\n errors.push({\n message: 'Trailing dot with no opacity value.',\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n\n const opacity = Number(opacitySuffix);\n if (isNaN(opacity)) {\n errors.push({\n message: `Invalid opacity value '${opacitySuffix}'.`,\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n if (opacity < 0) {\n errors.push({\n message: 'Opacity cannot be negative.',\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n if (opacity > 100) {\n errors.push({\n message: `Opacity '${opacitySuffix}' exceeds 100.`,\n offset,\n length: token.length,\n raw,\n });\n return { type: 'unknown', raw };\n }\n\n return {\n type: 'color-token',\n name: tokenName,\n opacity: opacitySuffix,\n raw,\n };\n }\n\n return { type: 'color-token', name, raw };\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Parse a style value string into typed tokens organized by\n * comma-separated groups and slash-separated parts.\n */\nexport function parseValue(\n src: string,\n opts: ValueParserOptions = {},\n): ValueParseResult {\n const errors: ValueError[] = [];\n\n // Check bracket balance first\n const bracketError = checkBracketBalance(src);\n if (bracketError) {\n errors.push({\n message: bracketError.message,\n offset: bracketError.position,\n length: 1,\n });\n return { groups: [], errors };\n }\n\n const scanned = scanTokens(src);\n\n const groups: ValueGroup[] = [];\n let currentParts: ValuePart[] = [];\n let currentTokens: ValueToken[] = [];\n\n const endPart = () => {\n if (currentTokens.length > 0) {\n currentParts.push({ tokens: currentTokens });\n currentTokens = [];\n }\n };\n\n const endGroup = () => {\n endPart();\n if (currentParts.length > 0) {\n groups.push({ parts: currentParts });\n } else {\n groups.push({ parts: [{ tokens: [] }] });\n }\n currentParts = [];\n };\n\n for (const scanned_token of scanned) {\n if (scanned_token.value) {\n const classified = classifyToken(\n scanned_token.value,\n scanned_token.offset,\n errors,\n opts,\n );\n currentTokens.push(classified);\n }\n if (scanned_token.isSlash) endPart();\n if (scanned_token.isComma) endGroup();\n }\n\n // Push final group\n if (\n currentTokens.length > 0 ||\n currentParts.length > 0 ||\n groups.length === 0\n ) {\n endGroup();\n }\n\n return { groups, errors };\n}\n\n/**\n * Extract all tokens of a specific type from a parse result.\n */\nexport function extractTokensByType<T extends ValueToken['type']>(\n result: ValueParseResult,\n type: T,\n): Extract<ValueToken, { type: T }>[] {\n const tokens: Extract<ValueToken, { type: T }>[] = [];\n for (const group of result.groups) {\n for (const part of group.parts) {\n for (const token of part.tokens) {\n if (token.type === type) {\n tokens.push(token as Extract<ValueToken, { type: T }>);\n }\n }\n }\n }\n return tokens;\n}\n\n/**\n * Get a flat list of all tokens from a parse result.\n */\nexport function flattenTokens(result: ValueParseResult): ValueToken[] {\n const tokens: ValueToken[] = [];\n for (const group of result.groups) {\n for (const part of group.parts) {\n tokens.push(...part.tokens);\n }\n }\n return tokens;\n}\n"],"mappings":";;;;AAqDA,MAAM,cAAc;AACpB,MAAM,YAAY;AAClB,MAAM,kBAAkB;AAExB,MAAM,cAAc,IAAI,IAAI;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,YAAY,IAAI,IAAI;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,iBAAiB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CAEA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { createRule } from "../create-rule.js";
|
|
2
|
+
import { getKeyName, getStringValue } from "../utils.js";
|
|
3
|
+
import { TastyContext, styleObjectListeners } from "../context.js";
|
|
4
|
+
import { parseStateKey } from "../parsers/state-key-parser.js";
|
|
5
|
+
|
|
6
|
+
//#region src/rules/no-own-at-root.ts
|
|
7
|
+
var no_own_at_root_default = createRule({
|
|
8
|
+
name: "no-own-at-root",
|
|
9
|
+
meta: {
|
|
10
|
+
type: "suggestion",
|
|
11
|
+
docs: { description: "Warn when @own() is used outside sub-element styles where it is redundant" },
|
|
12
|
+
messages: { ownAtRoot: "@own() is redundant outside sub-element styles. Use the inner selector directly instead (e.g. :hover instead of @own(:hover))." },
|
|
13
|
+
schema: []
|
|
14
|
+
},
|
|
15
|
+
defaultOptions: [],
|
|
16
|
+
create(context) {
|
|
17
|
+
const ctx = new TastyContext(context);
|
|
18
|
+
function isInsideSubElement(node) {
|
|
19
|
+
let current = node.parent;
|
|
20
|
+
while (current) {
|
|
21
|
+
if (current.type === "Property" && !current.computed && current.key.type === "Identifier" && /^[A-Z]/.test(current.key.name)) return true;
|
|
22
|
+
current = current.parent;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
function handleStyleObject(node) {
|
|
27
|
+
if (!ctx.isStyleObject(node)) return;
|
|
28
|
+
if (isInsideSubElement(node)) return;
|
|
29
|
+
for (const prop of node.properties) {
|
|
30
|
+
if (prop.type !== "Property" || prop.computed) continue;
|
|
31
|
+
const key = getKeyName(prop.key);
|
|
32
|
+
if (key === null) continue;
|
|
33
|
+
if (/^[A-Z]/.test(key) || key.startsWith("@") || key.startsWith("&")) continue;
|
|
34
|
+
if (prop.value.type !== "ObjectExpression") continue;
|
|
35
|
+
for (const stateProp of prop.value.properties) {
|
|
36
|
+
if (stateProp.type !== "Property") continue;
|
|
37
|
+
const stateKey = !stateProp.computed ? getKeyName(stateProp.key) : getStringValue(stateProp.key);
|
|
38
|
+
if (stateKey === null || stateKey === "") continue;
|
|
39
|
+
if (parseStateKey(stateKey).hasOwn) context.report({
|
|
40
|
+
node: stateProp.key,
|
|
41
|
+
messageId: "ownAtRoot"
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
ImportDeclaration(node) {
|
|
48
|
+
ctx.trackImport(node);
|
|
49
|
+
},
|
|
50
|
+
...styleObjectListeners(handleStyleObject)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
export { no_own_at_root_default as default };
|
|
57
|
+
//# sourceMappingURL=no-own-at-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-own-at-root.js","names":[],"sources":["../../src/rules/no-own-at-root.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport { createRule } from '../create-rule.js';\nimport { TastyContext, styleObjectListeners } from '../context.js';\nimport { getKeyName, getStringValue } from '../utils.js';\nimport { parseStateKey } from '../parsers/state-key-parser.js';\n\ntype MessageIds = 'ownAtRoot';\n\nexport default createRule<[], MessageIds>({\n name: 'no-own-at-root',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Warn when @own() is used outside sub-element styles where it is redundant',\n },\n messages: {\n ownAtRoot:\n '@own() is redundant outside sub-element styles. Use the inner selector directly instead (e.g. :hover instead of @own(:hover)).',\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n const ctx = new TastyContext(context);\n\n function isInsideSubElement(node: TSESTree.Node): boolean {\n let current: TSESTree.Node | undefined = node.parent;\n while (current) {\n if (\n current.type === 'Property' &&\n !current.computed &&\n current.key.type === 'Identifier' &&\n /^[A-Z]/.test(current.key.name)\n ) {\n return true;\n }\n current = current.parent;\n }\n return false;\n }\n\n function handleStyleObject(node: TSESTree.ObjectExpression) {\n if (!ctx.isStyleObject(node)) return;\n\n const insideSubElement = isInsideSubElement(node);\n\n if (insideSubElement) return;\n\n for (const prop of node.properties) {\n if (prop.type !== 'Property' || prop.computed) continue;\n\n const key = getKeyName(prop.key);\n if (key === null) continue;\n\n if (/^[A-Z]/.test(key) || key.startsWith('@') || key.startsWith('&'))\n continue;\n\n if (prop.value.type !== 'ObjectExpression') continue;\n\n for (const stateProp of prop.value.properties) {\n if (stateProp.type !== 'Property') continue;\n\n const stateKey = !stateProp.computed\n ? getKeyName(stateProp.key)\n : getStringValue(stateProp.key);\n if (stateKey === null || stateKey === '') continue;\n\n const result = parseStateKey(stateKey);\n\n if (result.hasOwn) {\n context.report({\n node: stateProp.key,\n messageId: 'ownAtRoot',\n });\n }\n }\n }\n }\n\n return {\n ImportDeclaration(node) {\n ctx.trackImport(node);\n },\n\n ...styleObjectListeners(handleStyleObject),\n };\n },\n});\n"],"mappings":";;;;;;AAQA,6BAAe,WAA2B;CACxC,MAAM;CACN,MAAM;EACJ,MAAM;EACN,MAAM,EACJ,aACE,6EACH;EACD,UAAU,EACR,WACE,kIACH;EACD,QAAQ,EAAE;EACX;CACD,gBAAgB,EAAE;CAClB,OAAO,SAAS;EACd,MAAM,MAAM,IAAI,aAAa,QAAQ;EAErC,SAAS,mBAAmB,MAA8B;GACxD,IAAI,UAAqC,KAAK;AAC9C,UAAO,SAAS;AACd,QACE,QAAQ,SAAS,cACjB,CAAC,QAAQ,YACT,QAAQ,IAAI,SAAS,gBACrB,SAAS,KAAK,QAAQ,IAAI,KAAK,CAE/B,QAAO;AAET,cAAU,QAAQ;;AAEpB,UAAO;;EAGT,SAAS,kBAAkB,MAAiC;AAC1D,OAAI,CAAC,IAAI,cAAc,KAAK,CAAE;AAI9B,OAFyB,mBAAmB,KAAK,CAE3B;AAEtB,QAAK,MAAM,QAAQ,KAAK,YAAY;AAClC,QAAI,KAAK,SAAS,cAAc,KAAK,SAAU;IAE/C,MAAM,MAAM,WAAW,KAAK,IAAI;AAChC,QAAI,QAAQ,KAAM;AAElB,QAAI,SAAS,KAAK,IAAI,IAAI,IAAI,WAAW,IAAI,IAAI,IAAI,WAAW,IAAI,CAClE;AAEF,QAAI,KAAK,MAAM,SAAS,mBAAoB;AAE5C,SAAK,MAAM,aAAa,KAAK,MAAM,YAAY;AAC7C,SAAI,UAAU,SAAS,WAAY;KAEnC,MAAM,WAAW,CAAC,UAAU,WACxB,WAAW,UAAU,IAAI,GACzB,eAAe,UAAU,IAAI;AACjC,SAAI,aAAa,QAAQ,aAAa,GAAI;AAI1C,SAFe,cAAc,SAAS,CAE3B,OACT,SAAQ,OAAO;MACb,MAAM,UAAU;MAChB,WAAW;MACZ,CAAC;;;;AAMV,SAAO;GACL,kBAAkB,MAAM;AACtB,QAAI,YAAY,KAAK;;GAGvB,GAAG,qBAAqB,kBAAkB;GAC3C;;CAEJ,CAAC"}
|
|
@@ -26,19 +26,23 @@ var valid_preset_default = createRule({
|
|
|
26
26
|
"revert-layer"
|
|
27
27
|
]);
|
|
28
28
|
function checkPresetValue(value, node) {
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
const segments = value.trim().split(/\s*\/\s*/);
|
|
30
|
+
if (segments.length === 0) return;
|
|
31
|
+
const nameSegment = segments[0].trim();
|
|
32
|
+
const modSegment = segments[1]?.trim();
|
|
33
|
+
if (!nameSegment) return;
|
|
34
|
+
if (CSS_GLOBAL_KEYWORDS.has(nameSegment)) return;
|
|
35
|
+
if (!PRESET_MODIFIERS.has(nameSegment)) {
|
|
36
|
+
if (ctx.config.presets.length > 0 && !ctx.config.presets.includes(nameSegment)) context.report({
|
|
37
|
+
node,
|
|
38
|
+
messageId: "unknownPreset",
|
|
39
|
+
data: { name: nameSegment }
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (modSegment && !PRESET_MODIFIERS.has(modSegment)) context.report({
|
|
39
43
|
node,
|
|
40
44
|
messageId: "unknownModifier",
|
|
41
|
-
data: { modifier:
|
|
45
|
+
data: { modifier: modSegment }
|
|
42
46
|
});
|
|
43
47
|
}
|
|
44
48
|
function checkObject(node) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"valid-preset.js","names":[],"sources":["../../src/rules/valid-preset.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport { createRule } from '../create-rule.js';\nimport { TastyContext, styleObjectListeners } from '../context.js';\nimport { getKeyName, getStringValue } from '../utils.js';\nimport { PRESET_MODIFIERS } from '../constants.js';\n\ntype MessageIds = 'unknownPreset' | 'unknownModifier';\n\nexport default createRule<[], MessageIds>({\n name: 'valid-preset',\n meta: {\n type: 'problem',\n docs: {\n description: 'Validate preset property values against config',\n },\n messages: {\n unknownPreset: \"Unknown preset '{{name}}'.\",\n unknownModifier: \"Unknown preset modifier '{{modifier}}'.\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n const ctx = new TastyContext(context);\n\n const CSS_GLOBAL_KEYWORDS = new Set([\n 'inherit',\n 'initial',\n 'unset',\n 'revert',\n 'revert-layer',\n ]);\n\n function checkPresetValue(value: string, node: TSESTree.Node): void {\n const
|
|
1
|
+
{"version":3,"file":"valid-preset.js","names":[],"sources":["../../src/rules/valid-preset.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport { createRule } from '../create-rule.js';\nimport { TastyContext, styleObjectListeners } from '../context.js';\nimport { getKeyName, getStringValue } from '../utils.js';\nimport { PRESET_MODIFIERS } from '../constants.js';\n\ntype MessageIds = 'unknownPreset' | 'unknownModifier';\n\nexport default createRule<[], MessageIds>({\n name: 'valid-preset',\n meta: {\n type: 'problem',\n docs: {\n description: 'Validate preset property values against config',\n },\n messages: {\n unknownPreset: \"Unknown preset '{{name}}'.\",\n unknownModifier: \"Unknown preset modifier '{{modifier}}'.\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n const ctx = new TastyContext(context);\n\n const CSS_GLOBAL_KEYWORDS = new Set([\n 'inherit',\n 'initial',\n 'unset',\n 'revert',\n 'revert-layer',\n ]);\n\n function checkPresetValue(value: string, node: TSESTree.Node): void {\n const segments = value.trim().split(/\\s*\\/\\s*/);\n if (segments.length === 0) return;\n\n const nameSegment = segments[0].trim();\n const modSegment = segments[1]?.trim();\n\n if (!nameSegment) return;\n if (CSS_GLOBAL_KEYWORDS.has(nameSegment)) return;\n\n // Mod-only shorthand: preset=\"bold\" (name defaults to inherit)\n if (!PRESET_MODIFIERS.has(nameSegment)) {\n if (\n ctx.config.presets.length > 0 &&\n !ctx.config.presets.includes(nameSegment)\n ) {\n context.report({\n node,\n messageId: 'unknownPreset',\n data: { name: nameSegment },\n });\n }\n }\n\n if (modSegment && !PRESET_MODIFIERS.has(modSegment)) {\n context.report({\n node,\n messageId: 'unknownModifier',\n data: { modifier: modSegment },\n });\n }\n }\n\n function checkObject(node: TSESTree.ObjectExpression): void {\n if (!ctx.isStyleObject(node)) return;\n\n for (const prop of node.properties) {\n if (prop.type !== 'Property' || prop.computed) continue;\n\n const key = getKeyName(prop.key);\n if (key !== 'preset') continue;\n\n const str = getStringValue(prop.value);\n if (str) {\n checkPresetValue(str, prop.value);\n continue;\n }\n\n if (prop.value.type === 'Literal' && prop.value.value === true) {\n continue;\n }\n\n if (prop.value.type === 'ObjectExpression') {\n for (const stateProp of prop.value.properties) {\n if (stateProp.type !== 'Property') continue;\n const stateStr = getStringValue(stateProp.value);\n if (stateStr) {\n checkPresetValue(stateStr, stateProp.value);\n }\n }\n }\n }\n }\n\n function handleStyleObject(node: TSESTree.ObjectExpression) {\n checkObject(node);\n }\n\n return {\n ImportDeclaration(node) {\n ctx.trackImport(node);\n },\n\n ...styleObjectListeners(handleStyleObject),\n };\n },\n});\n"],"mappings":";;;;;;AAQA,2BAAe,WAA2B;CACxC,MAAM;CACN,MAAM;EACJ,MAAM;EACN,MAAM,EACJ,aAAa,kDACd;EACD,UAAU;GACR,eAAe;GACf,iBAAiB;GAClB;EACD,QAAQ,EAAE;EACX;CACD,gBAAgB,EAAE;CAClB,OAAO,SAAS;EACd,MAAM,MAAM,IAAI,aAAa,QAAQ;EAErC,MAAM,sBAAsB,IAAI,IAAI;GAClC;GACA;GACA;GACA;GACA;GACD,CAAC;EAEF,SAAS,iBAAiB,OAAe,MAA2B;GAClE,MAAM,WAAW,MAAM,MAAM,CAAC,MAAM,WAAW;AAC/C,OAAI,SAAS,WAAW,EAAG;GAE3B,MAAM,cAAc,SAAS,GAAG,MAAM;GACtC,MAAM,aAAa,SAAS,IAAI,MAAM;AAEtC,OAAI,CAAC,YAAa;AAClB,OAAI,oBAAoB,IAAI,YAAY,CAAE;AAG1C,OAAI,CAAC,iBAAiB,IAAI,YAAY,EACpC;QACE,IAAI,OAAO,QAAQ,SAAS,KAC5B,CAAC,IAAI,OAAO,QAAQ,SAAS,YAAY,CAEzC,SAAQ,OAAO;KACb;KACA,WAAW;KACX,MAAM,EAAE,MAAM,aAAa;KAC5B,CAAC;;AAIN,OAAI,cAAc,CAAC,iBAAiB,IAAI,WAAW,CACjD,SAAQ,OAAO;IACb;IACA,WAAW;IACX,MAAM,EAAE,UAAU,YAAY;IAC/B,CAAC;;EAIN,SAAS,YAAY,MAAuC;AAC1D,OAAI,CAAC,IAAI,cAAc,KAAK,CAAE;AAE9B,QAAK,MAAM,QAAQ,KAAK,YAAY;AAClC,QAAI,KAAK,SAAS,cAAc,KAAK,SAAU;AAG/C,QADY,WAAW,KAAK,IAAI,KACpB,SAAU;IAEtB,MAAM,MAAM,eAAe,KAAK,MAAM;AACtC,QAAI,KAAK;AACP,sBAAiB,KAAK,KAAK,MAAM;AACjC;;AAGF,QAAI,KAAK,MAAM,SAAS,aAAa,KAAK,MAAM,UAAU,KACxD;AAGF,QAAI,KAAK,MAAM,SAAS,mBACtB,MAAK,MAAM,aAAa,KAAK,MAAM,YAAY;AAC7C,SAAI,UAAU,SAAS,WAAY;KACnC,MAAM,WAAW,eAAe,UAAU,MAAM;AAChD,SAAI,SACF,kBAAiB,UAAU,UAAU,MAAM;;;;EAOrD,SAAS,kBAAkB,MAAiC;AAC1D,eAAY,KAAK;;AAGnB,SAAO;GACL,kBAAkB,MAAM;AACtB,QAAI,YAAY,KAAK;;GAGvB,GAAG,qBAAqB,kBAAkB;GAC3C;;CAEJ,CAAC"}
|
|
@@ -11,7 +11,6 @@ var valid_state_key_default = createRule({
|
|
|
11
11
|
docs: { description: "Validate state key syntax in style mapping objects" },
|
|
12
12
|
messages: {
|
|
13
13
|
invalidStateKey: "{{reason}}",
|
|
14
|
-
ownOutsideSubElement: "@own() can only be used inside sub-element styles.",
|
|
15
14
|
unknownAlias: "Unknown state alias '{{alias}}'. Configured aliases: {{known}}."
|
|
16
15
|
},
|
|
17
16
|
schema: []
|
|
@@ -36,10 +35,6 @@ var valid_state_key_default = createRule({
|
|
|
36
35
|
messageId: "invalidStateKey",
|
|
37
36
|
data: { reason: error.message }
|
|
38
37
|
});
|
|
39
|
-
if (result.hasOwn && !insideSubElement) context.report({
|
|
40
|
-
node: keyNode,
|
|
41
|
-
messageId: "ownOutsideSubElement"
|
|
42
|
-
});
|
|
43
38
|
const allKnown = [...ctx.config.states, ...localAliases];
|
|
44
39
|
if (allKnown.length > 0) {
|
|
45
40
|
for (const alias of result.referencedAliases) if (!allKnown.includes(alias)) context.report({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"valid-state-key.js","names":[],"sources":["../../src/rules/valid-state-key.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport { createRule } from '../create-rule.js';\nimport { TastyContext, styleObjectListeners } from '../context.js';\nimport {\n getKeyName,\n getStringValue,\n collectLocalStateAliases,\n findRootStyleObject,\n} from '../utils.js';\nimport { parseStateKey } from '../parsers/state-key-parser.js';\nimport type { StateKeyParserOptions } from '../parsers/state-key-parser.js';\n\ntype MessageIds = 'invalidStateKey' | '
|
|
1
|
+
{"version":3,"file":"valid-state-key.js","names":[],"sources":["../../src/rules/valid-state-key.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport { createRule } from '../create-rule.js';\nimport { TastyContext, styleObjectListeners } from '../context.js';\nimport {\n getKeyName,\n getStringValue,\n collectLocalStateAliases,\n findRootStyleObject,\n} from '../utils.js';\nimport { parseStateKey } from '../parsers/state-key-parser.js';\nimport type { StateKeyParserOptions } from '../parsers/state-key-parser.js';\n\ntype MessageIds = 'invalidStateKey' | 'unknownAlias';\n\nexport default createRule<[], MessageIds>({\n name: 'valid-state-key',\n meta: {\n type: 'problem',\n docs: {\n description: 'Validate state key syntax in style mapping objects',\n },\n messages: {\n invalidStateKey: '{{reason}}',\n unknownAlias:\n \"Unknown state alias '{{alias}}'. Configured aliases: {{known}}.\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n const ctx = new TastyContext(context);\n\n const parserOpts: StateKeyParserOptions = {\n knownAliases: ctx.config.states,\n };\n\n function isInsideSubElement(node: TSESTree.Node): boolean {\n let current: TSESTree.Node | undefined = node.parent;\n while (current) {\n if (\n current.type === 'Property' &&\n !current.computed &&\n current.key.type === 'Identifier' &&\n /^[A-Z]/.test(current.key.name)\n ) {\n return true;\n }\n current = current.parent;\n }\n return false;\n }\n\n function checkStateKey(\n key: string,\n keyNode: TSESTree.Node,\n insideSubElement: boolean,\n localAliases: string[],\n ): void {\n if (key === '') return;\n\n const result = parseStateKey(key, parserOpts);\n\n // Report all parse/validation errors\n for (const error of result.errors) {\n context.report({\n node: keyNode,\n messageId: 'invalidStateKey',\n data: { reason: error.message },\n });\n }\n\n // Check aliases against config and local definitions\n const allKnown = [...ctx.config.states, ...localAliases];\n if (allKnown.length > 0) {\n for (const alias of result.referencedAliases) {\n if (!allKnown.includes(alias)) {\n context.report({\n node: keyNode,\n messageId: 'unknownAlias',\n data: {\n alias,\n known: allKnown.join(', '),\n },\n });\n }\n }\n }\n }\n\n function handleStyleObject(node: TSESTree.ObjectExpression) {\n if (!ctx.isStyleObject(node)) return;\n\n const insideSubElement = isInsideSubElement(node);\n const rootObj = findRootStyleObject(node);\n const localAliases = collectLocalStateAliases(rootObj);\n\n for (const prop of node.properties) {\n if (prop.type !== 'Property' || prop.computed) continue;\n\n const key = getKeyName(prop.key);\n if (key === null) continue;\n\n if (/^[A-Z]/.test(key) || key.startsWith('@') || key.startsWith('&'))\n continue;\n\n if (prop.value.type !== 'ObjectExpression') continue;\n\n for (const stateProp of prop.value.properties) {\n if (stateProp.type !== 'Property') continue;\n\n const stateKey = !stateProp.computed\n ? getKeyName(stateProp.key)\n : getStringValue(stateProp.key);\n if (stateKey === null) continue;\n\n checkStateKey(\n stateKey,\n stateProp.key,\n insideSubElement,\n localAliases,\n );\n }\n }\n }\n\n return {\n ImportDeclaration(node) {\n ctx.trackImport(node);\n },\n\n ...styleObjectListeners(handleStyleObject),\n };\n },\n});\n"],"mappings":";;;;;;AAcA,8BAAe,WAA2B;CACxC,MAAM;CACN,MAAM;EACJ,MAAM;EACN,MAAM,EACJ,aAAa,sDACd;EACD,UAAU;GACR,iBAAiB;GACjB,cACE;GACH;EACD,QAAQ,EAAE;EACX;CACD,gBAAgB,EAAE;CAClB,OAAO,SAAS;EACd,MAAM,MAAM,IAAI,aAAa,QAAQ;EAErC,MAAM,aAAoC,EACxC,cAAc,IAAI,OAAO,QAC1B;EAED,SAAS,mBAAmB,MAA8B;GACxD,IAAI,UAAqC,KAAK;AAC9C,UAAO,SAAS;AACd,QACE,QAAQ,SAAS,cACjB,CAAC,QAAQ,YACT,QAAQ,IAAI,SAAS,gBACrB,SAAS,KAAK,QAAQ,IAAI,KAAK,CAE/B,QAAO;AAET,cAAU,QAAQ;;AAEpB,UAAO;;EAGT,SAAS,cACP,KACA,SACA,kBACA,cACM;AACN,OAAI,QAAQ,GAAI;GAEhB,MAAM,SAAS,cAAc,KAAK,WAAW;AAG7C,QAAK,MAAM,SAAS,OAAO,OACzB,SAAQ,OAAO;IACb,MAAM;IACN,WAAW;IACX,MAAM,EAAE,QAAQ,MAAM,SAAS;IAChC,CAAC;GAIJ,MAAM,WAAW,CAAC,GAAG,IAAI,OAAO,QAAQ,GAAG,aAAa;AACxD,OAAI,SAAS,SAAS,GACpB;SAAK,MAAM,SAAS,OAAO,kBACzB,KAAI,CAAC,SAAS,SAAS,MAAM,CAC3B,SAAQ,OAAO;KACb,MAAM;KACN,WAAW;KACX,MAAM;MACJ;MACA,OAAO,SAAS,KAAK,KAAK;MAC3B;KACF,CAAC;;;EAMV,SAAS,kBAAkB,MAAiC;AAC1D,OAAI,CAAC,IAAI,cAAc,KAAK,CAAE;GAE9B,MAAM,mBAAmB,mBAAmB,KAAK;GAEjD,MAAM,eAAe,yBADL,oBAAoB,KAAK,CACa;AAEtD,QAAK,MAAM,QAAQ,KAAK,YAAY;AAClC,QAAI,KAAK,SAAS,cAAc,KAAK,SAAU;IAE/C,MAAM,MAAM,WAAW,KAAK,IAAI;AAChC,QAAI,QAAQ,KAAM;AAElB,QAAI,SAAS,KAAK,IAAI,IAAI,IAAI,WAAW,IAAI,IAAI,IAAI,WAAW,IAAI,CAClE;AAEF,QAAI,KAAK,MAAM,SAAS,mBAAoB;AAE5C,SAAK,MAAM,aAAa,KAAK,MAAM,YAAY;AAC7C,SAAI,UAAU,SAAS,WAAY;KAEnC,MAAM,WAAW,CAAC,UAAU,WACxB,WAAW,UAAU,IAAI,GACzB,eAAe,UAAU,IAAI;AACjC,SAAI,aAAa,KAAM;AAEvB,mBACE,UACA,UAAU,KACV,kBACA,aACD;;;;AAKP,SAAO;GACL,kBAAkB,MAAM;AACtB,QAAI,YAAY,KAAK;;GAGvB,GAAG,qBAAqB,kBAAkB;GAC3C;;CAEJ,CAAC"}
|