@scalewing/react 1.47.0 → 1.48.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 +67 -0
- package/README.md +171 -4
- package/dist/command-palette.test-support.d.ts +21 -0
- package/dist/command-palette.test-support.js +55 -0
- package/dist/components/AppHeader.d.ts +3 -0
- package/dist/components/AppShell.d.ts +4 -3
- package/dist/components/AppShell.js +24 -7
- package/dist/components/Band.d.ts +30 -0
- package/dist/components/Band.js +23 -0
- package/dist/components/ButtonLink.d.ts +33 -0
- package/dist/components/ButtonLink.js +27 -0
- package/dist/components/CommandPalette.d.ts +12 -0
- package/dist/components/CommandPalette.js +143 -0
- package/dist/components/CommandPaletteTrigger.d.ts +9 -0
- package/dist/components/CommandPaletteTrigger.js +16 -0
- package/dist/components/ContextSwitcher.d.ts +12 -0
- package/dist/components/ContextSwitcher.js +62 -0
- package/dist/components/FixtureGroup.d.ts +9 -0
- package/dist/components/FixtureGroup.js +16 -0
- package/dist/components/FixtureRow.d.ts +10 -0
- package/dist/components/FixtureRow.js +46 -0
- package/dist/components/GlyphTile.d.ts +9 -3
- package/dist/components/GlyphTile.js +15 -4
- package/dist/components/SiteFooter.d.ts +12 -0
- package/dist/components/SiteFooter.js +23 -0
- package/dist/components/SiteHeader.d.ts +14 -0
- package/dist/components/SiteHeader.js +24 -0
- package/dist/components/Skeleton.d.ts +22 -0
- package/dist/components/Skeleton.js +30 -0
- package/dist/components/app-shell/AppShellBar.d.ts +23 -0
- package/dist/components/app-shell/AppShellBar.js +25 -0
- package/dist/components/app-shell/types.d.ts +36 -1
- package/dist/components/app-shell/validate.d.ts +4 -3
- package/dist/components/app-shell/validate.js +21 -3
- package/dist/components/command-palette/PaletteList.d.ts +20 -0
- package/dist/components/command-palette/PaletteList.js +21 -0
- package/dist/components/command-palette/shortcut.d.ts +19 -0
- package/dist/components/command-palette/shortcut.js +75 -0
- package/dist/components/command-palette/types.d.ts +72 -0
- package/dist/components/command-palette/types.js +2 -0
- package/dist/components/command-palette/validate.d.ts +10 -0
- package/dist/components/command-palette/validate.js +50 -0
- package/dist/components/context-switcher/SwitcherOption.d.ts +17 -0
- package/dist/components/context-switcher/SwitcherOption.js +20 -0
- package/dist/components/context-switcher/SwitcherPopup.d.ts +31 -0
- package/dist/components/context-switcher/SwitcherPopup.js +111 -0
- package/dist/components/context-switcher/options.d.ts +33 -0
- package/dist/components/context-switcher/options.js +60 -0
- package/dist/components/context-switcher/types.d.ts +96 -0
- package/dist/components/context-switcher/types.js +1 -0
- package/dist/components/context-switcher/use-switcher-list.d.ts +29 -0
- package/dist/components/context-switcher/use-switcher-list.js +93 -0
- package/dist/components/context-switcher/validate.d.ts +8 -0
- package/dist/components/context-switcher/validate.js +94 -0
- package/dist/components/fixture/fixture-list-context.d.ts +4 -0
- package/dist/components/fixture/fixture-list-context.js +9 -0
- package/dist/components/fixture/types.d.ts +50 -0
- package/dist/components/fixture/types.js +1 -0
- package/dist/components/fixture/validate.d.ts +8 -0
- package/dist/components/fixture/validate.js +36 -0
- package/dist/components/site-footer/types.d.ts +31 -0
- package/dist/components/site-footer/types.js +1 -0
- package/dist/components/site-footer/validate.d.ts +7 -0
- package/dist/components/site-footer/validate.js +22 -0
- package/dist/components/site-header/SiteHeaderLinks.d.ts +7 -0
- package/dist/components/site-header/SiteHeaderLinks.js +7 -0
- package/dist/components/site-header/types.d.ts +38 -0
- package/dist/components/site-header/types.js +1 -0
- package/dist/components/site-header/use-menu-dismiss.d.ts +8 -0
- package/dist/components/site-header/use-menu-dismiss.js +62 -0
- package/dist/components/site-header/validate.d.ts +7 -0
- package/dist/components/site-header/validate.js +17 -0
- package/dist/components/use-element-height.d.ts +10 -0
- package/dist/components/use-element-height.js +35 -0
- package/dist/context-switcher.test-support.d.ts +9 -0
- package/dist/context-switcher.test-support.js +41 -0
- package/dist/css/css-app-shell-page-bar.d.ts +3 -0
- package/dist/css/css-app-shell-page-bar.js +81 -0
- package/dist/css/css-app-shell.js +6 -1
- package/dist/css/css-band.d.ts +10 -0
- package/dist/css/css-band.js +101 -0
- package/dist/css/css-button-link.d.ts +3 -0
- package/dist/css/css-button-link.js +48 -0
- package/dist/css/css-command-palette-key.d.ts +1 -0
- package/dist/css/css-command-palette-key.js +33 -0
- package/dist/css/css-command-palette-trigger.d.ts +2 -0
- package/dist/css/css-command-palette-trigger.js +88 -0
- package/dist/css/css-command-palette.d.ts +2 -0
- package/dist/css/css-command-palette.js +209 -0
- package/dist/css/css-components.js +24 -0
- package/dist/css/css-context-switcher-trigger.d.ts +15 -0
- package/dist/css/css-context-switcher-trigger.js +175 -0
- package/dist/css/css-context-switcher.d.ts +4 -0
- package/dist/css/css-context-switcher.js +219 -0
- package/dist/css/css-count-pill.d.ts +2 -2
- package/dist/css/css-count-pill.js +11 -3
- package/dist/css/css-fixture.d.ts +5 -0
- package/dist/css/css-fixture.js +260 -0
- package/dist/css/css-glyph-tile.d.ts +2 -0
- package/dist/css/css-glyph-tile.js +29 -1
- package/dist/css/css-site-footer.d.ts +2 -0
- package/dist/css/css-site-footer.js +152 -0
- package/dist/css/css-site-header.d.ts +2 -0
- package/dist/css/css-site-header.js +262 -0
- package/dist/css/css-skeleton.d.ts +10 -0
- package/dist/css/css-skeleton.js +110 -0
- package/dist/css/stacking.js +7 -4
- package/dist/css/stylesheet.js +16 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +10 -0
- package/dist/styles.css +2008 -719
- package/package.json +2 -2
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { typographyVariants } from '@scalewing/tokens';
|
|
2
|
+
import { quietFill } from './quiet-fill.js';
|
|
3
|
+
import { coarsePointerQuery, touchTarget } from './touch-target.js';
|
|
4
|
+
const label = typographyVariants.label;
|
|
5
|
+
/* The full trigger's least width, a named geometry of this control. */
|
|
6
|
+
const triggerMinWidth = '12rem';
|
|
7
|
+
const trigger = '.sw-command-palette-trigger';
|
|
8
|
+
const compact = `${trigger}.sw-command-palette-trigger-compact`;
|
|
9
|
+
/*
|
|
10
|
+
* The trigger: a search-looking pill (the surface inside the border
|
|
11
|
+
* hairline, fully rounded) holding the glyph, the placeholder words in the
|
|
12
|
+
* muted colour taking the free space, and the key hint at the end; the sm
|
|
13
|
+
* control height, the 44 px target on a coarse pointer. `compact` is the
|
|
14
|
+
* glyph alone in a round quiet button. Hover takes the quiet fill.
|
|
15
|
+
*/
|
|
16
|
+
export function cssCommandPaletteTriggerClasses() {
|
|
17
|
+
return `${trigger} {
|
|
18
|
+
align-items: center;
|
|
19
|
+
appearance: none;
|
|
20
|
+
background: var(--sw-color-surface);
|
|
21
|
+
border: 1px solid var(--sw-color-border);
|
|
22
|
+
border-radius: var(--sw-radius-pill);
|
|
23
|
+
box-sizing: border-box;
|
|
24
|
+
color: var(--sw-color-muted);
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
display: inline-flex;
|
|
27
|
+
font-family: var(--sw-font-sans);
|
|
28
|
+
font-size: ${label.fontSize}px;
|
|
29
|
+
font-weight: 400;
|
|
30
|
+
gap: var(--sw-space-2);
|
|
31
|
+
letter-spacing: ${label.letterSpacing}px;
|
|
32
|
+
line-height: ${label.lineHeight}px;
|
|
33
|
+
margin: 0;
|
|
34
|
+
max-width: 100%;
|
|
35
|
+
min-height: var(--sw-control-sm-min-height);
|
|
36
|
+
min-width: min(${triggerMinWidth}, 100%);
|
|
37
|
+
padding-inline: var(--sw-space-3) var(--sw-space-2);
|
|
38
|
+
text-align: start;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.sw-command-palette-trigger-icon {
|
|
42
|
+
display: inline-flex;
|
|
43
|
+
flex: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.sw-command-palette-trigger-text {
|
|
47
|
+
flex: 1 1 auto;
|
|
48
|
+
min-width: 0;
|
|
49
|
+
overflow: hidden;
|
|
50
|
+
text-overflow: ellipsis;
|
|
51
|
+
white-space: nowrap;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@media (hover: hover) {
|
|
55
|
+
${trigger}:hover { background: ${quietFill}; color: var(--sw-color-text); }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
${trigger}:focus-visible {
|
|
59
|
+
outline: var(--sw-focus-ring-width) solid var(--sw-color-accent);
|
|
60
|
+
outline-offset: var(--sw-focus-ring-offset);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
${compact} {
|
|
64
|
+
background: transparent;
|
|
65
|
+
border-color: transparent;
|
|
66
|
+
justify-content: center;
|
|
67
|
+
min-width: var(--sw-control-sm-min-height);
|
|
68
|
+
padding: 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media ${coarsePointerQuery} {
|
|
72
|
+
${trigger} { min-height: ${touchTarget}; }
|
|
73
|
+
${compact} { min-width: ${touchTarget}; }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@media (forced-colors: active) {
|
|
77
|
+
${trigger} { color: ButtonText; }
|
|
78
|
+
}`;
|
|
79
|
+
}
|
|
80
|
+
export function commandPaletteTriggerClassCatalog() {
|
|
81
|
+
return [
|
|
82
|
+
'sw-command-palette-trigger',
|
|
83
|
+
'sw-command-palette-trigger-compact',
|
|
84
|
+
'sw-command-palette-trigger-icon',
|
|
85
|
+
'sw-command-palette-trigger-text',
|
|
86
|
+
'sw-command-palette-key',
|
|
87
|
+
];
|
|
88
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { typographyVariants } from '@scalewing/tokens';
|
|
2
|
+
import { breakpointQuery } from './breakpoints.js';
|
|
3
|
+
import { cssCommandPaletteKeyClasses } from './css-command-palette-key.js';
|
|
4
|
+
import { commandPaletteTriggerClassCatalog, cssCommandPaletteTriggerClasses, } from './css-command-palette-trigger.js';
|
|
5
|
+
import { quietFill } from './quiet-fill.js';
|
|
6
|
+
import { coarsePointerQuery, touchTarget } from './touch-target.js';
|
|
7
|
+
const body = typographyVariants.body;
|
|
8
|
+
const caption = typographyVariants.caption;
|
|
9
|
+
const label = typographyVariants.label;
|
|
10
|
+
/* The palette's width, a named geometry of this control. */
|
|
11
|
+
const paletteWidth = '40rem';
|
|
12
|
+
/* Its distance from the window's top: a tenth of the height, at least space-2. */
|
|
13
|
+
const paletteTop = 'max(var(--sw-space-2), 10vh)';
|
|
14
|
+
const fromMd = breakpointQuery('from', 'md');
|
|
15
|
+
/*
|
|
16
|
+
* The palette: a modal dialog on the top layer near the window's top (not
|
|
17
|
+
* centred, so results grow downward), glass like Dialog, 40rem wide (the
|
|
18
|
+
* window less space-2 each side on a phone). Its body is a column: the
|
|
19
|
+
* field, the listbox (the only part that scrolls), the message, the hint.
|
|
20
|
+
*/
|
|
21
|
+
function frameRules() {
|
|
22
|
+
return `.sw-command-palette {
|
|
23
|
+
background: var(--sw-glass-fill);
|
|
24
|
+
border: 1px solid var(--sw-glass-border);
|
|
25
|
+
border-radius: var(--sw-radius-lg);
|
|
26
|
+
box-shadow: var(--sw-elevation-sm), inset 0 1px 0 var(--sw-glass-specular);
|
|
27
|
+
backdrop-filter: blur(var(--sw-glass-blur)) saturate(var(--sw-glass-saturate));
|
|
28
|
+
-webkit-backdrop-filter: blur(var(--sw-glass-blur)) saturate(var(--sw-glass-saturate));
|
|
29
|
+
box-sizing: border-box;
|
|
30
|
+
color: var(--sw-color-text);
|
|
31
|
+
margin: var(--sw-space-2) auto auto;
|
|
32
|
+
max-height: calc(100dvh - 2 * var(--sw-space-2));
|
|
33
|
+
max-width: calc(100% - 2 * var(--sw-space-2));
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
padding: 0;
|
|
36
|
+
width: ${paletteWidth};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@media ${fromMd} {
|
|
40
|
+
.sw-command-palette {
|
|
41
|
+
margin-top: ${paletteTop};
|
|
42
|
+
max-height: calc(100dvh - ${paletteTop} - var(--sw-space-8));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.sw-command-palette::backdrop {
|
|
47
|
+
background: color-mix(in srgb, var(--sw-color-text) 28%, transparent);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.sw-command-palette-body {
|
|
51
|
+
display: flex;
|
|
52
|
+
flex-direction: column;
|
|
53
|
+
max-height: inherit;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
[data-theme] input.sw-command-palette-field {
|
|
57
|
+
background: transparent;
|
|
58
|
+
border: 0;
|
|
59
|
+
border-bottom: 1px solid var(--sw-color-border);
|
|
60
|
+
border-radius: 0;
|
|
61
|
+
box-sizing: border-box;
|
|
62
|
+
flex: none;
|
|
63
|
+
font-size: ${body.fontSize}px;
|
|
64
|
+
letter-spacing: ${body.letterSpacing}px;
|
|
65
|
+
line-height: ${body.lineHeight}px;
|
|
66
|
+
min-height: ${touchTarget};
|
|
67
|
+
padding: var(--sw-space-3) var(--sw-space-4);
|
|
68
|
+
width: 100%;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
[data-theme] input.sw-command-palette-field:focus,
|
|
72
|
+
[data-theme] input.sw-command-palette-field:focus-visible {
|
|
73
|
+
border-bottom-color: var(--sw-color-accent);
|
|
74
|
+
box-shadow: inset 0 -1px 0 var(--sw-color-accent);
|
|
75
|
+
outline: none;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.sw-command-palette-list {
|
|
79
|
+
flex: 1 1 auto;
|
|
80
|
+
min-height: 0;
|
|
81
|
+
overflow-y: auto;
|
|
82
|
+
overscroll-behavior: contain;
|
|
83
|
+
padding: var(--sw-space-1) var(--sw-space-2);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.sw-command-palette-heading {
|
|
87
|
+
color: var(--sw-color-muted);
|
|
88
|
+
font-family: var(--sw-font-sans);
|
|
89
|
+
font-size: ${caption.fontSize}px;
|
|
90
|
+
font-weight: 600;
|
|
91
|
+
letter-spacing: ${caption.letterSpacing}px;
|
|
92
|
+
line-height: ${caption.lineHeight}px;
|
|
93
|
+
padding: var(--sw-space-2) var(--sw-space-2) var(--sw-space-1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.sw-command-palette-message,
|
|
97
|
+
.sw-command-palette-hint {
|
|
98
|
+
color: var(--sw-color-muted);
|
|
99
|
+
font-family: var(--sw-font-sans);
|
|
100
|
+
font-size: ${caption.fontSize}px;
|
|
101
|
+
letter-spacing: ${caption.letterSpacing}px;
|
|
102
|
+
line-height: ${caption.lineHeight}px;
|
|
103
|
+
margin: 0;
|
|
104
|
+
padding: var(--sw-space-3) var(--sw-space-4);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.sw-command-palette-hint {
|
|
108
|
+
border-top: 1px solid var(--sw-color-border);
|
|
109
|
+
flex: none;
|
|
110
|
+
}`;
|
|
111
|
+
}
|
|
112
|
+
/*
|
|
113
|
+
* A result: its mark, its label over its muted detail, and on the active
|
|
114
|
+
* row (`aria-selected`, the arrow keys' or the pointer's) the quiet fill
|
|
115
|
+
* and the Enter key cap at the end. The sm control height, 44 px on a
|
|
116
|
+
* coarse pointer. On the fill the detail moves toward the text colour to
|
|
117
|
+
* keep 4.5:1. Forced colours draw the active row in Highlight.
|
|
118
|
+
*/
|
|
119
|
+
function itemRules() {
|
|
120
|
+
return `.sw-command-palette-item {
|
|
121
|
+
align-items: center;
|
|
122
|
+
border-radius: var(--sw-radius-sm);
|
|
123
|
+
box-sizing: border-box;
|
|
124
|
+
cursor: pointer;
|
|
125
|
+
display: flex;
|
|
126
|
+
font-family: var(--sw-font-sans);
|
|
127
|
+
font-size: ${label.fontSize}px;
|
|
128
|
+
gap: var(--sw-space-3);
|
|
129
|
+
letter-spacing: ${label.letterSpacing}px;
|
|
130
|
+
line-height: ${label.lineHeight}px;
|
|
131
|
+
min-height: var(--sw-control-sm-min-height);
|
|
132
|
+
overflow-wrap: anywhere;
|
|
133
|
+
padding: var(--sw-space-1) var(--sw-space-2);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.sw-command-palette-item[aria-selected='true'] {
|
|
137
|
+
background: ${quietFill};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.sw-command-palette-icon {
|
|
141
|
+
display: inline-flex;
|
|
142
|
+
flex: none;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.sw-command-palette-words {
|
|
146
|
+
display: flex;
|
|
147
|
+
flex: 1 1 auto;
|
|
148
|
+
flex-direction: column;
|
|
149
|
+
min-width: 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.sw-command-palette-label {
|
|
153
|
+
font-weight: 500;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.sw-command-palette-detail {
|
|
157
|
+
color: var(--sw-color-muted);
|
|
158
|
+
font-size: ${caption.fontSize}px;
|
|
159
|
+
letter-spacing: ${caption.letterSpacing}px;
|
|
160
|
+
line-height: ${caption.lineHeight}px;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.sw-command-palette-item[aria-selected='true'] .sw-command-palette-detail {
|
|
164
|
+
color: color-mix(in srgb, var(--sw-color-muted) 70%, var(--sw-color-text));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@media ${coarsePointerQuery} {
|
|
168
|
+
.sw-command-palette-item { min-height: ${touchTarget}; }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@media (forced-colors: active) {
|
|
172
|
+
.sw-command-palette { border-color: CanvasText; }
|
|
173
|
+
.sw-command-palette-item[aria-selected='true'] { background: Highlight; color: HighlightText; forced-color-adjust: none; }
|
|
174
|
+
.sw-command-palette-item[aria-selected='true'] .sw-command-palette-detail,
|
|
175
|
+
.sw-command-palette-item[aria-selected='true'] .sw-command-palette-key { border-color: HighlightText; color: HighlightText; }
|
|
176
|
+
[data-theme] input.sw-command-palette-field:focus-visible { border-bottom-color: Highlight; box-shadow: inset 0 -1px 0 Highlight; }
|
|
177
|
+
}`;
|
|
178
|
+
}
|
|
179
|
+
/*
|
|
180
|
+
* CommandPalette and CommandPaletteTrigger (see components/CommandPalette.tsx):
|
|
181
|
+
* the trigger is `css-command-palette-trigger.ts`, the shared key cap
|
|
182
|
+
* `css-command-palette-key.ts`.
|
|
183
|
+
*/
|
|
184
|
+
export function cssCommandPaletteClasses() {
|
|
185
|
+
return `${cssCommandPaletteKeyClasses()}
|
|
186
|
+
|
|
187
|
+
${cssCommandPaletteTriggerClasses()}
|
|
188
|
+
|
|
189
|
+
${frameRules()}
|
|
190
|
+
|
|
191
|
+
${itemRules()}`;
|
|
192
|
+
}
|
|
193
|
+
export function commandPaletteClassCatalog() {
|
|
194
|
+
return [
|
|
195
|
+
...commandPaletteTriggerClassCatalog(),
|
|
196
|
+
'sw-command-palette',
|
|
197
|
+
'sw-command-palette-body',
|
|
198
|
+
'sw-command-palette-field',
|
|
199
|
+
'sw-command-palette-list',
|
|
200
|
+
'sw-command-palette-heading',
|
|
201
|
+
'sw-command-palette-item',
|
|
202
|
+
'sw-command-palette-icon',
|
|
203
|
+
'sw-command-palette-words',
|
|
204
|
+
'sw-command-palette-label',
|
|
205
|
+
'sw-command-palette-detail',
|
|
206
|
+
'sw-command-palette-message',
|
|
207
|
+
'sw-command-palette-hint',
|
|
208
|
+
];
|
|
209
|
+
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { cssChartToneClasses } from './chart-tones.js';
|
|
2
2
|
import { cssActionBarClasses } from './css-action-bar.js';
|
|
3
3
|
import { cssActionMenuClasses } from './css-action-menu.js';
|
|
4
|
+
import { cssCommandPaletteClasses } from './css-command-palette.js';
|
|
5
|
+
import { cssContextSwitcherClasses } from './css-context-switcher.js';
|
|
4
6
|
import { cssAccordionClasses } from './css-accordion.js';
|
|
5
7
|
import { cssButtonClasses } from './css-button.js';
|
|
8
|
+
import { cssButtonLinkClasses } from './css-button-link.js';
|
|
6
9
|
import { cssCalendarButtonClasses } from './css-calendar-button.js';
|
|
7
10
|
import { cssDateRangeClasses } from './css-date-range.js';
|
|
8
11
|
import { cssFileFieldClasses } from './css-file-field.js';
|
|
9
12
|
import { cssArticleClasses } from './css-article.js';
|
|
10
13
|
import { cssDocumentViewerClasses } from './css-document-viewer.js';
|
|
14
|
+
import { cssFixtureClasses } from './css-fixture.js';
|
|
11
15
|
import { cssListClasses } from './css-list.js';
|
|
12
16
|
import { cssMarkdownClasses } from './css-markdown.js';
|
|
13
17
|
import { cssCountPillClasses } from './css-count-pill.js';
|
|
@@ -38,6 +42,7 @@ import { cssSplitClasses } from './css-split.js';
|
|
|
38
42
|
import { cssSwitchClasses } from './css-switch.js';
|
|
39
43
|
import { cssTextClasses } from './css-text.js';
|
|
40
44
|
import { cssFontMonoClasses } from './css-font-mono.js';
|
|
45
|
+
import { cssSkeletonClasses } from './css-skeleton.js';
|
|
41
46
|
import { cssSpinnerClasses } from './css-spinner.js';
|
|
42
47
|
import { cssProgressClasses } from './css-progress.js';
|
|
43
48
|
import { cssNoticeClasses } from './css-notice.js';
|
|
@@ -45,6 +50,9 @@ import { cssGlyphTileClasses } from './css-glyph-tile.js';
|
|
|
45
50
|
import { cssTooltipClasses } from './css-tooltip.js';
|
|
46
51
|
import { cssInfoTipClasses } from './css-info-tip.js';
|
|
47
52
|
import { cssSeparatorClasses } from './css-separator.js';
|
|
53
|
+
import { cssBandClasses } from './css-band.js';
|
|
54
|
+
import { cssSiteFooterClasses } from './css-site-footer.js';
|
|
55
|
+
import { cssSiteHeaderClasses } from './css-site-header.js';
|
|
48
56
|
import { cssStatTileClasses } from './css-stat-tile.js';
|
|
49
57
|
import { cssDescriptionListClasses } from './css-description-list.js';
|
|
50
58
|
import { cssTabsClasses } from './css-tabs.js';
|
|
@@ -140,6 +148,8 @@ ${cssFontMonoClasses()}
|
|
|
140
148
|
|
|
141
149
|
${cssButtonClasses()}
|
|
142
150
|
|
|
151
|
+
${cssButtonLinkClasses()}
|
|
152
|
+
|
|
143
153
|
${cssCheckboxClasses()}
|
|
144
154
|
|
|
145
155
|
${cssRadioGroupClasses()}
|
|
@@ -158,6 +168,8 @@ ${cssDateRangeClasses()}
|
|
|
158
168
|
|
|
159
169
|
${cssListClasses()}
|
|
160
170
|
|
|
171
|
+
${cssFixtureClasses()}
|
|
172
|
+
|
|
161
173
|
${cssFileFieldClasses()}
|
|
162
174
|
|
|
163
175
|
${cssArticleClasses()}
|
|
@@ -186,6 +198,12 @@ ${cssChromeClasses()}
|
|
|
186
198
|
|
|
187
199
|
${cssSectionNavClasses()}
|
|
188
200
|
|
|
201
|
+
${cssBandClasses()}
|
|
202
|
+
|
|
203
|
+
${cssSiteFooterClasses()}
|
|
204
|
+
|
|
205
|
+
${cssSiteHeaderClasses()}
|
|
206
|
+
|
|
189
207
|
${cssAppShellClasses()}
|
|
190
208
|
|
|
191
209
|
${cssDialogClasses()}
|
|
@@ -204,6 +222,10 @@ ${cssSelectClasses()}
|
|
|
204
222
|
|
|
205
223
|
${cssActionMenuClasses()}
|
|
206
224
|
|
|
225
|
+
${cssContextSwitcherClasses()}
|
|
226
|
+
|
|
227
|
+
${cssCommandPaletteClasses()}
|
|
228
|
+
|
|
207
229
|
${cssComboboxClasses()}
|
|
208
230
|
${cssMultiSelectClasses()}
|
|
209
231
|
|
|
@@ -213,6 +235,8 @@ ${cssSwitchClasses()}
|
|
|
213
235
|
|
|
214
236
|
${cssSpinnerClasses()}
|
|
215
237
|
|
|
238
|
+
${cssSkeletonClasses()}
|
|
239
|
+
|
|
216
240
|
${cssProgressClasses()}
|
|
217
241
|
|
|
218
242
|
${cssNoticeClasses()}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const contextSwitcherTriggerAppearances: readonly ["framed", "text", "pill", "icon"];
|
|
2
|
+
/**
|
|
3
|
+
* How a ContextSwitcher's trigger looks: `framed` (the default) is the
|
|
4
|
+
* outlined control; `text` is its content and a chevron with no fill until
|
|
5
|
+
* hovered or open; `pill` is a rounded outlined pill at label weight;
|
|
6
|
+
* `icon` is a glyph alone in a round quiet button with no chevron.
|
|
7
|
+
*/
|
|
8
|
+
export type ContextSwitcherTriggerAppearance = (typeof contextSwitcherTriggerAppearances)[number];
|
|
9
|
+
export declare const contextSwitcherWidths: readonly ["content", "full"];
|
|
10
|
+
/** `full` makes the trigger fill its column, such as a sidebar's top. */
|
|
11
|
+
export type ContextSwitcherWidth = (typeof contextSwitcherWidths)[number];
|
|
12
|
+
/** The modifier class of an appearance, such as `sw-context-switcher-trigger-pill`. */
|
|
13
|
+
export declare function contextSwitcherTriggerClass(appearance: ContextSwitcherTriggerAppearance): string;
|
|
14
|
+
export declare function cssContextSwitcherTriggerClasses(): string;
|
|
15
|
+
export declare function contextSwitcherTriggerClassCatalog(): string[];
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { typographyVariants } from '@scalewing/tokens';
|
|
2
|
+
import { chevronStroke } from './chevron.js';
|
|
3
|
+
import { quietFill } from './quiet-fill.js';
|
|
4
|
+
import { coarsePointerQuery, touchTarget } from './touch-target.js';
|
|
5
|
+
const label = typographyVariants.label;
|
|
6
|
+
export const contextSwitcherTriggerAppearances = [
|
|
7
|
+
'framed',
|
|
8
|
+
'text',
|
|
9
|
+
'pill',
|
|
10
|
+
'icon',
|
|
11
|
+
];
|
|
12
|
+
export const contextSwitcherWidths = ['content', 'full'];
|
|
13
|
+
/** The modifier class of an appearance, such as `sw-context-switcher-trigger-pill`. */
|
|
14
|
+
export function contextSwitcherTriggerClass(appearance) {
|
|
15
|
+
return `sw-context-switcher-trigger-${appearance}`;
|
|
16
|
+
}
|
|
17
|
+
const trigger = '.sw-context-switcher-trigger';
|
|
18
|
+
const framed = `${trigger}.${contextSwitcherTriggerClass('framed')}`;
|
|
19
|
+
const pill = `${trigger}.${contextSwitcherTriggerClass('pill')}`;
|
|
20
|
+
const icon = `${trigger}.${contextSwitcherTriggerClass('icon')}`;
|
|
21
|
+
/*
|
|
22
|
+
* Every trigger: a real button in label type in the text colour, its
|
|
23
|
+
* content (a mark and words, which may be two lines) taking the free space
|
|
24
|
+
* at the inline start, then the shared muted chevron pointing down; the sm
|
|
25
|
+
* control height, the 44 px target on a coarse pointer. A transparent
|
|
26
|
+
* border is kept for forced colours. The quiet fill shows while open and
|
|
27
|
+
* under a hovering pointer, so the open state is seen as well as read.
|
|
28
|
+
*/
|
|
29
|
+
function baseRules() {
|
|
30
|
+
return `.sw-context-switcher {
|
|
31
|
+
display: inline-flex;
|
|
32
|
+
max-width: 100%;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.sw-context-switcher-full {
|
|
36
|
+
display: flex;
|
|
37
|
+
width: 100%;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
${trigger} {
|
|
41
|
+
align-items: center;
|
|
42
|
+
appearance: none;
|
|
43
|
+
background: transparent;
|
|
44
|
+
border: 1px solid transparent;
|
|
45
|
+
border-radius: var(--sw-radius-sm);
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
color: var(--sw-color-text);
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
display: inline-flex;
|
|
50
|
+
font-family: var(--sw-font-sans);
|
|
51
|
+
font-size: ${label.fontSize}px;
|
|
52
|
+
font-weight: 500;
|
|
53
|
+
gap: var(--sw-space-2);
|
|
54
|
+
letter-spacing: ${label.letterSpacing}px;
|
|
55
|
+
line-height: ${label.lineHeight}px;
|
|
56
|
+
margin: 0;
|
|
57
|
+
max-width: 100%;
|
|
58
|
+
min-height: var(--sw-control-sm-min-height);
|
|
59
|
+
padding-block: var(--sw-space-1);
|
|
60
|
+
padding-inline: var(--sw-space-3) var(--sw-space-2);
|
|
61
|
+
text-align: start;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.sw-context-switcher-full ${trigger} {
|
|
65
|
+
width: 100%;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.sw-context-switcher-trigger-content {
|
|
69
|
+
align-items: center;
|
|
70
|
+
display: flex;
|
|
71
|
+
flex: 1 1 auto;
|
|
72
|
+
gap: var(--sw-space-2);
|
|
73
|
+
min-width: 0;
|
|
74
|
+
overflow-wrap: anywhere;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
${trigger}:not(.${contextSwitcherTriggerClass('icon')})::after {
|
|
78
|
+
${chevronStroke}
|
|
79
|
+
content: '';
|
|
80
|
+
flex: none;
|
|
81
|
+
transform: translateY(-25%) rotate(45deg);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
${trigger}[aria-expanded='true'] {
|
|
85
|
+
background: ${quietFill};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@media (hover: hover) {
|
|
89
|
+
${trigger}:hover {
|
|
90
|
+
background: ${quietFill};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
${trigger}:focus-visible {
|
|
95
|
+
outline: var(--sw-focus-ring-width) solid var(--sw-color-accent);
|
|
96
|
+
outline-offset: var(--sw-focus-ring-offset);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@media ${coarsePointerQuery} {
|
|
100
|
+
${trigger} { min-height: ${touchTarget}; }
|
|
101
|
+
}`;
|
|
102
|
+
}
|
|
103
|
+
/*
|
|
104
|
+
* The appearances: `framed` the field's glass fill inside the border
|
|
105
|
+
* hairline; `pill` the same hairline on the surface, fully rounded, at
|
|
106
|
+
* label weight; `icon` a round button as wide as it is tall, the glyph
|
|
107
|
+
* centred and muted, no chevron. Two classes, so each outranks the base.
|
|
108
|
+
*/
|
|
109
|
+
function appearanceRules() {
|
|
110
|
+
return `${framed} {
|
|
111
|
+
background: var(--sw-glass-fill);
|
|
112
|
+
border-color: var(--sw-color-border);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
${pill} {
|
|
116
|
+
background: var(--sw-color-surface);
|
|
117
|
+
border-color: var(--sw-color-border);
|
|
118
|
+
border-radius: var(--sw-radius-pill);
|
|
119
|
+
font-weight: ${label.fontWeight};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
${framed}[aria-expanded='true'],
|
|
123
|
+
${pill}[aria-expanded='true'] {
|
|
124
|
+
background: ${quietFill};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@media (hover: hover) {
|
|
128
|
+
${framed}:hover,
|
|
129
|
+
${pill}:hover {
|
|
130
|
+
background: ${quietFill};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
${icon} {
|
|
135
|
+
border-radius: var(--sw-radius-pill);
|
|
136
|
+
color: var(--sw-color-muted);
|
|
137
|
+
justify-content: center;
|
|
138
|
+
min-width: var(--sw-control-sm-min-height);
|
|
139
|
+
padding: 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
${icon} .sw-context-switcher-trigger-content {
|
|
143
|
+
flex: none;
|
|
144
|
+
justify-content: center;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
${icon}[aria-expanded='true'] {
|
|
148
|
+
color: var(--sw-color-text);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@media ${coarsePointerQuery} {
|
|
152
|
+
${icon} { min-width: ${touchTarget}; }
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@media (forced-colors: active) {
|
|
156
|
+
${trigger}::after { border-color: CanvasText; }
|
|
157
|
+
${trigger}[aria-expanded='true'] { border-color: Highlight; }
|
|
158
|
+
${icon} { color: ButtonText; }
|
|
159
|
+
}`;
|
|
160
|
+
}
|
|
161
|
+
/* ContextSwitcher's trigger (see components/ContextSwitcher.tsx). */
|
|
162
|
+
export function cssContextSwitcherTriggerClasses() {
|
|
163
|
+
return `${baseRules()}
|
|
164
|
+
|
|
165
|
+
${appearanceRules()}`;
|
|
166
|
+
}
|
|
167
|
+
export function contextSwitcherTriggerClassCatalog() {
|
|
168
|
+
return [
|
|
169
|
+
'sw-context-switcher',
|
|
170
|
+
'sw-context-switcher-full',
|
|
171
|
+
'sw-context-switcher-trigger',
|
|
172
|
+
'sw-context-switcher-trigger-content',
|
|
173
|
+
...contextSwitcherTriggerAppearances.map(contextSwitcherTriggerClass),
|
|
174
|
+
];
|
|
175
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The trigger's width, set on the open popup so it is never narrower. */
|
|
2
|
+
export declare const contextSwitcherTriggerWidthVariable = "--sw-context-switcher-trigger-width";
|
|
3
|
+
export declare function cssContextSwitcherClasses(): string;
|
|
4
|
+
export declare function contextSwitcherClassCatalog(): string[];
|