@webority/theme 0.9.2 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/webority-theme.css +1 -1
- package/package.json +1 -1
- package/scss/wui/_controls.scss +1 -1
- package/scss/wui/_data.scss +32 -1
- package/scss/wui/_media.scss +68 -2
- package/scss/wui/_navigation.scss +14 -12
- package/scss/wui/_utilities.scss +27 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority/theme",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"description": "Webority shared design system — Bootstrap 5.3 SCSS overrides, --wui-* tokens, and shared component CSS. The single source of brand chrome for React portals and Razor sites.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"publishConfig": {
|
package/scss/wui/_controls.scss
CHANGED
|
@@ -1283,7 +1283,7 @@ wui-select[compact] {
|
|
|
1283
1283
|
align-items: center;
|
|
1284
1284
|
gap: 8px;
|
|
1285
1285
|
padding: 9px 14px;
|
|
1286
|
-
border:
|
|
1286
|
+
border: 1px solid var(--color-border);
|
|
1287
1287
|
border-radius: 999px;
|
|
1288
1288
|
font-size: 14px;
|
|
1289
1289
|
font-weight: 500;
|
package/scss/wui/_data.scss
CHANGED
|
@@ -58,6 +58,19 @@
|
|
|
58
58
|
align-items: center;
|
|
59
59
|
text-align: center;
|
|
60
60
|
padding: 40px 24px;
|
|
61
|
+
// An empty ledger still renders its header row, whose nowrap cells can push the
|
|
62
|
+
// table wider than the viewport, so `.table-wrap` scrolls horizontally with no
|
|
63
|
+
// data to justify it. This state row spans the full scroll width, so without a
|
|
64
|
+
// pin the message centres over that width and slides off screen on mobile.
|
|
65
|
+
// Stick it to the scrollport's left edge and size it to the visible wrap width
|
|
66
|
+
// (`100cqw`, from the container on `.table-wrap`), so the message stays centred
|
|
67
|
+
// and fully in view no matter how far the header scrolls. `left: 0` is relative
|
|
68
|
+
// to the scroll container; on a wide screen `100cqw` equals the content width, so
|
|
69
|
+
// this is a no-op there.
|
|
70
|
+
position: sticky;
|
|
71
|
+
left: 0;
|
|
72
|
+
width: 100cqw;
|
|
73
|
+
box-sizing: border-box;
|
|
61
74
|
}
|
|
62
75
|
.tbl-empty-icon {
|
|
63
76
|
display: inline-grid;
|
|
@@ -96,10 +109,23 @@
|
|
|
96
109
|
}
|
|
97
110
|
// The empty state owns its own padding and is not a row you can act on — no
|
|
98
111
|
// cell padding, no border, and no hover fill from .table / .table-ledger.
|
|
99
|
-
.table td.wui-table-empty:has(> .tbl-empty)
|
|
112
|
+
.table td.wui-table-empty:has(> .tbl-empty),
|
|
113
|
+
.table td.wui-table-empty:has(> .tbl-empty-plain) {
|
|
100
114
|
padding: 0;
|
|
101
115
|
border-bottom: 0;
|
|
102
116
|
}
|
|
117
|
+
// A plain-string empty (no `.tbl-empty` wrapper) — carries the padding the cell
|
|
118
|
+
// used to own, plus the same viewport pin as `.tbl-empty` so it stays on screen
|
|
119
|
+
// when a narrow ledger scrolls horizontally (see the pin note on `.tbl-empty`).
|
|
120
|
+
.tbl-empty-plain {
|
|
121
|
+
padding: 36px 24px;
|
|
122
|
+
text-align: center;
|
|
123
|
+
color: var(--color-text-muted);
|
|
124
|
+
position: sticky;
|
|
125
|
+
left: 0;
|
|
126
|
+
width: 100cqw;
|
|
127
|
+
box-sizing: border-box;
|
|
128
|
+
}
|
|
103
129
|
.table tbody tr:hover td.wui-table-empty:has(> .tbl-empty),
|
|
104
130
|
.table-ledger tbody tr:hover td.wui-table-empty:has(> .tbl-empty) {
|
|
105
131
|
background: transparent;
|
|
@@ -253,6 +279,11 @@
|
|
|
253
279
|
// class (set --wui-table-pad) without overriding this selector. Bottom padding is now
|
|
254
280
|
// included (was 0) so the last row isn't flush against the card edge.
|
|
255
281
|
padding: var(--wui-table-pad, 20px);
|
|
282
|
+
// Query container for the empty-state pin below. The header row can force the
|
|
283
|
+
// ledger wider than the viewport, so on a narrow screen `.table-wrap` scrolls
|
|
284
|
+
// horizontally; `100cqw` here is the *visible* wrap width regardless of that
|
|
285
|
+
// scroll, which is what keeps the empty message on screen (see `.tbl-empty`).
|
|
286
|
+
container-type: inline-size;
|
|
256
287
|
}
|
|
257
288
|
.table-ledger {
|
|
258
289
|
border-spacing: 0;
|
package/scss/wui/_media.scss
CHANGED
|
@@ -893,6 +893,10 @@
|
|
|
893
893
|
border: 1px dashed color-mix(in srgb, var(--color-border-strong) 75%, transparent);
|
|
894
894
|
cursor: pointer;
|
|
895
895
|
transition: border-color 0.18s;
|
|
896
|
+
// Query container so the overlay can drop its label on a small ring (see the @container
|
|
897
|
+
// rule after .set-uploader-overlay). container-type also makes the ring the containing
|
|
898
|
+
// block for the absolute overlay — same role its position:relative already plays.
|
|
899
|
+
container-type: inline-size;
|
|
896
900
|
}
|
|
897
901
|
.set-uploader-ring:hover,
|
|
898
902
|
.set-uploader:hover .set-uploader-ring,
|
|
@@ -925,10 +929,16 @@
|
|
|
925
929
|
flex-direction: column;
|
|
926
930
|
align-items: center;
|
|
927
931
|
justify-content: center;
|
|
928
|
-
gap
|
|
932
|
+
// Label + gap scale with the ring so a small (sm, 72px) ring's overlay stays legible and
|
|
933
|
+
// uncramped instead of wrapping a fixed 11px "Update photo" into a tight disc where it
|
|
934
|
+
// overlaps the initials. Clamped so md/lg land on the same 11px / 4px gap as before.
|
|
935
|
+
gap: clamp(2px, calc(var(--wui-logo-size) * 0.035), 4px);
|
|
936
|
+
padding: 0 6%;
|
|
929
937
|
background: var(--color-scrim-strong);
|
|
930
938
|
color: #fff;
|
|
931
|
-
font-size: 11px;
|
|
939
|
+
font-size: clamp(9px, calc(var(--wui-logo-size) * 0.1), 11px);
|
|
940
|
+
line-height: 1.15;
|
|
941
|
+
text-align: center;
|
|
932
942
|
font-weight: 600;
|
|
933
943
|
opacity: 0;
|
|
934
944
|
transition: opacity 0.18s;
|
|
@@ -938,6 +948,62 @@
|
|
|
938
948
|
.set-uploader:focus-visible .set-uploader-overlay {
|
|
939
949
|
opacity: 1;
|
|
940
950
|
}
|
|
951
|
+
// A ring too small to fit "Update photo" without cramping it over the initials (sm = 72px,
|
|
952
|
+
// and any custom size below ~95px) drops the label and shows the icon alone — a compact edit
|
|
953
|
+
// affordance. The lone icon grows a little so it reads as the whole overlay's cue. Driven by a
|
|
954
|
+
// container query on the ring, so it works for every size, preset or custom px.
|
|
955
|
+
@container (max-width: 95px) {
|
|
956
|
+
.set-uploader-overlay > span {
|
|
957
|
+
display: none;
|
|
958
|
+
}
|
|
959
|
+
.set-uploader-overlay > .wui-icon {
|
|
960
|
+
width: calc(var(--wui-logo-size) * 0.34);
|
|
961
|
+
height: calc(var(--wui-logo-size) * 0.34);
|
|
962
|
+
}
|
|
963
|
+
// The label has no room in the ring, so surface it as a hover/focus tooltip below the ring
|
|
964
|
+
// (reusing the AppTooltip surface look). Text comes from data-overlay-label on the ring — a
|
|
965
|
+
// distinct attribute from data-wui-tip so the global tooltip rule never fires this on a large
|
|
966
|
+
// ring. Only rendered inside this container query, so md/lg (label visible) never get it.
|
|
967
|
+
.set-uploader-ring[data-overlay-label]::after {
|
|
968
|
+
content: attr(data-overlay-label);
|
|
969
|
+
position: absolute;
|
|
970
|
+
top: calc(100% + 8px);
|
|
971
|
+
left: 50%;
|
|
972
|
+
transform: translateX(-50%);
|
|
973
|
+
z-index: var(--wui-z-menu, 1080);
|
|
974
|
+
width: max-content;
|
|
975
|
+
max-width: 160px;
|
|
976
|
+
padding: 6px 10px;
|
|
977
|
+
border-radius: var(--radius, 10px);
|
|
978
|
+
corner-shape: squircle;
|
|
979
|
+
background: var(--color-surface);
|
|
980
|
+
color: var(--color-text);
|
|
981
|
+
border: 1px solid var(--color-border-light);
|
|
982
|
+
box-shadow: var(--wui-shadow-overlay);
|
|
983
|
+
font-size: 0.75rem;
|
|
984
|
+
font-weight: 500;
|
|
985
|
+
line-height: 1.3;
|
|
986
|
+
white-space: nowrap;
|
|
987
|
+
pointer-events: none;
|
|
988
|
+
opacity: 0;
|
|
989
|
+
visibility: hidden;
|
|
990
|
+
transition:
|
|
991
|
+
opacity 0.12s ease,
|
|
992
|
+
visibility 0.12s;
|
|
993
|
+
}
|
|
994
|
+
// :not(:disabled) — a disabled/loading picker can't be updated, so it shows no tooltip
|
|
995
|
+
// (mirrors the overlay, which isn't rendered in those states).
|
|
996
|
+
.set-uploader:not(:disabled):hover .set-uploader-ring[data-overlay-label]::after,
|
|
997
|
+
.set-uploader:not(:disabled):focus-visible .set-uploader-ring[data-overlay-label]::after {
|
|
998
|
+
opacity: 1;
|
|
999
|
+
visibility: visible;
|
|
1000
|
+
}
|
|
1001
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1002
|
+
.set-uploader-ring[data-overlay-label]::after {
|
|
1003
|
+
transition: none;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
941
1007
|
// While uploading: keep the overlay (spinner) visible and signal it's not
|
|
942
1008
|
// clickable.
|
|
943
1009
|
.set-uploader-overlay.is-loading {
|
|
@@ -213,14 +213,12 @@
|
|
|
213
213
|
font-weight: 600;
|
|
214
214
|
}
|
|
215
215
|
// Static fallback underline (no-JS / first paint); the sliding ink bar takes over once
|
|
216
|
-
// wired.
|
|
217
|
-
// — reads as belonging to the label yet never touches a rounded container edge. Matches
|
|
218
|
-
// the wired ink bar's inset below.
|
|
216
|
+
// wired. Spans the tab's full width (inset defaults to 0), matching the wired ink bar below.
|
|
219
217
|
.app-tab.active::after {
|
|
220
218
|
content: "";
|
|
221
219
|
position: absolute;
|
|
222
|
-
left: var(--wui-tab-underline-inset,
|
|
223
|
-
right: var(--wui-tab-underline-inset,
|
|
220
|
+
left: var(--wui-tab-underline-inset, 0px);
|
|
221
|
+
right: var(--wui-tab-underline-inset, 0px);
|
|
224
222
|
bottom: -1px;
|
|
225
223
|
height: 2px;
|
|
226
224
|
border-radius: 2px;
|
|
@@ -268,18 +266,22 @@
|
|
|
268
266
|
left: 0;
|
|
269
267
|
bottom: -1px;
|
|
270
268
|
height: 2px;
|
|
271
|
-
//
|
|
272
|
-
//
|
|
273
|
-
//
|
|
274
|
-
width: max(0px, calc(var(--wui-tab-w, 0) - var(--wui-tab-underline-inset,
|
|
269
|
+
// Spans the tab's FULL width (the inset defaults to 0). A consumer can inset it via
|
|
270
|
+
// `--wui-tab-underline-inset`; falls to 0 rather than going negative on a tab narrower than
|
|
271
|
+
// any inset it sets. Pills keep the inset at 0 too (the pill fills the tab).
|
|
272
|
+
width: max(0px, calc(var(--wui-tab-w, 0) - var(--wui-tab-underline-inset, 0px) * 2));
|
|
275
273
|
background: var(--color-primary);
|
|
276
274
|
border-radius: 2px;
|
|
277
|
-
transform: translateX(calc(var(--wui-tab-x, 0) + var(--wui-tab-underline-inset,
|
|
275
|
+
transform: translateX(calc(var(--wui-tab-x, 0) + var(--wui-tab-underline-inset, 0px)));
|
|
278
276
|
opacity: 0;
|
|
279
277
|
pointer-events: none;
|
|
278
|
+
// Smooth ease-OUT (no overshoot), not the elastic bounce: a full-width bar sits flush to the
|
|
279
|
+
// edge tabs, so an elastic overshoot would push it past the strip and the `overflow-x: auto`
|
|
280
|
+
// clip would shear off its rounded corner. A decelerating slide reaches the tab exactly and
|
|
281
|
+
// never crosses the edge, so the radius is always intact.
|
|
280
282
|
transition:
|
|
281
|
-
transform 0.42s var(--wui-ease-
|
|
282
|
-
width 0.42s var(--wui-ease-
|
|
283
|
+
transform 0.42s var(--wui-ease-out-quart),
|
|
284
|
+
width 0.42s var(--wui-ease-out-quart),
|
|
283
285
|
opacity 0.15s ease;
|
|
284
286
|
}
|
|
285
287
|
.app-tabs[data-wui-tabs] .app-tab-indicator {
|
package/scss/wui/_utilities.scss
CHANGED
|
@@ -600,13 +600,17 @@
|
|
|
600
600
|
|
|
601
601
|
display: flex;
|
|
602
602
|
align-items: center;
|
|
603
|
+
// On phones the trailing action drops onto its own row BELOW the content (the flex `gap`
|
|
604
|
+
// supplies the vertical space) so a button never crushes the message into a sliver; from md
|
|
605
|
+
// up it sits inline at the right — a VIEWPORT rule, not the callout's own width. See the
|
|
606
|
+
// `.info-callout-action` breakpoint below.
|
|
607
|
+
flex-wrap: wrap;
|
|
603
608
|
gap: 12px;
|
|
604
609
|
padding: 14px 18px;
|
|
605
610
|
border: 1px solid var(--callout-border);
|
|
606
611
|
// A thick coloured left edge — the callout's signature aside marker.
|
|
607
612
|
border-left: 4px solid var(--callout-accent);
|
|
608
|
-
border-radius:
|
|
609
|
-
corner-shape: squircle;
|
|
613
|
+
border-radius: 8px;
|
|
610
614
|
background: var(--callout-bg);
|
|
611
615
|
font-size: 14px;
|
|
612
616
|
// Sub-content (the body/subtitle) reads at #252F4A / 400; the heading and the
|
|
@@ -690,14 +694,30 @@
|
|
|
690
694
|
min-width: 0;
|
|
691
695
|
font-size: 12px;
|
|
692
696
|
}
|
|
693
|
-
// Trailing action slot — a button (or any node)
|
|
697
|
+
// Trailing action slot — a button (or any node). Mobile-first: on phones it takes its own full
|
|
698
|
+
// row below the content (left-aligned there); from md up it collapses to its natural width and
|
|
699
|
+
// sits inline at the right edge of the content row.
|
|
694
700
|
.info-callout-action {
|
|
695
|
-
flex:
|
|
701
|
+
flex: 1 1 100%;
|
|
696
702
|
align-self: center;
|
|
697
|
-
display:
|
|
703
|
+
display: flex;
|
|
704
|
+
justify-content: flex-start;
|
|
698
705
|
align-items: center;
|
|
699
706
|
gap: 8px;
|
|
700
707
|
}
|
|
708
|
+
// From md up the row never wraps — the content shrinks to seat the action inline at the right,
|
|
709
|
+
// so a button stays beside the text on any large screen, even when the callout sits in a narrow
|
|
710
|
+
// column (the wrap-below is a phones-only treatment).
|
|
711
|
+
@include media-breakpoint-up(md) {
|
|
712
|
+
.info-callout {
|
|
713
|
+
flex-wrap: nowrap;
|
|
714
|
+
}
|
|
715
|
+
.info-callout-action {
|
|
716
|
+
flex: none;
|
|
717
|
+
justify-content: initial;
|
|
718
|
+
margin-left: auto;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
701
721
|
.info-callout-heading {
|
|
702
722
|
font-size: 14px;
|
|
703
723
|
font-weight: 600;
|
|
@@ -751,9 +771,8 @@
|
|
|
751
771
|
// the heading to the variant. Only the heading takes the variant colour — the body
|
|
752
772
|
// stays dark ink so the message reads calmly.
|
|
753
773
|
.alert {
|
|
754
|
-
--bs-alert-border-radius:
|
|
755
|
-
border-radius:
|
|
756
|
-
corner-shape: squircle;
|
|
774
|
+
--bs-alert-border-radius: 8px;
|
|
775
|
+
border-radius: 8px;
|
|
757
776
|
padding: 16px 18px;
|
|
758
777
|
border-width: 1px;
|
|
759
778
|
}
|