@elastic/distillate 0.0.0 → 0.1.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/LICENSE.txt +93 -0
- package/NOTICE.txt +30 -0
- package/README.md +142 -0
- package/THIRD_PARTY_LICENSES.md +768 -0
- package/dist/cjs/collector.js +420 -0
- package/dist/cjs/collector.js.map +1 -0
- package/dist/cjs/css_scan.js +186 -0
- package/dist/cjs/css_scan.js.map +1 -0
- package/dist/cjs/dom_sink.js +40 -0
- package/dist/cjs/dom_sink.js.map +1 -0
- package/dist/cjs/emotion.js +189 -0
- package/dist/cjs/emotion.js.map +1 -0
- package/dist/cjs/engine.js +79 -0
- package/dist/cjs/engine.js.map +1 -0
- package/dist/cjs/environment.js +9 -0
- package/dist/cjs/environment.js.map +1 -0
- package/dist/cjs/hash.js +86 -0
- package/dist/cjs/hash.js.map +1 -0
- package/dist/cjs/idents.js +23 -0
- package/dist/cjs/idents.js.map +1 -0
- package/dist/cjs/index.js +42 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/instance.js +34 -0
- package/dist/cjs/instance.js.map +1 -0
- package/dist/cjs/local_vars.js +100 -0
- package/dist/cjs/local_vars.js.map +1 -0
- package/dist/cjs/minify.js +77 -0
- package/dist/cjs/minify.js.map +1 -0
- package/dist/cjs/names.js +77 -0
- package/dist/cjs/names.js.map +1 -0
- package/dist/cjs/nesting.js +406 -0
- package/dist/cjs/nesting.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/runtime.js +257 -0
- package/dist/cjs/runtime.js.map +1 -0
- package/dist/cjs/styles/authoring.js +169 -0
- package/dist/cjs/styles/authoring.js.map +1 -0
- package/dist/cjs/styles/declarations.js +139 -0
- package/dist/cjs/styles/declarations.js.map +1 -0
- package/dist/cjs/styles/index.js +32 -0
- package/dist/cjs/styles/index.js.map +1 -0
- package/dist/cjs/styles/module.js +233 -0
- package/dist/cjs/styles/module.js.map +1 -0
- package/dist/cjs/styles/registry.js +187 -0
- package/dist/cjs/styles/registry.js.map +1 -0
- package/dist/cjs/styles/types.js +9 -0
- package/dist/cjs/styles/types.js.map +1 -0
- package/dist/cjs/testing.js +37 -0
- package/dist/cjs/testing.js.map +1 -0
- package/dist/cjs/theme.js +249 -0
- package/dist/cjs/theme.js.map +1 -0
- package/dist/cjs/tokens/contextual_var.js +39 -0
- package/dist/cjs/tokens/contextual_var.js.map +1 -0
- package/dist/cjs/tokens/index.js +24 -0
- package/dist/cjs/tokens/index.js.map +1 -0
- package/dist/cjs/tokens/kind.js +14 -0
- package/dist/cjs/tokens/kind.js.map +1 -0
- package/dist/cjs/tokens/light_dark.js +42 -0
- package/dist/cjs/tokens/light_dark.js.map +1 -0
- package/dist/cjs/tokens/scale_token.js +28 -0
- package/dist/cjs/tokens/scale_token.js.map +1 -0
- package/dist/cjs/tokens/theme_token.js +28 -0
- package/dist/cjs/tokens/theme_token.js.map +1 -0
- package/dist/cjs/var_invariant.js +115 -0
- package/dist/cjs/var_invariant.js.map +1 -0
- package/dist/collector.d.ts +84 -0
- package/dist/collector.d.ts.map +1 -0
- package/dist/collector.js +416 -0
- package/dist/collector.js.map +1 -0
- package/dist/css_scan.d.ts +57 -0
- package/dist/css_scan.d.ts.map +1 -0
- package/dist/css_scan.js +180 -0
- package/dist/css_scan.js.map +1 -0
- package/dist/dom_sink.d.ts +27 -0
- package/dist/dom_sink.d.ts.map +1 -0
- package/dist/dom_sink.js +36 -0
- package/dist/dom_sink.js.map +1 -0
- package/dist/emotion.d.ts +47 -0
- package/dist/emotion.d.ts.map +1 -0
- package/dist/emotion.js +184 -0
- package/dist/emotion.js.map +1 -0
- package/dist/engine.d.ts +41 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +75 -0
- package/dist/engine.js.map +1 -0
- package/dist/environment.d.ts +43 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +8 -0
- package/dist/environment.js.map +1 -0
- package/dist/hash.d.ts +2 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +82 -0
- package/dist/hash.js.map +1 -0
- package/dist/idents.d.ts +9 -0
- package/dist/idents.d.ts.map +1 -0
- package/dist/idents.js +19 -0
- package/dist/idents.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/instance.d.ts +16 -0
- package/dist/instance.d.ts.map +1 -0
- package/dist/instance.js +30 -0
- package/dist/instance.js.map +1 -0
- package/dist/local_vars.d.ts +75 -0
- package/dist/local_vars.d.ts.map +1 -0
- package/dist/local_vars.js +92 -0
- package/dist/local_vars.js.map +1 -0
- package/dist/minify.d.ts +11 -0
- package/dist/minify.d.ts.map +1 -0
- package/dist/minify.js +73 -0
- package/dist/minify.js.map +1 -0
- package/dist/names.d.ts +39 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +70 -0
- package/dist/names.js.map +1 -0
- package/dist/nesting.d.ts +59 -0
- package/dist/nesting.d.ts.map +1 -0
- package/dist/nesting.js +400 -0
- package/dist/nesting.js.map +1 -0
- package/dist/runtime.d.ts +36 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +252 -0
- package/dist/runtime.js.map +1 -0
- package/dist/styles/authoring.d.ts +59 -0
- package/dist/styles/authoring.d.ts.map +1 -0
- package/dist/styles/authoring.js +155 -0
- package/dist/styles/authoring.js.map +1 -0
- package/dist/styles/declarations.d.ts +10 -0
- package/dist/styles/declarations.d.ts.map +1 -0
- package/dist/styles/declarations.js +132 -0
- package/dist/styles/declarations.js.map +1 -0
- package/dist/styles/index.d.ts +7 -0
- package/dist/styles/index.d.ts.map +1 -0
- package/dist/styles/index.js +12 -0
- package/dist/styles/index.js.map +1 -0
- package/dist/styles/module.d.ts +5 -0
- package/dist/styles/module.d.ts.map +1 -0
- package/dist/styles/module.js +229 -0
- package/dist/styles/module.js.map +1 -0
- package/dist/styles/registry.d.ts +48 -0
- package/dist/styles/registry.d.ts.map +1 -0
- package/dist/styles/registry.js +182 -0
- package/dist/styles/registry.js.map +1 -0
- package/dist/styles/types.d.ts +211 -0
- package/dist/styles/types.d.ts.map +1 -0
- package/dist/styles/types.js +8 -0
- package/dist/styles/types.js.map +1 -0
- package/dist/testing.d.ts +10 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +31 -0
- package/dist/testing.js.map +1 -0
- package/dist/theme.d.ts +85 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +240 -0
- package/dist/theme.js.map +1 -0
- package/dist/tokens/contextual_var.d.ts +35 -0
- package/dist/tokens/contextual_var.d.ts.map +1 -0
- package/dist/tokens/contextual_var.js +33 -0
- package/dist/tokens/contextual_var.js.map +1 -0
- package/dist/tokens/index.d.ts +5 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +11 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/kind.d.ts +2 -0
- package/dist/tokens/kind.d.ts.map +1 -0
- package/dist/tokens/kind.js +10 -0
- package/dist/tokens/kind.js.map +1 -0
- package/dist/tokens/light_dark.d.ts +20 -0
- package/dist/tokens/light_dark.d.ts.map +1 -0
- package/dist/tokens/light_dark.js +37 -0
- package/dist/tokens/light_dark.js.map +1 -0
- package/dist/tokens/scale_token.d.ts +20 -0
- package/dist/tokens/scale_token.d.ts.map +1 -0
- package/dist/tokens/scale_token.js +23 -0
- package/dist/tokens/scale_token.js.map +1 -0
- package/dist/tokens/theme_token.d.ts +20 -0
- package/dist/tokens/theme_token.d.ts.map +1 -0
- package/dist/tokens/theme_token.js +23 -0
- package/dist/tokens/theme_token.js.map +1 -0
- package/dist/var_invariant.d.ts +25 -0
- package/dist/var_invariant.d.ts.map +1 -0
- package/dist/var_invariant.js +108 -0
- package/dist/var_invariant.js.map +1 -0
- package/docs/concepts/authoring.md +115 -0
- package/docs/concepts/collection.md +66 -0
- package/docs/concepts/distillery.md +47 -0
- package/docs/concepts/index.md +18 -0
- package/docs/concepts/naming-and-output.md +123 -0
- package/docs/concepts/ordering.md +61 -0
- package/docs/concepts/single-copy.md +103 -0
- package/docs/concepts/tokens.md +99 -0
- package/docs/docset.yml +53 -0
- package/docs/examples/01-stylesheet.ts +20 -0
- package/docs/examples/02-artifact.ts +26 -0
- package/docs/examples/03-variants.ts +40 -0
- package/docs/examples/04-emotion.ts +33 -0
- package/docs/examples/05-var-invariant.ts +31 -0
- package/docs/examples/06-payload.ts +85 -0
- package/docs/examples/fixture.ts +22 -0
- package/docs/getting-started/index.md +14 -0
- package/docs/getting-started/installation.md +30 -0
- package/docs/getting-started/quick-start.md +61 -0
- package/docs/getting-started/your-first-stylesheet.md +57 -0
- package/docs/guides/compact-artifacts.md +87 -0
- package/docs/guides/emotion-migration.md +60 -0
- package/docs/guides/index.md +17 -0
- package/docs/guides/name-collisions.md +37 -0
- package/docs/guides/non-css-surfaces.md +73 -0
- package/docs/guides/react-renderer.md +158 -0
- package/docs/guides/theming.md +107 -0
- package/docs/guides/var-invariant.md +24 -0
- package/docs/guides/vs-emotion.md +61 -0
- package/docs/index.md +73 -0
- package/docs/logo.svg +7 -0
- package/docs/playground/index.html +12 -0
- package/docs/playground/package.json +23 -0
- package/docs/playground/src/app/app.tsx +109 -0
- package/docs/playground/src/app/css_panel.tsx +119 -0
- package/docs/playground/src/app/editor_panel.tsx +87 -0
- package/docs/playground/src/app/index.ts +8 -0
- package/docs/playground/src/app/monaco_css_editor.tsx +84 -0
- package/docs/playground/src/app/monaco_source_editor.tsx +132 -0
- package/docs/playground/src/app/preview_panel.tsx +99 -0
- package/docs/playground/src/app/tokens_panel.tsx +117 -0
- package/docs/playground/src/app/types.ts +10 -0
- package/docs/playground/src/examples/snippets.test.ts +28 -0
- package/docs/playground/src/examples/snippets.ts +418 -0
- package/docs/playground/src/lib/compile.test.ts +157 -0
- package/docs/playground/src/lib/compile.ts +242 -0
- package/docs/playground/src/lib/demo_environment.test.ts +123 -0
- package/docs/playground/src/lib/demo_environment.ts +140 -0
- package/docs/playground/src/lib/editor_lib.test.ts +39 -0
- package/docs/playground/src/lib/editor_lib.ts +142 -0
- package/docs/playground/src/lib/format_css.test.ts +41 -0
- package/docs/playground/src/lib/format_css.ts +71 -0
- package/docs/playground/src/main.tsx +25 -0
- package/docs/playground/src/setup/chrome.test.ts +47 -0
- package/docs/playground/src/setup/chrome.ts +365 -0
- package/docs/playground/src/setup/monaco_env.ts +64 -0
- package/docs/playground/tsconfig.json +22 -0
- package/docs/playground/vite.config.ts +37 -0
- package/docs/playground/vitest.config.ts +35 -0
- package/docs/playground.md +28 -0
- package/docs/reference/api/emotion.md +372 -0
- package/docs/reference/api/index-1.md +2180 -0
- package/docs/reference/api/index.md +9 -0
- package/docs/reference/api/testing.md +92 -0
- package/docs/reference/api.md +12 -0
- package/docs/reference/entry-points.md +125 -0
- package/docs/reference/environment.md +60 -0
- package/docs/reference/index.md +11 -0
- package/docs/reference/okf-map.md +92 -0
- package/package.json +127 -4
- package/src/collector.ts +526 -0
- package/src/css_scan.ts +263 -0
- package/src/dom_sink.ts +65 -0
- package/src/emotion.ts +311 -0
- package/src/engine.ts +191 -0
- package/src/environment.ts +56 -0
- package/src/hash.ts +111 -0
- package/src/idents.ts +21 -0
- package/src/index.ts +93 -0
- package/src/instance.ts +49 -0
- package/src/local_vars.ts +220 -0
- package/src/minify.ts +87 -0
- package/src/names.ts +129 -0
- package/src/nesting.ts +596 -0
- package/src/runtime.ts +428 -0
- package/src/styles/authoring.ts +244 -0
- package/src/styles/declarations.ts +172 -0
- package/src/styles/index.ts +58 -0
- package/src/styles/module.ts +396 -0
- package/src/styles/registry.ts +261 -0
- package/src/styles/types.ts +283 -0
- package/src/testing.ts +48 -0
- package/src/theme.ts +454 -0
- package/src/tokens/contextual_var.ts +72 -0
- package/src/tokens/index.ts +17 -0
- package/src/tokens/kind.ts +13 -0
- package/src/tokens/light_dark.ts +58 -0
- package/src/tokens/scale_token.ts +41 -0
- package/src/tokens/theme_token.ts +42 -0
- package/src/var_invariant.ts +147 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
navigation_title: Single-copy invariant
|
|
3
|
+
description: Exactly one copy of Distillate may load at runtime.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Single-copy invariant
|
|
7
|
+
|
|
8
|
+
The engine keeps module-scope state:
|
|
9
|
+
|
|
10
|
+
- A `WeakSet` of values produced inside `variants(...)`, so `collector.use(module)` can skip them.
|
|
11
|
+
- A `WeakMap` from module to dependent-entry lists, so auto-collection does not walk the whole registry per handle.
|
|
12
|
+
- Per-registry emotion caches (template wrappers, sinks).
|
|
13
|
+
|
|
14
|
+
Two copies of the module mean two caches. Variants from copy A look unmarked to copy B's collector, so they ship in every artifact and inflate CSS. That reads as a payload regression, not a throw.
|
|
15
|
+
|
|
16
|
+
## What the package does
|
|
17
|
+
|
|
18
|
+
On import, `src/instance.ts` stores a random identity token on `globalThis[Symbol.for('elastic.distillate.instance')]`. A later import with a different token logs a `console.warn`. It warns rather than throws because two copies degrade output without breaking it. A reload (HMR, a fresh vitest registry) also mints a new token, so a warning is not proof of two physical packages.
|
|
19
|
+
|
|
20
|
+
The package `sideEffects` field lists `**/instance.ts` and `**/instance.js` so bundlers do not tree-shake the guard away.
|
|
21
|
+
|
|
22
|
+
## What consumers must do
|
|
23
|
+
|
|
24
|
+
Do not nest a second version of `@elastic/distillate` in an app's `node_modules`. When a **library** bundles, mark Distillate external so the app supplies the one copy. When an **app** bundles, force every importer to resolve the copy at the project root.
|
|
25
|
+
|
|
26
|
+
### Vite
|
|
27
|
+
|
|
28
|
+
`ssr.external` leaves Distillate out of the SSR bundle (Node loads the package once). `resolve.dedupe` makes client and SSR resolve the same physical directory. `build.rollupOptions.external` is for library builds; do not set it in an app that must ship Distillate to the browser.
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { defineConfig } from 'vite';
|
|
32
|
+
|
|
33
|
+
export default defineConfig({
|
|
34
|
+
resolve: {
|
|
35
|
+
dedupe: ['@elastic/distillate'],
|
|
36
|
+
},
|
|
37
|
+
ssr: {
|
|
38
|
+
external: [
|
|
39
|
+
'@elastic/distillate',
|
|
40
|
+
'@elastic/distillate/emotion',
|
|
41
|
+
'@elastic/distillate/testing',
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
// Library packages only — omit this block in an application:
|
|
45
|
+
build: {
|
|
46
|
+
rollupOptions: {
|
|
47
|
+
external: ['@elastic/distillate', /^@elastic\/distillate\//],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Rollup (library)
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
export default {
|
|
57
|
+
external: ['@elastic/distillate', /^@elastic\/distillate\//],
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### webpack
|
|
62
|
+
|
|
63
|
+
Library:
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
module.exports = {
|
|
67
|
+
externals: {
|
|
68
|
+
'@elastic/distillate': '@elastic/distillate',
|
|
69
|
+
'@elastic/distillate/emotion': '@elastic/distillate/emotion',
|
|
70
|
+
'@elastic/distillate/testing': '@elastic/distillate/testing',
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
App — pin every importer to the hoisted package:
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
module.exports = {
|
|
79
|
+
resolve: {
|
|
80
|
+
alias: {
|
|
81
|
+
'@elastic/distillate$': require.resolve('@elastic/distillate'),
|
|
82
|
+
'@elastic/distillate/emotion$': require.resolve(
|
|
83
|
+
'@elastic/distillate/emotion'
|
|
84
|
+
),
|
|
85
|
+
'@elastic/distillate/testing$': require.resolve(
|
|
86
|
+
'@elastic/distillate/testing'
|
|
87
|
+
),
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Plugin-host architectures
|
|
94
|
+
|
|
95
|
+
In a platform where many independently built plugins share one runtime (Kibana-style), the platform — not any individual plugin — must own the single copy. Declare Distillate as a **platform-provided shared dependency** (similar to how `react` and `react-dom` are shared), and configure each plugin build to externalize all three entry points. A plugin that bundles its own copy will silently inflate every artifact it emits and break variant tree-shaking across the module boundary.
|
|
96
|
+
|
|
97
|
+
## Dual-package hazard
|
|
98
|
+
|
|
99
|
+
The package is published as ESM (`dist/`, reached through the `import` export condition) with a parallel CommonJS build (`dist/cjs/`, reached through `require`) so hosts that transpile to CommonJS — a Kibana-style server plugin, for instance — can `require('@elastic/distillate')` without hitting Node's `ERR_REQUIRE_ESM`. Both builds compile from the same `src/`, but they are two physically distinct sets of files.
|
|
100
|
+
|
|
101
|
+
That reintroduces the single-copy problem one level up: if one importer in a process reaches the package through `import` and another reaches it through `require`, Node loads **both** builds, each with its own module-scope state and its own identity token. This is the same failure mode as two copies in `node_modules`, described above — a `console.warn`, not a crash, and it silently inflates artifact CSS because variants from one build look unmarked to the other build's collector.
|
|
102
|
+
|
|
103
|
+
This is a real risk specifically where a host mixes module systems for the same dependency — for example, a plugin-host platform where some plugins bundle Distillate via `import` and others load it via `require`. It is not a risk merely because both `dist/` and `dist/cjs/` exist on disk; a consistent toolchain resolves to exactly one of them. Pick one export condition for a given runtime and keep every importer on it — the platform-external, dedupe, and alias configuration above pins the *physical directory*; it does not by itself prevent a second, differently-loaded copy of that directory if some other part of the same process resolves the package through the other condition.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
navigation_title: Tokens and vars
|
|
3
|
+
description: Theme trees, lightDark, cq, contextualVar, and module-local vars groups.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Tokens and vars
|
|
7
|
+
|
|
8
|
+
Author a nested value tree. `createDistillery` derives `CssToken` / `ScaleToken` leaves and the `themeVars` registry. Branded values stringify through `Symbol.toPrimitive`, which is why they interpolate into tagged templates.
|
|
9
|
+
|
|
10
|
+
## Theme tokens
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
const distillery = createDistillery({
|
|
14
|
+
prefix: 'eui',
|
|
15
|
+
themeScope: '.eui-view',
|
|
16
|
+
theme: {
|
|
17
|
+
colors: {
|
|
18
|
+
ink: lightDark('#111', '#eee'),
|
|
19
|
+
warning: '#FACB3D',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
const { ink } = distillery.tokens.colors;
|
|
24
|
+
String(ink); <1>
|
|
25
|
+
ink.cssVar; <2>
|
|
26
|
+
ink.path; <3>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
1. Interpolates as `var(--eui-colors-ink)`. This is what tagged templates splice in.
|
|
30
|
+
2. Custom-property name: `--eui-colors-ink`.
|
|
31
|
+
3. Slash path matching `themeVars` keys: `colors/ink`.
|
|
32
|
+
|
|
33
|
+
A string leaf is scheme-invariant (`light === dark`). `lightDark(light, dark)` is scheme-varying and both sides must be CSS `<color>` values. Emission uses `light-dark(light, dark)` when the two values differ. Unread theme tokens are pruned from the theme block.
|
|
34
|
+
|
|
35
|
+
`zipSchemes(light, dark)` folds two per-scheme trees into this form: equal strings stay bare, differing strings become `lightDark`, and `ScaleToken` leaves must agree.
|
|
36
|
+
|
|
37
|
+
Named variations go on `variations` in `createDistillery`. Declaring a variation does not emit it; name it at `renderStyles` with `{ flatten }` or `{ alternates }`. Variations extend the base only. `ScaleToken` leaves must match the base because they inline and cannot vary. See [declare and select variations](../guides/theming.md).
|
|
38
|
+
|
|
39
|
+
`themeToken(path, cssVar)` remains the constructor derivation calls. Paths are slash-delimited (`colors/ink`), matching `themeVars` keys.
|
|
40
|
+
|
|
41
|
+
A surface that cannot resolve `var(--x)` (a headless SVG rasterizer, for example) should call `distillery.resolveValues(scheme, variation?)` instead of walking `themeVars` by hand. That walk returns nested literal strings for one scheme, including `ScaleToken.value`. A surface that still wants the stylesheet, but has no color scheme for `light-dark()` to resolve against, passes `{ scheme }` to `renderStyles`. See [read values outside CSS](../guides/non-css-surfaces.md).
|
|
42
|
+
|
|
43
|
+
The `chip` module below uses `tokens.colors.surface` from the [quick start](../getting-started/quick-start.md) token tree.
|
|
44
|
+
|
|
45
|
+
## Scale tokens
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const gap = cq('8px', '2cqi');
|
|
49
|
+
String(gap); <1>
|
|
50
|
+
gap.cq; <2>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
1. Inlines as `8px`. No custom property, nothing to prune.
|
|
54
|
+
2. Container-relative value: `2cqi`. Use this when the declaration should track container size.
|
|
55
|
+
|
|
56
|
+
`cq` is an alias of `scaleToken`.
|
|
57
|
+
|
|
58
|
+
## Shared contextual vars
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const foreground = contextualVar(
|
|
62
|
+
'vars/app/tone/foreground',
|
|
63
|
+
'--eui-app-tone-foreground'
|
|
64
|
+
);
|
|
65
|
+
String(foreground); <1>
|
|
66
|
+
String(foreground.name); <2>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
1. Interpolating the var **reads** it: `var(--eui-app-tone-foreground)`.
|
|
70
|
+
2. Writing `.name` **declares** the property: `--eui-app-tone-foreground`.
|
|
71
|
+
|
|
72
|
+
Register the path in `sharedVars` so two modules can share the name without either owning it.
|
|
73
|
+
|
|
74
|
+
## Module-local `vars`
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const chip = distillery.createStyleModule('chip', ({ css, tokens, vars }) => {
|
|
78
|
+
const look = vars('look', {
|
|
79
|
+
bg: tokens.colors.surface,
|
|
80
|
+
unusedBorder: tokens.colors.accent, <1>
|
|
81
|
+
});
|
|
82
|
+
return {
|
|
83
|
+
root: css`
|
|
84
|
+
${look} <2>
|
|
85
|
+
background: ${look.bg}; <3>
|
|
86
|
+
`,
|
|
87
|
+
loud: css`
|
|
88
|
+
${look.set({ bg: tokens.colors.accent })} <4>
|
|
89
|
+
`,
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
1. Never referenced, so this key is pruned — and so is the `colors.accent` default it would have pulled in.
|
|
95
|
+
2. Emits default declarations (`--eui-chip-look-bg: var(--eui-colors-surface)`).
|
|
96
|
+
3. Reads the var.
|
|
97
|
+
4. Override on this handle. Override entries emit after defaults, so stacking `root` and the modifier class wins.
|
|
98
|
+
|
|
99
|
+
Local-var names are `cssVarName(prefix, path)` (`--${prefix}-${module}-${group}-${key}`). A collision with a theme or shared var throws at module construction. See [name collisions](../guides/name-collisions.md).
|
package/docs/docset.yml
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
2
|
+
# or more contributor license agreements. Licensed under the Elastic License
|
|
3
|
+
# 2.0; you may not use this file except in compliance with the Elastic License
|
|
4
|
+
# 2.0.
|
|
5
|
+
|
|
6
|
+
project: 'Distillate'
|
|
7
|
+
# Internal Codex publication needs a `registry:` environment name and a
|
|
8
|
+
# `codex.group` from the docs team. Those values are not public; leave them
|
|
9
|
+
# unset until onboarding. Isolated GitHub Pages builds do not need them.
|
|
10
|
+
# Vite playground, its description page, and executable fixtures live under `docs/` but are not pages.
|
|
11
|
+
exclude:
|
|
12
|
+
- playground/**
|
|
13
|
+
- playground.md
|
|
14
|
+
- examples/**
|
|
15
|
+
toc:
|
|
16
|
+
- file: index.md
|
|
17
|
+
- folder: getting-started
|
|
18
|
+
children:
|
|
19
|
+
- file: index.md
|
|
20
|
+
- file: installation.md
|
|
21
|
+
- file: quick-start.md
|
|
22
|
+
- file: your-first-stylesheet.md
|
|
23
|
+
- folder: concepts
|
|
24
|
+
children:
|
|
25
|
+
- file: index.md
|
|
26
|
+
- file: distillery.md
|
|
27
|
+
- file: tokens.md
|
|
28
|
+
- file: authoring.md
|
|
29
|
+
- file: collection.md
|
|
30
|
+
- file: naming-and-output.md
|
|
31
|
+
- file: ordering.md
|
|
32
|
+
- file: single-copy.md
|
|
33
|
+
- folder: guides
|
|
34
|
+
children:
|
|
35
|
+
- file: index.md
|
|
36
|
+
- file: vs-emotion.md
|
|
37
|
+
- file: theming.md
|
|
38
|
+
- file: non-css-surfaces.md
|
|
39
|
+
- file: compact-artifacts.md
|
|
40
|
+
- file: react-renderer.md
|
|
41
|
+
- file: emotion-migration.md
|
|
42
|
+
- file: var-invariant.md
|
|
43
|
+
- file: name-collisions.md
|
|
44
|
+
- folder: reference
|
|
45
|
+
children:
|
|
46
|
+
- file: index.md
|
|
47
|
+
- file: entry-points.md
|
|
48
|
+
- file: environment.md
|
|
49
|
+
- file: api.md
|
|
50
|
+
- folder: api
|
|
51
|
+
- file: okf-map.md
|
|
52
|
+
subs:
|
|
53
|
+
pkg: '@elastic/distillate'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
3
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
4
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
5
|
+
* 2.0.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createExampleDistillery } from './fixture';
|
|
9
|
+
|
|
10
|
+
/** Emits the full readable stylesheet for every registered module. */
|
|
11
|
+
export const run = (): string => {
|
|
12
|
+
const distillery = createExampleDistillery();
|
|
13
|
+
distillery.createStyleModule('demo', ({ css, tokens }) => ({
|
|
14
|
+
root: css`
|
|
15
|
+
color: ${tokens.colors.ink};
|
|
16
|
+
padding: ${tokens.gap};
|
|
17
|
+
`,
|
|
18
|
+
}));
|
|
19
|
+
return distillery.renderStyles(distillery.stylesheetCollector());
|
|
20
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
3
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
4
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
5
|
+
* 2.0.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createExampleDistillery } from './fixture';
|
|
9
|
+
|
|
10
|
+
/** Collects one handle and emits a compact, self-contained payload. */
|
|
11
|
+
export const run = (): string => {
|
|
12
|
+
const distillery = createExampleDistillery();
|
|
13
|
+
const demo = distillery.createStyleModule('demo', ({ css, tokens }) => ({
|
|
14
|
+
root: css`
|
|
15
|
+
color: ${tokens.colors.ink};
|
|
16
|
+
padding: ${tokens.gap};
|
|
17
|
+
`,
|
|
18
|
+
unused: css`
|
|
19
|
+
color: ${tokens.colors.accent};
|
|
20
|
+
`,
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
const collector = distillery.artifactCollector('compact');
|
|
24
|
+
collector.use(demo.handles.root);
|
|
25
|
+
return distillery.renderStyles(collector);
|
|
26
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
3
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
4
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
5
|
+
* 2.0.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { variants } from '../../src/index';
|
|
9
|
+
|
|
10
|
+
import { createExampleDistillery } from './fixture';
|
|
11
|
+
|
|
12
|
+
export interface VariantExample {
|
|
13
|
+
readonly withoutVariants: string;
|
|
14
|
+
readonly withLoud: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Variant entries stay off always-on collection until a handle is named. */
|
|
18
|
+
export const run = (): VariantExample => {
|
|
19
|
+
const distillery = createExampleDistillery();
|
|
20
|
+
const demo = distillery.createStyleModule('toned', ({ css, tokens }) => ({
|
|
21
|
+
root: css`
|
|
22
|
+
color: ${tokens.colors.ink};
|
|
23
|
+
`,
|
|
24
|
+
tone: variants(
|
|
25
|
+
['calm', 'loud'] as const,
|
|
26
|
+
(tone) => css`
|
|
27
|
+
outline-color: ${tone === 'calm' ? tokens.colors.surface : tokens.colors.accent};
|
|
28
|
+
`
|
|
29
|
+
),
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
const collector = distillery.artifactCollector('readable');
|
|
33
|
+
collector.use(demo);
|
|
34
|
+
const withoutVariants = distillery.renderStyles(collector);
|
|
35
|
+
|
|
36
|
+
collector.useHandles([demo.handles.tone.loud]);
|
|
37
|
+
const withLoud = distillery.renderStyles(collector);
|
|
38
|
+
|
|
39
|
+
return { withoutVariants, withLoud };
|
|
40
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
3
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
4
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
5
|
+
* 2.0.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createEmotion } from '../../src/emotion';
|
|
9
|
+
|
|
10
|
+
import { createExampleDistillery } from './fixture';
|
|
11
|
+
|
|
12
|
+
export interface EmotionExample {
|
|
13
|
+
readonly className: string;
|
|
14
|
+
readonly stylesheet: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Emotion-shaped authoring over the same distillery. */
|
|
18
|
+
export const run = (): EmotionExample => {
|
|
19
|
+
const distillery = createExampleDistillery();
|
|
20
|
+
const emotion = createEmotion(distillery);
|
|
21
|
+
const { colors, gap } = distillery.tokens;
|
|
22
|
+
const { ink, accent } = colors;
|
|
23
|
+
const card = emotion.css`
|
|
24
|
+
color: ${ink};
|
|
25
|
+
&:hover {
|
|
26
|
+
color: ${accent};
|
|
27
|
+
}
|
|
28
|
+
@media (min-width: 600px) {
|
|
29
|
+
padding: ${gap};
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
return { className: String(card), stylesheet: emotion.stylesheet() };
|
|
33
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
3
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
4
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
5
|
+
* 2.0.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
assertVarRefsHaveDeclarations,
|
|
10
|
+
findVarRefViolations,
|
|
11
|
+
} from '../../src/testing';
|
|
12
|
+
|
|
13
|
+
import { createExampleDistillery } from './fixture';
|
|
14
|
+
|
|
15
|
+
export interface VarInvariantExample {
|
|
16
|
+
readonly css: string;
|
|
17
|
+
readonly violationCount: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Checks that every `var(...)` in emitted CSS has a matching declaration. */
|
|
21
|
+
export const run = (): VarInvariantExample => {
|
|
22
|
+
const distillery = createExampleDistillery();
|
|
23
|
+
distillery.createStyleModule('demo', ({ css, tokens }) => ({
|
|
24
|
+
root: css`
|
|
25
|
+
color: ${tokens.colors.ink};
|
|
26
|
+
`,
|
|
27
|
+
}));
|
|
28
|
+
const css = distillery.renderStyles(distillery.stylesheetCollector());
|
|
29
|
+
assertVarRefsHaveDeclarations(css);
|
|
30
|
+
return { css, violationCount: findVarRefViolations(css).length };
|
|
31
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
3
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
4
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
5
|
+
* 2.0.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { variants } from '../../src/index';
|
|
9
|
+
|
|
10
|
+
import { createExampleDistillery } from './fixture';
|
|
11
|
+
|
|
12
|
+
export interface PayloadExample {
|
|
13
|
+
readonly stylesheet: string;
|
|
14
|
+
readonly artifact: string;
|
|
15
|
+
readonly stylesheetBytes: number;
|
|
16
|
+
readonly artifactBytes: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const utf8Bytes = (css: string): number =>
|
|
20
|
+
new TextEncoder().encode(css).byteLength;
|
|
21
|
+
|
|
22
|
+
/** Full readable stylesheet versus a compact artifact from one named render. */
|
|
23
|
+
export const run = (): PayloadExample => {
|
|
24
|
+
const distillery = createExampleDistillery();
|
|
25
|
+
const panel = distillery.createStyleModule(
|
|
26
|
+
'panel',
|
|
27
|
+
({ css, tokens, vars }) => {
|
|
28
|
+
const look = vars('look', {
|
|
29
|
+
bg: tokens.colors.surface,
|
|
30
|
+
fg: tokens.colors.ink,
|
|
31
|
+
ring: tokens.colors.accent,
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
root: css`
|
|
35
|
+
${look}
|
|
36
|
+
display: grid;
|
|
37
|
+
gap: ${tokens.gap};
|
|
38
|
+
padding: ${tokens.gap};
|
|
39
|
+
background: ${look.bg};
|
|
40
|
+
color: ${look.fg};
|
|
41
|
+
`,
|
|
42
|
+
title: css`
|
|
43
|
+
margin: 0;
|
|
44
|
+
color: ${tokens.colors.accent};
|
|
45
|
+
`,
|
|
46
|
+
tone: variants(['calm', 'loud', 'danger'] as const, (tone) => {
|
|
47
|
+
if (tone === 'calm') {
|
|
48
|
+
return css`
|
|
49
|
+
outline-color: ${tokens.colors.surface};
|
|
50
|
+
`;
|
|
51
|
+
}
|
|
52
|
+
if (tone === 'loud') {
|
|
53
|
+
return css`
|
|
54
|
+
${look}
|
|
55
|
+
outline-color: ${look.ring};
|
|
56
|
+
outline-width: ${tokens.gap};
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
return css`
|
|
60
|
+
outline-color: ${tokens.colors.ink};
|
|
61
|
+
background: ${tokens.colors.accent};
|
|
62
|
+
color: ${tokens.colors.surface};
|
|
63
|
+
`;
|
|
64
|
+
}),
|
|
65
|
+
footer: css`
|
|
66
|
+
color: ${tokens.colors.accent};
|
|
67
|
+
padding: ${tokens.gap};
|
|
68
|
+
border-color: ${tokens.colors.ink};
|
|
69
|
+
`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const stylesheet = distillery.renderStyles(distillery.stylesheetCollector());
|
|
75
|
+
const collector = distillery.artifactCollector('compact');
|
|
76
|
+
collector.useHandles([panel.handles.root, panel.handles.tone.calm]);
|
|
77
|
+
const artifact = distillery.renderStyles(collector);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
stylesheet,
|
|
81
|
+
artifact,
|
|
82
|
+
stylesheetBytes: utf8Bytes(stylesheet),
|
|
83
|
+
artifactBytes: utf8Bytes(artifact),
|
|
84
|
+
};
|
|
85
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
3
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
4
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
5
|
+
* 2.0.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { cq, createDistillery, lightDark } from '../../src/index';
|
|
9
|
+
|
|
10
|
+
export const createExampleDistillery = () =>
|
|
11
|
+
createDistillery({
|
|
12
|
+
prefix: 'eui',
|
|
13
|
+
themeScope: '.eui-view',
|
|
14
|
+
theme: {
|
|
15
|
+
colors: {
|
|
16
|
+
ink: lightDark('#111', '#eee'),
|
|
17
|
+
accent: lightDark('#06c', '#8cf'),
|
|
18
|
+
surface: lightDark('#fff', '#000'),
|
|
19
|
+
},
|
|
20
|
+
gap: cq('8px', '2cqi'),
|
|
21
|
+
},
|
|
22
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
navigation_title: Getting started
|
|
3
|
+
description: Install Distillate and emit your first stylesheet.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Getting started
|
|
7
|
+
|
|
8
|
+
{{pkg}} targets Node.js 20 and later, published as ESM with a parallel CommonJS build for hosts that can only `require(...)`. Three pages get a library bound and emitting CSS:
|
|
9
|
+
|
|
10
|
+
- [Installation](installation.md)
|
|
11
|
+
- [Quick start](quick-start.md)
|
|
12
|
+
- [Your first stylesheet](your-first-stylesheet.md)
|
|
13
|
+
|
|
14
|
+
After that, read [the distillery](../concepts/distillery.md) and [naming and output](../concepts/naming-and-output.md), or try the [playground](https://elastic.github.io/distillate/playground/).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
navigation_title: Installation
|
|
3
|
+
description: Add Distillate to a project.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Installation
|
|
7
|
+
|
|
8
|
+
The only supported install is the published package on the public npm registry:
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install @elastic/distillate
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
pnpm and yarn work the same way (`pnpm add @elastic/distillate`). The package declares `engines.node` `>=20`. Git URL installs, GitHub Packages, and GitHub Release tarballs are not supported.
|
|
15
|
+
|
|
16
|
+
The primary build is ESM (`"type": "module"`), reached through the `import` export condition. A parallel CommonJS build is published under the `require` condition for hosts whose loader cannot use ESM — for example a plugin-host platform (Kibana-style) whose server code is transpiled to CommonJS and calls `require(...)` rather than `import`. Bundlers and Node's own resolver pick whichever condition matches automatically; you do not select one yourself. See [dual-package hazard](../concepts/single-copy.md#dual-package-hazard) for the one thing this adds to watch for.
|
|
17
|
+
|
|
18
|
+
## Entry points
|
|
19
|
+
|
|
20
|
+
| Specifier | Use |
|
|
21
|
+
| ----------------------------- | ------------------------------------------------ |
|
|
22
|
+
| `@elastic/distillate` | Engine, authoring, tokens, collector, renderer. |
|
|
23
|
+
| `@elastic/distillate/emotion` | `createEmotion`, `createDomSink`. |
|
|
24
|
+
| `@elastic/distillate/testing` | Var-invariant helpers. Does not import `stylis`. |
|
|
25
|
+
|
|
26
|
+
The root and emotion entries both reach `stylis@4.4.0`. Do not hoist a different stylis version; nested templates walk a pinned `compile()` tree shape.
|
|
27
|
+
|
|
28
|
+
## Bundlers
|
|
29
|
+
|
|
30
|
+
Exactly one copy of `@elastic/distillate` may load. Two copies break `variants(...)` tree-shaking. Library builds should list it as an external; apps should dedupe to the project-root install. Vite, Rollup, and webpack snippets: [single-copy invariant](../concepts/single-copy.md).
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
navigation_title: Quick start
|
|
3
|
+
description: Bind an environment, author a module, and emit CSS.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Quick start
|
|
7
|
+
|
|
8
|
+
Three calls cover the happy path: bind, author, emit.
|
|
9
|
+
|
|
10
|
+
## Bind
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { createDistillery, cq, lightDark } from '@elastic/distillate';
|
|
14
|
+
|
|
15
|
+
const distillery = createDistillery({
|
|
16
|
+
prefix: 'eui',
|
|
17
|
+
themeScope: '.eui-view',
|
|
18
|
+
theme: {
|
|
19
|
+
colors: {
|
|
20
|
+
ink: lightDark('#111', '#eee'),
|
|
21
|
+
accent: lightDark('#06c', '#8cf'),
|
|
22
|
+
surface: lightDark('#fff', '#000'),
|
|
23
|
+
},
|
|
24
|
+
gap: cq('8px', '2cqi'),
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`prefix` must be a CSS identifier segment. `themeScope` is the selector that wraps emitted theme-variable declarations. Theme-tree keys match `/^[A-Za-z_][A-Za-z0-9_]*$/`. Strings and `lightDark` leaves become theme vars named `cssVarName(prefix, path)`; `cq` / `scaleToken` leaves inline. Differing `lightDark` values fold into `light-dark(...)`.
|
|
30
|
+
|
|
31
|
+
## Author
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const demo = distillery.createStyleModule('demo', ({ css, tokens }) => ({
|
|
35
|
+
root: css`
|
|
36
|
+
color: ${tokens.colors.ink}; <1>
|
|
37
|
+
padding: ${tokens.gap}; <2>
|
|
38
|
+
`,
|
|
39
|
+
}));
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
1. Theme token: records a dependency, emits `var(--eui-colors-ink)`.
|
|
43
|
+
2. Scale token: inlines `8px`.
|
|
44
|
+
|
|
45
|
+
## Emit
|
|
46
|
+
|
|
47
|
+
A full readable stylesheet:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
distillery.renderStyles(distillery.stylesheetCollector()); // readable: .demo-root, --eui-colors-ink
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
A compact artifact that includes only `demo.handles.root`:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const collector = distillery.artifactCollector('compact');
|
|
57
|
+
collector.use(demo.handles.root); // unused handles and tokens drop out
|
|
58
|
+
distillery.renderStyles(collector); // compact: .a, --a
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Those outputs are asserted in [`docs/examples/`](https://github.com/elastic/distillate/tree/main/docs/examples). Next: [your first stylesheet](your-first-stylesheet.md), [declare and select variations](../guides/theming.md), or skip to [naming and output](../concepts/naming-and-output.md).
|