A build config made with defineConfig from postcss-uxdsl/config, a theme file that points $schema at the packaged postcss-uxdsl/schema/theme.schema.json (so an editor validates and completes it) and overrides only palette.primary.main, and three sources. scripts/capture-capabilities.js runs each command below and stores what it printed; npm test runs it again with --check, so this page cannot keep showing output the CLI no longer produces. Absolute paths are shown as <project>.
uxdsl.config.cjs// The build config of the small project whose real CLI output the playground's /docs/cli
// page shows (captured by scripts/capture-capabilities.js). `defineConfig` is the typed
// helper from `postcss-uxdsl/config`. The theme is not named here: `uxdsl build` discovers
// `uxdsl.theme.json` next to this file.
const path = require('path');
const { defineConfig } = require('postcss-uxdsl/config');
module.exports = defineConfig({
entry: path.join(__dirname, 'src/main.uxdsl'),
outFile: path.join(__dirname, 'dist/app.css'),
});uxdsl.theme.json{
"$schema": "../../node_modules/postcss-uxdsl/schema/theme.schema.json",
"breakpoints": { "xs": 0, "sm": 480, "md": 768, "lg": 1024, "xl": 1280 },
"palette": {
"primary": { "main": "#0f766e" }
}
}src/card.uxdsl.card {
@ds-surface(contained);
display: flex;
flex-direction: xs(column) md(row);
gap: density(4);
}src/button.uxdsl.save {
@ds-button(contained primary 2);
}src/legacy.uxdsl/* Left out of the entry with --exclude: an old stylesheet nothing imports any more. */
.old-banner {
color: palette(primary-main);
}--src, --out, --excludeRewrites the entry's @import list from every .uxdsl file under --src; --exclude leaves files out by name.
$ uxdsl generate-entry --src src --out src/main.uxdsl --exclude legacy.uxdsl
[uxdsl] Scanning src for .uxdsl files...
[uxdsl] Generated entry file at src/main.uxdsl with 2 imports.It wrote src/main.uxdsl:
/* AUTO-GENERATED FILE - DO NOT EDIT MANUALLY */
/* Generated by uxdsl generate-entry */
/* --- Application & Component Imports --- */
@import './button.uxdsl';
@import './card.uxdsl';--config, --entryWith no flags, uxdsl build finds uxdsl.config.cjs in the current directory and the theme file next to it. --config names the config file; --entry with --out compiles one file to one output instead of the config's entry.
$ uxdsl build
[uxdsl] Theme config detected
[uxdsl] built dist/app.css (52381 bytes)52381179$ uxdsl build --config uxdsl.config.cjs
[uxdsl] Theme config detected
[uxdsl] unchanged dist/app.css (compiled output identical to the file on disk; not rewritten)$ uxdsl build --entry src/card.uxdsl --out dist/card.css
[uxdsl] Theme config detected
[uxdsl] built dist/card.css (51359 bytes)5135917--include-theme and --no-include-theme--include-theme is the default: the entry also defines every token in :root, once. A second entry — a component or CSS-Module stylesheet — passes --no-include-theme to emit only its rules, consuming the tokens the first entry already defined. The same card.uxdsl, both ways:
$ uxdsl build --entry src/card.uxdsl --out dist/card-with-theme.css --include-theme
[uxdsl] Theme config detected
[uxdsl] built dist/card-with-theme.css (51359 bytes)5135917$ uxdsl build --entry src/card.uxdsl --out dist/card-only.css --no-include-theme
[uxdsl] built dist/card-only.css (466 bytes)It wrote dist/card-only.css:
.card {
padding: var(--uxdsl__surface__contained-padding);
border-radius: var(--uxdsl__surface__contained-radius);
background: var(--uxdsl__surface__contained-bg);
color: var(--uxdsl__surface__contained-color);
border: var(--uxdsl__surface__contained-border);
box-shadow: var(--uxdsl__surface__contained-shadow);
display: flex;
flex-direction: column;
gap: var(--uxdsl__density__4);
}@media (min-width: 768px) {.card {
flex-direction: row;
}
}4660--sourcemapWrites <outFile>.map next to the CSS and a sourceMappingURL comment, so devtools point at the .uxdsl line that produced a rule. --sourcemap=inline embeds the map instead.
$ uxdsl build --entry src/card.uxdsl --out dist/card-mapped.css --no-include-theme --sourcemap
[uxdsl] built dist/card-mapped.css (510 bytes) + card-mapped.css.map (408 bytes)It wrote dist/card-mapped.css:
.card {
padding: var(--uxdsl__surface__contained-padding);
border-radius: var(--uxdsl__surface__contained-radius);
background: var(--uxdsl__surface__contained-bg);
color: var(--uxdsl__surface__contained-color);
border: var(--uxdsl__surface__contained-border);
box-shadow: var(--uxdsl__surface__contained-shadow);
display: flex;
flex-direction: column;
gap: var(--uxdsl__density__4);
}@media (min-width: 768px) {.card {
flex-direction: row;
}
}
/*# sourceMappingURL=card-mapped.css.map */["../src/card.uxdsl","<no source>"]card-mapped.csscard-mapped.css.map--strict-themeFails the build, before writing anything, when a family you declared was partly filled from the base theme. This project overrides only palette.primary.main, so the bare flag fails; scoped to the families that must be complete (--strict-theme=breakpoints) it passes.
$ uxdsl build --strict-theme
[uxdsl] Error: --strict-theme: the following theme families you declared are partially filled from defaults: palette. Provide every key of these families explicitly, or drop --strict-theme/strictTheme if inheriting some of them is intentional.$ uxdsl build --strict-theme=breakpoints
[uxdsl] Theme config detected
[uxdsl] unchanged dist/app.css (compiled output identical to the file on disk; not rewritten)--diff, --strict, --contrastuxdsl theme prints the effective theme — the same discovery and resolution as build, no CSS written. --diff prints only what your theme file mentions, one row per leaf labeled project or default, and says on stderr where a family mixes the two. --strict exits non-zero when a declared family was partly inherited. --contrast runs the WCAG gate and prints its full JSON report; the Contrast page runs the same function in your browser.
$ uxdsl themestdout is a JSON document of 13233 bytes; an excerpt:
{
"palette": {
"primary": {
"main": "#0f766e",
"light": "#a855f7",
"dark": "#581c87",
"contrast": "#ffffff"
}
}
}$ uxdsl theme --diff
[uxdsl] palette.primary mixes your values (main) with base values (light, dark, contrast)stdout is a JSON document; an excerpt:
[
{
"path": "palette.primary.main",
"value": "#0f766e",
"source": "project"
},
{
"path": "palette.primary.light",
"value": "#a855f7",
"source": "default"
},
{
"path": "palette.primary.dark",
"value": "#581c87",
"source": "default"
},
{
"path": "palette.primary.contrast",
"value": "#ffffff",
"source": "default"
}
]$ uxdsl theme --strict
[uxdsl] Error: --strict: the following theme families you declared are partially filled from defaults: palette. Provide every key of these families explicitly, or drop --strict if inheriting some of them is intentional.true$ uxdsl theme --strict=breakpoints$ uxdsl theme --contrast
[uxdsl] Error: --contrast: 123 contrast pairs fail WCAG for this theme. The JSON report on stdout lists each one with its mode, component, state, breakpoint and resolved colors.stdout is a JSON document of 289550 bytes; an excerpt:
[
{
"mode": "light",
"family": "surface",
"component": "outlined",
"tone": "surface",
"state": "base",
"pair": "text",
"background": "own-bg-or-ambient",
"breakpoint": 0,
"required": 4.5,
"ratio": 1,
"reason": "1.00:1 < 4.5:1"
},
{
"mode": "light",
"family": "surface",
"component": "outlined",
"tone": "surface",
"state": "base",
"pair": "border",
"background": "ambient",
"breakpoint": 0,
"required": 3,
"ratio": 1,
"reason": "1.00:1 < 3:1"
}
]uxdsl watch builds, then rebuilds when a source changes. A broken edit is reported and the last good CSS stays on disk; the next valid save recovers. A session, recorded by the capture script as it edited the file:
start: uxdsl watch
[uxdsl] Theme config detected
[uxdsl] built dist/app.css (52381 bytes)
[uxdsl] watching for changes...
edit src/card.uxdsl: add border-radius: rounded(3);
[uxdsl] change src/card.uxdsl
[uxdsl] Theme config detected
[uxdsl] built dist/app.css (52423 bytes)
edit src/card.uxdsl: add xxl(2rem), a breakpoint that is not configured
[uxdsl] change src/card.uxdsl
[uxdsl] Theme config detected
[uxdsl] build failed: postcss-uxdsl: src/card.uxdsl:5:3: UXD_BREAKPOINT_UNKNOWN: xxl(...) is not a configured breakpoint or a known CSS function; configured breakpoints: xs, sm, md, lg, xl.
undo the edit
[uxdsl] change src/card.uxdsl
[uxdsl] Theme config detected
[uxdsl] built dist/app.css (52381 bytes)