Files
webstudio/packages/css-data/bin/css-to-ws.ts
Oleg Isonen 8de2fd47f6 fix: CSS shorthand properties not saved when value contains var() (#5688)
Shorthand properties like background: var(--color) were silently dropped
when pasting into the CSS editor because the shorthand expander can't
handle unresolved var() references.

Fix: CSS vars from the current element's computed styles are now
resolved before expanding shorthands. Inline and nested fallbacks
(var(--a, var(--b))) are supported. If a var still can't be resolved, a
toast error is shown instead of silently dropping the property.
2026-04-12 17:14:01 +02:00

56 lines
1.7 KiB
TypeScript
Executable File

#!/usr/bin/env tsx
import { parseArgs, type ParseArgsConfig } from "node:util";
import * as path from "node:path";
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { camelCaseProperty, parseCss } from "../src/parse-css";
const cliOptions = {
allowPositionals: true,
strict: true,
} as const satisfies ParseArgsConfig;
const cliArgs = parseArgs({ args: process.argv.slice(2), ...cliOptions });
if (cliArgs.positionals.length < 2) {
console.error("Please provide the source and destination paths");
process.exit(1);
}
const sourcePath = path.resolve(process.cwd(), cliArgs.positionals[0]);
const destinationPath = path.resolve(process.cwd(), cliArgs.positionals[1]);
const objectGroupBy = <Item>(list: Item[], by: (item: Item) => string) => {
const records: Record<string, Item[]> = {};
for (const item of list) {
const key = by(item);
let list = records[key];
if (list === undefined) {
list = [];
records[key] = list;
}
list.push(item);
}
return records;
};
const css = readFileSync(sourcePath, "utf8");
const parsed = parseCss(css, new Map()).styles.map(
({ property, ...styleDecl }) => ({
selector: styleDecl.selector,
breakpoint: styleDecl.breakpoint,
state: styleDecl.state,
property: camelCaseProperty(property),
value: styleDecl.value,
})
);
const records = objectGroupBy(parsed, (item) => item.selector);
mkdirSync(path.dirname(destinationPath), { recursive: true });
const code = `/* eslint-disable */
/* This file was generated by css-to-ws.ts */
export const styles = ${JSON.stringify(records, null, 2)};
`;
writeFileSync(destinationPath, code, "utf8");
console.info("✅ CSS parsed and Webstudio Data generated");