From e3d50f2128e5f27c834455f5c11de0dd6364d9fe Mon Sep 17 00:00:00 2001 From: Ku6epXBOCTuK Date: Tue, 8 Sep 2026 07:18:57 +0500 Subject: [PATCH] refactor: update css vars lint rules and fix them --- web/eslint-plugins/design-tokens/lists.js | 4 +-- .../design-tokens/no-hardcoded-in-svelte.js | 27 +++++++++++-------- .../lib/components/kit/CatalogGroup.svelte | 2 +- .../lib/components/kit/CatalogToolbar.svelte | 4 +-- .../lib/components/kit/CheckerCanvas.svelte | 14 +++++----- web/src/lib/components/kit/CodeBlock.svelte | 2 +- web/src/lib/components/kit/Dropzone.svelte | 2 +- web/src/lib/components/kit/ImageCard.svelte | 2 +- web/src/lib/components/kit/MetaList.svelte | 2 +- .../lib/components/kit/PanelHeading.svelte | 2 +- .../lib/components/kit/SchemaToolView.svelte | 5 +++- .../lib/components/kit/SettingGroup.svelte | 2 +- .../lib/components/kit/SettingsFooter.svelte | 2 +- web/src/lib/components/kit/StepCard.svelte | 4 +-- web/src/lib/components/kit/ToolCard.svelte | 8 +++--- .../components/kit/fields/ColorField.svelte | 4 +-- .../components/kit/fields/SelectField.svelte | 2 +- .../components/kit/fields/TextField.svelte | 2 +- .../lib/components/kit/ui/LangToggle.svelte | 2 +- web/src/lib/components/kit/ui/Toggle.svelte | 2 +- web/src/preview.css | 7 +++++ web/src/routes/preview/+layout.svelte | 4 +-- web/src/routes/preview/+page.svelte | 2 +- web/src/routes/preview/kit/+page.svelte | 7 +++-- .../routes/preview/list-tools/+page.svelte | 4 +-- 25 files changed, 69 insertions(+), 49 deletions(-) diff --git a/web/eslint-plugins/design-tokens/lists.js b/web/eslint-plugins/design-tokens/lists.js index c5222e1..f72ad22 100644 --- a/web/eslint-plugins/design-tokens/lists.js +++ b/web/eslint-plugins/design-tokens/lists.js @@ -6,14 +6,14 @@ // Properties that accept a COLOR. // ===================================================================== export const COLOR_PROPS = - /^(color|background|background-color|border|border-color|border-top|border-right|border-bottom|border-left|outline|outline-color|box-shadow|text-shadow|fill|stroke|fill-color|stroke-color|stop-color|flood-color|lighting-color|column-rule|column-rule-color|text-decoration|text-decoration-color|caret-color|accent-color|border-top-color|border-right-color|border-bottom-color|border-left-color)$/; + /^(color|background|background-color|background-image|border|border-color|border-top|border-right|border-bottom|border-left|outline|outline-color|box-shadow|text-shadow|fill|stroke|fill-color|stroke-color|stop-color|flood-color|lighting-color|column-rule|column-rule-color|text-decoration|text-decoration-color|caret-color|accent-color|border-top-color|border-right-color|border-bottom-color|border-left-color)$/; // ===================================================================== // Properties that accept a SIZE (px/rem/em). // z-index is handled separately (it's an integer, not a length). // ===================================================================== export const SIZE_PROPS = - /^(width|height|min-width|max-width|min-height|max-height|padding|padding-top|padding-right|padding-bottom|padding-left|margin|margin-top|margin-right|margin-bottom|margin-left|gap|column-gap|row-gap|top|right|bottom|left|inset|font-size|letter-spacing|word-spacing|line-height|border-radius|border-top-left-radius|border-top-right-radius|border-bottom-left-radius|border-bottom-right-radius|border-width|border-top-width|border-right-width|border-bottom-width|border-left-width|flex-basis|background-size|border-spacing)$/; + /^(width|height|min-width|max-width|min-height|max-height|padding|padding-top|padding-right|padding-bottom|padding-left|margin|margin-top|margin-right|margin-bottom|margin-left|gap|column-gap|row-gap|top|right|bottom|left|inset|font|font-size|letter-spacing|word-spacing|line-height|border-radius|border-top-left-radius|border-top-right-radius|border-bottom-left-radius|border-bottom-right-radius|border-width|border-top-width|border-right-width|border-bottom-width|border-left-width|flex-basis|background-size|background-position|border-spacing|grid-template-columns|grid-template-rows)$/; // ===================================================================== // SHORTHAND properties that accept BOTH a color and a size. The browser diff --git a/web/eslint-plugins/design-tokens/no-hardcoded-in-svelte.js b/web/eslint-plugins/design-tokens/no-hardcoded-in-svelte.js index 9053fb7..d652078 100644 --- a/web/eslint-plugins/design-tokens/no-hardcoded-in-svelte.js +++ b/web/eslint-plugins/design-tokens/no-hardcoded-in-svelte.js @@ -9,6 +9,7 @@ import { DURATION_PROPS, FORBIDDEN_DURATION_TOKEN, FORBIDDEN_SIZE_TOKEN, + MIXED_PROPS, SIZE_PROPS, } from "./lists.js"; import { getStyleNodeLoc, getStyleRoot } from "./style-context.js"; @@ -125,13 +126,16 @@ export default { // Sub-rule 2: sizes. // Fire only on a real remaining px/rem/em token — percentages // (width: 80%) and unitless values (line-height: 1.5) stay legal. - // Only legal absolute length is a single 1px border line. - if (SIZE_PROPS.test(prop)) { + // The only legal absolute length is a 0px reset line. + // MIXED_PROPS (border/outline shorthands) are checked for their + // SIZE half too — a border width must come from var(--size-*). + if (SIZE_PROPS.test(prop) || MIXED_PROPS.test(prop)) { const withoutVars = stripVars(value); - const match = withoutVars.match(FORBIDDEN_SIZE_TOKEN); - if (match) { + const reported = new Set(); + for (const match of withoutVars.matchAll(FORBIDDEN_SIZE_TOKEN)) { const shown = match[0]; - if (shown !== "1px" && shown !== "0px") { + if (shown !== "0px" && !reported.has(shown)) { + reported.add(shown); report(decl, "hardcodedSize", { prop, value: shown }); } } @@ -150,12 +154,13 @@ export default { ) .trim(); if (withoutKeywords !== "" && withoutKeywords !== "0") { - const match = value.match(COLOR_LITERAL); - if (match) { - report(decl, "hardcodedColor", { - prop, - value: match[0].trim(), - }); + const reported = new Set(); + for (const match of value.matchAll(COLOR_LITERAL)) { + const shown = match[0].trim(); + if (!reported.has(shown)) { + reported.add(shown); + report(decl, "hardcodedColor", { prop, value: shown }); + } } } } diff --git a/web/src/lib/components/kit/CatalogGroup.svelte b/web/src/lib/components/kit/CatalogGroup.svelte index 90deefc..0a5b464 100644 --- a/web/src/lib/components/kit/CatalogGroup.svelte +++ b/web/src/lib/components/kit/CatalogGroup.svelte @@ -31,7 +31,7 @@ justify-content: space-between; gap: var(--space-xl); padding-bottom: var(--space-m); - border-bottom: 1px solid var(--color-border); + border-bottom: var(--size-border) solid var(--color-border); } .group-title span { font: var(--font-size-s) var(--font-mono); diff --git a/web/src/lib/components/kit/CatalogToolbar.svelte b/web/src/lib/components/kit/CatalogToolbar.svelte index beb60da..c5e5885 100644 --- a/web/src/lib/components/kit/CatalogToolbar.svelte +++ b/web/src/lib/components/kit/CatalogToolbar.svelte @@ -55,7 +55,7 @@ align-items: center; gap: var(--space-m); padding: var(--space-m) var(--space-l); - border: 1px solid var(--color-border); + border: var(--size-border) solid var(--color-border); border-radius: var(--radius-m); background: var(--color-panel); color: var(--color-text-muted); @@ -78,7 +78,7 @@ color: var(--color-text-muted); } .catalog-filters button { - border: 1px solid var(--color-border); + border: var(--size-border) solid var(--color-border); background: transparent; color: var(--color-text-muted); font: var(--font-size-s) var(--font-mono); diff --git a/web/src/lib/components/kit/CheckerCanvas.svelte b/web/src/lib/components/kit/CheckerCanvas.svelte index ad2b755..1f495e3 100644 --- a/web/src/lib/components/kit/CheckerCanvas.svelte +++ b/web/src/lib/components/kit/CheckerCanvas.svelte @@ -22,16 +22,16 @@ overflow: hidden; background-color: var(--color-text); background-image: - linear-gradient(45deg, #1a2129 25%, transparent 25%), - linear-gradient(-45deg, #1a2129 25%, transparent 25%), - linear-gradient(45deg, transparent 75%, #1a2129 75%), - linear-gradient(-45deg, transparent 75%, #1a2129 75%); + linear-gradient(45deg, var(--color-checker-main) 25%, transparent 25%), + linear-gradient(-45deg, var(--color-checker-main) 25%, transparent 25%), + linear-gradient(45deg, transparent 75%, var(--color-checker-main) 75%), + linear-gradient(-45deg, transparent 75%, var(--color-checker-main) 75%); background-size: var(--space-xl) var(--space-xl); background-position: 0 0, - 0 10px, - 10px -10px, - -10px 0; + 0 calc(var(--space-xl) / 2), + calc(var(--space-xl) / 2) calc(-1 * var(--space-xl) / 2), + calc(-1 * var(--space-xl) / 2) 0; } .checker-canvas--sm { diff --git a/web/src/lib/components/kit/CodeBlock.svelte b/web/src/lib/components/kit/CodeBlock.svelte index 6f2fee9..2180bba 100644 --- a/web/src/lib/components/kit/CodeBlock.svelte +++ b/web/src/lib/components/kit/CodeBlock.svelte @@ -24,7 +24,7 @@ diff --git a/web/src/lib/components/kit/StepCard.svelte b/web/src/lib/components/kit/StepCard.svelte index 7de116d..a90944a 100644 --- a/web/src/lib/components/kit/StepCard.svelte +++ b/web/src/lib/components/kit/StepCard.svelte @@ -45,9 +45,9 @@