@scalewing/react 1.27.0 → 1.29.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +99 -3
  3. package/dist/components/Checkbox.js +5 -4
  4. package/dist/components/DenominationGrid.d.ts +4 -1
  5. package/dist/components/DenominationGrid.js +8 -3
  6. package/dist/components/Dialog.d.ts +28 -4
  7. package/dist/components/Dialog.js +20 -2
  8. package/dist/components/GlyphTile.d.ts +21 -0
  9. package/dist/components/GlyphTile.js +17 -0
  10. package/dist/components/MultiSelect.d.ts +10 -0
  11. package/dist/components/MultiSelect.js +62 -0
  12. package/dist/components/Notice.d.ts +69 -0
  13. package/dist/components/Notice.js +48 -0
  14. package/dist/components/Progress.d.ts +3 -1
  15. package/dist/components/Progress.js +4 -0
  16. package/dist/components/SegmentedControl.d.ts +8 -0
  17. package/dist/components/SegmentedControl.js +4 -3
  18. package/dist/components/Toast.d.ts +20 -4
  19. package/dist/components/Toast.js +44 -21
  20. package/dist/components/checkbox/CheckboxControl.d.ts +9 -0
  21. package/dist/components/checkbox/CheckboxControl.js +9 -0
  22. package/dist/components/denomination-grid/DenominationStrip.d.ts +5 -2
  23. package/dist/components/denomination-grid/DenominationStrip.js +2 -2
  24. package/dist/components/denomination-grid/DenominationTiles.d.ts +5 -2
  25. package/dist/components/denomination-grid/DenominationTiles.js +2 -2
  26. package/dist/components/denomination-grid/types.d.ts +9 -0
  27. package/dist/components/dialog/DialogFooter.d.ts +14 -0
  28. package/dist/components/dialog/DialogFooter.js +11 -0
  29. package/dist/components/dialog/DialogTitle.d.ts +11 -4
  30. package/dist/components/dialog/DialogTitle.js +8 -6
  31. package/dist/components/multi-select/MultiSelectPanel.d.ts +25 -0
  32. package/dist/components/multi-select/MultiSelectPanel.js +41 -0
  33. package/dist/components/multi-select/types.d.ts +35 -0
  34. package/dist/components/multi-select/types.js +1 -0
  35. package/dist/components/multi-select/validate.d.ts +3 -0
  36. package/dist/components/multi-select/validate.js +25 -0
  37. package/dist/components/toast/ToastContent.d.ts +22 -0
  38. package/dist/components/toast/ToastContent.js +21 -0
  39. package/dist/components/toast/use-toast-hold.d.ts +28 -0
  40. package/dist/components/toast/use-toast-hold.js +53 -0
  41. package/dist/components/toast/use-toast-timer.d.ts +15 -0
  42. package/dist/components/toast/use-toast-timer.js +34 -0
  43. package/dist/css/css-components.js +16 -0
  44. package/dist/css/css-denomination-grid.js +4 -0
  45. package/dist/css/css-denomination-label.d.ts +10 -0
  46. package/dist/css/css-denomination-label.js +36 -0
  47. package/dist/css/css-dialog-frame.d.ts +2 -0
  48. package/dist/css/css-dialog-frame.js +83 -0
  49. package/dist/css/css-dialog.js +20 -4
  50. package/dist/css/css-glyph-tile.d.ts +5 -0
  51. package/dist/css/css-glyph-tile.js +57 -0
  52. package/dist/css/css-multi-select.d.ts +2 -0
  53. package/dist/css/css-multi-select.js +156 -0
  54. package/dist/css/css-notice.d.ts +22 -0
  55. package/dist/css/css-notice.js +168 -0
  56. package/dist/css/css-progress.d.ts +3 -0
  57. package/dist/css/css-progress.js +13 -6
  58. package/dist/css/css-segmented.js +58 -0
  59. package/dist/css/css-toast-card.d.ts +5 -0
  60. package/dist/css/css-toast-card.js +122 -0
  61. package/dist/css/css-variables.js +12 -1
  62. package/dist/css/stacking.js +5 -2
  63. package/dist/css/stylesheet.js +10 -0
  64. package/dist/index.d.ts +8 -5
  65. package/dist/index.js +7 -4
  66. package/dist/styles.css +522 -3
  67. package/package.json +2 -2
@@ -0,0 +1,22 @@
1
+ export declare const noticeTones: readonly ["info", "success", "warning", "danger"];
2
+ export declare const noticeVariants: readonly ["default", "band"];
3
+ /** `default` is a rounded note in the flow; `band` a full-width strip of page chrome. */
4
+ export type NoticeVariant = (typeof noticeVariants)[number];
5
+ /** The notice's meaning: information, a good outcome, a caution, a refusal. */
6
+ export type NoticeTone = (typeof noticeTones)[number];
7
+ /**
8
+ * How much of a tone's color the notice's fill mixes into the surface. Info
9
+ * uses the derived accent tint instead (ADR 0011), which already keeps the
10
+ * accent readable on every palette.
11
+ */
12
+ export declare const noticeTintShare = 0.1;
13
+ /**
14
+ * How far the notice's words move from the tone's color toward the text
15
+ * color, so they read darker than the tone on a light fill (lighter on a
16
+ * dark one) and keep 4.5:1 on the tint (`notice.test.tsx`).
17
+ */
18
+ export declare const noticeInkTextShare = 0.3;
19
+ /** The semantic color a tone is drawn from. */
20
+ export declare function noticeToneColor(tone: NoticeTone): string;
21
+ export declare function cssNoticeClasses(): string;
22
+ export declare function noticeClassCatalog(): string[];
@@ -0,0 +1,168 @@
1
+ import { typographyVariants } from '@scalewing/tokens';
2
+ export const noticeTones = ['info', 'success', 'warning', 'danger'];
3
+ export const noticeVariants = ['default', 'band'];
4
+ /**
5
+ * How much of a tone's color the notice's fill mixes into the surface. Info
6
+ * uses the derived accent tint instead (ADR 0011), which already keeps the
7
+ * accent readable on every palette.
8
+ */
9
+ export const noticeTintShare = 0.1;
10
+ /**
11
+ * How far the notice's words move from the tone's color toward the text
12
+ * color, so they read darker than the tone on a light fill (lighter on a
13
+ * dark one) and keep 4.5:1 on the tint (`notice.test.tsx`).
14
+ */
15
+ export const noticeInkTextShare = 0.3;
16
+ /** The semantic color a tone is drawn from. */
17
+ export function noticeToneColor(tone) {
18
+ return tone === 'info' ? 'accent' : tone;
19
+ }
20
+ function toneFill(tone) {
21
+ if (tone === 'info')
22
+ return 'var(--sw-color-accentSubtle)';
23
+ return `color-mix(in srgb, var(--sw-color-${tone}) ${noticeTintShare * 100}%, var(--sw-color-surface))`;
24
+ }
25
+ function toneInk(tone) {
26
+ const toneShare = Math.round((1 - noticeInkTextShare) * 100);
27
+ return `color-mix(in srgb, var(--sw-color-${noticeToneColor(tone)}) ${toneShare}%, var(--sw-color-text))`;
28
+ }
29
+ function toneRules() {
30
+ return noticeTones
31
+ .map((tone) => `.sw-notice-${tone} { --sw-notice-fill: ${toneFill(tone)}; --sw-notice-ink: ${toneInk(tone)}; }`)
32
+ .join('\n');
33
+ }
34
+ const label = typographyVariants.label;
35
+ const body = typographyVariants.body;
36
+ const caption = typographyVariants.caption;
37
+ /*
38
+ * A tinted block in the page: the tone's fill, its words in the tone's ink,
39
+ * label-size type. An optional glyph leads; the title (a bold lead) and a
40
+ * text message share a row while they fit and wrap under one another when
41
+ * they do not; a message of elements (a field, a checkbox) is stacked under
42
+ * the title. An action ends the row (a small Button
43
+ * overhangs the padding rather than growing it) and drops under the text on
44
+ * a narrow column. Controls inside keep their own colors. Forced
45
+ * colors draw a border instead of the fill.
46
+ */
47
+ export function cssNoticeClasses() {
48
+ return `${toneRules()}
49
+
50
+ .sw-notice {
51
+ align-items: flex-start;
52
+ background: var(--sw-notice-fill);
53
+ border-radius: var(--sw-radius-sm);
54
+ box-sizing: border-box;
55
+ color: var(--sw-notice-ink);
56
+ column-gap: var(--sw-space-2);
57
+ display: flex;
58
+ flex-wrap: wrap;
59
+ font-family: var(--sw-font-sans);
60
+ font-size: ${label.fontSize}px;
61
+ letter-spacing: ${label.letterSpacing}px;
62
+ line-height: ${label.lineHeight}px;
63
+ min-width: 0;
64
+ padding: var(--sw-space-2) var(--sw-space-3);
65
+ row-gap: var(--sw-space-2);
66
+ /* Muted words of a control inside (a field's or a checkbox's
67
+ description) take the ink, which keeps 4.5:1 on the fill. */
68
+ --sw-color-muted: var(--sw-notice-ink);
69
+ }
70
+
71
+ .sw-notice-icon {
72
+ display: inline-flex;
73
+ flex: none;
74
+ min-height: ${label.lineHeight}px;
75
+ align-items: center;
76
+ }
77
+
78
+ .sw-notice-content {
79
+ align-items: baseline;
80
+ column-gap: var(--sw-space-2);
81
+ display: flex;
82
+ flex: 1 1 16rem;
83
+ flex-wrap: wrap;
84
+ min-width: 0;
85
+ row-gap: var(--sw-space-1);
86
+ }
87
+
88
+ .sw-notice-stacked {
89
+ align-items: stretch;
90
+ flex-direction: column;
91
+ row-gap: var(--sw-space-2);
92
+ }
93
+
94
+ .sw-notice-title {
95
+ font-weight: ${label.fontWeight};
96
+ min-width: 0;
97
+ }
98
+
99
+ .sw-notice-body {
100
+ flex: 1 1 auto;
101
+ font-weight: ${body.fontWeight};
102
+ min-width: 0;
103
+ }
104
+
105
+ .sw-notice-action {
106
+ align-items: center;
107
+ align-self: flex-start;
108
+ display: inline-flex;
109
+ flex: none;
110
+ min-height: ${label.lineHeight}px;
111
+ }
112
+
113
+ /* A small Button keeps the note one text line tall: it overhangs the
114
+ padding evenly instead of growing the row. */
115
+ .sw-notice-action > .sw-button {
116
+ margin-block: calc((${label.lineHeight}px - var(--sw-control-sm-min-height)) / 2);
117
+ }
118
+
119
+ /* A band across the page's full width, such as an environment strip
120
+ above the app header: square, the xs control height, caption type,
121
+ its words centered on one line that wraps on a phone. A glyph or an
122
+ action stays on the words' row (no wrap): the words wrap instead. */
123
+ .sw-notice-band {
124
+ align-items: center;
125
+ border-radius: 0;
126
+ flex-wrap: nowrap;
127
+ font-size: ${caption.fontSize}px;
128
+ justify-content: center;
129
+ letter-spacing: ${caption.letterSpacing}px;
130
+ line-height: ${caption.lineHeight}px;
131
+ min-height: var(--sw-control-xs-min-height);
132
+ padding: var(--sw-space-1) var(--sw-space-4);
133
+ text-align: center;
134
+ width: 100%;
135
+ }
136
+
137
+ .sw-notice-band .sw-notice-content {
138
+ flex: 0 1 auto;
139
+ justify-content: center;
140
+ }
141
+
142
+ .sw-notice-band .sw-notice-icon,
143
+ .sw-notice-band .sw-notice-action { min-height: ${caption.lineHeight}px; }
144
+
145
+ .sw-notice-band .sw-notice-action { align-self: center; }
146
+
147
+ .sw-notice-band .sw-notice-action > .sw-button {
148
+ margin-block: calc((${caption.lineHeight}px - var(--sw-control-sm-min-height)) / 2);
149
+ }
150
+
151
+ @media (forced-colors: active) {
152
+ .sw-notice { border: 1px solid CanvasText; }
153
+ .sw-notice-band { border-width: 0 0 1px; }
154
+ }`;
155
+ }
156
+ export function noticeClassCatalog() {
157
+ return [
158
+ 'sw-notice',
159
+ ...noticeTones.map((tone) => `sw-notice-${tone}`),
160
+ 'sw-notice-icon',
161
+ 'sw-notice-content',
162
+ 'sw-notice-stacked',
163
+ 'sw-notice-title',
164
+ 'sw-notice-body',
165
+ 'sw-notice-action',
166
+ 'sw-notice-band',
167
+ ];
168
+ }
@@ -1,2 +1,5 @@
1
+ export declare const progressTones: readonly ["accent", "success", "warning", "danger"];
2
+ /** The bar's color: the accent, or success, warning (time running out) or danger. */
3
+ export type ProgressTone = (typeof progressTones)[number];
1
4
  export declare function cssProgressClasses(): string;
2
5
  export declare function progressClassCatalog(): string[];
@@ -1,4 +1,15 @@
1
1
  import { typographyVariants } from '@scalewing/tokens';
2
+ export const progressTones = [
3
+ 'accent',
4
+ 'success',
5
+ 'warning',
6
+ 'danger',
7
+ ];
8
+ function toneRules() {
9
+ return progressTones
10
+ .map((tone) => `.sw-progress-${tone} { --sw-progress-color: var(--sw-color-${tone}); }`)
11
+ .join('\n');
12
+ }
2
13
  const label = typographyVariants.label;
3
14
  const caption = typographyVariants.caption;
4
15
  export function cssProgressClasses() {
@@ -11,9 +22,7 @@ export function cssProgressClasses() {
11
22
  width: 100%;
12
23
  }
13
24
 
14
- .sw-progress-accent { --sw-progress-color: var(--sw-color-accent); }
15
- .sw-progress-success { --sw-progress-color: var(--sw-color-success); }
16
- .sw-progress-danger { --sw-progress-color: var(--sw-color-danger); }
25
+ ${toneRules()}
17
26
 
18
27
  .sw-progress-heading {
19
28
  align-items: baseline;
@@ -66,9 +75,7 @@ export function cssProgressClasses() {
66
75
  export function progressClassCatalog() {
67
76
  return [
68
77
  'sw-progress',
69
- 'sw-progress-accent',
70
- 'sw-progress-success',
71
- 'sw-progress-danger',
78
+ ...progressTones.map((tone) => `sw-progress-${tone}`),
72
79
  'sw-progress-heading',
73
80
  'sw-progress-label',
74
81
  'sw-progress-count',
@@ -1,6 +1,60 @@
1
1
  import { trackInset, typographyVariants } from '@scalewing/tokens';
2
2
  const body = typographyVariants.body;
3
3
  const data = typographyVariants.data;
4
+ const label = typographyVariants.label;
5
+ /*
6
+ * Items with a mark (a glyph tile before the label) centre the mark and
7
+ * the label a space-2 gap apart; the mark keeps its size. On the compact
8
+ * track every item also takes the md control height and label type, so
9
+ * the row stays even; the track is the subtle fill (two classes, so
10
+ * reduced transparency keeps it) and the selected item is the surface
11
+ * raised by the small elevation, so the choice shows on a white canvas
12
+ * too. A filled track keeps its own look and only gains the marks. The
13
+ * error outline is restated after these rules so an icon track keeps it.
14
+ * In forced colours the selected item is outlined in Highlight; a focused
15
+ * selected item keeps that outline, offset by the focus ring's offset.
16
+ */
17
+ function iconRules() {
18
+ const compact = '.sw-segmented-with-icons:not(.sw-segmented-filled)';
19
+ return `.sw-segmented${compact} {
20
+ background: var(--sw-color-subtle);
21
+ border-color: transparent;
22
+ }
23
+
24
+ ${compact} .sw-segmented-item-selected {
25
+ box-shadow: var(--sw-elevation-sm);
26
+ }
27
+
28
+ .sw-segmented-with-icons .sw-segmented-item {
29
+ align-items: center;
30
+ display: inline-flex;
31
+ gap: var(--sw-space-2);
32
+ justify-content: center;
33
+ }
34
+
35
+ ${compact} .sw-segmented-item {
36
+ font-size: ${label.fontSize}px;
37
+ letter-spacing: ${label.letterSpacing}px;
38
+ line-height: ${label.lineHeight}px;
39
+ min-height: var(--sw-control-md-min-height);
40
+ padding-inline: var(--sw-space-2) var(--sw-space-3);
41
+ }
42
+
43
+ .sw-segmented-item-icon {
44
+ display: inline-flex;
45
+ flex: none;
46
+ }
47
+
48
+ .sw-segmented.sw-segmented-with-icons[aria-invalid='true'] {
49
+ border-color: var(--sw-color-danger);
50
+ }
51
+
52
+ @media (forced-colors: active) {
53
+ .sw-segmented${compact} { border-color: CanvasText; }
54
+ ${compact} .sw-segmented-item-selected { outline: 2px solid Highlight; }
55
+ .sw-segmented.sw-segmented-with-icons[aria-invalid='true'] { border-color: Mark; }
56
+ }`;
57
+ }
4
58
  /*
5
59
  * The control and its error message. The wrapper takes the track's place in
6
60
  * the layout: inline beside text and stretched in a Stack (compact), block
@@ -106,6 +160,8 @@ export function cssSegmentedClasses() {
106
160
  color: var(--sw-color-onAccent);
107
161
  }
108
162
 
163
+ ${iconRules()}
164
+
109
165
  .sw-segmented-disabled {
110
166
  opacity: var(--sw-disabled-opacity);
111
167
  }
@@ -122,6 +178,8 @@ export function segmentedClassCatalog() {
122
178
  'sw-segmented-item',
123
179
  'sw-segmented-item-selected',
124
180
  'sw-segmented-filled',
181
+ 'sw-segmented-with-icons',
182
+ 'sw-segmented-item-icon',
125
183
  'sw-segmented-disabled',
126
184
  ];
127
185
  }
@@ -0,0 +1,5 @@
1
+ export declare const toastPlacements: readonly ["bottom", "top-end"];
2
+ /** Where a toast that does not travel shows: centered at the bottom, or the top end corner. */
3
+ export type ToastPlacement = (typeof toastPlacements)[number];
4
+ export declare function cssToastCardClasses(): string;
5
+ export declare function toastCardClassCatalog(): string[];
@@ -0,0 +1,122 @@
1
+ import { typographyVariants } from '@scalewing/tokens';
2
+ import { toastMaxWidth } from './css-toast.js';
3
+ export const toastPlacements = ['bottom', 'top-end'];
4
+ const label = typographyVariants.label;
5
+ const body = typographyVariants.body;
6
+ /*
7
+ * The toast as a card: a bold title over a muted detail, an action at the
8
+ * end of the row, and a thin line that runs down with the time left.
9
+ *
10
+ * `top-end` puts it in the top corner at the end of the line, clear of the
11
+ * safe area, at most a dialog's reading width; it drops in from above. A
12
+ * toast with an action or the remaining line takes the pointer, so hover
13
+ * can hold it (and the action can be pressed); the bottom toast stays
14
+ * click-through. The line is a scale from full to empty over the toast's
15
+ * duration (`--sw-toast-duration`), held while the toast is paused; it is
16
+ * a measure of time, not decoration, so it runs under reduced motion too.
17
+ */
18
+ export function cssToastCardClasses() {
19
+ return `.sw-toast-title {
20
+ display: block;
21
+ font-size: ${label.fontSize}px;
22
+ font-weight: ${label.fontWeight};
23
+ letter-spacing: ${label.letterSpacing}px;
24
+ line-height: ${label.lineHeight}px;
25
+ }
26
+
27
+ .sw-toast-detail {
28
+ color: var(--sw-color-muted);
29
+ font-size: ${label.fontSize}px;
30
+ font-weight: ${body.fontWeight};
31
+ letter-spacing: ${label.letterSpacing}px;
32
+ line-height: ${label.lineHeight}px;
33
+ }
34
+
35
+ .sw-toast-row:has(.sw-toast-title) { align-items: flex-start; }
36
+
37
+ .sw-toast-row .sw-toast-body { flex: 1 1 auto; }
38
+
39
+ .sw-button.sw-toast-action {
40
+ flex: none;
41
+ margin-block: calc((${label.lineHeight}px - var(--sw-control-sm-min-height)) / 2);
42
+ }
43
+
44
+ .sw-toast-interactive { pointer-events: auto; }
45
+
46
+ .sw-toast-top-end {
47
+ bottom: auto;
48
+ left: auto;
49
+ max-width: min(var(--sw-dialog-max), ${toastMaxWidth});
50
+ right: max(var(--sw-space-4), env(safe-area-inset-right, 0px));
51
+ top: max(var(--sw-space-4), env(safe-area-inset-top, 0px));
52
+ translate: none;
53
+ }
54
+
55
+ .sw-toast-top-end:dir(rtl) {
56
+ left: max(var(--sw-space-4), env(safe-area-inset-left, 0px));
57
+ right: auto;
58
+ }
59
+
60
+ .sw-toast-top-end:popover-open {
61
+ animation: sw-toast-drop var(--sw-motion-default) var(--sw-motion-easing);
62
+ }
63
+
64
+ @keyframes sw-toast-drop {
65
+ from {
66
+ opacity: 0;
67
+ translate: 0 calc(-1 * var(--sw-space-3));
68
+ }
69
+ to {
70
+ opacity: 1;
71
+ translate: none;
72
+ }
73
+ }
74
+
75
+ .sw-toast-remaining {
76
+ background: var(--sw-color-border);
77
+ border-radius: var(--sw-radius-pill);
78
+ display: block;
79
+ height: var(--sw-space-1);
80
+ margin-top: var(--sw-space-2);
81
+ overflow: hidden;
82
+ position: relative;
83
+ }
84
+
85
+ .sw-toast-remaining::after {
86
+ animation: sw-toast-remaining var(--sw-toast-duration, 0ms) linear forwards;
87
+ background: var(--sw-toast-tone, var(--sw-color-accent));
88
+ content: '';
89
+ inset: 0;
90
+ position: absolute;
91
+ transform-origin: left center;
92
+ }
93
+
94
+ .sw-toast-remaining:dir(rtl)::after { transform-origin: right center; }
95
+
96
+ .sw-toast-paused .sw-toast-remaining::after { animation-play-state: paused; }
97
+
98
+ @keyframes sw-toast-remaining {
99
+ from { transform: scaleX(1); }
100
+ to { transform: scaleX(0); }
101
+ }
102
+
103
+ @media (prefers-reduced-motion: reduce) {
104
+ .sw-toast-top-end:popover-open { animation: none; }
105
+ }
106
+
107
+ @media (forced-colors: active) {
108
+ .sw-toast-remaining { background: Canvas; border: 1px solid CanvasText; }
109
+ .sw-toast-remaining::after { background: CanvasText; }
110
+ }`;
111
+ }
112
+ export function toastCardClassCatalog() {
113
+ return [
114
+ 'sw-toast-title',
115
+ 'sw-toast-detail',
116
+ 'sw-toast-action',
117
+ 'sw-toast-interactive',
118
+ 'sw-toast-top-end',
119
+ 'sw-toast-remaining',
120
+ 'sw-toast-paused',
121
+ ];
122
+ }
@@ -1,10 +1,18 @@
1
- import { controlScale, disabledOpacity, focusRing, quietOpacity, radiusScale, secondaryActionBorder, semanticColorKeys, spacingScale, spacingSteps, splitScale, } from '@scalewing/tokens';
1
+ import { categoricalColorKeys, categoricalColors, onCategorical, controlScale, disabledOpacity, focusRing, quietOpacity, radiusScale, secondaryActionBorder, semanticColorKeys, spacingScale, spacingSteps, splitScale, } from '@scalewing/tokens';
2
2
  function colorDeclarations(theme) {
3
3
  return [
4
4
  ...semanticColorKeys.map((key) => ` --sw-color-${key}: ${theme.colors[key]};`),
5
5
  ` --sw-button-secondary-border: ${secondaryActionBorder(theme.colors)};`,
6
6
  ].join('\n');
7
7
  }
8
+ /* The categorical fills of the theme's scheme and the glyph drawn on them. */
9
+ function categoricalDeclarations(theme) {
10
+ const fills = categoricalColors[theme.colorScheme];
11
+ return [
12
+ ...categoricalColorKeys.map((key) => ` --sw-categorical-${key}: ${fills[key]};`),
13
+ ` --sw-categorical-on: ${onCategorical};`,
14
+ ].join('\n');
15
+ }
8
16
  function glassDeclarations(theme) {
9
17
  return ` --sw-glass-blur: ${theme.glass.blur}px;
10
18
  --sw-glass-saturate: ${theme.glass.saturate};
@@ -38,6 +46,7 @@ ${control}
38
46
  --sw-container-max: 72rem;
39
47
  --sw-dialog-max: 32rem;
40
48
  --sw-dialog-max-lg: 56rem;
49
+ --sw-dialog-max-xl: 65rem;
41
50
  --sw-select-max: 16rem;
42
51
  --sw-split-min: ${splitScale.min}rem;
43
52
  --sw-split-size: ${splitScale.size}rem;
@@ -53,11 +62,13 @@ export function cssVariables(light, dark) {
53
62
  return `:root,
54
63
  [data-theme='light'] {
55
64
  ${colorDeclarations(light)}
65
+ ${categoricalDeclarations(light)}
56
66
  ${sharedDeclarations(light)}
57
67
  }
58
68
 
59
69
  [data-theme='dark'] {
60
70
  ${colorDeclarations(dark)}
71
+ ${categoricalDeclarations(dark)}
61
72
  ${sharedDeclarations(dark)}
62
73
  }`;
63
74
  }
@@ -14,8 +14,8 @@
14
14
  * surface that scrolls up under it (the header is the page's way back, the
15
15
  * strip its way between sections, and a popup opens downward).
16
16
  * 5. `popup`: a popup outside any lifted surface (Select list, ActionMenu
17
- * list, Tooltip, the DateField and CalendarButton calendar) over
18
- * everything in the page.
17
+ * list, MultiSelect panel, Tooltip, the DateField and CalendarButton
18
+ * calendar) over everything in the page.
19
19
  *
20
20
  * Dialog and Toast sit on the browser's top layer, above all of these.
21
21
  */
@@ -33,6 +33,9 @@ const openPopups = [
33
33
  '.sw-select-list',
34
34
  // Rendered only while open; on the top layer where the popover API exists.
35
35
  '.sw-action-menu-list',
36
+ // MultiSelect's panel. Rendered only while open; on the top layer where
37
+ // the popover API exists.
38
+ '.sw-multi-select-panel',
36
39
  '.sw-tooltip:not([hidden])',
37
40
  // DateField and CalendarButton share it. Rendered only while open; on the
38
41
  // top layer where the popover API exists.
@@ -9,6 +9,8 @@ import { checkboxClassCatalog } from './css-checkbox.js';
9
9
  import { radioGroupClassCatalog } from './css-radio-group.js';
10
10
  import { spinnerClassCatalog } from './css-spinner.js';
11
11
  import { progressClassCatalog } from './css-progress.js';
12
+ import { noticeClassCatalog } from './css-notice.js';
13
+ import { glyphTileClassCatalog } from './css-glyph-tile.js';
12
14
  import { tooltipClassCatalog } from './css-tooltip.js';
13
15
  import { infoTipClassCatalog } from './css-info-tip.js';
14
16
  import { separatorClassCatalog } from './css-separator.js';
@@ -34,9 +36,12 @@ import { tableClassCatalog } from './css-table.js';
34
36
  import { chromeClassCatalog } from './css-chrome.js';
35
37
  import { sectionNavClassCatalog } from './css-section-nav.js';
36
38
  import { dialogClassCatalog } from './css-dialog.js';
39
+ import { dialogFrameClassCatalog } from './css-dialog-frame.js';
37
40
  import { selectClassCatalog } from './css-select.js';
41
+ import { multiSelectClassCatalog } from './css-multi-select.js';
38
42
  import { splitClassCatalog } from './css-split.js';
39
43
  import { toastClassCatalog } from './css-toast.js';
44
+ import { toastCardClassCatalog } from './css-toast-card.js';
40
45
  import { cssDocumentCanvas } from './css-document.js';
41
46
  import { cssPaletteAttributes } from './css-palettes.js';
42
47
  import { cssUtilities } from './css-utilities.js';
@@ -64,9 +69,11 @@ export function utilityClassCatalog() {
64
69
  ...chromeClassCatalog(),
65
70
  ...sectionNavClassCatalog(),
66
71
  ...dialogClassCatalog(),
72
+ ...dialogFrameClassCatalog(),
67
73
  ...accordionClassCatalog(),
68
74
  ...selectClassCatalog(),
69
75
  ...actionMenuClassCatalog(),
76
+ ...multiSelectClassCatalog(),
70
77
  ...actionBarClassCatalog(),
71
78
  ...switchClassCatalog(),
72
79
  ...dateFieldClassCatalog(),
@@ -75,6 +82,8 @@ export function utilityClassCatalog() {
75
82
  ...radioGroupClassCatalog(),
76
83
  ...spinnerClassCatalog(),
77
84
  ...progressClassCatalog(),
85
+ ...noticeClassCatalog(),
86
+ ...glyphTileClassCatalog(),
78
87
  ...tooltipClassCatalog(),
79
88
  ...infoTipClassCatalog(),
80
89
  ...separatorClassCatalog(),
@@ -90,6 +99,7 @@ export function utilityClassCatalog() {
90
99
  ...stepsClassCatalog(),
91
100
  ...splitClassCatalog(),
92
101
  ...toastClassCatalog(),
102
+ ...toastCardClassCatalog(),
93
103
  ...responsiveClassCatalog(),
94
104
  ...boxBorderClassCatalog(),
95
105
  ];
package/dist/index.d.ts CHANGED
@@ -7,7 +7,9 @@ export { DateField, type DateFieldLabels, type DateFieldProps, type WeekStart, }
7
7
  export { CalendarButton, type CalendarButtonLabels, type CalendarButtonProps, type CalendarButtonRange, } from './components/CalendarButton.js';
8
8
  export { Checkbox, type CheckboxProps } from './components/Checkbox.js';
9
9
  export { Spinner, type SpinnerProps, type SpinnerSize, } from './components/Spinner.js';
10
- export { Progress, type ProgressProps, type ProgressTone, } from './components/Progress.js';
10
+ export { GlyphTile, glyphTileSizes, type GlyphTileHue, type GlyphTileProps, type GlyphTileSize, } from './components/GlyphTile.js';
11
+ export { Notice, noticeTones, noticeVariants, type NoticeProps, type NoticeRole, type NoticeTone, type NoticeVariant, } from './components/Notice.js';
12
+ export { Progress, progressTones, type ProgressProps, type ProgressTone, } from './components/Progress.js';
11
13
  export { Tooltip, type TooltipProps, type TooltipRelationship, } from './components/Tooltip.js';
12
14
  export { InfoTip, type InfoTipProps } from './components/InfoTip.js';
13
15
  export { RadioGroup, type RadioGroupOption, type RadioGroupProps, } from './components/RadioGroup.js';
@@ -18,10 +20,10 @@ export { Button, type ButtonProps, type ButtonSize, type ButtonVariant, } from '
18
20
  export { Box, type BoxBorder, type BoxElement, type BoxProps, } from './components/Box.js';
19
21
  export { ButtonGroup, type ButtonGroupJustify, type ButtonGroupProps, } from './components/ButtonGroup.js';
20
22
  export { Card, type CardProps, type CardVariant } from './components/Card.js';
21
- export { Dialog, type DialogProps, type DialogSize, type DialogTitleLevel, } from './components/Dialog.js';
23
+ export { Dialog, dialogSizes, type DialogProps, type DialogRole, type DialogSize, type DialogTitleLevel, } from './components/Dialog.js';
22
24
  export { StatTile, type StatTileEmphasis, type StatTileProps, type StatTileTone, statTileTones, } from './components/StatTile.js';
23
25
  export { TabPanel, type TabItem, type TabPanelProps, Tabs, type TabsProps, tabId, tabPanelId, } from './components/Tabs.js';
24
- export { Toast, toastTones } from './components/Toast.js';
26
+ export { Toast, toastPlacements, toastTones, type ToastAction, type ToastPlacement, } from './components/Toast.js';
25
27
  export type { ToastProps, ToastTone } from './components/Toast.js';
26
28
  export { Field, type FieldProps, type FieldSize } from './components/Field.js';
27
29
  export { Step, type StepHeadingLevel, type StepProps, Steps, type StepsLabels, type StepsProps, type StepStatus, } from './components/Steps.js';
@@ -34,6 +36,7 @@ export { SectionNav, type SectionNavItem, type SectionNavProps, } from './compon
34
36
  export { SegmentedControl, type SegmentedControlProps, type SegmentedControlVariant, type SegmentedItem, } from './components/SegmentedControl.js';
35
37
  export { Select } from './components/Select.js';
36
38
  export type { SelectAction, SelectOption, SelectProps, SelectWidth, } from './components/Select.js';
39
+ export { MultiSelect, type MultiSelectAlign, type MultiSelectOption, type MultiSelectProps, } from './components/MultiSelect.js';
37
40
  export { Stack, type Align, type Justify, type StackProps, } from './components/Stack.js';
38
41
  export { Table, TableBody, TableCell, TableHeader, TableRow, type TableBodyProps, type TableCellProps, type TableColumnWidth, type TableDensity, type TableHeaderProps, type TableLayout, type TableProps, type TableRowProps, type TableSort, type TableVerticalAlign, } from './components/Table.js';
39
42
  export { Text, type TextAlign, type TextElement, type TextProps, } from './components/Text.js';
@@ -50,7 +53,7 @@ export { Grid } from './components/Grid.js';
50
53
  export type { GridColumns, GridProps } from './components/Grid.js';
51
54
  export type { GridColumnSpan } from './css/css-grid-span.js';
52
55
  export type { ColumnSpanProps } from './column-span-classes.js';
53
- export { DenominationGrid } from './components/DenominationGrid.js';
54
- export type { DenominationGridColumn, DenominationGridEntry, DenominationGridLayout, DenominationGridProps, DenominationGridRow, DenominationGridRowEmphasis, DenominationGridRowRole, DenominationGridTone, DenominationLabelWidth, } from './components/DenominationGrid.js';
56
+ export { DenominationGrid, denominationLabelAppearances, } from './components/DenominationGrid.js';
57
+ export type { DenominationGridColumn, DenominationGridEntry, DenominationGridLayout, DenominationGridProps, DenominationGridRow, DenominationGridRowEmphasis, DenominationGridRowRole, DenominationGridTone, DenominationLabelAppearance, DenominationLabelWidth, } from './components/DenominationGrid.js';
55
58
  export { FilterChips } from './components/FilterChips.js';
56
59
  export type { FilterChipOption, FilterChipsProps, } from './components/FilterChips.js';
package/dist/index.js CHANGED
@@ -6,7 +6,9 @@ export { DateField, } from './components/DateField.js';
6
6
  export { CalendarButton, } from './components/CalendarButton.js';
7
7
  export { Checkbox } from './components/Checkbox.js';
8
8
  export { Spinner, } from './components/Spinner.js';
9
- export { Progress, } from './components/Progress.js';
9
+ export { GlyphTile, glyphTileSizes, } from './components/GlyphTile.js';
10
+ export { Notice, noticeTones, noticeVariants, } from './components/Notice.js';
11
+ export { Progress, progressTones, } from './components/Progress.js';
10
12
  export { Tooltip, } from './components/Tooltip.js';
11
13
  export { InfoTip } from './components/InfoTip.js';
12
14
  export { RadioGroup, } from './components/RadioGroup.js';
@@ -17,10 +19,10 @@ export { Button, } from './components/Button.js';
17
19
  export { Box, } from './components/Box.js';
18
20
  export { ButtonGroup, } from './components/ButtonGroup.js';
19
21
  export { Card } from './components/Card.js';
20
- export { Dialog, } from './components/Dialog.js';
22
+ export { Dialog, dialogSizes, } from './components/Dialog.js';
21
23
  export { StatTile, statTileTones, } from './components/StatTile.js';
22
24
  export { TabPanel, Tabs, tabId, tabPanelId, } from './components/Tabs.js';
23
- export { Toast, toastTones } from './components/Toast.js';
25
+ export { Toast, toastPlacements, toastTones, } from './components/Toast.js';
24
26
  export { Field } from './components/Field.js';
25
27
  export { Step, Steps, } from './components/Steps.js';
26
28
  export { Stepper, } from './components/Stepper.js';
@@ -30,6 +32,7 @@ export { Nav } from './components/Nav.js';
30
32
  export { SectionNav, } from './components/SectionNav.js';
31
33
  export { SegmentedControl, } from './components/SegmentedControl.js';
32
34
  export { Select } from './components/Select.js';
35
+ export { MultiSelect, } from './components/MultiSelect.js';
33
36
  export { Stack, } from './components/Stack.js';
34
37
  export { Table, TableBody, TableCell, TableHeader, TableRow, } from './components/Table.js';
35
38
  export { Text, } from './components/Text.js';
@@ -39,5 +42,5 @@ export { breakpointQuery } from './css/breakpoints.js';
39
42
  export { Separator } from './components/Separator.js';
40
43
  export { DescriptionItem, DescriptionList, } from './components/DescriptionList.js';
41
44
  export { Grid } from './components/Grid.js';
42
- export { DenominationGrid } from './components/DenominationGrid.js';
45
+ export { DenominationGrid, denominationLabelAppearances, } from './components/DenominationGrid.js';
43
46
  export { FilterChips } from './components/FilterChips.js';