@timmo001/groundwork-ui 0.9.15 → 0.9.16
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/custom-elements.json +44 -1
- package/package.json +1 -1
- package/src/element.ts +2 -38
- package/src/index.ts +2 -0
- package/src/scrollbars.ts +148 -0
- package/src/styles.ts +0 -99
package/custom-elements.json
CHANGED
|
@@ -20762,6 +20762,14 @@
|
|
|
20762
20762
|
"module": "src/styles.js"
|
|
20763
20763
|
}
|
|
20764
20764
|
},
|
|
20765
|
+
{
|
|
20766
|
+
"kind": "js",
|
|
20767
|
+
"name": "*",
|
|
20768
|
+
"declaration": {
|
|
20769
|
+
"name": "*",
|
|
20770
|
+
"module": "src/scrollbars.js"
|
|
20771
|
+
}
|
|
20772
|
+
},
|
|
20765
20773
|
{
|
|
20766
20774
|
"kind": "js",
|
|
20767
20775
|
"name": "*",
|
|
@@ -22839,6 +22847,41 @@
|
|
|
22839
22847
|
}
|
|
22840
22848
|
]
|
|
22841
22849
|
},
|
|
22850
|
+
{
|
|
22851
|
+
"kind": "javascript-module",
|
|
22852
|
+
"path": "src/scrollbars.ts",
|
|
22853
|
+
"declarations": [
|
|
22854
|
+
{
|
|
22855
|
+
"kind": "variable",
|
|
22856
|
+
"name": "scrollbars",
|
|
22857
|
+
"default": "new CSSStyleSheet()",
|
|
22858
|
+
"description": "The page's scrollbars for a shadow root: a small rounded thumb on a clear\ntrack with no arrow buttons, squaring off at the ends of its track. Every\n`gw-` element adopts it; add it to an app's own components' styles to match.\nThe `--gw-scrollbar-*` properties restyle it as they do the page's."
|
|
22859
|
+
},
|
|
22860
|
+
{
|
|
22861
|
+
"kind": "function",
|
|
22862
|
+
"name": "followPageScroll",
|
|
22863
|
+
"description": "Sets `--gw-scrollbar-top`, `-bottom`, `-left` and `-right` on the root as\nthe page scrolls, 0 against that end and 1 elsewhere, so the window's\nscrollbar thumb squares off at the ends like the others. The window's\nscrollbar doesn't repaint for the scroll-driven animation the themes give\nother scrollers. Every `gw-` element starts it when it's defined."
|
|
22864
|
+
}
|
|
22865
|
+
],
|
|
22866
|
+
"exports": [
|
|
22867
|
+
{
|
|
22868
|
+
"kind": "js",
|
|
22869
|
+
"name": "scrollbars",
|
|
22870
|
+
"declaration": {
|
|
22871
|
+
"name": "scrollbars",
|
|
22872
|
+
"module": "src/scrollbars.ts"
|
|
22873
|
+
}
|
|
22874
|
+
},
|
|
22875
|
+
{
|
|
22876
|
+
"kind": "js",
|
|
22877
|
+
"name": "followPageScroll",
|
|
22878
|
+
"declaration": {
|
|
22879
|
+
"name": "followPageScroll",
|
|
22880
|
+
"module": "src/scrollbars.ts"
|
|
22881
|
+
}
|
|
22882
|
+
}
|
|
22883
|
+
]
|
|
22884
|
+
},
|
|
22842
22885
|
{
|
|
22843
22886
|
"kind": "javascript-module",
|
|
22844
22887
|
"path": "src/styles.ts",
|
|
@@ -22859,7 +22902,7 @@
|
|
|
22859
22902
|
{
|
|
22860
22903
|
"kind": "variable",
|
|
22861
22904
|
"name": "base",
|
|
22862
|
-
"default": "css` :host { font-family: var(--gw-font-sans); color: var(--gw-color-text-primary); } *, *::before, *::after { box-sizing: border-box; }
|
|
22905
|
+
"default": "css` :host { font-family: var(--gw-font-sans); color: var(--gw-color-text-primary); } *, *::before, *::after { box-sizing: border-box; } :host([hidden]), [hidden] { display: none !important; } :focus-visible { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: var(--gw-focus-offset); } .icon { flex: none; width: var(--gw-icon-size, 1.25rem); height: var(--gw-icon-size, 1.25rem); fill: currentColor; } :host([tone=\"accent\"]) { --gw-tone: var(--gw-color-accent); --gw-tone-fill: var(--gw-color-fill-accent-quiet); --gw-tone-border: var(--gw-color-border-accent); } :host([tone=\"info\"]) { --gw-tone: var(--gw-color-info); --gw-tone-fill: var(--gw-color-fill-info-quiet); --gw-tone-border: var(--gw-color-border-info); } :host([tone=\"success\"]) { --gw-tone: var(--gw-color-success); --gw-tone-fill: var(--gw-color-fill-success-quiet); --gw-tone-border: var(--gw-color-border-success); } :host([tone=\"warning\"]) { --gw-tone: var(--gw-color-warning); --gw-tone-fill: var(--gw-color-fill-warning-quiet); --gw-tone-border: var(--gw-color-border-warning); } :host([tone=\"danger\"]) { --gw-tone: var(--gw-color-danger); --gw-tone-fill: var(--gw-color-fill-danger-quiet); --gw-tone-border: var(--gw-color-border-danger); } :host([tone=\"important\"]) { --gw-tone: var(--gw-color-important); --gw-tone-fill: var(--gw-color-fill-important-quiet); --gw-tone-border: var(--gw-color-border-important); } /* :host too, since * in a shadow root doesn't match it, and the skeletons pulse on their host */ @media (prefers-reduced-motion: reduce) { :host, *, *::before, *::after { animation-duration: 0s !important; transition-duration: 0s !important; } } `",
|
|
22863
22906
|
"description": "What every component shares: box sizing, the focus ring, icons and the\ntones that set `--gw-tone` from a `tone` attribute."
|
|
22864
22907
|
},
|
|
22865
22908
|
{
|
package/package.json
CHANGED
package/src/element.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
|
+
import { followPageScroll, scrollbars } from "./scrollbars.js";
|
|
8
9
|
|
|
9
10
|
/** How a property reads its attribute and writes it back. */
|
|
10
11
|
export interface PropertyOptions {
|
|
@@ -136,43 +137,6 @@ const toAttribute = (value: PropertyValue, type: PropertyOptions["type"]) => {
|
|
|
136
137
|
const attributeName = (name: string, options: PropertyOptions) =>
|
|
137
138
|
options.attribute === undefined ? name.toLowerCase() : options.attribute;
|
|
138
139
|
|
|
139
|
-
let followingPageScroll = false;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Sets `--gw-scrollbar-top`, `-bottom`, `-left` and `-right` on the root as
|
|
143
|
-
* the page scrolls, 0 against that end and 1 elsewhere, so the window's
|
|
144
|
-
* scrollbar thumb squares off at the ends like the others. The window's
|
|
145
|
-
* scrollbar doesn't repaint for the scroll-driven animation the themes give
|
|
146
|
-
* other scrollers.
|
|
147
|
-
*/
|
|
148
|
-
const followPageScroll = () => {
|
|
149
|
-
if (followingPageScroll) return;
|
|
150
|
-
|
|
151
|
-
followingPageScroll = true;
|
|
152
|
-
|
|
153
|
-
const root = document.documentElement;
|
|
154
|
-
|
|
155
|
-
const set = (edge: string, against: boolean) => {
|
|
156
|
-
const value = against ? "0" : "1";
|
|
157
|
-
|
|
158
|
-
if (root.style.getPropertyValue(`--gw-scrollbar-${edge}`) !== value)
|
|
159
|
-
root.style.setProperty(`--gw-scrollbar-${edge}`, value);
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const update = () => {
|
|
163
|
-
const page = document.scrollingElement ?? root;
|
|
164
|
-
|
|
165
|
-
set("top", page.scrollTop <= 0);
|
|
166
|
-
set("bottom", page.scrollTop + page.clientHeight >= page.scrollHeight - 1);
|
|
167
|
-
set("left", page.scrollLeft <= 0);
|
|
168
|
-
set("right", page.scrollLeft + page.clientWidth >= page.scrollWidth - 1);
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
update();
|
|
172
|
-
addEventListener("scroll", update, { passive: true });
|
|
173
|
-
new ResizeObserver(update).observe(root);
|
|
174
|
-
};
|
|
175
|
-
|
|
176
140
|
/**
|
|
177
141
|
* The base for every `gw-` element, with no framework underneath.
|
|
178
142
|
*
|
|
@@ -263,7 +227,7 @@ export class GwElement extends HTMLElement {
|
|
|
263
227
|
if (own.shadow) {
|
|
264
228
|
const root = this.attachShadow(own.shadowRootOptions);
|
|
265
229
|
|
|
266
|
-
root.adoptedStyleSheets = [...own.styles];
|
|
230
|
+
root.adoptedStyleSheets = [scrollbars, ...own.styles];
|
|
267
231
|
this.renderRoot = root;
|
|
268
232
|
} else {
|
|
269
233
|
this.renderRoot = this;
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The small scrollbars `themes.css` gives the page, as a sheet for shadow
|
|
3
|
+
* roots, which the page's rules can't reach, and the page scroll tracking
|
|
4
|
+
* that squares the window's thumb off at its ends.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The page's scrollbars for a shadow root: a small rounded thumb on a clear
|
|
11
|
+
* track with no arrow buttons, squaring off at the ends of its track. Every
|
|
12
|
+
* `gw-` element adopts it; add it to an app's own components' styles to match.
|
|
13
|
+
* The `--gw-scrollbar-*` properties restyle it as they do the page's.
|
|
14
|
+
*/
|
|
15
|
+
export const scrollbars = new CSSStyleSheet();
|
|
16
|
+
|
|
17
|
+
scrollbars.replaceSync(`
|
|
18
|
+
@supports not selector(::-webkit-scrollbar) {
|
|
19
|
+
* {
|
|
20
|
+
scrollbar-width: thin;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
* {
|
|
25
|
+
animation:
|
|
26
|
+
gw-scrollbar-edges-y linear both,
|
|
27
|
+
gw-scrollbar-edges-x linear both;
|
|
28
|
+
animation-timeline: scroll(self y), scroll(self x);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@keyframes gw-scrollbar-edges-y {
|
|
32
|
+
0% {
|
|
33
|
+
--gw-scrollbar-top: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
1% {
|
|
37
|
+
--gw-scrollbar-top: 1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
99% {
|
|
41
|
+
--gw-scrollbar-bottom: 1;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
100% {
|
|
45
|
+
--gw-scrollbar-bottom: 0;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@keyframes gw-scrollbar-edges-x {
|
|
50
|
+
0% {
|
|
51
|
+
--gw-scrollbar-left: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
1% {
|
|
55
|
+
--gw-scrollbar-left: 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
99% {
|
|
59
|
+
--gw-scrollbar-right: 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
100% {
|
|
63
|
+
--gw-scrollbar-right: 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
::-webkit-scrollbar {
|
|
68
|
+
width: var(--gw-scrollbar-size, 0.4rem);
|
|
69
|
+
height: var(--gw-scrollbar-size, 0.4rem);
|
|
70
|
+
background: var(--gw-scrollbar-track, transparent);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
::-webkit-scrollbar-thumb {
|
|
74
|
+
background: var(
|
|
75
|
+
--gw-scrollbar-thumb,
|
|
76
|
+
color-mix(
|
|
77
|
+
in oklab,
|
|
78
|
+
var(--gw-color-text-secondary, currentColor) 45%,
|
|
79
|
+
transparent
|
|
80
|
+
)
|
|
81
|
+
);
|
|
82
|
+
border-radius:
|
|
83
|
+
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-top, 1))
|
|
84
|
+
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-top, 1))
|
|
85
|
+
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-bottom, 1))
|
|
86
|
+
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-bottom, 1));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
::-webkit-scrollbar-thumb:horizontal {
|
|
90
|
+
border-radius:
|
|
91
|
+
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-left, 1))
|
|
92
|
+
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-right, 1))
|
|
93
|
+
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-right, 1))
|
|
94
|
+
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-left, 1));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
::-webkit-scrollbar-thumb:hover {
|
|
98
|
+
background: var(
|
|
99
|
+
--gw-scrollbar-thumb,
|
|
100
|
+
color-mix(
|
|
101
|
+
in oklab,
|
|
102
|
+
var(--gw-color-text-secondary, currentColor) 70%,
|
|
103
|
+
transparent
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
::-webkit-scrollbar-corner {
|
|
109
|
+
background: transparent;
|
|
110
|
+
}
|
|
111
|
+
`);
|
|
112
|
+
|
|
113
|
+
let followingPageScroll = false;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Sets `--gw-scrollbar-top`, `-bottom`, `-left` and `-right` on the root as
|
|
117
|
+
* the page scrolls, 0 against that end and 1 elsewhere, so the window's
|
|
118
|
+
* scrollbar thumb squares off at the ends like the others. The window's
|
|
119
|
+
* scrollbar doesn't repaint for the scroll-driven animation the themes give
|
|
120
|
+
* other scrollers. Every `gw-` element starts it when it's defined.
|
|
121
|
+
*/
|
|
122
|
+
export const followPageScroll = () => {
|
|
123
|
+
if (followingPageScroll) return;
|
|
124
|
+
|
|
125
|
+
followingPageScroll = true;
|
|
126
|
+
|
|
127
|
+
const root = document.documentElement;
|
|
128
|
+
|
|
129
|
+
const set = (edge: string, against: boolean) => {
|
|
130
|
+
const value = against ? "0" : "1";
|
|
131
|
+
|
|
132
|
+
if (root.style.getPropertyValue(`--gw-scrollbar-${edge}`) !== value)
|
|
133
|
+
root.style.setProperty(`--gw-scrollbar-${edge}`, value);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const update = () => {
|
|
137
|
+
const page = document.scrollingElement ?? root;
|
|
138
|
+
|
|
139
|
+
set("top", page.scrollTop <= 0);
|
|
140
|
+
set("bottom", page.scrollTop + page.clientHeight >= page.scrollHeight - 1);
|
|
141
|
+
set("left", page.scrollLeft <= 0);
|
|
142
|
+
set("right", page.scrollLeft + page.clientWidth >= page.scrollWidth - 1);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
update();
|
|
146
|
+
addEventListener("scroll", update, { passive: true });
|
|
147
|
+
new ResizeObserver(update).observe(root);
|
|
148
|
+
};
|
package/src/styles.ts
CHANGED
|
@@ -48,105 +48,6 @@ export const base = css`
|
|
|
48
48
|
box-sizing: border-box;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
/* The page's small scrollbars, as the themes set them, for scrolling parts
|
|
52
|
-
inside components, which the page's rules can't reach. Each scroller
|
|
53
|
-
follows its own scroll for the thumb's square ends */
|
|
54
|
-
@supports not selector(::-webkit-scrollbar) {
|
|
55
|
-
* {
|
|
56
|
-
scrollbar-width: thin;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
* {
|
|
61
|
-
animation:
|
|
62
|
-
gw-scrollbar-edges-y linear both,
|
|
63
|
-
gw-scrollbar-edges-x linear both;
|
|
64
|
-
animation-timeline: scroll(self y), scroll(self x);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
@keyframes gw-scrollbar-edges-y {
|
|
68
|
-
0% {
|
|
69
|
-
--gw-scrollbar-top: 0;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
1% {
|
|
73
|
-
--gw-scrollbar-top: 1;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
99% {
|
|
77
|
-
--gw-scrollbar-bottom: 1;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
100% {
|
|
81
|
-
--gw-scrollbar-bottom: 0;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
@keyframes gw-scrollbar-edges-x {
|
|
86
|
-
0% {
|
|
87
|
-
--gw-scrollbar-left: 0;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
1% {
|
|
91
|
-
--gw-scrollbar-left: 1;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
99% {
|
|
95
|
-
--gw-scrollbar-right: 1;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
100% {
|
|
99
|
-
--gw-scrollbar-right: 0;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
::-webkit-scrollbar {
|
|
104
|
-
width: var(--gw-scrollbar-size, 0.4rem);
|
|
105
|
-
height: var(--gw-scrollbar-size, 0.4rem);
|
|
106
|
-
background: var(--gw-scrollbar-track, transparent);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
::-webkit-scrollbar-thumb {
|
|
110
|
-
background: var(
|
|
111
|
-
--gw-scrollbar-thumb,
|
|
112
|
-
color-mix(
|
|
113
|
-
in oklab,
|
|
114
|
-
var(--gw-color-text-secondary, currentColor) 45%,
|
|
115
|
-
transparent
|
|
116
|
-
)
|
|
117
|
-
);
|
|
118
|
-
border-radius: calc(
|
|
119
|
-
var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-top, 1)
|
|
120
|
-
)
|
|
121
|
-
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-top, 1))
|
|
122
|
-
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-bottom, 1))
|
|
123
|
-
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-bottom, 1));
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
::-webkit-scrollbar-thumb:horizontal {
|
|
127
|
-
border-radius: calc(
|
|
128
|
-
var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-left, 1)
|
|
129
|
-
)
|
|
130
|
-
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-right, 1))
|
|
131
|
-
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-right, 1))
|
|
132
|
-
calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-left, 1));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
::-webkit-scrollbar-thumb:hover {
|
|
136
|
-
background: var(
|
|
137
|
-
--gw-scrollbar-thumb,
|
|
138
|
-
color-mix(
|
|
139
|
-
in oklab,
|
|
140
|
-
var(--gw-color-text-secondary, currentColor) 70%,
|
|
141
|
-
transparent
|
|
142
|
-
)
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
::-webkit-scrollbar-corner {
|
|
147
|
-
background: transparent;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
51
|
:host([hidden]),
|
|
151
52
|
[hidden] {
|
|
152
53
|
display: none !important;
|