@dxos/ui-theme 0.9.0 → 0.9.1-staging.ee54ba693a
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/dist/lib/browser/index.mjs +37 -7
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +37 -7
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/plugin/node-cjs/main.css +56 -27
- package/dist/plugin/node-cjs/main.css.map +2 -2
- package/dist/plugin/node-cjs/meta.json +1 -1
- package/dist/plugin/node-esm/main.css +56 -27
- package/dist/plugin/node-esm/main.css.map +2 -2
- package/dist/plugin/node-esm/meta.json +1 -1
- package/dist/types/src/util/index.d.ts +2 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/mx.d.ts.map +1 -1
- package/dist/types/src/util/tv.d.ts +27 -0
- package/dist/types/src/util/tv.d.ts.map +1 -0
- package/dist/types/src/util/tv.test.d.ts +2 -0
- package/dist/types/src/util/tv.test.d.ts.map +1 -0
- package/dist/types/src/util/tw-merge-config.d.ts +17 -0
- package/dist/types/src/util/tw-merge-config.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -7
- package/src/Theme.stories.tsx +1 -1
- package/src/css/components/button.css +10 -9
- package/src/css/components/state.css +2 -25
- package/src/css/components/surface.css +65 -12
- package/src/css/components/tag.css +2 -2
- package/src/css/layout/size.css +1 -1
- package/src/css/theme/semantic.css +162 -75
- package/src/css/theme/spacing.css +7 -5
- package/src/util/index.ts +2 -0
- package/src/util/mx.ts +5 -35
- package/src/util/tv.test.ts +38 -0
- package/src/util/tv.ts +45 -0
- package/src/util/tw-merge-config.ts +46 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/ui-theme",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1-staging.ee54ba693a",
|
|
4
4
|
"description": "A set of design system tokens to use with DXOS UI.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -48,21 +48,22 @@
|
|
|
48
48
|
"postcss-nesting": "^13.0.1",
|
|
49
49
|
"tailwind-merge": "^3.5.0",
|
|
50
50
|
"tailwind-scrollbar": "^4.0.0",
|
|
51
|
+
"tailwind-variants": "^3.2.2",
|
|
51
52
|
"tailwindcss": "^4.3.0",
|
|
52
53
|
"tailwindcss-radix": "^4.0.2",
|
|
53
|
-
"@dxos/log": "0.9.
|
|
54
|
-
"@dxos/
|
|
55
|
-
"@dxos/
|
|
54
|
+
"@dxos/log": "0.9.1-staging.ee54ba693a",
|
|
55
|
+
"@dxos/node-std": "0.9.1-staging.ee54ba693a",
|
|
56
|
+
"@dxos/util": "0.9.1-staging.ee54ba693a"
|
|
56
57
|
},
|
|
57
58
|
"devDependencies": {
|
|
58
59
|
"@types/lodash.merge": "^4.6.6",
|
|
59
60
|
"@types/postcss-import": "^14.0.3",
|
|
60
|
-
"esbuild": "0.28.
|
|
61
|
+
"esbuild": "0.28.1",
|
|
61
62
|
"vite": "^8.0.16",
|
|
62
|
-
"@dxos/ui-types": "0.9.
|
|
63
|
+
"@dxos/ui-types": "0.9.1-staging.ee54ba693a"
|
|
63
64
|
},
|
|
64
65
|
"peerDependencies": {
|
|
65
|
-
"react": "~19.2.
|
|
66
|
+
"react": "~19.2.7"
|
|
66
67
|
},
|
|
67
68
|
"publishConfig": {
|
|
68
69
|
"access": "public"
|
package/src/Theme.stories.tsx
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { type Meta } from '@storybook/react-vite';
|
|
6
6
|
import React, { useLayoutEffect, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { hues, hueShades } from './defs';
|
|
9
9
|
import { mx } from './util';
|
|
10
10
|
|
|
11
11
|
// prettier-ignore
|
|
@@ -18,9 +18,15 @@
|
|
|
18
18
|
color: var(--dx-valence-text, inherit);
|
|
19
19
|
background: var(--dx-valence-bg, var(--color-input-bg));
|
|
20
20
|
}
|
|
21
|
+
/* Toggle / tab group: the selected item reads as standard text on a surface-relative fill (selected-surface
|
|
22
|
+
* tracks the enclosing --surface-bg, so it stays visible on any surface); unselected items recede to subdued. */
|
|
21
23
|
&[aria-pressed='true'],
|
|
22
24
|
&[aria-checked='true'] {
|
|
23
|
-
@apply text-
|
|
25
|
+
@apply text-base-fg bg-selected-surface;
|
|
26
|
+
}
|
|
27
|
+
&[aria-pressed='false'],
|
|
28
|
+
&[aria-checked='false'] {
|
|
29
|
+
@apply text-description;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
/* Disabled styles */
|
|
@@ -32,14 +38,9 @@
|
|
|
32
38
|
&[data-variant='ghost'] {
|
|
33
39
|
@apply bg-transparent;
|
|
34
40
|
&:hover {
|
|
35
|
-
/*
|
|
36
|
-
* so
|
|
37
|
-
|
|
38
|
-
background: light-dark(
|
|
39
|
-
oklch(from var(--surface-bg, var(--color-base-surface)) calc(l - 0.05) c h),
|
|
40
|
-
oklch(from var(--surface-bg, var(--color-base-surface)) calc(l + 0.05) c h)
|
|
41
|
-
);
|
|
42
|
-
@apply text-inherit;
|
|
41
|
+
/* Shares the surface-derived control hover (--color-hover-surface tracks the enclosing
|
|
42
|
+
* --surface-bg) so every variant tints consistently on any background. */
|
|
43
|
+
@apply bg-hover-surface text-inherit;
|
|
43
44
|
}
|
|
44
45
|
&[data-state='open'] {
|
|
45
46
|
@apply bg-input-bg;
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
*/
|
|
20
20
|
.dx-hover {
|
|
21
21
|
@apply cursor-pointer
|
|
22
|
-
hover:bg-hover-surface! hover:text-hover-fg!
|
|
22
|
+
hover:bg-hover-surface-subtle! hover:text-hover-fg!
|
|
23
23
|
hover:aria-selected:bg-selected-surface-hover hover:aria-selected:text-selected-fg
|
|
24
24
|
hover:aria-[current=true]:bg-current-surface-hover hover:aria-[current=true]:text-current-fg;
|
|
25
25
|
}
|
|
26
26
|
.dx-hover-row {
|
|
27
|
-
@apply group-hover/row:bg-hover-surface! group-hover/row:text-hover-fg!
|
|
27
|
+
@apply group-hover/row:bg-hover-surface-subtle! group-hover/row:text-hover-fg!
|
|
28
28
|
group-hover/row:group-aria-selected/row:bg-selected-surface-hover!
|
|
29
29
|
group-hover/row:group-aria-selected/row:text-selected-fg!
|
|
30
30
|
group-hover/row:group-aria-[current=true]/row:bg-current-surface-hover!
|
|
@@ -74,26 +74,3 @@
|
|
|
74
74
|
hover:data-[highlighted]:bg-current-surface-hover;
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
|
|
78
|
-
@layer dx-tokens {
|
|
79
|
-
/*
|
|
80
|
-
* Sidebars sit on a different surface than the main content, so nudge the state highlights to
|
|
81
|
-
* keep contrast: offset each token off its `*-base` (see semantic.css) — darker in light mode,
|
|
82
|
-
* lighter in dark. Tune the magnitude via --dx-sidebar-l-shift.
|
|
83
|
-
*/
|
|
84
|
-
.dx-main-sidebar {
|
|
85
|
-
--dx-sidebar-l-shift: 0.04;
|
|
86
|
-
--color-hover-surface: light-dark(
|
|
87
|
-
oklch(from var(--dx-hover-surface-base) calc(l - var(--dx-sidebar-l-shift)) c h),
|
|
88
|
-
oklch(from var(--dx-hover-surface-base) calc(l + var(--dx-sidebar-l-shift)) c h)
|
|
89
|
-
);
|
|
90
|
-
--color-current-surface: light-dark(
|
|
91
|
-
oklch(from var(--dx-current-surface-base) calc(l - var(--dx-sidebar-l-shift)) c h),
|
|
92
|
-
oklch(from var(--dx-current-surface-base) calc(l + var(--dx-sidebar-l-shift)) c h)
|
|
93
|
-
);
|
|
94
|
-
--color-current-surface-hover: light-dark(
|
|
95
|
-
oklch(from var(--dx-current-surface-hover-base) calc(l - var(--dx-sidebar-l-shift)) c h),
|
|
96
|
-
oklch(from var(--dx-current-surface-hover-base) calc(l + var(--dx-sidebar-l-shift)) c h)
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Surfaces
|
|
3
|
+
*
|
|
4
|
+
* A surface zone paints a background AND publishes its colour as `--surface-bg`, so descendant
|
|
5
|
+
* controls can derive a visible hover/current highlight from the actual surface (see the
|
|
6
|
+
* derivation block below) and surface-matching elements (avatars, gradients) can read it directly.
|
|
7
|
+
*
|
|
8
|
+
* Always enter a surface via one of these `dx-*-surface` classes. A bare `bg-*-surface` utility
|
|
9
|
+
* paints the colour but does NOT publish `--surface-bg`, so control hover collapses onto the
|
|
10
|
+
* base-surface fallback and can become invisible when the surface shares that elevation.
|
|
3
11
|
*/
|
|
4
12
|
|
|
5
13
|
@layer dx-components {
|
|
@@ -8,42 +16,87 @@
|
|
|
8
16
|
--surface-bg: var(--color-base-surface);
|
|
9
17
|
}
|
|
10
18
|
|
|
19
|
+
.dx-deck-surface {
|
|
20
|
+
@apply bg-deck-surface text-base-fg;
|
|
21
|
+
--surface-bg: var(--color-deck-surface);
|
|
22
|
+
}
|
|
23
|
+
|
|
11
24
|
.dx-sidebar-surface {
|
|
12
25
|
@apply bg-sidebar-surface text-base-fg;
|
|
13
26
|
--surface-bg: var(--color-sidebar-surface);
|
|
14
27
|
}
|
|
15
28
|
|
|
29
|
+
.dx-header-surface {
|
|
30
|
+
@apply bg-header-surface text-base-fg;
|
|
31
|
+
--surface-bg: var(--color-header-surface);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.dx-card-surface {
|
|
35
|
+
@apply bg-card-surface text-base-fg;
|
|
36
|
+
--surface-bg: var(--color-card-surface);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.dx-group-surface {
|
|
40
|
+
@apply bg-group-surface text-base-fg;
|
|
41
|
+
--surface-bg: var(--color-group-surface);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.dx-input-surface {
|
|
45
|
+
@apply bg-input-surface text-base-fg;
|
|
46
|
+
--surface-bg: var(--color-input-surface);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.dx-toolbar-surface {
|
|
50
|
+
@apply bg-toolbar-surface text-base-fg;
|
|
51
|
+
--surface-bg: var(--color-toolbar-surface);
|
|
52
|
+
}
|
|
53
|
+
|
|
16
54
|
.dx-modal-surface {
|
|
17
55
|
@apply bg-modal-surface text-base-fg backdrop-blur-md;
|
|
18
56
|
--surface-bg: var(--color-modal-surface);
|
|
19
57
|
}
|
|
20
58
|
|
|
21
|
-
.dx-attention-surface {
|
|
22
|
-
@apply bg-attention-surface text-base-fg;
|
|
23
|
-
--surface-bg: var(--color-attention-surface);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
59
|
.dx-popover-surface {
|
|
27
60
|
@apply bg-popover-surface text-base-fg backdrop-blur-md;
|
|
28
61
|
--surface-bg: var(--color-popover-surface);
|
|
29
62
|
}
|
|
63
|
+
|
|
64
|
+
.dx-attention-surface {
|
|
65
|
+
@apply bg-attention-surface text-base-fg;
|
|
66
|
+
--surface-bg: var(--color-attention-surface);
|
|
67
|
+
}
|
|
30
68
|
}
|
|
31
69
|
|
|
32
70
|
@layer dx-tokens {
|
|
33
71
|
/*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
72
|
+
* Re-derive the state colours (hover, current, selected) off the host surface for every context
|
|
73
|
+
* that publishes its own --surface-bg. Custom-property substitution runs once per scope, so the
|
|
74
|
+
* formula must be repeated here (it cannot simply inherit from semantic.css, which resolved it
|
|
75
|
+
* against the root surface). Listing all surface zones in one block keeps the offsets identical
|
|
76
|
+
* across surfaces — there is no per-surface divergence to tune.
|
|
77
|
+
*
|
|
78
|
+
* Magnitudes mirror semantic.css; selected-* track current-* via the aliases declared there.
|
|
40
79
|
*/
|
|
80
|
+
.dx-base-surface,
|
|
81
|
+
.dx-deck-surface,
|
|
82
|
+
.dx-sidebar-surface,
|
|
83
|
+
.dx-header-surface,
|
|
84
|
+
.dx-card-surface,
|
|
85
|
+
.dx-group-surface,
|
|
86
|
+
.dx-input-surface,
|
|
87
|
+
.dx-toolbar-surface,
|
|
41
88
|
.dx-modal-surface,
|
|
42
|
-
.dx-popover-surface
|
|
89
|
+
.dx-popover-surface,
|
|
90
|
+
.dx-attention-surface,
|
|
91
|
+
.dx-main-sidebar {
|
|
43
92
|
--color-hover-surface: light-dark(
|
|
44
93
|
oklch(from var(--surface-bg) calc(l - 0.08) c h),
|
|
45
94
|
oklch(from var(--surface-bg) calc(l + 0.08) c h)
|
|
46
95
|
);
|
|
96
|
+
--color-hover-surface-subtle: light-dark(
|
|
97
|
+
oklch(from var(--surface-bg) calc(l - 0.02) c h),
|
|
98
|
+
oklch(from var(--surface-bg) calc(l + 0.02) c h)
|
|
99
|
+
);
|
|
47
100
|
--color-current-surface: light-dark(
|
|
48
101
|
oklch(from var(--surface-bg) calc(l - 0.1) c h),
|
|
49
102
|
oklch(from var(--surface-bg) calc(l + 0.1) c h)
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
.dx-tag--anchor {
|
|
13
13
|
/* NOTE: Margin offsets padding so that border is flush with text. This should only apply to anchor tags inside of Codemirror. */
|
|
14
|
-
@apply inline cursor-pointer px-[4px] py-0.5;
|
|
14
|
+
@apply inline-block cursor-pointer px-[4px] py-0.5;
|
|
15
15
|
/** TODO(burdon): Configure secondary color. */
|
|
16
|
-
@apply bg-input-surface ring ring-neutral-border rounded-sm;
|
|
16
|
+
@apply bg-input-surface ring-inset ring ring-neutral-border rounded-sm;
|
|
17
17
|
&:hover {
|
|
18
18
|
@apply bg-hover-surface;
|
|
19
19
|
}
|
package/src/css/layout/size.css
CHANGED
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
.dx-card-popover {
|
|
67
|
-
@apply inline-card-max-width bg-
|
|
67
|
+
@apply inline-card-max-width bg-popover-surface;
|
|
68
68
|
max-width: min(var(--radix-popper-available-width), var(--spacing-card-max-width));
|
|
69
69
|
max-height: min(var(--radix-popper-available-height), var(--spacing-card-max-height));
|
|
70
70
|
}
|
|
@@ -13,95 +13,180 @@
|
|
|
13
13
|
* Elevation ladder — strictly monotonic, z-order low → high.
|
|
14
14
|
* Dark: darker = lower. Light: lighter = higher (inverted toward white).
|
|
15
15
|
*
|
|
16
|
-
* Level Name
|
|
17
|
-
* 0 void
|
|
18
|
-
* 1
|
|
19
|
-
* 2 chrome
|
|
20
|
-
* 3
|
|
21
|
-
* 4 raised
|
|
22
|
-
* 5 bar
|
|
23
|
-
* 6 modal
|
|
24
|
-
* 7 float
|
|
16
|
+
* Level Name Roles
|
|
17
|
+
* 0 void deck, scrim base
|
|
18
|
+
* 1 base base content, L0 icon rail
|
|
19
|
+
* 2 chrome L1/R sidebars, header
|
|
20
|
+
* 3 card card
|
|
21
|
+
* 4 raised group, input, focus/attention
|
|
22
|
+
* 5 bar dialog/modal, toolbar (sticky, drop-shadowed)
|
|
23
|
+
* 6 modal popover, menu, toast, tooltip
|
|
24
|
+
* 7 float
|
|
25
25
|
*
|
|
26
26
|
* These are private (--dx-*) knobs — use named surface tokens in components, not these directly.
|
|
27
27
|
*/
|
|
28
28
|
--dx-elevation-0: light-dark(var(--color-neutral-300), var(--color-neutral-950));
|
|
29
|
-
--dx-elevation-1: light-dark(var(--color-neutral-
|
|
30
|
-
--dx-elevation-2: light-dark(var(--color-neutral-
|
|
31
|
-
--dx-elevation-3: light-dark(var(--color-neutral-125), var(--color-neutral-
|
|
32
|
-
--dx-elevation-4: light-dark(var(--color-neutral-
|
|
33
|
-
--dx-elevation-5: light-dark(var(--color-neutral-
|
|
34
|
-
--dx-elevation-6: light-dark(var(--color-neutral-
|
|
35
|
-
--dx-elevation-7: light-dark(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
--color-base-surface: var(--dx-elevation-3);
|
|
42
|
-
--color-card-surface: var(--dx-elevation-3);
|
|
43
|
-
--color-group-surface: var(--dx-elevation-4);
|
|
44
|
-
/* Subtle alternate of group-surface for zebra striping (e.g. calendar months) — offset off
|
|
45
|
-
* elevation-4 via relative oklch so it tracks the ramp: darker in light mode, lighter in dark. */
|
|
46
|
-
--color-group-alt-surface: light-dark(
|
|
47
|
-
oklch(from var(--dx-elevation-4) calc(l - 0.03) c h),
|
|
48
|
-
oklch(from var(--dx-elevation-4) calc(l + 0.03) c h)
|
|
49
|
-
);
|
|
50
|
-
--color-input-surface: var(--dx-elevation-4);
|
|
51
|
-
--color-toolbar-surface: var(--dx-elevation-5);
|
|
52
|
-
--color-modal-surface: var(--dx-elevation-6);
|
|
53
|
-
--color-popover-surface: var(--dx-elevation-6);
|
|
29
|
+
--dx-elevation-1: light-dark(var(--color-neutral-300), var(--color-neutral-925));
|
|
30
|
+
--dx-elevation-2: light-dark(var(--color-neutral-200), var(--color-neutral-900));
|
|
31
|
+
--dx-elevation-3: light-dark(var(--color-neutral-125), var(--color-neutral-875));
|
|
32
|
+
--dx-elevation-4: light-dark(var(--color-neutral-125), var(--color-neutral-850));
|
|
33
|
+
--dx-elevation-5: light-dark(var(--color-neutral-100), var(--color-neutral-825));
|
|
34
|
+
--dx-elevation-6: light-dark(var(--color-neutral-75), var(--color-neutral-800));
|
|
35
|
+
--dx-elevation-7: light-dark(var(--color-neutral-50), var(--color-neutral-775));
|
|
36
|
+
--dx-elevation-8: light-dark(white, var(--color-neutral-750));
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Elevation 0
|
|
40
|
+
*/
|
|
54
41
|
|
|
55
|
-
|
|
56
|
-
--color-l0-surface: var(--dx-elevation-1);
|
|
57
|
-
--color-l1-surface: var(--dx-elevation-2);
|
|
58
|
-
--color-r0-surface: var(--dx-elevation-2);
|
|
59
|
-
--color-r1-surface: var(--dx-elevation-2);
|
|
42
|
+
--color-deck-surface: var(--dx-elevation-0);
|
|
60
43
|
|
|
44
|
+
/* Translucent dimming layer; tracks the lowest elevation (void) rather than a raw neutral. */
|
|
61
45
|
--color-scrim-surface: light-dark(
|
|
62
|
-
oklch(from var(--
|
|
63
|
-
oklch(from var(--
|
|
46
|
+
oklch(from var(--dx-elevation-0) l c h / 0.5),
|
|
47
|
+
oklch(from var(--dx-elevation-0) l c h / 0.25)
|
|
64
48
|
);
|
|
65
49
|
|
|
66
|
-
|
|
67
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Elevation 1
|
|
52
|
+
*/
|
|
68
53
|
|
|
54
|
+
--color-card-surface: var(--dx-elevation-1);
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Elevation 2
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
--color-base-surface: var(--dx-elevation-2);
|
|
69
61
|
--color-base-fg: light-dark(var(--color-neutral-950), var(--color-neutral-150));
|
|
70
62
|
|
|
63
|
+
/* Map attention to focus-surface logic so that elements acting as active attention zones highlight correctly on focus. */
|
|
64
|
+
--color-attention-surface: var(--dx-elevation-2);
|
|
65
|
+
--color-attention-contains: oklch(from var(--color-accent-bg) l c h / 0.3);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Elevation 3
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
--color-header-surface: var(--dx-elevation-3);
|
|
72
|
+
|
|
73
|
+
--color-sidebar-surface: var(--dx-elevation-3);
|
|
71
74
|
/* Sidebar body text. Default sits one ramp stop below the current/selected emphasis. */
|
|
72
75
|
--color-sidebar-fg: light-dark(var(--color-neutral-700), var(--color-neutral-250));
|
|
73
76
|
--color-sidebar-current-fg: light-dark(var(--color-neutral-950), var(--color-neutral-75));
|
|
74
77
|
|
|
75
|
-
/*
|
|
76
|
-
--color-
|
|
78
|
+
/* Sidebar / panel layout levels */
|
|
79
|
+
--color-l0-surface: var(--dx-elevation-2);
|
|
80
|
+
--color-l1-surface: var(--dx-elevation-3);
|
|
81
|
+
--color-r0-surface: var(--dx-elevation-3);
|
|
82
|
+
--color-r1-surface: var(--dx-elevation-3);
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Elevation 4
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
--color-toolbar-surface: var(--dx-elevation-4);
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Elevation 5
|
|
92
|
+
*/
|
|
93
|
+
|
|
94
|
+
/* Focus — a raised content surface (one level above card) so an attended pane reads as lifted. */
|
|
95
|
+
--color-focus-surface: var(--dx-elevation-5);
|
|
77
96
|
--color-focus-ring: light-dark(var(--color-blue-400), var(--color-blue-600));
|
|
78
97
|
--color-focus-ring-subtle: light-dark(var(--color-neutral-300), var(--color-neutral-600));
|
|
79
98
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
99
|
+
--color-group-surface: var(--dx-elevation-5);
|
|
100
|
+
/* Subtle alternate of group-surface for zebra striping (e.g. calendar months) — offset off
|
|
101
|
+
* elevation-4 via relative oklch so it tracks the ramp: darker in light mode, lighter in dark. */
|
|
102
|
+
--color-group-alt-surface: light-dark(
|
|
103
|
+
oklch(from var(--dx-elevation-5) calc(l - 0.03) c h),
|
|
104
|
+
oklch(from var(--dx-elevation-5) calc(l + 0.03) c h)
|
|
105
|
+
);
|
|
83
106
|
|
|
84
|
-
|
|
107
|
+
--color-input-surface: var(--dx-elevation-5);
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Elevation 6
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
--color-modal-surface: var(--dx-elevation-6);
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Elevation 7
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
--color-popover-surface: var(--dx-elevation-7);
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Elevation 8
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Misc
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
--color-inverse-surface: light-dark(var(--color-neutral-800), var(--color-neutral-200));
|
|
130
|
+
--color-inverse-fg: light-dark(var(--color-neutral-50), var(--color-neutral-950));
|
|
131
|
+
|
|
132
|
+
/*
|
|
133
|
+
* Text emphasis — foregrounds at decreasing emphasis, anchored on --color-base-fg (strongest):
|
|
134
|
+
* base-fg → description → subdued → placeholder (weakest).
|
|
135
|
+
* Tuned for legibility against the surfaces rather than mapped to the elevation ladder (which
|
|
136
|
+
* governs backgrounds, not text contrast), so these stay explicit neutrals.
|
|
137
|
+
*/
|
|
138
|
+
--color-description: light-dark(var(--color-neutral-600), var(--color-neutral-400));
|
|
139
|
+
--color-subdued: light-dark(var(--color-neutral-500), var(--color-neutral-600));
|
|
140
|
+
--color-placeholder: light-dark(var(--color-neutral-400), var(--color-neutral-600));
|
|
141
|
+
|
|
142
|
+
/*
|
|
143
|
+
* Controls — the input/control fill is a deliberate off-ladder token (cf. the grid "paper"
|
|
144
|
+
* surfaces). It backs text inputs and the default/ghost button (bg-input-bg) and must contrast
|
|
145
|
+
* whatever surface it sits on: a subtle inset well in light mode, a raised fill in dark mode that
|
|
146
|
+
* reads lighter than the topmost surface. Do not map it to an elevation level.
|
|
147
|
+
*/
|
|
85
148
|
--color-input-bg: light-dark(var(--color-neutral-250), var(--color-neutral-700));
|
|
86
|
-
--color-input-fg:
|
|
149
|
+
--color-input-fg: var(--color-base-fg);
|
|
87
150
|
|
|
88
|
-
/*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
151
|
+
/*
|
|
152
|
+
* State surfaces (hover, current, selected) are derived from the host surface (--surface-bg) via
|
|
153
|
+
* relative oklch — darker in light mode, lighter in dark — so a highlight stays visible at any
|
|
154
|
+
* elevation. The values here resolve against the root --surface-bg (= base-surface, set in
|
|
155
|
+
* base.css), giving the correct default for content outside any surface zone. Surface zones
|
|
156
|
+
* publish their own --surface-bg and re-derive these tokens in surface.css, which is where the
|
|
157
|
+
* substitution re-runs for that subtree.
|
|
158
|
+
*
|
|
159
|
+
* Offset magnitudes (lightness): hover ∓0.08, subtle ∓0.02, current ∓0.10, current-hover ∓0.12.
|
|
160
|
+
* Keep these in sync with the per-zone re-derivation in components/surface.css.
|
|
92
161
|
*/
|
|
93
|
-
--
|
|
94
|
-
|
|
162
|
+
--color-hover-surface: light-dark(
|
|
163
|
+
oklch(from var(--surface-bg, var(--color-base-surface)) calc(l - 0.08) c h),
|
|
164
|
+
oklch(from var(--surface-bg, var(--color-base-surface)) calc(l + 0.08) c h)
|
|
165
|
+
);
|
|
95
166
|
--color-hover-fg: light-dark(var(--color-neutral-950), var(--color-neutral-150));
|
|
96
167
|
|
|
168
|
+
/*
|
|
169
|
+
* Subtle region hover for large highlight targets (list rows, tiles) where the full
|
|
170
|
+
* control-strength hover reads as too heavy. Consumed by `.dx-hover` / `.dx-hover-row`;
|
|
171
|
+
* controls (buttons) keep --color-hover-surface.
|
|
172
|
+
*/
|
|
173
|
+
--color-hover-surface-subtle: light-dark(
|
|
174
|
+
oklch(from var(--surface-bg, var(--color-base-surface)) calc(l - 0.02) c h),
|
|
175
|
+
oklch(from var(--surface-bg, var(--color-base-surface)) calc(l + 0.02) c h)
|
|
176
|
+
);
|
|
177
|
+
|
|
97
178
|
/* current (aria-current) */
|
|
98
|
-
--
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
179
|
+
--color-current-surface: light-dark(
|
|
180
|
+
oklch(from var(--surface-bg, var(--color-base-surface)) calc(l - 0.1) c h),
|
|
181
|
+
oklch(from var(--surface-bg, var(--color-base-surface)) calc(l + 0.1) c h)
|
|
182
|
+
);
|
|
183
|
+
--color-current-surface-hover: light-dark(
|
|
184
|
+
oklch(from var(--surface-bg, var(--color-base-surface)) calc(l - 0.12) c h),
|
|
185
|
+
oklch(from var(--surface-bg, var(--color-base-surface)) calc(l + 0.12) c h)
|
|
186
|
+
);
|
|
102
187
|
--color-current-fg: light-dark(var(--color-neutral-950), var(--color-neutral-50));
|
|
103
188
|
|
|
104
|
-
/* selected (aria-selected) */
|
|
189
|
+
/* selected (aria-selected) tracks current */
|
|
105
190
|
--color-selected-surface: var(--color-current-surface);
|
|
106
191
|
--color-selected-surface-hover: var(--color-current-surface-hover);
|
|
107
192
|
--color-selected-fg: var(--color-current-fg);
|
|
@@ -113,13 +198,15 @@
|
|
|
113
198
|
--color-accent-text: light-dark(var(--color-blue-600), var(--color-blue-400));
|
|
114
199
|
--color-accent-text-hover: light-dark(var(--color-blue-500), var(--color-blue-500));
|
|
115
200
|
|
|
201
|
+
/* Unaccented */
|
|
116
202
|
--color-un-accent: var(--color-neutral-400);
|
|
117
203
|
--color-un-accent-hover: var(--color-neutral-500);
|
|
118
204
|
|
|
119
205
|
/* Separator */
|
|
120
|
-
--color-primary-separator: light-dark(var(--color-neutral-
|
|
206
|
+
--color-primary-separator: light-dark(var(--color-neutral-200), var(--color-neutral-800));
|
|
121
207
|
--color-separator: light-dark(var(--color-neutral-200), var(--color-neutral-700));
|
|
122
|
-
--color-
|
|
208
|
+
--color-input-separator: light-dark(var(--color-neutral-250), var(--color-neutral-750));
|
|
209
|
+
--color-subdued-separator: light-dark(var(--color-neutral-250), var(--color-neutral-775));
|
|
123
210
|
--color-active-separator: light-dark(var(--color-blue-500), var(--color-blue-500));
|
|
124
211
|
|
|
125
212
|
/* Scrollbar */
|
|
@@ -128,16 +215,21 @@
|
|
|
128
215
|
--color-scrollbar-thumb-active: light-dark(var(--color-neutral-200), var(--color-neutral-600));
|
|
129
216
|
--color-scrollbar-thumb-hover: light-dark(var(--color-neutral-200), var(--color-neutral-600));
|
|
130
217
|
|
|
131
|
-
/* Sheet */
|
|
132
|
-
--color-axis-selected-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
|
|
133
|
-
--color-axis-selected-text: light-dark(var(--color-neutral-100), var(--color-neutral-900));
|
|
134
|
-
--color-axis-surface: light-dark(var(--color-neutral-50), var(--color-neutral-800));
|
|
135
|
-
--color-axis-text: light-dark(var(--color-neutral-800), var(--color-neutral-200));
|
|
136
|
-
|
|
137
218
|
/*
|
|
138
|
-
* Grid
|
|
219
|
+
* Sheet / Grid — intentionally OFF the elevation ladder.
|
|
139
220
|
* NOTE: Update main.css when changing grid tokens (and restart dev server).
|
|
221
|
+
*
|
|
222
|
+
* These are "paper" surfaces for the data grid: maximum-contrast canvases (near-white in light,
|
|
223
|
+
* near-black in dark) plus saturated selection/comment accents. The elevation ladder is
|
|
224
|
+
* monotonic (light: lighter = higher), so it cannot express a surface that is simultaneously the
|
|
225
|
+
* lightest in light mode and the darkest in dark mode. Keep these as explicit neutrals/accents;
|
|
226
|
+
* do not fold them into --dx-elevation-*.
|
|
140
227
|
*/
|
|
228
|
+
--color-axis-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
|
|
229
|
+
--color-axis-text: light-dark(var(--color-neutral-700), var(--color-neutral-300));
|
|
230
|
+
--color-axis-selected-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
|
|
231
|
+
--color-axis-selected-text: light-dark(var(--color-neutral-100), var(--color-neutral-900));
|
|
232
|
+
|
|
141
233
|
--color-grid-surface: light-dark(var(--color-neutral-50), var(--color-neutral-950));
|
|
142
234
|
--color-grid-fg: light-dark(var(--color-neutral-950), var(--color-neutral-50));
|
|
143
235
|
--color-grid-line: light-dark(var(--color-neutral-200), var(--color-neutral-800));
|
|
@@ -149,9 +241,4 @@
|
|
|
149
241
|
oklch(from var(--color-green-400) l c h / 0.5),
|
|
150
242
|
oklch(from var(--color-green-600) l c h / 0.5)
|
|
151
243
|
);
|
|
152
|
-
|
|
153
|
-
/* Text */
|
|
154
|
-
--color-placeholder: light-dark(var(--color-neutral-400), var(--color-neutral-600));
|
|
155
|
-
--color-subdued: light-dark(var(--color-neutral-500), var(--color-neutral-600));
|
|
156
|
-
--color-description: light-dark(var(--color-neutral-600), var(--color-neutral-400));
|
|
157
244
|
}
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
/** Minimal trim to allow for ring/outline. */
|
|
32
32
|
--spacing-form-chrome: var(--spacing-trim-xs);
|
|
33
33
|
--spacing-form-gap: var(--spacing-trim-sm);
|
|
34
|
-
--spacing-form-section-gap: var(--spacing-trim-
|
|
34
|
+
--spacing-form-section-gap: var(--spacing-trim-md);
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Density: md (default).
|
|
@@ -84,10 +84,12 @@
|
|
|
84
84
|
--dx-lacuna-4: 0.5rem;
|
|
85
85
|
--dx-lacuna-6: 0.75rem;
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
--dx-gutter-sm:
|
|
89
|
-
|
|
90
|
-
--dx-gutter-
|
|
87
|
+
/* Form: 8px */
|
|
88
|
+
--dx-gutter-sm: 0.5rem;
|
|
89
|
+
/* Dialog: 16px */
|
|
90
|
+
--dx-gutter-md: 1rem;
|
|
91
|
+
/* Card: 32px */
|
|
92
|
+
--dx-gutter-lg: 2rem;
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
:root {
|
package/src/util/index.ts
CHANGED
package/src/util/mx.ts
CHANGED
|
@@ -4,45 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
import { extendTailwindMerge, validators } from 'tailwind-merge';
|
|
6
6
|
|
|
7
|
-
type AdditionalClassGroups
|
|
7
|
+
import { type AdditionalClassGroups, twMergeConfig } from './tw-merge-config';
|
|
8
8
|
|
|
9
9
|
export const mx = extendTailwindMerge<AdditionalClassGroups>({
|
|
10
10
|
extend: {
|
|
11
|
+
...twMergeConfig.extend,
|
|
11
12
|
classGroups: {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'font-thin',
|
|
16
|
-
'font-extralight',
|
|
17
|
-
'font-light',
|
|
18
|
-
'font-normal',
|
|
19
|
-
'font-medium',
|
|
20
|
-
'font-semibold',
|
|
21
|
-
'font-bold',
|
|
22
|
-
'font-extrabold',
|
|
23
|
-
'font-black',
|
|
24
|
-
// Arbitrary numbers
|
|
25
|
-
validators.isArbitraryNumber,
|
|
26
|
-
],
|
|
27
|
-
|
|
28
|
-
density: ['dx-density-sm', 'dx-density-md', 'dx-density-lg'],
|
|
29
|
-
|
|
30
|
-
'dx-focus-ring': [
|
|
31
|
-
'dx-focus-ring',
|
|
32
|
-
'dx-focus-ring-inset',
|
|
33
|
-
'dx-focus-ring-always',
|
|
34
|
-
'dx-focus-ring-inset-always',
|
|
35
|
-
'dx-focus-ring-group',
|
|
36
|
-
'dx-focus-ring-group-x',
|
|
37
|
-
'dx-focus-ring-group-y',
|
|
38
|
-
'dx-focus-ring-group-always',
|
|
39
|
-
'dx-focus-ring-group-x-always',
|
|
40
|
-
'dx-focus-ring-group-y-always',
|
|
41
|
-
'dx-focus-ring-inset-over-all',
|
|
42
|
-
'dx-focus-ring-inset-over-all-always',
|
|
43
|
-
'dx-focus-ring-main',
|
|
44
|
-
'dx-focus-ring-main-always',
|
|
45
|
-
],
|
|
13
|
+
...twMergeConfig.extend.classGroups,
|
|
14
|
+
// Arbitrary numeric font-weights require a validator (not expressible as a plain string token).
|
|
15
|
+
'font-weight': [...twMergeConfig.extend.classGroups['font-weight'], validators.isArbitraryNumber],
|
|
46
16
|
},
|
|
47
17
|
},
|
|
48
18
|
});
|