@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.
@@ -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; } /* The page's small scrollbars, as the themes set them, for scrolling parts inside components, which the page's rules can't reach. Each scroller follows its own scroll for the thumb's square ends */ @supports not selector(::-webkit-scrollbar) { * { scrollbar-width: thin; } } * { animation: gw-scrollbar-edges-y linear both, gw-scrollbar-edges-x linear both; animation-timeline: scroll(self y), scroll(self x); } @keyframes gw-scrollbar-edges-y { 0% { --gw-scrollbar-top: 0; } 1% { --gw-scrollbar-top: 1; } 99% { --gw-scrollbar-bottom: 1; } 100% { --gw-scrollbar-bottom: 0; } } @keyframes gw-scrollbar-edges-x { 0% { --gw-scrollbar-left: 0; } 1% { --gw-scrollbar-left: 1; } 99% { --gw-scrollbar-right: 1; } 100% { --gw-scrollbar-right: 0; } } ::-webkit-scrollbar { width: var(--gw-scrollbar-size, 0.4rem); height: var(--gw-scrollbar-size, 0.4rem); background: var(--gw-scrollbar-track, transparent); } ::-webkit-scrollbar-thumb { background: var( --gw-scrollbar-thumb, color-mix( in oklab, var(--gw-color-text-secondary, currentColor) 45%, transparent ) ); border-radius: calc( var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-top, 1) ) calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-top, 1)) calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-bottom, 1)) calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-bottom, 1)); } ::-webkit-scrollbar-thumb:horizontal { border-radius: calc( var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-left, 1) ) calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-right, 1)) calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-right, 1)) calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-left, 1)); } ::-webkit-scrollbar-thumb:hover { background: var( --gw-scrollbar-thumb, color-mix( in oklab, var(--gw-color-text-secondary, currentColor) 70%, transparent ) ); } ::-webkit-scrollbar-corner { background: transparent; } :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; } } `",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timmo001/groundwork-ui",
3
- "version": "0.9.15",
3
+ "version": "0.9.16",
4
4
  "description": "Groundwork's framework-free web components, styled by the --gw-* tokens",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
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
@@ -9,6 +9,8 @@ export * from "./element.js";
9
9
 
10
10
  export * from "./styles.js";
11
11
 
12
+ export * from "./scrollbars.js";
13
+
12
14
  export * from "./motion.js";
13
15
 
14
16
  export * from "./fields.js";
@@ -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;