@getvitops/generator 0.6.0 → 0.7.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/CHANGELOG.md +86 -0
- package/README.md +6 -0
- package/assets/css/patterns/code.css +3 -3
- package/assets/css/patterns/list.css +12 -32
- package/dist/index.d.mts +7 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +97 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -4
- package/schema.json +5 -1
- package/site.schema.json +5 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# @getvitops/generator
|
|
2
|
+
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @getvitops/utils@0.7.0
|
|
8
|
+
|
|
9
|
+
## 0.6.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 2cc847d: Package-resident agent skill + `vitops docs`:
|
|
14
|
+
- `@getvitops/cli` now ships the `vitops-design-system` agent skill inside the package
|
|
15
|
+
(`skill/SKILL.md`). `vitops agents` no longer emits a generated skill into the repo — it
|
|
16
|
+
symlinks `.agents/skills/` and `.claude/skills/` entries to the installed package (logical
|
|
17
|
+
`node_modules/@getvitops/cli/skill` target, surviving version bumps) and writes the
|
|
18
|
+
AGENTS.md pointer block. Old generated-skill directories are migrated automatically;
|
|
19
|
+
`--docs-dir` keeps the emit-files layout.
|
|
20
|
+
- New `vitops docs [topic]` command prints reference docs to stdout, rendered live from the
|
|
21
|
+
project's `design-system.json` (topics: classes, authoring, formats, color, scales,
|
|
22
|
+
patterns, elements; `--all` concatenates).
|
|
23
|
+
- `renderSkill()` removed from `@getvitops/generator` (superseded by the packaged skill).
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- @getvitops/utils@0.6.0
|
|
28
|
+
|
|
29
|
+
## 0.5.0
|
|
30
|
+
|
|
31
|
+
### Minor Changes
|
|
32
|
+
|
|
33
|
+
- Ship design-system context to downstream agents:
|
|
34
|
+
- JSON Schema descriptions: every `design-system.json` and site-config field now carries a
|
|
35
|
+
`description` (authored in the zod schemas via `desc()`), emitted into `schema.json` /
|
|
36
|
+
`site.schema.json` for editor hovers and agent consumption.
|
|
37
|
+
- New generated OKF docs: `authoring.md` (field reference walked from the JSON Schema),
|
|
38
|
+
`formats.md` (tailwind vs css vs bricks, including the TW_CLASH utilities Tailwind
|
|
39
|
+
provides natively), and `concepts/{color,scales,patterns}.md` (seeded OKLCH colour
|
|
40
|
+
system, fluid modular scales, pattern token cascade + override hooks).
|
|
41
|
+
- `vitops agents` now emits a generated `vitops-design-system` agent skill into
|
|
42
|
+
`.agents/skills/vitops-design-system/` (SKILL.md + the docs bundle as `references/`,
|
|
43
|
+
with an idempotent `.claude/skills/` symlink) and writes a compact pointer block into
|
|
44
|
+
`AGENTS.md`. Pass `--docs-dir` for the legacy docs-only layout.
|
|
45
|
+
- `TW_CLASH` and `BASE_HOOK` are exported from `@getvitops/generator`.
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- @getvitops/utils@0.5.0
|
|
50
|
+
|
|
51
|
+
## 0.4.0
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- Updated dependencies [d7e6491]
|
|
56
|
+
- @getvitops/utils@0.4.0
|
|
57
|
+
|
|
58
|
+
## 0.3.0
|
|
59
|
+
|
|
60
|
+
### Patch Changes
|
|
61
|
+
|
|
62
|
+
- Updated dependencies
|
|
63
|
+
- @getvitops/utils@0.3.0
|
|
64
|
+
|
|
65
|
+
## 0.2.1
|
|
66
|
+
|
|
67
|
+
### Patch Changes
|
|
68
|
+
|
|
69
|
+
- d28aae7: Fix Tailwind output: the `.centered > *` default (`grid-column: measure`) was emitted unlayered,
|
|
70
|
+
which in Tailwind v4 outranks every layer — so track utilities (`.spotlight`/`.breakout`/
|
|
71
|
+
`.fullbleed`) never overrode it and all `.centered` children fell back to `measure`. Emit the
|
|
72
|
+
structural rules (and the animation engine + patterns) in `@layer components` so the track/spacing
|
|
73
|
+
`@utility` classes (utilities layer) win.
|
|
74
|
+
- @getvitops/utils@0.2.1
|
|
75
|
+
|
|
76
|
+
## 0.2.0
|
|
77
|
+
|
|
78
|
+
### Minor Changes
|
|
79
|
+
|
|
80
|
+
- Redesign the colour system: seeded OKLCH tonal scales plus functional semantic tokens
|
|
81
|
+
(`bg`/`text`/`solid`/`on-solid`, `muted`/`bold`), with named-alias back-compat. Updates the
|
|
82
|
+
framework CSS, the schema, and the generated docs to the new token model.
|
|
83
|
+
|
|
84
|
+
### Patch Changes
|
|
85
|
+
|
|
86
|
+
- @getvitops/utils@0.2.0
|
package/README.md
CHANGED
|
@@ -33,3 +33,9 @@ await generate({
|
|
|
33
33
|
| `bricks` | `styles.min.css`, `bricks-colors-*.json`, `bricks-variables.json`, `tokens.json`, JS, `bricks/`, `docs/` |
|
|
34
34
|
|
|
35
35
|
See the [`design-system.json` schema](./schema.json) for the config shape.
|
|
36
|
+
|
|
37
|
+
## Changelog
|
|
38
|
+
|
|
39
|
+
This package's history: [`CHANGELOG.md`](./CHANGELOG.md) (shipped in the npm tarball, so it
|
|
40
|
+
also reads from `node_modules/@getvitops/generator/CHANGELOG.md`). `@getvitops/core`, `generator`,
|
|
41
|
+
`utils`, `cli`, `vite` and `astro` share one version and are released together.
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Consumes the generated token cascade (src/css/generated/tokens.css).
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/* ── Inline code
|
|
7
|
-
zero specificity (like the schema-generated
|
|
6
|
+
/* ── Inline code — prose <code> that isn't inside a <pre>. Element-level at
|
|
7
|
+
zero specificity (like the schema-generated btn/link patterns) so bare
|
|
8
8
|
<code> needs no class and any explicit class overrides it. .font-code styles
|
|
9
|
-
type only; this adds the
|
|
9
|
+
type only; this adds the boxed treatment. ── */
|
|
10
10
|
:where(:not(pre) > code) {
|
|
11
11
|
font-family: var(--font-mono);
|
|
12
12
|
font-size: 0.85em;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Consumes the generated token cascade (src/css/generated/tokens.css).
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/* ── List family — base list, facets, filtered search, virtual,
|
|
6
|
+
/* ── List family — base list, facets, filtered search, virtual, tag list ──── */
|
|
7
7
|
.list {
|
|
8
8
|
--_p: var(--p-list, var(--p-list-group, var(--p-default)));
|
|
9
9
|
--_b: var(--b-list, var(--b-list-group, var(--b-default)));
|
|
@@ -216,11 +216,15 @@
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
219
|
+
/* ── Tag list — a bordered field of dismissable tags plus a free-text input.
|
|
220
|
+
Items are the generated `.tag` pattern (+ `.tag__remove` from tag.css): a tag is
|
|
221
|
+
the editable/dismissable label, a badge is the static one — so this needs no
|
|
222
|
+
parallel item styling of its own. ── */
|
|
223
|
+
.tag-list {
|
|
224
|
+
--_p: var(--p-tag-list, var(--p-control, var(--p-default)));
|
|
225
|
+
--_b: var(--b-tag-list, var(--b-control, var(--b-default)));
|
|
226
|
+
--_br: var(--br-tag-list, var(--br-control, var(--br-default)));
|
|
227
|
+
--_fs: var(--fs-tag-list, var(--fs-control, var(--fs-default)));
|
|
224
228
|
|
|
225
229
|
display: flex;
|
|
226
230
|
flex-wrap: wrap;
|
|
@@ -232,31 +236,7 @@
|
|
|
232
236
|
align-items: center;
|
|
233
237
|
font-size: var(--_fs);
|
|
234
238
|
|
|
235
|
-
.
|
|
236
|
-
display: inline-flex;
|
|
237
|
-
align-items: center;
|
|
238
|
-
gap: 0.25rem;
|
|
239
|
-
padding: 0.25rem 0.5rem;
|
|
240
|
-
border-radius: var(--br-chip, var(--br-tag, 0.25rem));
|
|
241
|
-
font-size: 0.875rem;
|
|
242
|
-
background: var(--color-surface-muted);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
.chip-list__chip-remove {
|
|
246
|
-
padding: 0;
|
|
247
|
-
background: transparent;
|
|
248
|
-
border: none;
|
|
249
|
-
cursor: pointer;
|
|
250
|
-
opacity: 0.6;
|
|
251
|
-
line-height: 1;
|
|
252
|
-
transition: opacity 0.15s ease;
|
|
253
|
-
|
|
254
|
-
&:hover {
|
|
255
|
-
opacity: 1;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
.chip-list__input {
|
|
239
|
+
.tag-list__input {
|
|
260
240
|
flex: 1;
|
|
261
241
|
min-inline-size: 6rem;
|
|
262
242
|
border: none;
|
|
@@ -266,7 +246,7 @@
|
|
|
266
246
|
}
|
|
267
247
|
|
|
268
248
|
&:focus-within {
|
|
269
|
-
outline: 2px solid var(--
|
|
249
|
+
outline: 2px solid var(--tag-list-focus-color, var(--color-brand-primary-muted));
|
|
270
250
|
outline-offset: 2px;
|
|
271
251
|
}
|
|
272
252
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -58,6 +58,7 @@ declare const DesignSystemSchema: z.ZodMiniObject<{
|
|
|
58
58
|
overrides: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
59
59
|
element: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
60
60
|
class: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
61
|
+
fill: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
61
62
|
default_role: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
62
63
|
base: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
63
64
|
states: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>>;
|
|
@@ -147,6 +148,7 @@ declare const jsonSchema: {
|
|
|
147
148
|
overrides: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
148
149
|
element: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
149
150
|
class: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
151
|
+
fill: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
150
152
|
default_role: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
151
153
|
base: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
152
154
|
states: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>>;
|
|
@@ -278,8 +280,9 @@ declare function generateDocs(ds: DesignSystem, assetsDir: string): Record<strin
|
|
|
278
280
|
*/
|
|
279
281
|
/**
|
|
280
282
|
* Pattern base geometry props → per-pattern override-hook shorthand. Each hook
|
|
281
|
-
* wraps the authored value (`padding: var(--p-
|
|
282
|
-
* consumer restyles one pattern by setting one variable.
|
|
283
|
+
* wraps the authored value (`padding: var(--p-btn, 0.4em 0.8em)`) so a
|
|
284
|
+
* consumer restyles one pattern by setting one variable. The hook is named after
|
|
285
|
+
* the pattern's key, not its class.
|
|
283
286
|
*/
|
|
284
287
|
declare const BASE_HOOK: Record<string, string>;
|
|
285
288
|
/**
|
|
@@ -497,6 +500,7 @@ declare const SiteConfigSchema: z.ZodMiniObject<{
|
|
|
497
500
|
overrides: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
498
501
|
element: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
499
502
|
class: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
503
|
+
fill: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
500
504
|
default_role: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
501
505
|
base: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
502
506
|
states: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>>;
|
|
@@ -992,6 +996,7 @@ declare const siteJsonSchema: {
|
|
|
992
996
|
overrides: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
993
997
|
element: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
994
998
|
class: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
999
|
+
fill: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
995
1000
|
default_role: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
996
1001
|
base: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
997
1002
|
states: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>>;
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/schema.ts","../src/generate.ts","../src/docs.ts","../src/shared.ts","../src/site.ts","../src/index.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/schema.ts","../src/generate.ts","../src/docs.ts","../src/shared.ts","../src/site.ts","../src/index.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -62,7 +62,8 @@ const Pattern = desc(z.object({
|
|
|
62
62
|
group: desc(z.optional(z.string()), "Token-cascade group this pattern belongs to (e.g. tag / control / panel); base declarations resolve through `--<prop>-<group>` before `--<prop>-default`."),
|
|
63
63
|
overrides: z.optional(desc(CssDecls, "Per-pattern token overrides, emitted as `--<prop>-<name>-group` values.")),
|
|
64
64
|
element: desc(z.optional(z.string()), "Style at element level via zero-specificity `:where(<element>)` (instead of, or alongside, a class)."),
|
|
65
|
-
class: desc(z.optional(z.string()), "Class name to emit (defaults to the pattern's key)."),
|
|
65
|
+
class: desc(z.optional(z.string()), "Class name to emit (defaults to the pattern's key when no `element` is set). Combined with `element`, the pattern emits one zero-specificity `:where(<element>, .<class>)` rule so the class works on any tag and any explicit class overrides it."),
|
|
66
|
+
fill: desc(z.optional(z.boolean()), "Whether this pattern is colour-filled (states/roles drive `background-color` + `on-solid` text) or text-coloured (they drive `color`). Defaults to true when `base` declares a background."),
|
|
66
67
|
default_role: desc(z.optional(z.string()), "Semantic colour role applied to the bare/default variant."),
|
|
67
68
|
base: z.optional(desc(CssDecls, "Base CSS declarations. Geometry properties (padding, border-radius, border, box-shadow, font-size) are wrapped in per-pattern override hooks (`--p-<name>`, `--br-<name>`, `--b-<name>`, `--ds-<name>`, `--fs-<name>`) so consumers can restyle one pattern by setting one variable.")),
|
|
68
69
|
states: desc(z.optional(z.record(z.string(), z.record(z.string(), z.unknown()))), "Interaction states (hover / active / focus-visible), each a map of shortcuts: `step` (intensify fills/text by n emphasis stops), `scale` (transform scale), `lift` (translateY + shadow), `shadow` (a shadow name → drop-shadow(var(--shadow-<name>)), or true → lift shadow), `ring` (focus ring), or raw `css` declarations. Hover rules are wrapped in `@media (hover: hover)`."),
|
|
@@ -159,8 +160,9 @@ function validate(input) {
|
|
|
159
160
|
*/
|
|
160
161
|
/**
|
|
161
162
|
* Pattern base geometry props → per-pattern override-hook shorthand. Each hook
|
|
162
|
-
* wraps the authored value (`padding: var(--p-
|
|
163
|
-
* consumer restyles one pattern by setting one variable.
|
|
163
|
+
* wraps the authored value (`padding: var(--p-btn, 0.4em 0.8em)`) so a
|
|
164
|
+
* consumer restyles one pattern by setting one variable. The hook is named after
|
|
165
|
+
* the pattern's key, not its class.
|
|
164
166
|
*/
|
|
165
167
|
const BASE_HOOK = {
|
|
166
168
|
padding: "p",
|
|
@@ -1012,9 +1014,10 @@ pattern CSS is assembled — token cascade, \`--p-<pattern>\`-style override hoo
|
|
|
1012
1014
|
shortcuts — is explained in [/concepts/patterns.md](../concepts/patterns.md).)
|
|
1013
1015
|
|
|
1014
1016
|
- Patterns: ${code(patterns)}.
|
|
1015
|
-
- Roles (for coloured patterns
|
|
1016
|
-
${code(patternRoles)} — e.g. \`badge-success\`, \`
|
|
1017
|
-
|
|
1017
|
+
- Roles (for coloured patterns — \`badge\`, \`tag\`, \`status\`, \`cta\`, \`btn\`, …):
|
|
1018
|
+
${code(patternRoles)} — e.g. \`badge-success\`, \`cta-danger\`. A pattern that also styles an
|
|
1019
|
+
element accepts the bare role class too (\`<button class="danger">\`). The default
|
|
1020
|
+
(unsuffixed) variant uses the pattern's \`default_role\`.
|
|
1018
1021
|
- Shape primitives: \`--br-<name>\` radii — ${code(radii)}.
|
|
1019
1022
|
`;
|
|
1020
1023
|
}
|
|
@@ -1343,16 +1346,25 @@ Shared geometry resolves through a variable chain, most-specific first:
|
|
|
1343
1346
|
|
|
1344
1347
|
## 2 — Base declarations & override hooks
|
|
1345
1348
|
|
|
1346
|
-
Each pattern's \`base\` block is emitted on its selector
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
+
Each pattern's \`base\` block is emitted on its selector:
|
|
1350
|
+
|
|
1351
|
+
- \`class\` only → \`.<class ?? name>\`, at normal class specificity.
|
|
1352
|
+
- \`element\` only → a **zero-specificity** \`:where(<element>)\` rule, so author CSS can always
|
|
1353
|
+
override it.
|
|
1354
|
+
- **both** → one \`:where(<element>, .<class>)\` rule (e.g. \`:where(button, .btn)\`). The element
|
|
1355
|
+
gets the styling with no class needed, the class carries it to any other tag, and — because the
|
|
1356
|
+
whole thing sits at zero specificity — any explicit class wins, including a louder pattern
|
|
1357
|
+
(\`.cta\`) or a component's own rule (\`.dialog__close\`).
|
|
1358
|
+
|
|
1359
|
+
Geometry properties are wrapped in a **per-pattern override hook**:
|
|
1349
1360
|
|
|
1350
1361
|
| base property | hook variable |
|
|
1351
1362
|
| --- | --- |
|
|
1352
1363
|
${hookTable}
|
|
1353
1364
|
|
|
1354
|
-
e.g. \`padding: var(--p-
|
|
1355
|
-
\`--p-
|
|
1365
|
+
e.g. \`padding: var(--p-btn, 0.4em 0.8em)\` — a consumer restyles every button by setting
|
|
1366
|
+
\`--p-btn\` on \`:root\`, without touching the pattern. The hook is named after the pattern's
|
|
1367
|
+
**key**, not its class.
|
|
1356
1368
|
|
|
1357
1369
|
## 3 — States
|
|
1358
1370
|
|
|
@@ -1374,7 +1386,10 @@ rules are wrapped in \`@media (hover: hover)\` so touch devices never stick.
|
|
|
1374
1386
|
## 4 — Role variants
|
|
1375
1387
|
|
|
1376
1388
|
\`roles\` lists semantic colour variants: class patterns emit \`.<pattern>-<role>\`
|
|
1377
|
-
(\`.badge-success\`)
|
|
1389
|
+
(\`.badge-success\`). A pattern with an \`element\` emits both the bare role class on the
|
|
1390
|
+
element and the \`-<role>\` form (\`:where(button, .btn).danger, .btn-danger\`), so the same
|
|
1391
|
+
variant works on a non-element host — both at class specificity, so neither outranks a
|
|
1392
|
+
plain class. Fill
|
|
1378
1393
|
patterns set \`background-color: var(--<role>-solid)\` + \`color: var(--<role>-on-solid)\`;
|
|
1379
1394
|
text patterns use the role's \`bold\` emphasis stop. \`default_role\` colours the bare,
|
|
1380
1395
|
unsuffixed pattern. States re-apply per variant with the variant's role.
|
|
@@ -1704,6 +1719,7 @@ function build(ds, format, assetsDir) {
|
|
|
1704
1719
|
generated["typography.css"] = typo;
|
|
1705
1720
|
}
|
|
1706
1721
|
const stateRules = (sel, role, states, colorProp = "background-color") => {
|
|
1722
|
+
const sels = Array.isArray(sel) ? sel : [sel];
|
|
1707
1723
|
let out = "";
|
|
1708
1724
|
for (const [state, spec] of Object.entries(states)) {
|
|
1709
1725
|
const body = [];
|
|
@@ -1721,7 +1737,8 @@ function build(ds, format, assetsDir) {
|
|
|
1721
1737
|
}
|
|
1722
1738
|
if (spec.css && typeof spec.css === "object") for (const [k, v] of Object.entries(spec.css)) body.push(`${k}: ${v};`);
|
|
1723
1739
|
if (!body.length) continue;
|
|
1724
|
-
const
|
|
1740
|
+
const pseudo = state === "hover" ? ":hover" : state === "active" ? ":active" : state === "focus-visible" ? ":focus-visible" : `:${state}`;
|
|
1741
|
+
const rule = `${sels.map((s) => `${s}${pseudo}`).join(",\n")} {\n ${body.join("\n ")}\n}\n`;
|
|
1725
1742
|
out += state === "hover" ? `@media (hover: hover) {\n${rule}}\n` : rule;
|
|
1726
1743
|
}
|
|
1727
1744
|
return out;
|
|
@@ -1731,11 +1748,12 @@ function build(ds, format, assetsDir) {
|
|
|
1731
1748
|
for (const [pname, p] of Object.entries(patterns?.items ?? {})) {
|
|
1732
1749
|
if (!p.base) continue;
|
|
1733
1750
|
const states = p.states ?? {};
|
|
1734
|
-
const
|
|
1735
|
-
const
|
|
1751
|
+
const cls = p.class ?? (p.element ? void 0 : pname);
|
|
1752
|
+
const elementSel = (extra = "") => `:where(${[p.element, cls && `.${cls}`].filter(Boolean).join(", ")})${extra}`;
|
|
1753
|
+
const defaultSel = p.element ? elementSel() : `.${cls}`;
|
|
1736
1754
|
const defaultRole = p.default_role ?? null;
|
|
1737
1755
|
const base = { ...p.base };
|
|
1738
|
-
const fills = pname === "button" || pname === "badge" || base["background-color"] != null || base["background"] != null;
|
|
1756
|
+
const fills = p.fill ?? (pname === "button" || pname === "badge" || base["background-color"] != null || base["background"] != null);
|
|
1739
1757
|
const colorProp = fills ? "background-color" : "color";
|
|
1740
1758
|
pat += `${defaultSel} {\n`;
|
|
1741
1759
|
if (Object.keys(states).length > 0) {
|
|
@@ -1753,10 +1771,10 @@ function build(ds, format, assetsDir) {
|
|
|
1753
1771
|
pat += decls(wrappedBase) + "\n}\n";
|
|
1754
1772
|
pat += stateRules(defaultSel, defaultRole, states, colorProp);
|
|
1755
1773
|
for (const role of p.roles ?? []) {
|
|
1756
|
-
const
|
|
1774
|
+
const variantSels = p.element ? [elementSel(`.${role}`), ...cls ? [`.${cls}-${role}`] : []] : [`.${cls}-${role}`];
|
|
1757
1775
|
const variantColorDecl = fills ? `background-color: var(--${role}-solid); color: var(--${role}-on-solid)` : `color: var(--color-${role}-bold)`;
|
|
1758
|
-
pat += `${
|
|
1759
|
-
pat += stateRules(
|
|
1776
|
+
pat += `${variantSels.join(",\n")} { ${variantColorDecl}; }\n`;
|
|
1777
|
+
pat += stateRules(variantSels, role, states, colorProp);
|
|
1760
1778
|
}
|
|
1761
1779
|
pat += "\n";
|
|
1762
1780
|
}
|
|
@@ -1992,7 +2010,7 @@ function build(ds, format, assetsDir) {
|
|
|
1992
2010
|
reverseIndex
|
|
1993
2011
|
}, null, 2);
|
|
1994
2012
|
})(),
|
|
1995
|
-
tailwind: emitTailwind({
|
|
2013
|
+
tailwind: format !== "tailwind" ? "" : emitTailwind({
|
|
1996
2014
|
ds,
|
|
1997
2015
|
expandedPalette,
|
|
1998
2016
|
scaleRoles,
|
|
@@ -3087,21 +3105,73 @@ function defaultConfig() {
|
|
|
3087
3105
|
top: 1e3
|
|
3088
3106
|
},
|
|
3089
3107
|
items: {
|
|
3090
|
-
|
|
3108
|
+
btn: {
|
|
3091
3109
|
group: "control",
|
|
3092
3110
|
element: "button",
|
|
3111
|
+
class: "btn",
|
|
3112
|
+
fill: false,
|
|
3113
|
+
overrides: {
|
|
3114
|
+
b: "1px solid transparent",
|
|
3115
|
+
fs: "inherit"
|
|
3116
|
+
},
|
|
3117
|
+
base: {
|
|
3118
|
+
display: "inline-flex",
|
|
3119
|
+
"align-items": "center",
|
|
3120
|
+
"justify-content": "center",
|
|
3121
|
+
gap: "0.4em",
|
|
3122
|
+
padding: "var(--p-btn-group)",
|
|
3123
|
+
"border-radius": "var(--br-btn-group)",
|
|
3124
|
+
border: "var(--b-btn-group)",
|
|
3125
|
+
"box-shadow": "var(--ds-btn-group)",
|
|
3126
|
+
background: "transparent",
|
|
3127
|
+
color: "inherit",
|
|
3128
|
+
"font-family": "inherit",
|
|
3129
|
+
"font-size": "var(--fs-btn-group)",
|
|
3130
|
+
"font-weight": "inherit",
|
|
3131
|
+
"text-decoration": "none",
|
|
3132
|
+
cursor: "pointer"
|
|
3133
|
+
},
|
|
3134
|
+
states: {
|
|
3135
|
+
hover: {
|
|
3136
|
+
step: 1,
|
|
3137
|
+
css: { "background-color": "var(--color-surface-muted)" }
|
|
3138
|
+
},
|
|
3139
|
+
"focus-visible": { ring: true }
|
|
3140
|
+
},
|
|
3141
|
+
roles: []
|
|
3142
|
+
},
|
|
3143
|
+
cta: {
|
|
3144
|
+
group: "control",
|
|
3145
|
+
class: "cta",
|
|
3146
|
+
fill: true,
|
|
3093
3147
|
default_role: "brand-primary",
|
|
3148
|
+
overrides: {
|
|
3149
|
+
p: "0.75em 1.5em",
|
|
3150
|
+
b: "none",
|
|
3151
|
+
ds: "var(--shadow-sm)",
|
|
3152
|
+
fs: "inherit"
|
|
3153
|
+
},
|
|
3094
3154
|
base: {
|
|
3095
|
-
|
|
3096
|
-
"
|
|
3097
|
-
|
|
3155
|
+
display: "inline-flex",
|
|
3156
|
+
"align-items": "center",
|
|
3157
|
+
"justify-content": "center",
|
|
3158
|
+
gap: "0.5em",
|
|
3159
|
+
padding: "var(--p-cta-group)",
|
|
3160
|
+
"border-radius": "var(--br-cta-group)",
|
|
3161
|
+
border: "var(--b-cta-group)",
|
|
3162
|
+
"font-family": "inherit",
|
|
3163
|
+
"font-size": "var(--fs-cta-group)",
|
|
3098
3164
|
"font-weight": "600",
|
|
3099
|
-
|
|
3165
|
+
"text-decoration": "none",
|
|
3100
3166
|
cursor: "pointer",
|
|
3101
|
-
|
|
3167
|
+
color: "var(--brand-primary-on-solid)",
|
|
3168
|
+
"box-shadow": "var(--ds-cta-group)"
|
|
3102
3169
|
},
|
|
3103
3170
|
states: {
|
|
3104
|
-
hover: {
|
|
3171
|
+
hover: {
|
|
3172
|
+
step: 1,
|
|
3173
|
+
lift: "1px"
|
|
3174
|
+
},
|
|
3105
3175
|
active: { scale: .97 },
|
|
3106
3176
|
"focus-visible": { ring: true }
|
|
3107
3177
|
},
|