@scalewing/react 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @scalewing/react
2
2
 
3
+ ## 1.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2444ec5: Button `variant="tertiary"` is a solid fill on `--sw-color-tertiary` with
8
+ `--sw-color-onTertiary`. `secondary` now fills with `--sw-color-secondary`
9
+ and draws `--sw-button-secondary-border`, which stays the hairline unless a
10
+ palette fills the secondary action (for example `signal`). The stylesheet
11
+ emits the new semantic colour properties. Default and cerulean themes look
12
+ unchanged.
13
+ - 622ab77: `Card variant="filled"` (`.sw-card-filled`) is a quiet `--sw-color-subtle`
14
+ fill with no border, for plain information apart from pressable rows.
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies [b5a56b7]
19
+ - Updated dependencies [2444ec5]
20
+ - Updated dependencies [622ab77]
21
+ - @scalewing/tokens@1.3.0
22
+
3
23
  ## 1.6.1
4
24
 
5
25
  ### Patch Changes
package/README.md CHANGED
@@ -66,6 +66,8 @@ Import the CSS once at the application entry. Do not copy it into your source tr
66
66
 
67
67
  `Separator` divides sections with a token-colored line. It is horizontal by default; use `orientation="vertical"` in a flex row. Set `decorative` when the line only supports layout so assistive technology ignores it.
68
68
 
69
+ `Card` defaults to `glass`; `outlined` and `elevated` are solid surfaces, and `filled` is a quiet `--sw-color-subtle` fill with no border for plain information apart from pressable rows.
70
+
69
71
  `Text` steps `display` and `heading` down to the compact token sizes below the `md` breakpoint; consumers do not size type per viewport.
70
72
 
71
73
  `Text` takes an optional `align` (`start`, `center`, `end`) mapped to generated `sw-text-align-*` classes, for a heading that must stay centered when it wraps.
@@ -11,7 +11,8 @@ export function buttonClassNames(options) {
11
11
  function variantRules() {
12
12
  return [
13
13
  `.sw-button-primary { background: var(--sw-color-accent); border-color: transparent; color: var(--sw-color-onAccent); }`,
14
- `.sw-button-secondary { background: var(--sw-color-surface); border-color: var(--sw-color-border); color: var(--sw-color-text); }`,
14
+ `.sw-button-secondary { background: var(--sw-color-secondary); border-color: var(--sw-button-secondary-border); color: var(--sw-color-onSecondary); }`,
15
+ `.sw-button-tertiary { background: var(--sw-color-tertiary); border-color: transparent; color: var(--sw-color-onTertiary); }`,
15
16
  `.sw-button-ghost { background: transparent; border-color: transparent; color: var(--sw-color-accent); }`,
16
17
  `.sw-button-danger { background: var(--sw-color-danger); border-color: transparent; color: var(--sw-color-onDanger); }`,
17
18
  ].join('\n');
@@ -74,6 +74,11 @@ export function cssComponentClasses() {
74
74
  box-shadow: var(--sw-elevation-sm);
75
75
  }
76
76
 
77
+ /* Plain information on a quiet fill, apart from rows that press. */
78
+ .sw-card-filled {
79
+ background: var(--sw-color-subtle);
80
+ }
81
+
77
82
  @media (prefers-reduced-transparency: reduce) {
78
83
  .sw-card-glass,
79
84
  .sw-app-header,
@@ -1,4 +1,4 @@
1
- import { colorsForPalette, createTheme, paletteHasStylesheet, palettesWithStylesheets, semanticColorKeys, } from '@scalewing/tokens';
1
+ import { colorsForPalette, createTheme, paletteHasStylesheet, palettesWithStylesheets, secondaryActionBorder, semanticColorKeys, } from '@scalewing/tokens';
2
2
  function paletteCustomProperties(id, scheme) {
3
3
  const overlay = colorsForPalette(id, scheme);
4
4
  const theme = createTheme({ colorScheme: scheme, palette: id });
@@ -8,6 +8,10 @@ function paletteCustomProperties(id, scheme) {
8
8
  lines.push(` --sw-color-${key}: ${theme.colors[key]};`);
9
9
  }
10
10
  }
11
+ // The secondary outline derives from these three, so it follows them.
12
+ if (overlay.secondary || overlay.surface || overlay.border) {
13
+ lines.push(` --sw-button-secondary-border: ${secondaryActionBorder(theme.colors)};`);
14
+ }
11
15
  lines.push(` --sw-glass-blur: ${theme.glass.blur}px;`);
12
16
  lines.push(` --sw-glass-saturate: ${theme.glass.saturate};`);
13
17
  lines.push(` --sw-glass-fill: ${theme.glass.fill};`);
@@ -1,8 +1,9 @@
1
- import { controlScale, disabledOpacity, focusRing, quietOpacity, radiusScale, semanticColorKeys, spacingScale, spacingSteps, splitScale, } from '@scalewing/tokens';
1
+ import { controlScale, disabledOpacity, focusRing, quietOpacity, radiusScale, secondaryActionBorder, semanticColorKeys, spacingScale, spacingSteps, splitScale, } from '@scalewing/tokens';
2
2
  function colorDeclarations(theme) {
3
- return semanticColorKeys
4
- .map((key) => ` --sw-color-${key}: ${theme.colors[key]};`)
5
- .join('\n');
3
+ return [
4
+ ...semanticColorKeys.map((key) => ` --sw-color-${key}: ${theme.colors[key]};`),
5
+ ` --sw-button-secondary-border: ${secondaryActionBorder(theme.colors)};`,
6
+ ].join('\n');
6
7
  }
7
8
  function glassDeclarations(theme) {
8
9
  return ` --sw-glass-blur: ${theme.glass.blur}px;
@@ -8,6 +8,7 @@
8
8
  --sw-color-accent: #3E3E24;
9
9
  --sw-color-onAccent: #FFFFFF;
10
10
  --sw-color-border: #C9C2AE;
11
+ --sw-button-secondary-border: #C9C2AE;
11
12
  --sw-glass-blur: 24px;
12
13
  --sw-glass-saturate: 1;
13
14
  --sw-glass-fill: rgba(255, 255, 255, 1);
@@ -23,6 +24,7 @@
23
24
  --sw-color-accent: #CEA453;
24
25
  --sw-color-onAccent: #101214;
25
26
  --sw-color-border: #3D5238;
27
+ --sw-button-secondary-border: #3D5238;
26
28
  --sw-glass-blur: 24px;
27
29
  --sw-glass-saturate: 1.8;
28
30
  --sw-glass-fill: rgba(60, 52, 40, 0.72);
@@ -8,6 +8,7 @@
8
8
  --sw-color-accent: #473333;
9
9
  --sw-color-onAccent: #FFFFFF;
10
10
  --sw-color-border: #E0CBA8;
11
+ --sw-button-secondary-border: #E0CBA8;
11
12
  --sw-glass-blur: 24px;
12
13
  --sw-glass-saturate: 1;
13
14
  --sw-glass-fill: rgba(255, 255, 255, 1);
@@ -23,6 +24,7 @@
23
24
  --sw-color-accent: #E8C69F;
24
25
  --sw-color-onAccent: #101214;
25
26
  --sw-color-border: #6B5353;
27
+ --sw-button-secondary-border: #6B5353;
26
28
  --sw-glass-blur: 24px;
27
29
  --sw-glass-saturate: 1.8;
28
30
  --sw-glass-fill: rgba(65, 59, 53, 0.72);
@@ -8,6 +8,7 @@
8
8
  --sw-color-accent: #A33B2B;
9
9
  --sw-color-onAccent: #FFFFFF;
10
10
  --sw-color-border: #D0D0B8;
11
+ --sw-button-secondary-border: #D0D0B8;
11
12
  --sw-glass-blur: 24px;
12
13
  --sw-glass-saturate: 1;
13
14
  --sw-glass-fill: rgba(255, 255, 255, 1);
@@ -23,6 +24,7 @@
23
24
  --sw-color-accent: #EEAF90;
24
25
  --sw-color-onAccent: #101214;
25
26
  --sw-color-border: #3A4158;
27
+ --sw-button-secondary-border: #3A4158;
26
28
  --sw-glass-blur: 24px;
27
29
  --sw-glass-saturate: 1.8;
28
30
  --sw-glass-fill: rgba(66, 54, 51, 0.72);
@@ -0,0 +1,31 @@
1
+ /* Generated by @scalewing/tokens. Do not edit by hand. */
2
+ :root,
3
+ [data-theme='light'] {
4
+ --sw-color-accent: #0066CC;
5
+ --sw-color-onAccent: #FFFFFF;
6
+ --sw-color-secondary: #1D1D1F;
7
+ --sw-color-onSecondary: #FFFFFF;
8
+ --sw-color-tertiary: #7C5CD6;
9
+ --sw-color-onTertiary: #FFFFFF;
10
+ --sw-button-secondary-border: #1D1D1F;
11
+ --sw-glass-blur: 24px;
12
+ --sw-glass-saturate: 1;
13
+ --sw-glass-fill: rgba(255, 255, 255, 1);
14
+ --sw-glass-border: rgba(210, 210, 215, 1);
15
+ --sw-glass-specular: rgba(255, 255, 255, 0);
16
+ }
17
+
18
+ [data-theme='dark'] {
19
+ --sw-color-accent: #5AC8FA;
20
+ --sw-color-onAccent: #101214;
21
+ --sw-color-secondary: #F5F5F7;
22
+ --sw-color-onSecondary: #101214;
23
+ --sw-color-tertiary: #C4B5FD;
24
+ --sw-color-onTertiary: #101214;
25
+ --sw-button-secondary-border: #F5F5F7;
26
+ --sw-glass-blur: 24px;
27
+ --sw-glass-saturate: 1.8;
28
+ --sw-glass-fill: rgba(39, 59, 70, 0.72);
29
+ --sw-glass-border: rgba(189, 233, 253, 0.22);
30
+ --sw-glass-specular: rgba(222, 244, 254, 0.28);
31
+ }
@@ -8,6 +8,7 @@
8
8
  --sw-color-accent: #A33B20;
9
9
  --sw-color-onAccent: #FFFFFF;
10
10
  --sw-color-border: #E5C48A;
11
+ --sw-button-secondary-border: #E5C48A;
11
12
  --sw-glass-blur: 24px;
12
13
  --sw-glass-saturate: 1;
13
14
  --sw-glass-fill: rgba(255, 255, 255, 1);
@@ -23,6 +24,7 @@
23
24
  --sw-color-accent: #FAA968;
24
25
  --sw-color-onAccent: #101214;
25
26
  --sw-color-border: #1A5A70;
27
+ --sw-button-secondary-border: #1A5A70;
26
28
  --sw-glass-blur: 24px;
27
29
  --sw-glass-saturate: 1.8;
28
30
  --sw-glass-fill: rgba(68, 53, 43, 0.72);
@@ -18,6 +18,7 @@
18
18
  --sw-color-accent: #FF2A6D;
19
19
  --sw-color-onAccent: #101214;
20
20
  --sw-color-border: #4A2C6A;
21
+ --sw-button-secondary-border: #4A2C6A;
21
22
  --sw-glass-blur: 24px;
22
23
  --sw-glass-saturate: 1.8;
23
24
  --sw-glass-fill: rgba(69, 31, 44, 0.72);
package/dist/styles.css CHANGED
@@ -7,11 +7,17 @@
7
7
  --sw-color-muted: #6E6E73;
8
8
  --sw-color-accent: #5B3DF5;
9
9
  --sw-color-onAccent: #FFFFFF;
10
+ --sw-color-secondary: #FFFFFF;
11
+ --sw-color-onSecondary: #1D1D1F;
12
+ --sw-color-tertiary: #48484A;
13
+ --sw-color-onTertiary: #FFFFFF;
14
+ --sw-color-subtle: #F2F2F5;
10
15
  --sw-color-danger: #B42318;
11
16
  --sw-color-onDanger: #FFFFFF;
12
17
  --sw-color-success: #087443;
13
18
  --sw-color-warning: #B54708;
14
19
  --sw-color-border: #D2D2D7;
20
+ --sw-button-secondary-border: #D2D2D7;
15
21
  --sw-space-0: 0px;
16
22
  --sw-space-1: 4px;
17
23
  --sw-space-2: 8px;
@@ -64,11 +70,17 @@
64
70
  --sw-color-muted: #A1A1A6;
65
71
  --sw-color-accent: #A78BFA;
66
72
  --sw-color-onAccent: #101214;
73
+ --sw-color-secondary: #1C1C1E;
74
+ --sw-color-onSecondary: #F5F5F7;
75
+ --sw-color-tertiary: #D1D1D6;
76
+ --sw-color-onTertiary: #101214;
77
+ --sw-color-subtle: #2C2C2E;
67
78
  --sw-color-danger: #F97066;
68
79
  --sw-color-onDanger: #101214;
69
80
  --sw-color-success: #5BE0A0;
70
81
  --sw-color-warning: #FDB022;
71
82
  --sw-color-border: #3A3A3C;
83
+ --sw-button-secondary-border: #3A3A3C;
72
84
  --sw-space-0: 0px;
73
85
  --sw-space-1: 4px;
74
86
  --sw-space-2: 8px;
@@ -134,6 +146,36 @@
134
146
  --sw-glass-specular: rgba(222, 244, 254, 0.28);
135
147
  }
136
148
 
149
+ [data-theme='light'][data-palette='signal'] {
150
+ --sw-color-accent: #0066CC;
151
+ --sw-color-onAccent: #FFFFFF;
152
+ --sw-color-secondary: #1D1D1F;
153
+ --sw-color-onSecondary: #FFFFFF;
154
+ --sw-color-tertiary: #7C5CD6;
155
+ --sw-color-onTertiary: #FFFFFF;
156
+ --sw-button-secondary-border: #1D1D1F;
157
+ --sw-glass-blur: 24px;
158
+ --sw-glass-saturate: 1;
159
+ --sw-glass-fill: rgba(255, 255, 255, 1);
160
+ --sw-glass-border: rgba(210, 210, 215, 1);
161
+ --sw-glass-specular: rgba(255, 255, 255, 0);
162
+ }
163
+
164
+ [data-theme='dark'][data-palette='signal'] {
165
+ --sw-color-accent: #5AC8FA;
166
+ --sw-color-onAccent: #101214;
167
+ --sw-color-secondary: #F5F5F7;
168
+ --sw-color-onSecondary: #101214;
169
+ --sw-color-tertiary: #C4B5FD;
170
+ --sw-color-onTertiary: #101214;
171
+ --sw-button-secondary-border: #F5F5F7;
172
+ --sw-glass-blur: 24px;
173
+ --sw-glass-saturate: 1.8;
174
+ --sw-glass-fill: rgba(39, 59, 70, 0.72);
175
+ --sw-glass-border: rgba(189, 233, 253, 0.22);
176
+ --sw-glass-specular: rgba(222, 244, 254, 0.28);
177
+ }
178
+
137
179
  [data-theme='light'][data-palette='navy'] {
138
180
  --sw-color-accent: #0A2540;
139
181
  --sw-color-onAccent: #FFFFFF;
@@ -342,6 +384,7 @@
342
384
  --sw-color-accent: #A33B20;
343
385
  --sw-color-onAccent: #FFFFFF;
344
386
  --sw-color-border: #E5C48A;
387
+ --sw-button-secondary-border: #E5C48A;
345
388
  --sw-glass-blur: 24px;
346
389
  --sw-glass-saturate: 1;
347
390
  --sw-glass-fill: rgba(255, 255, 255, 1);
@@ -357,6 +400,7 @@
357
400
  --sw-color-accent: #FAA968;
358
401
  --sw-color-onAccent: #101214;
359
402
  --sw-color-border: #1A5A70;
403
+ --sw-button-secondary-border: #1A5A70;
360
404
  --sw-glass-blur: 24px;
361
405
  --sw-glass-saturate: 1.8;
362
406
  --sw-glass-fill: rgba(68, 53, 43, 0.72);
@@ -372,6 +416,7 @@
372
416
  --sw-color-accent: #3E3E24;
373
417
  --sw-color-onAccent: #FFFFFF;
374
418
  --sw-color-border: #C9C2AE;
419
+ --sw-button-secondary-border: #C9C2AE;
375
420
  --sw-glass-blur: 24px;
376
421
  --sw-glass-saturate: 1;
377
422
  --sw-glass-fill: rgba(255, 255, 255, 1);
@@ -387,6 +432,7 @@
387
432
  --sw-color-accent: #CEA453;
388
433
  --sw-color-onAccent: #101214;
389
434
  --sw-color-border: #3D5238;
435
+ --sw-button-secondary-border: #3D5238;
390
436
  --sw-glass-blur: 24px;
391
437
  --sw-glass-saturate: 1.8;
392
438
  --sw-glass-fill: rgba(60, 52, 40, 0.72);
@@ -402,6 +448,7 @@
402
448
  --sw-color-accent: #A33B2B;
403
449
  --sw-color-onAccent: #FFFFFF;
404
450
  --sw-color-border: #D0D0B8;
451
+ --sw-button-secondary-border: #D0D0B8;
405
452
  --sw-glass-blur: 24px;
406
453
  --sw-glass-saturate: 1;
407
454
  --sw-glass-fill: rgba(255, 255, 255, 1);
@@ -417,6 +464,7 @@
417
464
  --sw-color-accent: #EEAF90;
418
465
  --sw-color-onAccent: #101214;
419
466
  --sw-color-border: #3A4158;
467
+ --sw-button-secondary-border: #3A4158;
420
468
  --sw-glass-blur: 24px;
421
469
  --sw-glass-saturate: 1.8;
422
470
  --sw-glass-fill: rgba(66, 54, 51, 0.72);
@@ -432,6 +480,7 @@
432
480
  --sw-color-accent: #473333;
433
481
  --sw-color-onAccent: #FFFFFF;
434
482
  --sw-color-border: #E0CBA8;
483
+ --sw-button-secondary-border: #E0CBA8;
435
484
  --sw-glass-blur: 24px;
436
485
  --sw-glass-saturate: 1;
437
486
  --sw-glass-fill: rgba(255, 255, 255, 1);
@@ -447,6 +496,7 @@
447
496
  --sw-color-accent: #E8C69F;
448
497
  --sw-color-onAccent: #101214;
449
498
  --sw-color-border: #6B5353;
499
+ --sw-button-secondary-border: #6B5353;
450
500
  --sw-glass-blur: 24px;
451
501
  --sw-glass-saturate: 1.8;
452
502
  --sw-glass-fill: rgba(65, 59, 53, 0.72);
@@ -472,6 +522,7 @@
472
522
  --sw-color-accent: #FF2A6D;
473
523
  --sw-color-onAccent: #101214;
474
524
  --sw-color-border: #4A2C6A;
525
+ --sw-button-secondary-border: #4A2C6A;
475
526
  --sw-glass-blur: 24px;
476
527
  --sw-glass-saturate: 1.8;
477
528
  --sw-glass-fill: rgba(69, 31, 44, 0.72);
@@ -700,6 +751,11 @@ body {
700
751
  box-shadow: var(--sw-elevation-sm);
701
752
  }
702
753
 
754
+ /* Plain information on a quiet fill, apart from rows that press. */
755
+ .sw-card-filled {
756
+ background: var(--sw-color-subtle);
757
+ }
758
+
703
759
  @media (prefers-reduced-transparency: reduce) {
704
760
  .sw-card-glass,
705
761
  .sw-app-header,
@@ -779,7 +835,8 @@ body {
779
835
  }
780
836
 
781
837
  .sw-button-primary { background: var(--sw-color-accent); border-color: transparent; color: var(--sw-color-onAccent); }
782
- .sw-button-secondary { background: var(--sw-color-surface); border-color: var(--sw-color-border); color: var(--sw-color-text); }
838
+ .sw-button-secondary { background: var(--sw-color-secondary); border-color: var(--sw-button-secondary-border); color: var(--sw-color-onSecondary); }
839
+ .sw-button-tertiary { background: var(--sw-color-tertiary); border-color: transparent; color: var(--sw-color-onTertiary); }
783
840
  .sw-button-ghost { background: transparent; border-color: transparent; color: var(--sw-color-accent); }
784
841
  .sw-button-danger { background: var(--sw-color-danger); border-color: transparent; color: var(--sw-color-onDanger); }
785
842
  .sw-button-xs { min-height: 28px; padding-inline: 10px; }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useContext, useEffect, useMemo, useState, } from 'react';
3
- import { createTheme, semanticColorKeys, } from '@scalewing/tokens';
3
+ import { createTheme, secondaryActionBorder, semanticColorKeys, } from '@scalewing/tokens';
4
4
  const ThemeContext = createContext(null);
5
5
  function schemeFromMedia() {
6
6
  if (typeof window === 'undefined' ||
@@ -16,6 +16,7 @@ function themeCssVars(theme) {
16
16
  for (const key of semanticColorKeys) {
17
17
  vars[`--sw-color-${key}`] = theme.colors[key];
18
18
  }
19
+ vars['--sw-button-secondary-border'] = secondaryActionBorder(theme.colors);
19
20
  vars['--sw-glass-blur'] = `${theme.glass.blur}px`;
20
21
  vars['--sw-glass-saturate'] = String(theme.glass.saturate);
21
22
  vars['--sw-glass-fill'] = theme.glass.fill;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalewing/react",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "Scalewing DOM components and package-owned CSS utilities.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -38,7 +38,7 @@
38
38
  "README.md"
39
39
  ],
40
40
  "dependencies": {
41
- "@scalewing/tokens": "^1.2.0"
41
+ "@scalewing/tokens": "^1.3.0"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "react": "^19.0.0",