@nordmanai/nif 0.2.8 → 0.2.9
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/index.js +572 -557
- package/dist/styles.css +1 -1
- package/dist/ui/config/nm-appearance.d.ts +13 -1
- package/dist/ui/lib/appearance/appearanceState.d.ts +2 -1
- package/package.json +1 -1
- package/registry/index.json +1 -1
- package/registry/ui/components/nm-ai/nm-ai.css +3 -3
- package/registry/ui/components/nm-alert/nm-alert.css +1 -1
- package/registry/ui/components/nm-button/nm-button.css +2 -2
- package/registry/ui/components/nm-button-group/nm-button-group.css +1 -1
- package/registry/ui/components/nm-calendar/nm-calendar.css +1 -1
- package/registry/ui/components/nm-card/nm-card.css +2 -2
- package/registry/ui/components/nm-chatbox/nm-chatbox.css +1 -1
- package/registry/ui/components/nm-checkbox/nm-checkbox.css +2 -2
- package/registry/ui/components/nm-chip/nm-chip.css +1 -1
- package/registry/ui/components/nm-code-block/nm-code-block.css +1 -1
- package/registry/ui/components/nm-collection/nm-collection.css +2 -2
- package/registry/ui/components/nm-color-picker/nm-color-picker.css +1 -1
- package/registry/ui/components/nm-combobox/nm-combobox.css +2 -2
- package/registry/ui/components/nm-command/nm-command.css +1 -1
- package/registry/ui/components/nm-composer/nm-composer.css +3 -3
- package/registry/ui/components/nm-date-picker/nm-date-picker.css +2 -2
- package/registry/ui/components/nm-dialog/nm-dialog.css +1 -1
- package/registry/ui/components/nm-drawer/nm-drawer.css +2 -2
- package/registry/ui/components/nm-dropdown/nm-dropdown.css +2 -2
- package/registry/ui/components/nm-dropdown-menu/nm-dropdown-menu.css +1 -1
- package/registry/ui/components/nm-field/nm-field.css +6 -6
- package/registry/ui/components/nm-hover-card/nm-hover-card.css +1 -1
- package/registry/ui/components/nm-input/nm-input.css +3 -3
- package/registry/ui/components/nm-input-group/nm-input-group.css +2 -2
- package/registry/ui/components/nm-message/nm-message.css +1 -1
- package/registry/ui/components/nm-native-select/nm-native-select.css +2 -2
- package/registry/ui/components/nm-popover/nm-popover.css +1 -1
- package/registry/ui/components/nm-prose/nm-prose.css +3 -3
- package/registry/ui/components/nm-questionnaire/nm-questionnaire.css +3 -3
- package/registry/ui/components/nm-radio-group/nm-radio-group.css +2 -2
- package/registry/ui/components/nm-segmented/nm-segmented.css +1 -1
- package/registry/ui/components/nm-select/nm-select.css +2 -2
- package/registry/ui/components/nm-separator/nm-separator.css +1 -1
- package/registry/ui/components/nm-side-panel/nm-side-panel.css +1 -1
- package/registry/ui/components/nm-sidebar/nm-sidebar.css +9 -9
- package/registry/ui/components/nm-spinner/nm-spinner.css +1 -1
- package/registry/ui/components/nm-switch/nm-switch.css +1 -1
- package/registry/ui/components/nm-table/nm-table.css +4 -4
- package/registry/ui/components/nm-tabs/nm-tabs.css +1 -1
- package/registry/ui/components/nm-textarea/nm-textarea.css +5 -5
- package/registry/ui/components/nm-toggle/nm-toggle.css +1 -1
- package/registry/ui/components/nordman-icon-button/nordman-icon-button.css +2 -2
- package/registry/ui/components/nordman-login/nordman-login.css +3 -3
- package/registry/ui/components/nordman-toggle/nordman-toggle.css +1 -1
- package/registry/ui/config/nm-appearance.ts +17 -0
- package/registry/ui/lib/appearance/appearanceState.ts +8 -0
- package/registry/ui/lib/appearance/applyAppearance.ts +3 -1
- package/registry/ui/lib/appearance/deriveTokens.ts +2 -0
- package/registry/ui/styles/light-appearance.css +3 -3
- package/registry/ui/styles/tokens.css +21 -0
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
.nm-sidebar-provider[data-height='sm'],
|
|
19
19
|
.nm-sidebar-provider[data-height='lg'] {
|
|
20
20
|
min-height: 0;
|
|
21
|
-
border: var(--nm-rule) solid var(--nm-
|
|
21
|
+
border: var(--nm-rule) solid var(--nm-border-strong);
|
|
22
22
|
border-radius: var(--nm-radius-lg);
|
|
23
23
|
}
|
|
24
24
|
.nm-sidebar-provider[data-height='sm'] {
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
order: 1;
|
|
49
49
|
}
|
|
50
50
|
.nm-sidebar[data-variant='sidebar'][data-side='left'] {
|
|
51
|
-
border-inline-end: var(--nm-rule) solid var(--nm-divider);
|
|
51
|
+
border-inline-end: var(--nm-rule) solid var(--nm-border-divider);
|
|
52
52
|
}
|
|
53
53
|
.nm-sidebar[data-variant='sidebar'][data-side='right'] {
|
|
54
|
-
border-inline-start: var(--nm-rule) solid var(--nm-divider);
|
|
54
|
+
border-inline-start: var(--nm-rule) solid var(--nm-border-divider);
|
|
55
55
|
}
|
|
56
56
|
.nm-sidebar[data-collapsible='offcanvas'] {
|
|
57
57
|
width: 0;
|
|
@@ -95,20 +95,20 @@
|
|
|
95
95
|
inset-block: 0;
|
|
96
96
|
inset-inline-start: 0;
|
|
97
97
|
width: var(--nm-sidebar-width);
|
|
98
|
-
border-inline-end: var(--nm-rule) solid var(--nm-
|
|
98
|
+
border-inline-end: var(--nm-rule) solid var(--nm-border-strong);
|
|
99
99
|
background: var(--nm-raised);
|
|
100
100
|
}
|
|
101
101
|
.nm-sidebar[data-side='right'][data-peek] .nm-sidebar__inner {
|
|
102
102
|
inset-inline-start: auto;
|
|
103
103
|
inset-inline-end: 0;
|
|
104
104
|
border-inline-end: 0;
|
|
105
|
-
border-inline-start: var(--nm-rule) solid var(--nm-
|
|
105
|
+
border-inline-start: var(--nm-rule) solid var(--nm-border-strong);
|
|
106
106
|
}
|
|
107
107
|
.nm-sidebar[data-variant='floating'][data-peek] .nm-sidebar__inner,
|
|
108
108
|
.nm-sidebar[data-variant='inset'][data-peek] .nm-sidebar__inner {
|
|
109
109
|
inset-block: var(--nm-space-8);
|
|
110
110
|
inset-inline-start: var(--nm-space-8);
|
|
111
|
-
border: var(--nm-rule) solid var(--nm-
|
|
111
|
+
border: var(--nm-rule) solid var(--nm-border-strong);
|
|
112
112
|
border-radius: var(--nm-radius-lg);
|
|
113
113
|
}
|
|
114
114
|
.nm-sidebar[data-variant='floating'][data-side='right'][data-peek] .nm-sidebar__inner,
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
padding-inline-start: 0;
|
|
133
133
|
}
|
|
134
134
|
.nm-sidebar[data-variant='floating'] .nm-sidebar__inner {
|
|
135
|
-
border: var(--nm-rule) solid var(--nm-
|
|
135
|
+
border: var(--nm-rule) solid var(--nm-border-strong);
|
|
136
136
|
border-radius: var(--nm-radius-lg);
|
|
137
137
|
background: var(--nm-raised);
|
|
138
138
|
}
|
|
@@ -392,7 +392,7 @@
|
|
|
392
392
|
opacity: var(--control-disabled-opacity);
|
|
393
393
|
}
|
|
394
394
|
.nm-sidebar__menu-button[data-variant='outline'] {
|
|
395
|
-
border-color: var(--nm-
|
|
395
|
+
border-color: var(--nm-border-strong);
|
|
396
396
|
background: var(--nm-raised);
|
|
397
397
|
}
|
|
398
398
|
.nm-sidebar__menu-button[data-variant='outline']:hover,
|
|
@@ -514,7 +514,7 @@
|
|
|
514
514
|
margin-inline-start: calc(var(--nm-icon-pad) + var(--nm-icon-button) / 2);
|
|
515
515
|
padding-inline-start: calc(var(--nm-icon-pad) + var(--nm-icon-button) / 2);
|
|
516
516
|
padding-block: var(--nm-space-2);
|
|
517
|
-
border-inline-start: var(--nm-rule) solid var(--nm-
|
|
517
|
+
border-inline-start: var(--nm-rule) solid var(--nm-border);
|
|
518
518
|
}
|
|
519
519
|
.nm-sidebar__menu-sub-button {
|
|
520
520
|
display: flex;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
box-sizing: border-box;
|
|
4
4
|
width: var(--nm-icon);
|
|
5
5
|
height: var(--nm-icon);
|
|
6
|
-
border: 2px solid var(--nm-
|
|
6
|
+
border: 2px solid var(--nm-border-strong);
|
|
7
7
|
border-top-color: var(--nm-fg);
|
|
8
8
|
border-radius: 50%;
|
|
9
9
|
animation: nm-spinner-turn 0.8s linear infinite;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
width: calc(var(--nm-switch-thumb) * 2);
|
|
8
8
|
height: var(--nm-switch-thumb);
|
|
9
9
|
padding: var(--nm-space-2);
|
|
10
|
-
border: var(--nm-rule) solid var(--nm-
|
|
10
|
+
border: var(--nm-rule) solid var(--nm-border-strong);
|
|
11
11
|
border-radius: var(--toggle-r);
|
|
12
12
|
background: var(--nm-panel);
|
|
13
13
|
cursor: pointer;
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
.nm-table__head {
|
|
34
34
|
padding: var(--nm-table-pad-y) var(--nm-table-pad-x);
|
|
35
|
-
border-bottom: var(--nm-rule) solid var(--nm-
|
|
35
|
+
border-bottom: var(--nm-rule) solid var(--nm-border-strong);
|
|
36
36
|
color: var(--nm-fg-muted);
|
|
37
37
|
font-size: var(--nm-type-ui-sm);
|
|
38
38
|
font-weight: var(--nm-weight-medium);
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
|
|
76
76
|
.nm-table[data-variant='default'] .nm-table__body .nm-table__row:not(:last-child),
|
|
77
77
|
.nm-table[data-variant='striped'] .nm-table__body .nm-table__row:not(:last-child) {
|
|
78
|
-
border-bottom: var(--nm-rule) solid var(--nm-
|
|
78
|
+
border-bottom: var(--nm-rule) solid var(--nm-border);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
.nm-table[data-variant='striped'] .nm-table__body .nm-table__row:nth-child(even) {
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
|
|
85
85
|
.nm-table[data-variant='lined'] .nm-table__head,
|
|
86
86
|
.nm-table[data-variant='lined'] .nm-table__cell {
|
|
87
|
-
border: var(--nm-rule) solid var(--nm-
|
|
87
|
+
border: var(--nm-rule) solid var(--nm-border);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
.nm-table[data-variant='plain'] .nm-table__head {
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
.nm-table__footer {
|
|
115
|
-
border-top: var(--nm-rule) solid var(--nm-
|
|
115
|
+
border-top: var(--nm-rule) solid var(--nm-border-strong);
|
|
116
116
|
background: var(--nm-raised);
|
|
117
117
|
font-weight: var(--nm-weight-medium);
|
|
118
118
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
width: 100%;
|
|
5
5
|
min-height: calc(var(--control-h) * 2.5);
|
|
6
6
|
padding: var(--field-area-py) var(--control-px);
|
|
7
|
-
border: var(--nm-rule) solid var(--nm-
|
|
7
|
+
border: var(--nm-rule) solid var(--nm-border-strong);
|
|
8
8
|
border-radius: var(--nm-control-r);
|
|
9
9
|
background: var(--nm-raised);
|
|
10
10
|
color: var(--nm-fg);
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
.nm-textarea:hover:not(:disabled) {
|
|
27
|
-
border-color: var(--nm-stroke);
|
|
27
|
+
border-color: var(--nm-border-stroke);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
.nm-textarea:focus-visible {
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
flex: none;
|
|
103
103
|
flex-direction: column;
|
|
104
104
|
width: var(--nm-side-panel-basis, 50%);
|
|
105
|
-
border-inline-start: var(--nm-rule) solid var(--nm-divider);
|
|
105
|
+
border-inline-start: var(--nm-rule) solid var(--nm-border-divider);
|
|
106
106
|
background: var(--nm-canvas);
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
height: 100%;
|
|
134
134
|
min-height: 100%;
|
|
135
135
|
padding: var(--nm-space-16);
|
|
136
|
-
border: var(--nm-rule) solid var(--nm-
|
|
136
|
+
border: var(--nm-rule) solid var(--nm-border-strong);
|
|
137
137
|
border-radius: var(--nm-control-r);
|
|
138
138
|
outline: none;
|
|
139
139
|
resize: none;
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
height: 100%;
|
|
157
157
|
padding: var(--nm-space-16);
|
|
158
158
|
overflow-y: auto;
|
|
159
|
-
border: var(--nm-rule) solid var(--nm-
|
|
159
|
+
border: var(--nm-rule) solid var(--nm-border-strong);
|
|
160
160
|
border-radius: var(--nm-control-r);
|
|
161
161
|
background: var(--nm-raised);
|
|
162
162
|
}
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
/* Raised sits on a surface of its own with an edge, so it reads on any background. Panel has no edge. */
|
|
34
34
|
.nm-icon-button--raised {
|
|
35
35
|
background: var(--nm-raised);
|
|
36
|
-
box-shadow: inset 0 0 0 var(--nm-rule) var(--nm-
|
|
36
|
+
box-shadow: inset 0 0 0 var(--nm-rule) var(--nm-border-strong);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.nm-icon-button--quiet {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
.nm-icon-button--quiet.nm-icon-button--active:not(:disabled) {
|
|
49
49
|
background: var(--nm-raised);
|
|
50
50
|
color: var(--nm-fg);
|
|
51
|
-
box-shadow: inset 0 0 0 var(--nm-rule) var(--nm-
|
|
51
|
+
box-shadow: inset 0 0 0 var(--nm-rule) var(--nm-border);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
.nm-icon-button--solid {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
.nm-login__error {
|
|
48
48
|
margin: 0;
|
|
49
49
|
color: var(--nm-fg);
|
|
50
|
-
border: var(--nm-rule) solid var(--nm-
|
|
50
|
+
border: var(--nm-rule) solid var(--nm-border-strong);
|
|
51
51
|
border-radius: var(--nm-control-r);
|
|
52
52
|
padding: var(--control-px);
|
|
53
53
|
font-size: var(--control-fs);
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
width: 100%;
|
|
90
90
|
height: var(--nm-field-h);
|
|
91
91
|
padding: 0 var(--control-px);
|
|
92
|
-
border: var(--nm-rule) solid var(--nm-
|
|
92
|
+
border: var(--nm-rule) solid var(--nm-border-strong);
|
|
93
93
|
border-radius: var(--nm-control-r);
|
|
94
94
|
background: var(--nm-raised);
|
|
95
95
|
color: var(--nm-fg);
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
.nm-login__control:focus {
|
|
101
|
-
border-color: var(--nm-stroke);
|
|
101
|
+
border-color: var(--nm-border-stroke);
|
|
102
102
|
outline: none;
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -55,6 +55,21 @@ export const NM_UI_SPACE_PERCENT = {
|
|
|
55
55
|
default: 100,
|
|
56
56
|
} as const;
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* How visible the borders are. Every border colour in the kit is mixed through one strength, so default is the kit as
|
|
60
|
+
* drawn, subtle is barely there, and none removes them. Geometry does not change: the border turns transparent and keeps
|
|
61
|
+
* its width. Fills and tracks that share the line colours are untouched, and so are state borders: focus, selection, checked and
|
|
62
|
+
* error keep their colour.
|
|
63
|
+
*/
|
|
64
|
+
export const NM_BORDER_STYLES = ['default', 'subtle', 'none'] as const;
|
|
65
|
+
export type NmBorderStyle = (typeof NM_BORDER_STYLES)[number];
|
|
66
|
+
export const NM_BORDER_STRENGTH: Record<NmBorderStyle, string> = {
|
|
67
|
+
default: '100%',
|
|
68
|
+
subtle: '35%',
|
|
69
|
+
none: '0%',
|
|
70
|
+
};
|
|
71
|
+
/** Set on the root beside the tokens, so a product can style a state without the appearance script: `:root[data-nm-borders="none"]`. */
|
|
72
|
+
export const NM_BORDER_ATTRIBUTE = 'data-nm-borders' as const;
|
|
58
73
|
export const NM_APPEARANCE_CONTRAST = {
|
|
59
74
|
min: 0,
|
|
60
75
|
max: 100,
|
|
@@ -183,6 +198,7 @@ export const NM_APPEARANCE_DEFAULTS = {
|
|
|
183
198
|
uiRadiusPercent: NM_UI_RADIUS_PERCENT.default,
|
|
184
199
|
uiSpacePercent: NM_UI_SPACE_PERCENT.default,
|
|
185
200
|
contrast: NM_APPEARANCE_CONTRAST.default,
|
|
201
|
+
borders: 'default' as NmBorderStyle,
|
|
186
202
|
} as const;
|
|
187
203
|
|
|
188
204
|
export const NM_APPEARANCE_CSS_VARS = [
|
|
@@ -241,6 +257,7 @@ export const NM_APPEARANCE_CSS_VARS = [
|
|
|
241
257
|
'--nm-ui-chip-min-height',
|
|
242
258
|
'--nm-radius-scale',
|
|
243
259
|
'--nm-space-scale',
|
|
260
|
+
'--nm-border-strength',
|
|
244
261
|
'--text-primary',
|
|
245
262
|
'--text-secondary',
|
|
246
263
|
'--text-tertiary',
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
NM_APPEARANCE_DEFAULTS,
|
|
5
5
|
NM_APPEARANCE_MODES,
|
|
6
6
|
NM_APPEARANCE_STORAGE_KEY,
|
|
7
|
+
NM_BORDER_STYLES,
|
|
7
8
|
NM_UI_FONT_SIZE_PX,
|
|
8
9
|
NM_UI_FONT_WEIGHT,
|
|
9
10
|
NM_UI_ICON_SIZE_PX,
|
|
@@ -12,6 +13,7 @@ import {
|
|
|
12
13
|
findThemePreset,
|
|
13
14
|
type NmAccentPreset,
|
|
14
15
|
type NmAppearanceMode,
|
|
16
|
+
type NmBorderStyle,
|
|
15
17
|
} from '../../config/nm-appearance.ts';
|
|
16
18
|
import { normalizeHexColor } from './color.ts';
|
|
17
19
|
|
|
@@ -28,6 +30,7 @@ export type NmAppearanceState = {
|
|
|
28
30
|
uiRadiusPercent: number;
|
|
29
31
|
uiSpacePercent: number;
|
|
30
32
|
contrast: number;
|
|
33
|
+
borders: NmBorderStyle;
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
export { NM_APPEARANCE_STORAGE_KEY };
|
|
@@ -36,6 +39,9 @@ function isMode(value: unknown): value is NmAppearanceMode {
|
|
|
36
39
|
return typeof value === 'string' && (NM_APPEARANCE_MODES as readonly string[]).includes(value);
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
function isBorderStyle(value: unknown): value is NmBorderStyle {
|
|
43
|
+
return typeof value === 'string' && (NM_BORDER_STYLES as readonly string[]).includes(value);
|
|
44
|
+
}
|
|
39
45
|
function isAccentPreset(value: unknown): value is NmAccentPreset {
|
|
40
46
|
return typeof value === 'string' && (NM_ACCENT_PRESETS as readonly string[]).includes(value);
|
|
41
47
|
}
|
|
@@ -82,6 +88,7 @@ export function createDefaultAppearanceState(): NmAppearanceState {
|
|
|
82
88
|
uiRadiusPercent: NM_APPEARANCE_DEFAULTS.uiRadiusPercent,
|
|
83
89
|
uiSpacePercent: NM_APPEARANCE_DEFAULTS.uiSpacePercent,
|
|
84
90
|
contrast: NM_APPEARANCE_CONTRAST.default,
|
|
91
|
+
borders: NM_APPEARANCE_DEFAULTS.borders,
|
|
85
92
|
};
|
|
86
93
|
return applyThemePresetPalette(base);
|
|
87
94
|
}
|
|
@@ -185,6 +192,7 @@ export function parseAppearanceState(raw: unknown): NmAppearanceState {
|
|
|
185
192
|
NM_APPEARANCE_CONTRAST.max,
|
|
186
193
|
defaults.contrast,
|
|
187
194
|
),
|
|
195
|
+
borders: isBorderStyle(record.borders) ? record.borders : defaults.borders,
|
|
188
196
|
};
|
|
189
197
|
}
|
|
190
198
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { NmAppearanceState } from './appearanceState.ts';
|
|
2
|
-
import { NM_APPEARANCE_APPLIED_EVENT, NM_APPEARANCE_CSS_VARS } from '../../config/nm-appearance.ts';
|
|
2
|
+
import { NM_APPEARANCE_APPLIED_EVENT, NM_APPEARANCE_CSS_VARS, NM_BORDER_ATTRIBUTE } from '../../config/nm-appearance.ts';
|
|
3
3
|
import { resolveAppearanceScheme } from './appearanceState.ts';
|
|
4
4
|
import { deriveAppearanceTokens } from './deriveTokens.ts';
|
|
5
5
|
import { createLogger } from '../../kit-logger.ts';
|
|
@@ -17,6 +17,7 @@ export function clearAppliedAppearance(root: HTMLElement = document.documentElem
|
|
|
17
17
|
NM_APPEARANCE_CSS_VARS.forEach((property) => {
|
|
18
18
|
root.style.removeProperty(property);
|
|
19
19
|
});
|
|
20
|
+
root.removeAttribute(NM_BORDER_ATTRIBUTE);
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export function applyAppearanceState(
|
|
@@ -29,6 +30,7 @@ export function applyAppearanceState(
|
|
|
29
30
|
Object.entries(tokens).forEach(([property, value]) => {
|
|
30
31
|
root.style.setProperty(property, value);
|
|
31
32
|
});
|
|
33
|
+
root.setAttribute(NM_BORDER_ATTRIBUTE, state.borders);
|
|
32
34
|
if (typeof window !== 'undefined') {
|
|
33
35
|
window.dispatchEvent(new CustomEvent(NM_APPEARANCE_APPLIED_EVENT));
|
|
34
36
|
}
|
|
@@ -2,6 +2,7 @@ import type { NmAppearanceState } from './appearanceState.ts';
|
|
|
2
2
|
import {
|
|
3
3
|
NM_ACCENT_HEX,
|
|
4
4
|
NM_APPEARANCE_CONTRAST,
|
|
5
|
+
NM_BORDER_STRENGTH,
|
|
5
6
|
NM_THEME_PRESETS,
|
|
6
7
|
NM_UI_FONT_SIZE_PX,
|
|
7
8
|
NM_UI_FONT_WEIGHT,
|
|
@@ -205,6 +206,7 @@ export function deriveAppearanceTokens(
|
|
|
205
206
|
...deriveUiControlTokens(state.uiFontSizePx, state.uiIconSizePx),
|
|
206
207
|
...deriveRadiusScale(state.uiRadiusPercent),
|
|
207
208
|
...deriveSpaceScale(state.uiSpacePercent),
|
|
209
|
+
'--nm-border-strength': NM_BORDER_STRENGTH[state.borders],
|
|
208
210
|
};
|
|
209
211
|
|
|
210
212
|
return {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
html.light .nm-panel-bar {
|
|
2
|
-
border-bottom-color: var(--nm-
|
|
2
|
+
border-bottom-color: var(--nm-border);
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
html.light .nm-collection__stage-bar {
|
|
6
|
-
border-bottom-color: var(--nm-
|
|
7
|
-
border-left-color: var(--nm-
|
|
6
|
+
border-bottom-color: var(--nm-border);
|
|
7
|
+
border-left-color: var(--nm-border);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
html.light .nm-list-item:not(.nm-list-item--face) {
|
|
@@ -321,6 +321,18 @@
|
|
|
321
321
|
--nm-knot-pulse: 3.2s;
|
|
322
322
|
--nm-knot-pulse-min: 0.4;
|
|
323
323
|
--nm-rule: 1px;
|
|
324
|
+
/* Borders. Every border colour is one of the line colours mixed through one strength, so a product can turn its
|
|
325
|
+
borders subtle or off in one place while the fills and tracks that share those colours keep theirs. The border
|
|
326
|
+
keeps its width and turns transparent, so nothing moves. State is not part of this: focus, selection, checked and error
|
|
327
|
+
borders keep the foreground or destructive colour, so a keyboard user and an active tab are never lost. */
|
|
328
|
+
--nm-border-strength: 100%;
|
|
329
|
+
--nm-border: color-mix(in srgb, var(--nm-line) var(--nm-border-strength), transparent);
|
|
330
|
+
--nm-border-strong: color-mix(in srgb, var(--nm-line-strong) var(--nm-border-strength), transparent);
|
|
331
|
+
--nm-border-stroke: color-mix(in srgb, var(--nm-stroke) var(--nm-border-strength), transparent);
|
|
332
|
+
--nm-border-divider: color-mix(in srgb, var(--nm-divider) var(--nm-border-strength), transparent);
|
|
333
|
+
/* A control whose only shape is its border (checkbox, radio) takes this fill, so it still has a shape with the
|
|
334
|
+
borders off. Transparent until then. */
|
|
335
|
+
--nm-borderless-fill: transparent;
|
|
324
336
|
--nm-rule-dash: 4px;
|
|
325
337
|
--nm-rule-gap: 4px;
|
|
326
338
|
--nm-rule-pair: 2.5rem;
|
|
@@ -439,3 +451,12 @@ html.light {
|
|
|
439
451
|
--nm-syntax-function: #6f42c1;
|
|
440
452
|
--nm-syntax-constant: #005cc5;
|
|
441
453
|
}
|
|
454
|
+
|
|
455
|
+
/* The border setting without the appearance script: set the attribute on the root. */
|
|
456
|
+
:root[data-nm-borders='subtle'] {
|
|
457
|
+
--nm-border-strength: 35%;
|
|
458
|
+
}
|
|
459
|
+
:root[data-nm-borders='none'] {
|
|
460
|
+
--nm-border-strength: 0%;
|
|
461
|
+
--nm-borderless-fill: var(--nm-inset);
|
|
462
|
+
}
|