@webority/theme 0.7.6 → 0.7.8
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/README.md +50 -0
- package/dist/webority-theme.css +1 -1
- package/package.json +1 -1
- package/scss/_components.scss +184 -14
- package/scss/_tokens.scss +11 -3
- package/scss/_variables.scss +17 -0
- package/scss/_wui-aliases.scss +35 -5
- package/scss/_wui-components.scss +3 -0
- package/scss/wui/_card.scss +2 -2
- package/scss/wui/_choice.scss +11 -4
- package/scss/wui/_controls.scss +65 -24
- package/scss/wui/_data.scss +20 -0
- package/scss/wui/_media.scss +9 -1
- package/scss/wui/_navigation.scss +4 -2
- package/scss/wui/_overlays.scss +254 -25
- package/scss/wui/_shell.scss +49 -5
- package/scss/wui/_utilities.scss +3 -1
- package/scss/wui/_workspace.scss +239 -0
package/scss/wui/_shell.scss
CHANGED
|
@@ -262,6 +262,26 @@
|
|
|
262
262
|
width: 0;
|
|
263
263
|
height: 0;
|
|
264
264
|
}
|
|
265
|
+
// Between the brand row and the nav — a workspace/tenant switcher, an environment
|
|
266
|
+
// badge. It must not shrink when the nav overflows. The full card has no place on
|
|
267
|
+
// the 88px rail, so the collapsed state hides it (the mobile drawer restores it).
|
|
268
|
+
// The compact twin (`sidebarStartCompact` / `<app-shell-sidebar-start-compact>`) is
|
|
269
|
+
// the inverse: hidden expanded, shown only on the desktop collapsed rail, sized for
|
|
270
|
+
// a 36px monogram control (AppWorkspaceSwitcher compact).
|
|
271
|
+
.app-sidebar-start {
|
|
272
|
+
flex: none;
|
|
273
|
+
margin-bottom: 8px;
|
|
274
|
+
overflow: hidden;
|
|
275
|
+
}
|
|
276
|
+
.app-sidebar-start-compact {
|
|
277
|
+
display: none;
|
|
278
|
+
flex: none;
|
|
279
|
+
margin-bottom: 8px;
|
|
280
|
+
// Centre the fixed square in the 88px rail so it lines up with the icon column.
|
|
281
|
+
justify-content: center;
|
|
282
|
+
align-items: center;
|
|
283
|
+
overflow: hidden;
|
|
284
|
+
}
|
|
265
285
|
.app-sidebar-foot {
|
|
266
286
|
flex: none;
|
|
267
287
|
padding-top: 12px;
|
|
@@ -366,12 +386,31 @@
|
|
|
366
386
|
gap: 0;
|
|
367
387
|
padding: 9px 0;
|
|
368
388
|
}
|
|
369
|
-
.app-shell.collapsed .app-nav-text,
|
|
370
389
|
.app-shell.collapsed .app-nav-badge,
|
|
371
390
|
.app-shell.collapsed .app-nav-group-label,
|
|
372
|
-
.app-shell.collapsed .app-sidebar-brand-text
|
|
391
|
+
.app-shell.collapsed .app-sidebar-brand-text,
|
|
392
|
+
.app-shell.collapsed .app-sidebar-start {
|
|
373
393
|
display: none;
|
|
374
394
|
}
|
|
395
|
+
// The label leaves the VISUAL flow but must stay in the accessibility tree — an
|
|
396
|
+
// icon-only rail link with display:none text has no accessible name (axe
|
|
397
|
+
// link-name, serious). Clip-rect keeps the name; no phantom gap since it takes
|
|
398
|
+
// no space.
|
|
399
|
+
.app-shell.collapsed .app-nav-text {
|
|
400
|
+
position: absolute;
|
|
401
|
+
width: 1px;
|
|
402
|
+
height: 1px;
|
|
403
|
+
margin: -1px;
|
|
404
|
+
padding: 0;
|
|
405
|
+
overflow: hidden;
|
|
406
|
+
clip-path: inset(50%);
|
|
407
|
+
white-space: nowrap;
|
|
408
|
+
border: 0;
|
|
409
|
+
}
|
|
410
|
+
// Swap: expanded slot off, compact monogram on — only when the author filled the compact slot.
|
|
411
|
+
.app-shell.collapsed .app-sidebar-start-compact {
|
|
412
|
+
display: flex;
|
|
413
|
+
}
|
|
375
414
|
|
|
376
415
|
// ── Badge tones ──────────────────────────────────────────────────────────────
|
|
377
416
|
// A nav badge can carry a status tone so an alert count reads red, not neutral.
|
|
@@ -492,7 +531,7 @@
|
|
|
492
531
|
// 36px = half the 72px topbar, so the button lines up with the topbar's centre.
|
|
493
532
|
top: 36px;
|
|
494
533
|
left: calc(var(--app-sidebar-w) - 12px);
|
|
495
|
-
z-index:
|
|
534
|
+
z-index: var(--wui-z-fixed);
|
|
496
535
|
width: 24px;
|
|
497
536
|
height: 24px;
|
|
498
537
|
display: inline-grid;
|
|
@@ -597,7 +636,7 @@
|
|
|
597
636
|
right: 0;
|
|
598
637
|
bottom: 0;
|
|
599
638
|
left: var(--app-sidebar-w);
|
|
600
|
-
z-index:
|
|
639
|
+
z-index: var(--wui-z-fixed);
|
|
601
640
|
background: color-mix(in srgb, var(--color-surface) 90%, transparent);
|
|
602
641
|
backdrop-filter: blur(50px);
|
|
603
642
|
-webkit-backdrop-filter: blur(50px);
|
|
@@ -638,9 +677,14 @@
|
|
|
638
677
|
}
|
|
639
678
|
.app-shell.app-shell.collapsed .app-nav-text,
|
|
640
679
|
.app-shell.app-shell.collapsed .app-nav-badge,
|
|
641
|
-
.app-shell.app-shell.collapsed .app-nav-group-label
|
|
680
|
+
.app-shell.app-shell.collapsed .app-nav-group-label,
|
|
681
|
+
.app-shell.app-shell.collapsed .app-sidebar-start {
|
|
642
682
|
display: revert;
|
|
643
683
|
}
|
|
684
|
+
// Drawer always shows full labels — the compact rail control has no role here.
|
|
685
|
+
.app-shell.app-shell.collapsed .app-sidebar-start-compact {
|
|
686
|
+
display: none;
|
|
687
|
+
}
|
|
644
688
|
.app-shell.app-shell .app-sidebar-toggle {
|
|
645
689
|
display: none;
|
|
646
690
|
}
|
package/scss/wui/_utilities.scss
CHANGED
|
@@ -89,7 +89,9 @@
|
|
|
89
89
|
bottom: calc(100% + 8px);
|
|
90
90
|
left: 50%;
|
|
91
91
|
transform: translateX(-50%);
|
|
92
|
-
|
|
92
|
+
// Same rung as the .is-portal variant below — an anchored infotip inside a
|
|
93
|
+
// modal must clear the same modal it was previously trapped under at 220.
|
|
94
|
+
z-index: var(--wui-z-menu);
|
|
93
95
|
display: flex;
|
|
94
96
|
flex-direction: column;
|
|
95
97
|
gap: 4px;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
// Every class here is namespaced `.workspace-switcher*`, and the rules that have to beat
|
|
2
|
+
// Bootstrap's own .dropdown-item/.dropdown-menu specificity are additionally scoped under
|
|
3
|
+
// the .workspace-switcher root — so this file cannot reach anything a product owns unless
|
|
4
|
+
// the product claims that same prefix (see the CHANGELOG's claimed-class-names section).
|
|
5
|
+
// Tenant / workspace switcher — shared by React <AppWorkspaceSwitcher> and Razor
|
|
6
|
+
// <app-workspace-switcher>. Both render a Bootstrap dropdown, so the menu chrome below
|
|
7
|
+
// keys on the shared classes rather than on either surface's own wrapper.
|
|
8
|
+
//
|
|
9
|
+
// Part of the wui-components layer — see _wui-components.scss for the whole picture and the
|
|
10
|
+
// load order. Order within the layer is LOAD-BEARING: these partials are a split of one
|
|
11
|
+
// stylesheet, not independent modules. Never reorder the imports.
|
|
12
|
+
|
|
13
|
+
.workspace-switcher {
|
|
14
|
+
// The switcher fills whatever slot it is dropped into (a sidebar rail, a topbar cell);
|
|
15
|
+
// the compact trigger opts out below because its whole point is a fixed square.
|
|
16
|
+
display: block;
|
|
17
|
+
width: 100%;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ── Trigger ──
|
|
21
|
+
.workspace-switcher-trigger {
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
gap: 10px;
|
|
25
|
+
width: 100%;
|
|
26
|
+
min-height: 48px;
|
|
27
|
+
padding: 6px 10px;
|
|
28
|
+
background: var(--color-bg-subtle);
|
|
29
|
+
border: 1px solid var(--color-border-light);
|
|
30
|
+
border-radius: var(--radius-lg);
|
|
31
|
+
corner-shape: squircle;
|
|
32
|
+
color: var(--color-text);
|
|
33
|
+
text-align: left;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
transition: background 180ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
36
|
+
}
|
|
37
|
+
.workspace-switcher-trigger:hover {
|
|
38
|
+
background: var(--color-primary-soft);
|
|
39
|
+
}
|
|
40
|
+
.workspace-switcher-trigger:focus-visible {
|
|
41
|
+
outline: 2px solid var(--color-primary);
|
|
42
|
+
outline-offset: 2px;
|
|
43
|
+
}
|
|
44
|
+
.workspace-switcher-trigger.is-compact {
|
|
45
|
+
width: 36px;
|
|
46
|
+
min-height: 36px;
|
|
47
|
+
height: 36px;
|
|
48
|
+
padding: 0;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
gap: 0;
|
|
51
|
+
border-radius: var(--radius);
|
|
52
|
+
}
|
|
53
|
+
.workspace-switcher-trigger-name {
|
|
54
|
+
flex: 1 1 auto;
|
|
55
|
+
min-width: 0;
|
|
56
|
+
font-size: 14px;
|
|
57
|
+
font-weight: 600;
|
|
58
|
+
// A workspace name is user data: truncate rather than let it push the chevron out.
|
|
59
|
+
overflow: hidden;
|
|
60
|
+
text-overflow: ellipsis;
|
|
61
|
+
white-space: nowrap;
|
|
62
|
+
}
|
|
63
|
+
.workspace-switcher-chevron {
|
|
64
|
+
flex: none;
|
|
65
|
+
color: var(--color-text-muted);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ── Monogram / logo ──
|
|
69
|
+
// One class for both so a logo swap never changes the layout box.
|
|
70
|
+
.workspace-switcher-mark {
|
|
71
|
+
flex: none;
|
|
72
|
+
display: inline-flex;
|
|
73
|
+
align-items: center;
|
|
74
|
+
justify-content: center;
|
|
75
|
+
width: 28px;
|
|
76
|
+
height: 28px;
|
|
77
|
+
border-radius: var(--radius);
|
|
78
|
+
corner-shape: squircle;
|
|
79
|
+
background: var(--color-primary-soft);
|
|
80
|
+
color: var(--color-primary);
|
|
81
|
+
font-size: 11px;
|
|
82
|
+
font-weight: 700;
|
|
83
|
+
letter-spacing: 0.02em;
|
|
84
|
+
line-height: 1;
|
|
85
|
+
object-fit: cover;
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ── Menu ──
|
|
90
|
+
.workspace-switcher .workspace-switcher-menu {
|
|
91
|
+
width: 280px;
|
|
92
|
+
max-width: 280px;
|
|
93
|
+
padding: 6px;
|
|
94
|
+
background: var(--color-surface);
|
|
95
|
+
border: 1px solid var(--color-border-light);
|
|
96
|
+
border-radius: var(--radius-lg);
|
|
97
|
+
corner-shape: squircle;
|
|
98
|
+
box-shadow: var(--wui-shadow-overlay);
|
|
99
|
+
}
|
|
100
|
+
.workspace-switcher-menu-label {
|
|
101
|
+
padding: 6px 10px 4px;
|
|
102
|
+
font-size: 11px;
|
|
103
|
+
font-weight: 700;
|
|
104
|
+
letter-spacing: 0.06em;
|
|
105
|
+
text-transform: uppercase;
|
|
106
|
+
color: var(--color-text-subtle);
|
|
107
|
+
}
|
|
108
|
+
.workspace-switcher-search {
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
gap: 8px;
|
|
112
|
+
margin: 2px 4px 6px;
|
|
113
|
+
padding: 6px 10px;
|
|
114
|
+
background: var(--color-bg-subtle);
|
|
115
|
+
border: 1px solid var(--color-border-light);
|
|
116
|
+
border-radius: var(--radius);
|
|
117
|
+
corner-shape: squircle;
|
|
118
|
+
color: var(--color-text-muted);
|
|
119
|
+
}
|
|
120
|
+
.workspace-switcher-search-input {
|
|
121
|
+
flex: 1 1 auto;
|
|
122
|
+
min-width: 0;
|
|
123
|
+
border: none;
|
|
124
|
+
background: transparent;
|
|
125
|
+
color: var(--color-text);
|
|
126
|
+
font-size: 13px;
|
|
127
|
+
outline: none;
|
|
128
|
+
}
|
|
129
|
+
.workspace-switcher-list {
|
|
130
|
+
display: flex;
|
|
131
|
+
flex-direction: column;
|
|
132
|
+
gap: 2px;
|
|
133
|
+
max-height: 264px;
|
|
134
|
+
overflow-y: auto;
|
|
135
|
+
scrollbar-width: thin;
|
|
136
|
+
scrollbar-color: var(--color-border-strong) transparent;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// The rows are Bootstrap dropdown items on both surfaces, so the shared item chrome has to
|
|
140
|
+
// be re-stated here — an identity row is a three-column grid, not a text line with a glyph.
|
|
141
|
+
.workspace-switcher .workspace-switcher-option,
|
|
142
|
+
.workspace-switcher .workspace-switcher-create {
|
|
143
|
+
display: flex;
|
|
144
|
+
align-items: center;
|
|
145
|
+
gap: 10px;
|
|
146
|
+
width: 100%;
|
|
147
|
+
padding: 7px 10px;
|
|
148
|
+
border: none;
|
|
149
|
+
border-radius: var(--radius);
|
|
150
|
+
corner-shape: squircle;
|
|
151
|
+
background: transparent;
|
|
152
|
+
color: var(--color-text);
|
|
153
|
+
font-size: 14px;
|
|
154
|
+
text-align: left;
|
|
155
|
+
text-decoration: none;
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
}
|
|
158
|
+
.workspace-switcher .workspace-switcher-option:hover,
|
|
159
|
+
.workspace-switcher .workspace-switcher-create:hover {
|
|
160
|
+
background: var(--color-bg-subtle);
|
|
161
|
+
color: var(--color-text);
|
|
162
|
+
}
|
|
163
|
+
.workspace-switcher .workspace-switcher-option:focus-visible,
|
|
164
|
+
.workspace-switcher .workspace-switcher-create:focus-visible,
|
|
165
|
+
.workspace-switcher .workspace-switcher-footer-action:focus-visible {
|
|
166
|
+
outline: 2px solid var(--color-primary);
|
|
167
|
+
outline-offset: 2px;
|
|
168
|
+
}
|
|
169
|
+
// The active workspace keeps its tint through hover, so the tick is never the only cue.
|
|
170
|
+
.workspace-switcher .workspace-switcher-option.is-active,
|
|
171
|
+
.workspace-switcher .workspace-switcher-option.is-active:hover {
|
|
172
|
+
background: var(--color-primary-soft);
|
|
173
|
+
color: var(--color-primary);
|
|
174
|
+
}
|
|
175
|
+
.workspace-switcher-option-name {
|
|
176
|
+
flex: 1 1 auto;
|
|
177
|
+
min-width: 0;
|
|
178
|
+
overflow: hidden;
|
|
179
|
+
text-overflow: ellipsis;
|
|
180
|
+
white-space: nowrap;
|
|
181
|
+
}
|
|
182
|
+
.workspace-switcher-badge {
|
|
183
|
+
flex: none;
|
|
184
|
+
padding: 1px 7px;
|
|
185
|
+
border-radius: 999px;
|
|
186
|
+
background: var(--color-bg-subtle);
|
|
187
|
+
color: var(--color-text-muted);
|
|
188
|
+
font-size: 11px;
|
|
189
|
+
font-weight: 600;
|
|
190
|
+
}
|
|
191
|
+
.workspace-switcher-tick {
|
|
192
|
+
flex: none;
|
|
193
|
+
color: var(--color-primary);
|
|
194
|
+
}
|
|
195
|
+
.workspace-switcher-empty {
|
|
196
|
+
padding: 14px 10px;
|
|
197
|
+
text-align: center;
|
|
198
|
+
font-size: 13px;
|
|
199
|
+
color: var(--color-text-muted);
|
|
200
|
+
}
|
|
201
|
+
.workspace-switcher .workspace-switcher-create {
|
|
202
|
+
color: var(--color-primary);
|
|
203
|
+
font-weight: 600;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ── Footer ──
|
|
207
|
+
// A single workspace still gets a menu: current row + this footer. The divider is what makes
|
|
208
|
+
// that read as a complete panel rather than a truncated list.
|
|
209
|
+
.workspace-switcher-footer {
|
|
210
|
+
margin-top: 6px;
|
|
211
|
+
padding-top: 6px;
|
|
212
|
+
border-top: 1px solid var(--color-border-light);
|
|
213
|
+
}
|
|
214
|
+
.workspace-switcher .workspace-switcher-footer-action {
|
|
215
|
+
display: flex;
|
|
216
|
+
align-items: center;
|
|
217
|
+
gap: 10px;
|
|
218
|
+
width: 100%;
|
|
219
|
+
padding: 7px 10px;
|
|
220
|
+
border: none;
|
|
221
|
+
border-radius: var(--radius);
|
|
222
|
+
corner-shape: squircle;
|
|
223
|
+
background: transparent;
|
|
224
|
+
color: var(--color-text-muted);
|
|
225
|
+
font-size: 13px;
|
|
226
|
+
text-align: left;
|
|
227
|
+
text-decoration: none;
|
|
228
|
+
cursor: pointer;
|
|
229
|
+
}
|
|
230
|
+
.workspace-switcher .workspace-switcher-footer-action:hover {
|
|
231
|
+
background: var(--color-bg-subtle);
|
|
232
|
+
color: var(--color-text);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@media (prefers-reduced-motion: reduce) {
|
|
236
|
+
.workspace-switcher-trigger {
|
|
237
|
+
transition: none;
|
|
238
|
+
}
|
|
239
|
+
}
|