@gjsify/adwaita-web 0.32.0 → 0.34.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/dist/adwaita-web.css +118 -55
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/elements/adw-combo-row.d.ts +10 -0
- package/lib/types/elements/adw-inline-view-switcher.d.ts +37 -1
- package/lib/types/elements/adw-navigation-split-view.d.ts +42 -0
- package/lib/types/elements/adw-overlay-split-view.d.ts +56 -0
- package/lib/types/elements/adw-spinner.d.ts +23 -0
- package/lib/types/elements/adw-view-stack.d.ts +12 -0
- package/lib/types/elements/adw-view-switcher-bar.d.ts +7 -5
- package/lib/types/elements/adw-view-switcher.d.ts +55 -3
- package/lib/types/elements/adw-wrap-box.d.ts +58 -3
- package/lib/types/styles.generated.d.ts +1 -1
- package/package.json +6 -6
- package/scss/_combo_row.scss +19 -0
- package/scss/_navigation_split_view.scss +52 -9
- package/scss/_navigation_view.scss +28 -4
- package/scss/_overlay_split_view.scss +122 -33
- package/scss/_panes.scss +57 -0
- package/scss/_sidebar.scss +8 -1
- package/scss/_spinner.scss +35 -21
- package/scss/_tab_view.scss +12 -13
- package/scss/_theme.scss +9 -0
- package/scss/_variables.scss +18 -1
- package/scss/_wrap_box.scss +9 -0
- package/scss/adwaita-skin.scss +1 -0
- package/src/adw-about-dialog.spec.ts +36 -0
- package/src/adw-avatar.spec.ts +37 -0
- package/src/adw-button-content.spec.ts +24 -0
- package/src/adw-row-state.spec.ts +49 -0
- package/src/adw-sidebar.spec.ts +32 -0
- package/src/adw-wrap-box.spec.ts +148 -1
- package/src/chrome.spec.ts +111 -12
- package/src/elements/adw-action-row.ts +11 -1
- package/src/elements/adw-combo-row.ts +17 -0
- package/src/elements/adw-inline-view-switcher.ts +91 -8
- package/src/elements/adw-navigation-split-view.ts +189 -14
- package/src/elements/adw-overlay-split-view.ts +395 -20
- package/src/elements/adw-spinner.ts +165 -21
- package/src/elements/adw-tab-view.ts +20 -2
- package/src/elements/adw-view-stack.ts +21 -0
- package/src/elements/adw-view-switcher-bar.ts +13 -5
- package/src/elements/adw-view-switcher.ts +103 -11
- package/src/elements/adw-wrap-box.ts +290 -135
- package/src/split-views.spec.ts +677 -2
- package/src/styles.generated.ts +1 -1
- package/src/view-switcher.spec.ts +219 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/adwaita-web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"description": "Adwaita/Libadwaita web components for browser targets",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"@codemirror/language": "^6.12.4",
|
|
42
42
|
"@codemirror/state": "^6.7.0",
|
|
43
43
|
"@codemirror/view": "^6.43.4",
|
|
44
|
-
"@gjsify/adwaita-core": "^0.
|
|
45
|
-
"@gjsify/adwaita-fonts": "^0.
|
|
46
|
-
"@gjsify/adwaita-icons": "^0.
|
|
44
|
+
"@gjsify/adwaita-core": "^0.34.0",
|
|
45
|
+
"@gjsify/adwaita-fonts": "^0.34.0",
|
|
46
|
+
"@gjsify/adwaita-icons": "^0.34.0",
|
|
47
47
|
"@lezer/highlight": "^1.2.3"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@gjsify/cli": "^0.
|
|
51
|
-
"@gjsify/unit": "^0.
|
|
50
|
+
"@gjsify/cli": "^0.34.0",
|
|
51
|
+
"@gjsify/unit": "^0.34.0",
|
|
52
52
|
"sass": "^1.101.0",
|
|
53
53
|
"typescript": "^6.0.3"
|
|
54
54
|
},
|
package/scss/_combo_row.scss
CHANGED
|
@@ -59,6 +59,11 @@ adw-combo-row {
|
|
|
59
59
|
// fill, making the icon theme-aware (matches libadwaita's dark theme).
|
|
60
60
|
// Using background-image with a data-URI SVG would NOT resolve
|
|
61
61
|
// `currentColor` in most browsers.
|
|
62
|
+
//
|
|
63
|
+
// `model_changed` (adw-combo-row.c:187-195) hides the arrow box entirely on
|
|
64
|
+
// a model of one item or none, so the row stops presenting itself as a
|
|
65
|
+
// chooser. `[data-presents-chooser='false']` below is that rule; the element
|
|
66
|
+
// publishes the attribute and disables the overlaid <select> alongside.
|
|
62
67
|
&::after {
|
|
63
68
|
content: "";
|
|
64
69
|
display: inline-block;
|
|
@@ -76,3 +81,17 @@ adw-combo-row {
|
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
}
|
|
84
|
+
|
|
85
|
+
// A model with one item or none: no arrow, and the row is not activatable
|
|
86
|
+
// (`model_changed`, adw-combo-row.c:187-195). Written as its own block rather
|
|
87
|
+
// than a modifier inside `.adw-row-value` so the two selectors that draw the
|
|
88
|
+
// arrow and the one that removes it read at the same specificity depth.
|
|
89
|
+
adw-combo-row[data-presents-chooser='false'] {
|
|
90
|
+
.adw-row-value::after {
|
|
91
|
+
display: none;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
select {
|
|
95
|
+
cursor: default;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
// _navigation_split_view.scss — adw-navigation-split-view styling (docked sidebar).
|
|
2
|
+
//
|
|
3
|
+
// Visibility is `data-pane-visible`, written by the element from
|
|
4
|
+
// `update_navigation_stack` (adw-navigation-split-view.c:342-405), not from the
|
|
5
|
+
// two flags. Two of that table's rules are not expressible as
|
|
6
|
+
// `.collapsed.show-content`: a LONE child stays visible whatever `show-content`
|
|
7
|
+
// says (:389-401), and with `sidebar-position: end` the CONTENT is the root page
|
|
8
|
+
// so the sidebar is pushed ON TOP of it rather than replacing it. This file used
|
|
9
|
+
// to key off the flags and got both wrong — a collapsed view with only a sidebar
|
|
10
|
+
// rendered blank.
|
|
11
|
+
//
|
|
2
12
|
// Reference: refs/adwaita-web/adwaita-web/docs/widgets/navigationsplitview.md
|
|
13
|
+
// Reference: refs/libadwaita/src/adw-navigation-split-view.c
|
|
3
14
|
// Reference: refs/libadwaita/src/stylesheet/widgets/_sidebars.scss
|
|
4
15
|
// Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
|
|
5
16
|
// Modifications: Adapted for @gjsify/adwaita-web Web Components.
|
|
@@ -11,38 +22,70 @@ adw-navigation-split-view {
|
|
|
11
22
|
min-width: 0;
|
|
12
23
|
flex: 1 1 auto;
|
|
13
24
|
|
|
25
|
+
// NO background here — it comes from the `.sidebar-pane` class the element
|
|
26
|
+
// applies while DOCKED (see _panes.scss). Collapsed, libadwaita builds no
|
|
27
|
+
// pane bins at all and the sidebar is an ordinary full-window navigation
|
|
28
|
+
// page; a background nailed to this private class made it sidebar-coloured
|
|
29
|
+
// at every width.
|
|
14
30
|
.adw-nsv-sidebar {
|
|
15
31
|
display: flex;
|
|
16
32
|
flex-direction: column;
|
|
17
33
|
min-height: 0;
|
|
18
34
|
flex-shrink: 0;
|
|
19
|
-
border-right: 1px solid var(--separator-color);
|
|
20
|
-
background-color: var(--sidebar-bg-color);
|
|
21
35
|
}
|
|
22
36
|
|
|
37
|
+
// The container MINIMUM, as CSS spells it: `measure_uncollapsed`
|
|
38
|
+
// (adw-navigation-split-view.c:264-267) is `sidebar_min + content_min`, which
|
|
39
|
+
// a flex row reaches by itself once the content may claim its own minimum.
|
|
40
|
+
// `min-width: 0` — the flex idiom for "let this be crushed" — was here, which
|
|
41
|
+
// is how the content pane could be squeezed to nothing while the sidebar,
|
|
42
|
+
// being `flex-shrink: 0`, kept its whole width.
|
|
23
43
|
.adw-nsv-content {
|
|
24
44
|
display: flex;
|
|
25
45
|
flex-direction: column;
|
|
26
|
-
min-width:
|
|
46
|
+
min-width: min-content;
|
|
27
47
|
min-height: 0;
|
|
28
48
|
flex: 1 1 auto;
|
|
29
49
|
background-color: var(--window-bg-color);
|
|
30
50
|
}
|
|
31
51
|
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
52
|
+
// `sidebar-position: end` docks the sidebar past the content. flex `order`
|
|
53
|
+
// flips the visual order without changing the slotting DOM order.
|
|
54
|
+
&.sidebar-end {
|
|
55
|
+
.adw-nsv-content {
|
|
56
|
+
order: 1;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.adw-nsv-sidebar {
|
|
60
|
+
order: 2;
|
|
61
|
+
}
|
|
35
62
|
}
|
|
36
63
|
|
|
37
|
-
|
|
38
|
-
|
|
64
|
+
// THE DIVIDER FOLLOWS THE VISUAL SIDE. `_sidebars.scss:1293-1302` makes it
|
|
65
|
+
// `:dir()` × `.end`, which is the product `.sidebar-at-visual-start` carries:
|
|
66
|
+
// under RTL a `start` sidebar is drawn on the right and its divider belongs on
|
|
67
|
+
// its left edge. A fixed `border-right` drew it on the wrong side for half the
|
|
68
|
+
// four combinations.
|
|
69
|
+
&.sidebar-at-visual-start .adw-nsv-sidebar {
|
|
70
|
+
border-right: 1px solid var(--separator-color);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
&:not(.sidebar-at-visual-start) .adw-nsv-sidebar {
|
|
74
|
+
border-left: 1px solid var(--separator-color);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Collapsed: whichever pane the STACK puts on top fills the view, and the
|
|
78
|
+
// other is not rendered at all.
|
|
79
|
+
&.collapsed {
|
|
80
|
+
[data-pane-visible='false'] {
|
|
39
81
|
display: none;
|
|
40
82
|
}
|
|
41
83
|
|
|
42
|
-
.adw-nsv-sidebar {
|
|
84
|
+
.adw-nsv-sidebar[data-pane-visible='true'] {
|
|
43
85
|
flex: 1 1 auto;
|
|
44
86
|
max-width: none;
|
|
45
87
|
border-right: none;
|
|
88
|
+
border-left: none;
|
|
46
89
|
}
|
|
47
90
|
}
|
|
48
91
|
}
|
|
@@ -16,9 +16,13 @@ adw-navigation-view {
|
|
|
16
16
|
background-color: var(--window-bg-color);
|
|
17
17
|
color: var(--window-fg-color);
|
|
18
18
|
|
|
19
|
-
// The page stack — fills the view
|
|
19
|
+
// The page stack — fills the view when it is given a height, and MEASURES the
|
|
20
|
+
// visible page when it is not. A flex column rather than a positioning
|
|
21
|
+
// context: the page is an in-flow item, so its content reaches the view.
|
|
20
22
|
.adw-navigation-view-pages {
|
|
21
23
|
flex: 1 1 auto;
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
22
26
|
position: relative;
|
|
23
27
|
box-sizing: border-box;
|
|
24
28
|
min-height: 0;
|
|
@@ -26,11 +30,31 @@ adw-navigation-view {
|
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
// A single navigation page — the visible one fills the view, the rest are
|
|
29
|
-
//
|
|
33
|
+
// `display: none`.
|
|
34
|
+
//
|
|
35
|
+
// IN FLOW, not absolute. It was `position: absolute; inset: 0` under a comment
|
|
36
|
+
// saying it had to be "so a transition can overlap two pages" — but two pages
|
|
37
|
+
// never overlap here: `adw-navigation-view.ts` marks every page but the
|
|
38
|
+
// visible one `[hidden]`, which is `display: none` below, and the push
|
|
39
|
+
// animation runs on `.visible-page` alone. So the absolute positioning bought
|
|
40
|
+
// an overlap that does not happen, and what it cost was the HEIGHT: an
|
|
41
|
+
// absolutely-positioned child contributes nothing to its parent, so the page
|
|
42
|
+
// stack measured 0, the view above it measured 0, and the page — `inset: 0` of
|
|
43
|
+
// a zero-height parent — measured 0 in turn. A closed circle.
|
|
44
|
+
//
|
|
45
|
+
// Inside a window that never showed, because a definite height arrived from
|
|
46
|
+
// outside. `<adw-about-dialog>` is the case where none does: its sheet is
|
|
47
|
+
// `position: fixed` with a width and no height, exactly as
|
|
48
|
+
// `adw-about-dialog.ui` declares it (`content-width` 360, no content-height —
|
|
49
|
+
// libadwaita takes the height from the content). The whole dialog rendered
|
|
50
|
+
// invisible, with a header bar inside it genuinely measuring 47px.
|
|
51
|
+
//
|
|
52
|
+
// `flex: 1 1 auto` keeps the fill: given a height the page still grows into
|
|
53
|
+
// it; without one it reports its content.
|
|
30
54
|
.adw-navigation-page {
|
|
31
55
|
box-sizing: border-box;
|
|
32
|
-
position:
|
|
33
|
-
|
|
56
|
+
position: relative;
|
|
57
|
+
flex: 1 1 auto;
|
|
34
58
|
display: flex;
|
|
35
59
|
flex-direction: column;
|
|
36
60
|
overflow: auto;
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
// _overlay_split_view.scss — adw-overlay-split-view styling.
|
|
2
|
+
//
|
|
3
|
+
// The GEOMETRY is no longer here. It used to be four `transform: translateX(±100%)`
|
|
4
|
+
// rules keyed on `.collapsed` / `.show-sidebar` / `.sidebar-end`, which can only
|
|
5
|
+
// express the two END STATES of a reveal — so `show-progress` was 0 or 1, the
|
|
6
|
+
// five `OVERLAY_SWIPE_*` conformance tables shipped unexercised, and the docked
|
|
7
|
+
// hide slid the wrong way for an `end` sidebar because the JS wrote `marginRight`
|
|
8
|
+
// whichever edge the pane was on.
|
|
9
|
+
//
|
|
10
|
+
// The element now writes the pane rect per frame from
|
|
11
|
+
// `layoutOverlaySplitView`, which is continuous and knows the edge (including
|
|
12
|
+
// under RTL, where a `start` sidebar is drawn on the RIGHT —
|
|
13
|
+
// `get_start_or_end`, adw-overlay-split-view.c:227-234). What is left here is
|
|
14
|
+
// what CSS genuinely owns: the box model, the stacking, and the transition that
|
|
15
|
+
// smooths a programmatic toggle.
|
|
16
|
+
//
|
|
2
17
|
// Reference: refs/libadwaita/src/adw-overlay-split-view.c
|
|
18
|
+
// Reference: refs/libadwaita/src/stylesheet/widgets/_sidebars.scss
|
|
3
19
|
// Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
|
|
4
20
|
// Modifications: Implemented as Web Component for @gjsify/adwaita-web.
|
|
5
21
|
|
|
@@ -11,38 +27,52 @@ adw-overlay-split-view {
|
|
|
11
27
|
position: relative;
|
|
12
28
|
overflow: hidden;
|
|
13
29
|
|
|
30
|
+
// NO background here. The pane colour comes from the `.sidebar-pane` /
|
|
31
|
+
// `.overlay-pane` class the element toggles (see _panes.scss), because which
|
|
32
|
+
// of the two a pane is in is exactly what decides its colour — hard-coding
|
|
33
|
+
// `--sidebar-bg-color` on this private class painted a collapsed overlay,
|
|
34
|
+
// which libadwaita puts on the window background, as though it were docked.
|
|
14
35
|
.adw-osv-sidebar {
|
|
15
|
-
background-color: var(--sidebar-bg-color);
|
|
16
36
|
overflow-y: auto;
|
|
17
37
|
flex-shrink: 0;
|
|
18
|
-
transition: transform 0.2s ease, opacity 0.2s ease, margin 0.2s ease;
|
|
19
38
|
z-index: 10;
|
|
20
39
|
align-self: stretch;
|
|
40
|
+
// Only `opacity` transitions. The offset is driven per frame, so animating
|
|
41
|
+
// it here would fight the swipe: a gesture would lag its own finger.
|
|
42
|
+
transition: opacity 0.2s ease;
|
|
21
43
|
}
|
|
22
44
|
|
|
45
|
+
// THE CONTAINER MINIMUM, as CSS spells it. `measure_uncollapsed`
|
|
46
|
+
// (adw-overlay-split-view.c:558-563) is `trunc(sidebar_min * progress) +
|
|
47
|
+
// content_min`, and a flex row reaches exactly that on its own PROVIDED the
|
|
48
|
+
// content is allowed to claim its own minimum: the sidebar is `flex-shrink: 0`
|
|
49
|
+
// with a `min-width` of `sidebar_min`, so the sum is the container's floor.
|
|
50
|
+
//
|
|
51
|
+
// `min-width: 0` was here instead — the flex idiom for "let this be crushed so
|
|
52
|
+
// an ellipsis can happen" — which is precisely how the content pane could be
|
|
53
|
+
// squeezed to nothing while the sidebar kept its whole width. A child that
|
|
54
|
+
// needs to truncate can still ask for `min-width: 0` itself; the PANE may not.
|
|
55
|
+
//
|
|
56
|
+
// Not computed in JS: a measured number would need the content's min-content
|
|
57
|
+
// size, which the DOM does not expose without a reflow, and the first attempt
|
|
58
|
+
// used `scrollWidth` — the pane's CURRENT width — which pinned the view at
|
|
59
|
+
// whatever it happened to be and stopped it responding to its breakpoint.
|
|
23
60
|
.adw-osv-content {
|
|
24
61
|
flex: 1;
|
|
25
|
-
min-width:
|
|
62
|
+
min-width: min-content;
|
|
26
63
|
min-height: 0;
|
|
27
64
|
display: flex;
|
|
28
65
|
flex-direction: column;
|
|
29
66
|
align-self: stretch;
|
|
30
67
|
}
|
|
31
68
|
|
|
32
|
-
// Docked
|
|
69
|
+
// Docked — the sidebar sits in the flex row and the hidden part is taken off
|
|
70
|
+
// its own edge by a negative margin the element computes.
|
|
33
71
|
&:not(.collapsed) .adw-osv-sidebar {
|
|
34
72
|
position: relative;
|
|
35
73
|
}
|
|
36
74
|
|
|
37
|
-
// Docked
|
|
38
|
-
// intrinsic width so internal elements don't reflow.
|
|
39
|
-
&:not(.collapsed):not(.show-sidebar) .adw-osv-sidebar {
|
|
40
|
-
transform: translateX(-100%);
|
|
41
|
-
opacity: 0;
|
|
42
|
-
pointer-events: none;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Docked + sidebar-end — dock the sidebar to the RIGHT of the content
|
|
75
|
+
// Docked + sidebar-end — dock the sidebar to the far side of the content
|
|
46
76
|
// (the Adw.OverlaySplitView { sidebar-position: end } layout). flex `order`
|
|
47
77
|
// flips the visual order without changing the slotting DOM order.
|
|
48
78
|
&:not(.collapsed).sidebar-end {
|
|
@@ -52,49 +82,108 @@ adw-overlay-split-view {
|
|
|
52
82
|
|
|
53
83
|
.adw-osv-sidebar {
|
|
54
84
|
order: 2;
|
|
55
|
-
border-inline-start: 1px solid var(--separator-color);
|
|
56
85
|
}
|
|
57
86
|
}
|
|
58
87
|
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
88
|
+
// THE DIVIDER FOLLOWS THE VISUAL SIDE, not the logical one. `_sidebars.scss`
|
|
89
|
+
// makes it `:dir()` × `.end` (:21-39), which is exactly the product
|
|
90
|
+
// `.sidebar-at-visual-start` already carries: under RTL a `start` sidebar is
|
|
91
|
+
// drawn on the right and its divider belongs on its left edge.
|
|
92
|
+
&:not(.collapsed) {
|
|
93
|
+
.adw-osv-sidebar {
|
|
94
|
+
border-inline-end: none;
|
|
95
|
+
border-inline-start: none;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&.sidebar-at-visual-start .adw-osv-sidebar {
|
|
99
|
+
border-right: 1px solid var(--separator-color);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&:not(.sidebar-at-visual-start) .adw-osv-sidebar {
|
|
103
|
+
border-left: 1px solid var(--separator-color);
|
|
104
|
+
}
|
|
62
105
|
}
|
|
63
106
|
|
|
64
|
-
// Overlay
|
|
107
|
+
// Overlay (collapsed) — the sidebar floats above the content at the absolute
|
|
108
|
+
// offset the element writes into `left`, which is the only property that can
|
|
109
|
+
// carry a mid-swipe position.
|
|
65
110
|
&.collapsed .adw-osv-sidebar {
|
|
66
111
|
position: absolute;
|
|
67
112
|
top: 0;
|
|
68
113
|
bottom: 0;
|
|
69
|
-
|
|
70
|
-
transform: translateX(-100%);
|
|
71
|
-
opacity: 0;
|
|
72
|
-
pointer-events: none;
|
|
114
|
+
box-shadow: 0 0 12px rgb(0 0 0 / 25%);
|
|
73
115
|
}
|
|
74
116
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
117
|
+
// THE TWO RESTING STATES ARE CSS. Everything BETWEEN them is JS.
|
|
118
|
+
//
|
|
119
|
+
// Dropping these is what shipped the docs-site regression. The offset is
|
|
120
|
+
// driven per frame from `layoutOverlaySplitView` — but a view that has never
|
|
121
|
+
// been measured drives nothing, and an absolutely-positioned pane with no
|
|
122
|
+
// `left` resolves to `left: 0` at full opacity. So a HIDDEN sidebar was
|
|
123
|
+
// painted over the content at the wrong edge, on a page whose slideshow
|
|
124
|
+
// builds each slide inside `display: none` and moves it in, so the first
|
|
125
|
+
// measurement never arrived and this fallback was the whole rendering.
|
|
126
|
+
//
|
|
127
|
+
// Not a second copy of the arithmetic: 0% and 100% ARE the two ends the JS
|
|
128
|
+
// interpolates between, and neither of them needs a pixel to say. The element
|
|
129
|
+
// clears its inline placement whenever it has no measurement, which is what
|
|
130
|
+
// hands control back to these rules instead of stranding a stale offset.
|
|
131
|
+
&.collapsed {
|
|
132
|
+
// Revealed: flush against the edge the pane is drawn on.
|
|
133
|
+
&.sidebar-at-visual-start .adw-osv-sidebar {
|
|
134
|
+
left: 0;
|
|
135
|
+
right: auto;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
&:not(.sidebar-at-visual-start) .adw-osv-sidebar {
|
|
139
|
+
left: auto;
|
|
140
|
+
right: 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Hidden: entirely off that same edge, and untouchable while it is there.
|
|
144
|
+
&:not(.show-sidebar) {
|
|
145
|
+
.adw-osv-sidebar {
|
|
146
|
+
opacity: 0;
|
|
147
|
+
pointer-events: none;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
&.sidebar-at-visual-start .adw-osv-sidebar {
|
|
151
|
+
left: auto;
|
|
152
|
+
right: 100%;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
&:not(.sidebar-at-visual-start) .adw-osv-sidebar {
|
|
156
|
+
left: 100%;
|
|
157
|
+
right: auto;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
79
160
|
}
|
|
80
161
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
162
|
+
// Docked and hidden — the pane takes no room in the row. The JS expresses
|
|
163
|
+
// this as a negative margin so it can animate; unmeasured, the end state is
|
|
164
|
+
// simply a pane of no width.
|
|
165
|
+
&:not(.collapsed):not(.show-sidebar) .adw-osv-sidebar {
|
|
166
|
+
width: 0;
|
|
167
|
+
min-width: 0;
|
|
168
|
+
overflow: hidden;
|
|
169
|
+
opacity: 0;
|
|
170
|
+
pointer-events: none;
|
|
85
171
|
}
|
|
86
172
|
|
|
87
|
-
// Backdrop —
|
|
173
|
+
// Backdrop — the click-outside shield. `hidden` is the element's, off
|
|
174
|
+
// `shieldVisible`; the OPACITY is the shadow-helper progress, so it fades with
|
|
175
|
+
// the reveal instead of appearing whole.
|
|
88
176
|
.adw-osv-backdrop {
|
|
89
177
|
display: none;
|
|
90
178
|
}
|
|
91
179
|
|
|
92
|
-
&.collapsed
|
|
180
|
+
&.collapsed .adw-osv-backdrop:not([hidden]) {
|
|
93
181
|
display: block;
|
|
94
182
|
position: absolute;
|
|
95
183
|
inset: 0;
|
|
96
|
-
background:
|
|
184
|
+
background: rgb(0 0 0 / 30%);
|
|
97
185
|
z-index: 9;
|
|
186
|
+
transition: opacity 0.2s ease;
|
|
98
187
|
}
|
|
99
188
|
}
|
|
100
189
|
|
package/scss/_panes.scss
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// _panes.scss — `.sidebar-pane` / `.content-pane` / `.overlay-pane`.
|
|
2
|
+
//
|
|
3
|
+
// These are libadwaita STYLE CLASSES, not private markup of one widget. Both
|
|
4
|
+
// split views document them as their CSS node tree
|
|
5
|
+
// (adw-navigation-split-view.c:157-165, adw-overlay-split-view.c:136-152) and
|
|
6
|
+
// both apply them to their pane bins, which makes them the supported hook an
|
|
7
|
+
// app themes a pane through. They lived nowhere in this stylesheet, so each
|
|
8
|
+
// split view hard-coded `--sidebar-bg-color` onto its own private pane div
|
|
9
|
+
// instead — with two consequences.
|
|
10
|
+
//
|
|
11
|
+
// The first is that an app writing the documented selector styles nothing, and
|
|
12
|
+
// gets no error saying so. Our own docs site is the evidence: every split-view
|
|
13
|
+
// example carried `class="sidebar"` on the sidebar toolbar view, hand-written
|
|
14
|
+
// by someone reaching for exactly this, matching no rule in the build.
|
|
15
|
+
//
|
|
16
|
+
// The second is a rendering defect, because the class is not constant — it is
|
|
17
|
+
// how the widget says which of its states a pane is in. A collapsed overlay
|
|
18
|
+
// sidebar is an `.overlay-pane`, on the WINDOW background, not the sidebar one
|
|
19
|
+
// (adw-overlay-split-view.c:718-741); a collapsed navigation split view has no
|
|
20
|
+
// pane bins at all, its pages being ordinary navigation pages. Painting the
|
|
21
|
+
// sidebar colour at every width, as the private rules did, got both wrong.
|
|
22
|
+
//
|
|
23
|
+
// Reference: refs/libadwaita/src/stylesheet/widgets/_sidebars.scss (.sidebar-pane, .overlay-pane)
|
|
24
|
+
// Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
|
|
25
|
+
// Modifications: Adapted for @gjsify/adwaita-web Web Components.
|
|
26
|
+
|
|
27
|
+
.sidebar-pane {
|
|
28
|
+
background-color: var(--sidebar-bg-color);
|
|
29
|
+
color: var(--sidebar-fg-color);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// A pane nested inside another sidebar pane defers to it rather than stacking a
|
|
33
|
+
// second tint (`.sidebar-pane .sidebar-pane`, _sidebars.scss). libadwaita also
|
|
34
|
+
// recolours the MIDDLE pane of a three-pane setup through
|
|
35
|
+
// `--secondary-sidebar-*`; that needs a split view nested in a split view to
|
|
36
|
+
// mean anything, and no such composition is rendered yet, so the tokens are
|
|
37
|
+
// defined (they are public API an app may already reference) and the selector
|
|
38
|
+
// is left for whoever builds the composition that can test it.
|
|
39
|
+
.sidebar-pane .sidebar-pane {
|
|
40
|
+
background-color: transparent;
|
|
41
|
+
color: inherit;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// `.content-pane` deliberately has NO rule here. libadwaita gives it no colour
|
|
45
|
+
// of its own — the window shows through — and writing `transparent` would be a
|
|
46
|
+
// claim, not a copy: it would override the `--window-bg-color` the navigation
|
|
47
|
+
// split view sets on its own content pane for the case where the view is not a
|
|
48
|
+
// window's direct child. The class is still applied, because being able to
|
|
49
|
+
// select it is the point.
|
|
50
|
+
|
|
51
|
+
// Collapsed: the sidebar floats ABOVE the content as a temporary panel, and
|
|
52
|
+
// libadwaita gives it the window colours rather than the sidebar ones — a panel
|
|
53
|
+
// over the content is not the same surface as a pane beside it.
|
|
54
|
+
.overlay-pane {
|
|
55
|
+
background-color: var(--window-bg-color);
|
|
56
|
+
color: var(--window-fg-color);
|
|
57
|
+
}
|
package/scss/_sidebar.scss
CHANGED
|
@@ -62,12 +62,19 @@ adw-sidebar {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// --- A single item row ---
|
|
65
|
+
//
|
|
66
|
+
// NO `width: 100%`. The list is a column flex container, so a row already
|
|
67
|
+
// stretches to it — and stretching SUBTRACTS the row's own margins, which is
|
|
68
|
+
// what puts the same 6px of air on both sides. `width: 100%` resolves against
|
|
69
|
+
// the containing block INSTEAD, which does not know about the margins, so
|
|
70
|
+
// every row came out 12px too wide: inset 6px on the left, hanging 6px past
|
|
71
|
+
// the right edge with its rounded corners cut off by the pane. Visible on any
|
|
72
|
+
// selected or hovered row, because only a filled row shows where it ends.
|
|
65
73
|
.adw-sidebar-item {
|
|
66
74
|
box-sizing: border-box;
|
|
67
75
|
display: flex;
|
|
68
76
|
align-items: center;
|
|
69
77
|
gap: var(--spacing-m);
|
|
70
|
-
width: 100%;
|
|
71
78
|
min-height: 36px;
|
|
72
79
|
// The native row has a context menu, so padding lives on the inner box and
|
|
73
80
|
// the row itself carries the menu margin + radius.
|
package/scss/_spinner.scss
CHANGED
|
@@ -1,32 +1,46 @@
|
|
|
1
|
-
// _spinner.scss — adw-spinner styling
|
|
1
|
+
// _spinner.scss — adw-spinner styling.
|
|
2
|
+
//
|
|
3
|
+
// Almost nothing is left here on purpose. The ring is an SVG the element draws
|
|
4
|
+
// per frame from `@gjsify/adwaita-core`'s `spinnerArc`, because the arc BREATHES
|
|
5
|
+
// (2.7 to 102.8 degrees) and CSS cannot express that: the `border-top-color`
|
|
6
|
+
// chase this file used to carry was a fixed 90-degree quarter-circle at 0.8s
|
|
7
|
+
// against libadwaita's 1.2s, with a hardcoded grey track and square-cut ends.
|
|
8
|
+
//
|
|
9
|
+
// What CSS still owns is the box: the element is `size × size` and the ring is
|
|
10
|
+
// centred inside it, which is how a 200px spinner shows a 64px ring
|
|
11
|
+
// (adw-spinner.c:95-99 hands the widget's real size to the paintable, which caps
|
|
12
|
+
// only the radius).
|
|
13
|
+
//
|
|
14
|
+
// There is deliberately NO `prefers-reduced-motion` rule. The C opts out of the
|
|
15
|
+
// animation setting explicitly (`adw_animation_set_follow_enable_animations_setting
|
|
16
|
+
// (…, FALSE)`, adw-spinner-paintable.c:537) — a frozen busy indicator reads as a
|
|
17
|
+
// hang. This file used to stop the animation there.
|
|
18
|
+
//
|
|
19
|
+
// Reference: refs/libadwaita/src/adw-spinner.c
|
|
20
|
+
// Reference: refs/libadwaita/src/adw-spinner-paintable.c
|
|
2
21
|
// Reference: refs/adwaita-web/adwaita-web/scss/_spinner.scss
|
|
3
|
-
// Reference: refs/libadwaita (Adw.Spinner)
|
|
4
22
|
// Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
|
|
5
23
|
// Modifications: Adapted for @gjsify/adwaita-web Web Components.
|
|
6
24
|
|
|
7
25
|
adw-spinner {
|
|
8
|
-
|
|
26
|
+
// The element writes the measured box onto `style` when it upgrades; these are
|
|
27
|
+
// the values in force until then, which are Adwaita's own minimum
|
|
28
|
+
// (adw-spinner.c:14, reported as both minimum and natural at :78-81).
|
|
29
|
+
display: inline-flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
justify-content: center;
|
|
9
32
|
box-sizing: border-box;
|
|
10
|
-
// Adw.Spinner measures 16 as BOTH its minimum and its natural size
|
|
11
|
-
// (adw-spinner.c:78-81), stroked at the documented "2px for 16px". The element
|
|
12
|
-
// overwrites both from `spinnerGeometry` when it upgrades; these are the values
|
|
13
|
-
// in force until then — the 24px/3px they replace were not from any source.
|
|
14
33
|
width: 16px;
|
|
15
34
|
height: 16px;
|
|
16
|
-
//
|
|
17
|
-
// is
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
border-radius: 50%;
|
|
21
|
-
animation: adw-spinner-spin 0.8s linear infinite;
|
|
35
|
+
// The arc strokes `currentColor` — `gtk_widget_get_color` (:432), the widget's
|
|
36
|
+
// TEXT colour, never the accent. The track is the same colour at 15%, which
|
|
37
|
+
// the SVG applies as `stroke-opacity`.
|
|
38
|
+
color: inherit;
|
|
22
39
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@keyframes adw-spinner-spin {
|
|
29
|
-
to {
|
|
30
|
-
transform: rotate(360deg);
|
|
40
|
+
svg {
|
|
41
|
+
display: block;
|
|
42
|
+
// The ring never grows past its own diameter, so an over-large box centres
|
|
43
|
+
// it rather than stretching it.
|
|
44
|
+
flex: none;
|
|
31
45
|
}
|
|
32
46
|
}
|
package/scss/_tab_view.scss
CHANGED
|
@@ -143,19 +143,18 @@ adw-tab-view {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
// `AdwTabPage:loading` swaps the icon image for
|
|
147
|
-
// (adw-tab.c:
|
|
148
|
-
//
|
|
149
|
-
.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
animation: none;
|
|
146
|
+
// `AdwTabPage:loading` swaps the icon image for an `AdwSpinnerPaintable`
|
|
147
|
+
// (`update_icons`, adw-tab.c:172-190) — the SAME paintable `Adw.Spinner` uses.
|
|
148
|
+
// So the tab mounts a real `<adw-spinner>` in the icon's slot and this block
|
|
149
|
+
// only places it. It used to restate `border: 2px`,
|
|
150
|
+
// `rgba(127, 127, 127, 0.25)` and `0.8s` under a comment claiming the geometry
|
|
151
|
+
// and keyframes were adw-spinner's and "not a second copy of them" — which is
|
|
152
|
+
// how it inherited every spinner defect independently.
|
|
153
|
+
.adw-tab-spinner {
|
|
154
|
+
flex: none;
|
|
155
|
+
|
|
156
|
+
&[hidden] {
|
|
157
|
+
display: none;
|
|
159
158
|
}
|
|
160
159
|
}
|
|
161
160
|
|
package/scss/_theme.scss
CHANGED
|
@@ -14,6 +14,15 @@
|
|
|
14
14
|
--headerbar-shade-color: rgba(0, 0, 6, 0.36);
|
|
15
15
|
--separator-color: rgba(255, 255, 255, 0.08);
|
|
16
16
|
--sidebar-bg-color: #2e2e32;
|
|
17
|
+
--sidebar-fg-color: #ffffff;
|
|
18
|
+
--sidebar-backdrop-color: #28282c;
|
|
19
|
+
--sidebar-shade-color: rgba(0, 0, 6, 0.25);
|
|
20
|
+
--sidebar-border-color: rgba(0, 0, 6, 0.36);
|
|
21
|
+
--secondary-sidebar-bg-color: #28282c;
|
|
22
|
+
--secondary-sidebar-fg-color: #ffffff;
|
|
23
|
+
--secondary-sidebar-backdrop-color: #252529;
|
|
24
|
+
--secondary-sidebar-shade-color: rgba(0, 0, 6, 0.25);
|
|
25
|
+
--secondary-sidebar-border-color: rgba(0, 0, 6, 0.36);
|
|
17
26
|
--card-bg-color: rgba(255, 255, 255, 0.08);
|
|
18
27
|
--card-fg-color: #ffffff;
|
|
19
28
|
--card-shade-color: rgba(0, 0, 6, 0.36);
|
package/scss/_variables.scss
CHANGED
|
@@ -24,8 +24,25 @@
|
|
|
24
24
|
// draws separators, instead of a harsh near-black line on a dark surface.
|
|
25
25
|
--separator-color: rgba(0, 0, 6, 0.1);
|
|
26
26
|
|
|
27
|
-
// Sidebar
|
|
27
|
+
// Sidebar / split panes. libadwaita defines the whole family, not just the
|
|
28
|
+
// background (_colors.scss:47-58), and only the background was here — so
|
|
29
|
+
// `.sidebar-pane` had no foreground to name, and an app overriding
|
|
30
|
+
// `--sidebar-fg-color` was overriding nothing.
|
|
28
31
|
--sidebar-bg-color: #ebebed;
|
|
32
|
+
--sidebar-fg-color: rgba(0, 0, 6, 0.8);
|
|
33
|
+
--sidebar-backdrop-color: #f2f2f4;
|
|
34
|
+
--sidebar-shade-color: rgba(0, 0, 6, 0.07);
|
|
35
|
+
--sidebar-border-color: rgba(0, 0, 6, 0.07);
|
|
36
|
+
|
|
37
|
+
// The MIDDLE pane of a three-pane setup. Nothing renders one yet; the tokens
|
|
38
|
+
// are defined because they are public API an app may already reference, and a
|
|
39
|
+
// half-present family reads as "this one is unsupported" rather than "this
|
|
40
|
+
// composition is not built yet".
|
|
41
|
+
--secondary-sidebar-bg-color: #f3f3f5;
|
|
42
|
+
--secondary-sidebar-fg-color: rgba(0, 0, 6, 0.8);
|
|
43
|
+
--secondary-sidebar-backdrop-color: #f6f6fa;
|
|
44
|
+
--secondary-sidebar-shade-color: rgba(0, 0, 6, 0.07);
|
|
45
|
+
--secondary-sidebar-border-color: rgba(0, 0, 6, 0.07);
|
|
29
46
|
|
|
30
47
|
// Cards / boxed lists
|
|
31
48
|
--card-bg-color: #ffffff;
|