@keyfunc/keybricks-ds 1.0.1 → 1.0.2
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/INTEGRATION.md +24 -1
- package/_scripts/build-tokens.mjs +3 -3
- package/components/_shared/frame-theme.js +5 -0
- package/package.json +1 -1
- package/tokens/alpha.css +0 -4
- package/tokens/charts.css +0 -6
- package/tokens/colors-extended.css +0 -1
- package/tokens/dark.css +4 -46
- package/tokens/interaction.css +0 -1
- package/tokens/theme.js +11 -0
- package/tokens/tokens.d.ts +1 -1
- package/tokens/tokens.js +1 -1
- package/tokens/tokens.json +2 -2
package/INTEGRATION.md
CHANGED
|
@@ -346,7 +346,30 @@ the CSS.
|
|
|
346
346
|
|
|
347
347
|
## Dark mode
|
|
348
348
|
|
|
349
|
-
|
|
349
|
+
Three states, decided by the `data-theme` attribute on `<html>`:
|
|
350
|
+
|
|
351
|
+
| `<html data-theme>` | Result |
|
|
352
|
+
| --- | --- |
|
|
353
|
+
| *(absent)* | light — or the OS preference, if `tokens/theme.js` is loaded |
|
|
354
|
+
| `"dark"` | dark, regardless of the OS |
|
|
355
|
+
| `"light"` | light, regardless of the OS |
|
|
356
|
+
|
|
357
|
+
```js
|
|
358
|
+
document.documentElement.dataset.theme = 'light' // or 'dark'; delete it to follow the OS
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
The stylesheet reads only the attribute — there is deliberately no `@media (prefers-color-scheme)`
|
|
362
|
+
in the tokens, because an OS media query on `:root` cannot be overridden by an attribute. To
|
|
363
|
+
follow the OS, load the bootstrap in `<head>` **before** `styles.css`:
|
|
364
|
+
|
|
365
|
+
```html
|
|
366
|
+
<script src="@keyfunc/keybricks-ds/tokens/theme.js"></script>
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
It stamps `data-theme` from the OS only when nothing is set, tracks OS changes live, and steps
|
|
370
|
+
aside the moment your app sets the attribute itself. Persist the user's choice yourself and
|
|
371
|
+
apply it before this script runs to avoid a flash.
|
|
372
|
+
|
|
350
373
|
If you build custom UI beside Keybricks components, reference the same semantic tokens and
|
|
351
374
|
it will flip for free. Two things to watch:
|
|
352
375
|
|
|
@@ -78,10 +78,10 @@ const q = s => JSON.stringify(s);
|
|
|
78
78
|
|
|
79
79
|
const outJson = JSON.stringify({
|
|
80
80
|
name: '@keyfunc/keybricks-ds', version, source: 'tokens/*.css',
|
|
81
|
-
note: 'Generated by
|
|
81
|
+
note: 'Generated by _scripts/build-tokens.mjs — CSS is the source of truth.', tokens
|
|
82
82
|
}, null, 2) + '\n';
|
|
83
83
|
|
|
84
|
-
const outJs = `/* Generated from tokens/*.css by
|
|
84
|
+
const outJs = `/* Generated from tokens/*.css by _scripts/build-tokens.mjs — do not edit by hand.
|
|
85
85
|
cssVar keeps theming live (preferred in components); light/dark are flattened
|
|
86
86
|
literals for canvas, PDF, native and export pipelines. */
|
|
87
87
|
|
|
@@ -102,7 +102,7 @@ export const tokenNames = ${JSON.stringify(names)};
|
|
|
102
102
|
export default { cssVar, light, dark, tokenNames };
|
|
103
103
|
`;
|
|
104
104
|
|
|
105
|
-
const outDts = `/* Generated from tokens/*.css by
|
|
105
|
+
const outDts = `/* Generated from tokens/*.css by _scripts/build-tokens.mjs — do not edit by hand. */
|
|
106
106
|
export type TokenName =
|
|
107
107
|
| ${names.map(q).join('\n | ')};
|
|
108
108
|
export type TokenKey =
|
|
@@ -10,6 +10,11 @@ window.addEventListener('message', function(e){
|
|
|
10
10
|
var m = e.data;
|
|
11
11
|
if (m && m.kb === 'theme') apply(m.theme);
|
|
12
12
|
});
|
|
13
|
+
/* Standalone (no host): follow the OS until the host answers. */
|
|
14
|
+
if (!document.documentElement.hasAttribute('data-theme')) {
|
|
15
|
+
var mq = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');
|
|
16
|
+
apply(mq && mq.matches ? 'dark' : 'light');
|
|
17
|
+
}
|
|
13
18
|
try {
|
|
14
19
|
if (window.parent !== window) window.parent.postMessage({ kb: 'theme-ask' }, '*');
|
|
15
20
|
} catch(e){}
|
package/package.json
CHANGED
package/tokens/alpha.css
CHANGED
|
@@ -21,7 +21,3 @@
|
|
|
21
21
|
--neutral-alpha-2:rgba(255,255,255,.02);--neutral-alpha-4:rgba(255,255,255,.04);--neutral-alpha-8:rgba(255,255,255,.08);--neutral-alpha-12:rgba(255,255,255,.12);--neutral-alpha-16:rgba(255,255,255,.16);--neutral-alpha-24:rgba(255,255,255,.24);--neutral-alpha-32:rgba(255,255,255,.32);--neutral-alpha-48:rgba(255,255,255,.48);--neutral-alpha-64:rgba(255,255,255,.64);--neutral-alpha-80:rgba(255,255,255,.8);
|
|
22
22
|
--brand-alpha-8:rgba(43,127,255,.1);--brand-alpha-12:rgba(43,127,255,.14);--brand-alpha-16:rgba(43,127,255,.2);--brand-alpha-24:rgba(43,127,255,.28);--brand-alpha-32:rgba(43,127,255,.36);
|
|
23
23
|
}
|
|
24
|
-
@media (prefers-color-scheme: dark){:root{
|
|
25
|
-
--neutral-alpha-2:rgba(255,255,255,.02);--neutral-alpha-4:rgba(255,255,255,.04);--neutral-alpha-8:rgba(255,255,255,.08);--neutral-alpha-12:rgba(255,255,255,.12);--neutral-alpha-16:rgba(255,255,255,.16);--neutral-alpha-24:rgba(255,255,255,.24);--neutral-alpha-32:rgba(255,255,255,.32);--neutral-alpha-48:rgba(255,255,255,.48);--neutral-alpha-64:rgba(255,255,255,.64);--neutral-alpha-80:rgba(255,255,255,.8);
|
|
26
|
-
--brand-alpha-8:rgba(43,127,255,.1);--brand-alpha-12:rgba(43,127,255,.14);--brand-alpha-16:rgba(43,127,255,.2);--brand-alpha-24:rgba(43,127,255,.28);--brand-alpha-32:rgba(43,127,255,.36);
|
|
27
|
-
}}
|
package/tokens/charts.css
CHANGED
|
@@ -47,9 +47,3 @@
|
|
|
47
47
|
--chart-heat-1:#162456;--chart-heat-2:#193cb8;--chart-heat-3:#1447e6;--chart-heat-4:#51a2ff;--chart-heat-5:#bedbff;
|
|
48
48
|
--chart-heat-ink:#0a0a0a;
|
|
49
49
|
}
|
|
50
|
-
@media (prefers-color-scheme: dark){:root{
|
|
51
|
-
--series-1:#51a2ff;--series-2:var(--teal-300);--series-3:var(--purple-300);--series-4:var(--orange-300);--series-5:var(--emerald-300);--series-6:var(--pink-300);--series-7:var(--cyan-300);--series-8:var(--amber-300);--series-9:var(--red-300);--series-10:var(--neutral-500);
|
|
52
|
-
--chart-grid:#1f1f1f;--chart-axis:#3f3f3f;--chart-label:#8f8f8f;--chart-pos:var(--emerald-400);--chart-neg:var(--red-400);--chart-total:var(--neutral-300);--chart-track:#1f1f1f;--chart-guide:#525252;--chart-area-alpha:.22; /* @kind other */
|
|
53
|
-
--chart-heat-1:#162456;--chart-heat-2:#193cb8;--chart-heat-3:#1447e6;--chart-heat-4:#51a2ff;--chart-heat-5:#bedbff;
|
|
54
|
-
--chart-heat-ink:#0a0a0a;
|
|
55
|
-
}}
|
|
@@ -37,4 +37,3 @@
|
|
|
37
37
|
}
|
|
38
38
|
/* Dark theme: deep-tint bg + 300-step fg keeps pills readable on #0a0a0a */
|
|
39
39
|
[data-theme="dark"]{--hue-gray-bg:#262626;--hue-gray-fg:#a1a1a1;--hue-blue-bg:#162456;--hue-blue-fg:#8ec5ff;--hue-green-bg:#00311d;--hue-green-fg:#8adeb3;--hue-orange-bg:#461700;--hue-orange-fg:#ffb798;--hue-amber-bg:#362400;--hue-amber-fg:#ffd280;--hue-teal-bg:#002f2a;--hue-teal-fg:#90d7cc;--hue-cyan-bg:#0b2d33;--hue-cyan-fg:#57daf3;--hue-purple-bg:#35085b;--hue-purple-fg:#d2b3ff;--hue-pink-bg:#460c33;--hue-pink-fg:#ffa4da;--hue-red-bg:#520006;--hue-red-fg:#ffa79f}
|
|
40
|
-
@media (prefers-color-scheme: dark){:root{--hue-gray-bg:#262626;--hue-gray-fg:#a1a1a1;--hue-blue-bg:#162456;--hue-blue-fg:#8ec5ff;--hue-green-bg:#00311d;--hue-green-fg:#8adeb3;--hue-orange-bg:#461700;--hue-orange-fg:#ffb798;--hue-amber-bg:#362400;--hue-amber-fg:#ffd280;--hue-teal-bg:#002f2a;--hue-teal-fg:#90d7cc;--hue-cyan-bg:#0b2d33;--hue-cyan-fg:#57daf3;--hue-purple-bg:#35085b;--hue-purple-fg:#d2b3ff;--hue-pink-bg:#460c33;--hue-pink-fg:#ffa4da;--hue-red-bg:#520006;--hue-red-fg:#ffa79f}}
|
package/tokens/dark.css
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
/* Keybricks dark theme — apply with <html data-theme="dark">.
|
|
1
|
+
/* Keybricks dark theme — apply with <html data-theme="dark">. To follow the OS, run
|
|
2
|
+
tokens/theme.js in <head>: it stamps data-theme="dark" when the OS prefers dark and
|
|
3
|
+
nothing is set. data-theme="light" always forces light. No @media here on purpose —
|
|
4
|
+
an OS media query in :root cannot be overridden by an attribute.
|
|
2
5
|
The source .fig ships a "Dark Mode" nav item but no dark frames, so these values
|
|
3
6
|
are an original, contrast-tested derivation of the light palette (same hue families).
|
|
4
7
|
|
|
@@ -49,48 +52,3 @@ color-scheme:dark;
|
|
|
49
52
|
}
|
|
50
53
|
[data-theme="dark"] body{background:var(--bg-app);color:var(--text-primary)}
|
|
51
54
|
[data-theme="dark"] img[src$="keybricks-logo.png"]{filter:none}
|
|
52
|
-
|
|
53
|
-
@media (prefers-color-scheme: dark){
|
|
54
|
-
:root{
|
|
55
|
-
|
|
56
|
-
color-scheme:dark;
|
|
57
|
-
/* Surfaces — 4 steps, each ~+6% luminance, so nesting reads without borders */
|
|
58
|
-
--bg-app:#0a0a0a;--bg-surface:#161616;--bg-raised:#1d1d1d;--bg-inset:#1f1f1f;--bg-hover:#262626;--bg-active:#2e2e2e;--bg-scrim:rgba(0,0,0,.6);
|
|
59
|
-
/* Text */
|
|
60
|
-
--text-primary:#fafafa;--text-heading:#f5f5f5;--text-strong:#e5e5e5;--text-body:#d4d4d4;--text-secondary:#a1a1a1;--text-muted:#737373;--text-inverse:#0a0a0a;
|
|
61
|
-
--on-accent:#ffffff;--action-dark-fg:#0a0a0a;
|
|
62
|
-
/* Borders */
|
|
63
|
-
--border-card:rgba(255,255,255,.09);--border-control:#333333;--border-subtle:#242424;--border-strong:#454545;
|
|
64
|
-
/* Actions */
|
|
65
|
-
--action-primary:#1f6feb;--action-primary-hover:#2b7fff;--action-primary-active:#1a5ec9;--action-dark:#fafafa;--action-dark-hover:#e5e5e5;--action-dark-active:#d4d4d4;
|
|
66
|
-
/* Press (active) fills — one step past the hover value in each family */
|
|
67
|
-
--bg-press:#3a3a3a;--soft-active:rgba(43,127,255,.32);--danger-active:#c10007;--danger-soft-active:rgba(251,44,54,.26);
|
|
68
|
-
--focus-ring:rgba(43,127,255,.32);--focus-border:#2b7fff;--selected-border:#51a2ff;
|
|
69
|
-
--soft-bg:rgba(43,127,255,.14);--soft-border:#2b7fff;--soft-hover:rgba(43,127,255,.24);
|
|
70
|
-
--info-bg:rgba(43,127,255,.14);--info-fg:#8ab8ff;
|
|
71
|
-
--link:#7cb0ff;--link-hover:#a8caff;
|
|
72
|
-
/* Structure */
|
|
73
|
-
--track:#303030;--dot-neutral:#737373;--skeleton:#242424;--checkbox-border:#4a4a4a;
|
|
74
|
-
--port-border:#3f3f3f;--dropzone-border:#3a3a3a;--dropzone-border-hover:#525252;
|
|
75
|
-
--edge:#4b5563;--chart-blue:#4d93ff;--purple-500:#c07cff;
|
|
76
|
-
--tooltip-bg:#f5f5f5;--tooltip-fg:#0a0a0a;
|
|
77
|
-
/* Category hues — glyph lifted for contrast, tile tint becomes a low-alpha wash */
|
|
78
|
-
--cat-source:#22c58f;--cat-source-bg:rgba(0,188,125,.16);
|
|
79
|
-
--cat-join:#5b9bff;--cat-join-bg:rgba(43,127,255,.16);
|
|
80
|
-
--cat-transform:#ff8b3d;--cat-transform-bg:rgba(255,105,0,.16);
|
|
81
|
-
--cat-merge:#c07cff;--cat-merge-bg:rgba(152,16,250,.18);
|
|
82
|
-
--cat-output:#22bfb2;--cat-output-bg:rgba(0,150,137,.18);
|
|
83
|
-
/* Status — solid dots keep the brand hue; tints/text lift for legibility */
|
|
84
|
-
--success:#00bc7d;--success-strong:#22c58f;--success-bg:rgba(0,188,125,.14);--success-text:#4ade9f;
|
|
85
|
-
--danger:#fb2c36;--danger-bg:rgba(251,44,54,.14);--danger-text:#ff8085;
|
|
86
|
-
--warning:#ffb900;--warning-bg:rgba(255,185,0,.14);--warning-text:#ffc55c;
|
|
87
|
-
/* Elevation reads as a deeper shadow plus a lighter surface, never a glow */
|
|
88
|
-
--shadow-node:0 1px 3px 0 rgba(0,0,0,.6),0 1px 2px -1px rgba(0,0,0,.5);
|
|
89
|
-
--shadow-selected:0 0 0 2px rgba(43,127,255,.32),0 1px 3px 0 rgba(0,0,0,.6);
|
|
90
|
-
--shadow-menu:0 4px 16px rgba(0,0,0,.55),0 1px 3px rgba(0,0,0,.4);
|
|
91
|
-
--shadow-modal:0 24px 64px rgba(0,0,0,.7),0 2px 8px rgba(0,0,0,.5);
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
body{background:var(--bg-app);color:var(--text-primary)}
|
|
95
|
-
img[src$="keybricks-logo.png"]{filter:none}
|
|
96
|
-
}
|
package/tokens/interaction.css
CHANGED
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
Reduced-motion users still get both states — neither is animated. */
|
|
15
15
|
:root{--press-filter:brightness(.94);/* @kind other */--press-filter-strong:brightness(.88)/* @kind other */}
|
|
16
16
|
[data-theme="dark"]{--press-filter:brightness(1.35);/* @kind other */--press-filter-strong:brightness(1.6)/* @kind other */}
|
|
17
|
-
@media (prefers-color-scheme: dark){:root{--press-filter:brightness(1.35);/* @kind other */--press-filter-strong:brightness(1.6)/* @kind other */}}
|
|
18
17
|
|
|
19
18
|
button:not(:disabled):not([data-press="own"]):active,
|
|
20
19
|
a:active,
|
package/tokens/theme.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/* Keybricks theme bootstrap — include in <head> BEFORE styles.css to avoid a flash:
|
|
2
|
+
<script src="@keyfunc/keybricks-ds/tokens/theme.js"></script>
|
|
3
|
+
Rules: an existing data-theme on <html> always wins ("light" forces light, "dark" forces
|
|
4
|
+
dark); with none set, the OS preference is stamped as data-theme and tracked live.
|
|
5
|
+
Your app owns persistence — set data-theme yourself from saved settings before this runs. */
|
|
6
|
+
(function () {
|
|
7
|
+
var html = document.documentElement, mq = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');
|
|
8
|
+
function follow() { if (!html.hasAttribute('data-theme') || html.dataset.themeSource === 'os') { html.setAttribute('data-theme', mq && mq.matches ? 'dark' : 'light'); html.dataset.themeSource = 'os'; } }
|
|
9
|
+
follow();
|
|
10
|
+
if (mq && mq.addEventListener) mq.addEventListener('change', follow);
|
|
11
|
+
})();
|
package/tokens/tokens.d.ts
CHANGED
package/tokens/tokens.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Generated from tokens/*.css by
|
|
1
|
+
/* Generated from tokens/*.css by _scripts/build-tokens.mjs — do not edit by hand.
|
|
2
2
|
cssVar keeps theming live (preferred in components); light/dark are flattened
|
|
3
3
|
literals for canvas, PDF, native and export pipelines. */
|
|
4
4
|
|
package/tokens/tokens.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keyfunc/keybricks-ds",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"source": "tokens/*.css",
|
|
5
|
-
"note": "Generated by
|
|
5
|
+
"note": "Generated by _scripts/build-tokens.mjs — CSS is the source of truth.",
|
|
6
6
|
"tokens": {
|
|
7
7
|
"--action-dark": {
|
|
8
8
|
"group": "colors",
|