UNPKG

@antebudimir/eslint-plugin-vanilla-extract

Version:

Comprehensive ESLint plugin for vanilla-extract with CSS property ordering, style validation, and best practices enforcement. Supports alphabetical, concentric and custom CSS ordering, auto-fixing, and zero-runtime safety.

180 lines (179 loc) 7.82 kB
/** * Mapping of physical CSS properties to their logical equivalents. * Includes margin, padding, border, inset, and positioning properties. */ /** * Direct physical → logical property mappings */ export const PHYSICAL_TO_LOGICAL = { // Margin properties 'margin-left': { logical: 'margin-inline-start' }, 'margin-right': { logical: 'margin-inline-end' }, 'margin-top': { logical: 'margin-block-start' }, 'margin-bottom': { logical: 'margin-block-end' }, marginLeft: { logical: 'marginInlineStart' }, marginRight: { logical: 'marginInlineEnd' }, marginTop: { logical: 'marginBlockStart' }, marginBottom: { logical: 'marginBlockEnd' }, // Padding properties 'padding-left': { logical: 'padding-inline-start' }, 'padding-right': { logical: 'padding-inline-end' }, 'padding-top': { logical: 'padding-block-start' }, 'padding-bottom': { logical: 'padding-block-end' }, paddingLeft: { logical: 'paddingInlineStart' }, paddingRight: { logical: 'paddingInlineEnd' }, paddingTop: { logical: 'paddingBlockStart' }, paddingBottom: { logical: 'paddingBlockEnd' }, // Border width properties 'border-left-width': { logical: 'border-inline-start-width' }, 'border-right-width': { logical: 'border-inline-end-width' }, 'border-top-width': { logical: 'border-block-start-width' }, 'border-bottom-width': { logical: 'border-block-end-width' }, borderLeftWidth: { logical: 'borderInlineStartWidth' }, borderRightWidth: { logical: 'borderInlineEndWidth' }, borderTopWidth: { logical: 'borderBlockStartWidth' }, borderBottomWidth: { logical: 'borderBlockEndWidth' }, // Border style properties 'border-left-style': { logical: 'border-inline-start-style' }, 'border-right-style': { logical: 'border-inline-end-style' }, 'border-top-style': { logical: 'border-block-start-style' }, 'border-bottom-style': { logical: 'border-block-end-style' }, borderLeftStyle: { logical: 'borderInlineStartStyle' }, borderRightStyle: { logical: 'borderInlineEndStyle' }, borderTopStyle: { logical: 'borderBlockStartStyle' }, borderBottomStyle: { logical: 'borderBlockEndStyle' }, // Border color properties 'border-left-color': { logical: 'border-inline-start-color' }, 'border-right-color': { logical: 'border-inline-end-color' }, 'border-top-color': { logical: 'border-block-start-color' }, 'border-bottom-color': { logical: 'border-block-end-color' }, borderLeftColor: { logical: 'borderInlineStartColor' }, borderRightColor: { logical: 'borderInlineEndColor' }, borderTopColor: { logical: 'borderBlockStartColor' }, borderBottomColor: { logical: 'borderBlockEndColor' }, // Border shorthand properties 'border-left': { logical: 'border-inline-start' }, 'border-right': { logical: 'border-inline-end' }, 'border-top': { logical: 'border-block-start' }, 'border-bottom': { logical: 'border-block-end' }, borderLeft: { logical: 'borderInlineStart' }, borderRight: { logical: 'borderInlineEnd' }, borderTop: { logical: 'borderBlockStart' }, borderBottom: { logical: 'borderBlockEnd' }, // Border radius properties 'border-top-left-radius': { logical: 'border-start-start-radius' }, 'border-top-right-radius': { logical: 'border-start-end-radius' }, 'border-bottom-left-radius': { logical: 'border-end-start-radius' }, 'border-bottom-right-radius': { logical: 'border-end-end-radius' }, borderTopLeftRadius: { logical: 'borderStartStartRadius' }, borderTopRightRadius: { logical: 'borderStartEndRadius' }, borderBottomLeftRadius: { logical: 'borderEndStartRadius' }, borderBottomRightRadius: { logical: 'borderEndEndRadius' }, // Inset properties left: { logical: 'inset-inline-start' }, right: { logical: 'inset-inline-end' }, top: { logical: 'inset-block-start' }, bottom: { logical: 'inset-block-end' }, 'inset-left': { logical: 'inset-inline-start' }, 'inset-right': { logical: 'inset-inline-end' }, 'inset-top': { logical: 'inset-block-start' }, 'inset-bottom': { logical: 'inset-block-end' }, insetLeft: { logical: 'insetInlineStart' }, insetRight: { logical: 'insetInlineEnd' }, insetTop: { logical: 'insetBlockStart' }, insetBottom: { logical: 'insetBlockEnd' }, // Overflow properties 'overflow-x': { logical: 'overflow-inline' }, 'overflow-y': { logical: 'overflow-block' }, overflowX: { logical: 'overflowInline' }, overflowY: { logical: 'overflowBlock' }, // Overscroll properties 'overscroll-behavior-x': { logical: 'overscroll-behavior-inline' }, 'overscroll-behavior-y': { logical: 'overscroll-behavior-block' }, overscrollBehaviorX: { logical: 'overscrollBehaviorInline' }, overscrollBehaviorY: { logical: 'overscrollBehaviorBlock' }, // Scroll margin properties 'scroll-margin-left': { logical: 'scroll-margin-inline-start' }, 'scroll-margin-right': { logical: 'scroll-margin-inline-end' }, 'scroll-margin-top': { logical: 'scroll-margin-block-start' }, 'scroll-margin-bottom': { logical: 'scroll-margin-block-end' }, scrollMarginLeft: { logical: 'scrollMarginInlineStart' }, scrollMarginRight: { logical: 'scrollMarginInlineEnd' }, scrollMarginTop: { logical: 'scrollMarginBlockStart' }, scrollMarginBottom: { logical: 'scrollMarginBlockEnd' }, // Scroll padding properties 'scroll-padding-left': { logical: 'scroll-padding-inline-start' }, 'scroll-padding-right': { logical: 'scroll-padding-inline-end' }, 'scroll-padding-top': { logical: 'scroll-padding-block-start' }, 'scroll-padding-bottom': { logical: 'scroll-padding-block-end' }, scrollPaddingLeft: { logical: 'scrollPaddingInlineStart' }, scrollPaddingRight: { logical: 'scrollPaddingInlineEnd' }, scrollPaddingTop: { logical: 'scrollPaddingBlockStart' }, scrollPaddingBottom: { logical: 'scrollPaddingBlockEnd' }, // Size properties width: { logical: 'inline-size' }, height: { logical: 'block-size' }, 'min-width': { logical: 'min-inline-size' }, 'min-height': { logical: 'min-block-size' }, 'max-width': { logical: 'max-inline-size' }, 'max-height': { logical: 'max-block-size' }, minWidth: { logical: 'minInlineSize' }, minHeight: { logical: 'minBlockSize' }, maxWidth: { logical: 'maxInlineSize' }, maxHeight: { logical: 'maxBlockSize' }, }; /** * Text-align directional values that should be replaced */ export const TEXT_ALIGN_PHYSICAL_VALUES = { left: 'start', right: 'end', }; /** * Float directional values that should be replaced */ export const FLOAT_PHYSICAL_VALUES = { left: 'inline-start', right: 'inline-end', }; /** * Clear directional values that should be replaced */ export const CLEAR_PHYSICAL_VALUES = { left: 'inline-start', right: 'inline-end', }; /** * Properties where the value (not the property name) needs to be checked for physical directions */ export const VALUE_BASED_PHYSICAL_PROPERTIES = new Set([ 'text-align', 'textAlign', 'float', 'clear', 'resize', ]); /** * Check if a property name is a physical property that should be converted */ export function isPhysicalProperty(propertyName) { return propertyName in PHYSICAL_TO_LOGICAL; } /** * Get the logical equivalent of a physical property */ export function getLogicalProperty(propertyName) { return PHYSICAL_TO_LOGICAL[propertyName]?.logical ?? null; } /** * Convert camelCase to kebab-case */ export function toKebabCase(name) { return name.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`); } /** * Convert kebab-case to camelCase */ export function toCamelCase(name) { return name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()); }