@timmo001/groundwork-ui 0.9.14 → 0.9.15

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.
@@ -16675,7 +16675,7 @@
16675
16675
  "text": "readonly CSSStyleSheet[]"
16676
16676
  },
16677
16677
  "static": true,
16678
- "default": "[ base, css` [popover] { position: fixed; box-sizing: border-box; flex-direction: column; padding: 0; margin: 0; overflow: hidden; color: var(--gw-color-text-primary); background: var(--gw-color-surface-overlay); border: 0 solid var(--gw-color-border-normal); box-shadow: var(--gw-shadow-l); transition: translate var(--gw-motion-normal) var(--gw-motion-easing), display var(--gw-motion-normal) allow-discrete, overlay var(--gw-motion-normal) allow-discrete; } [popover]:popover-open { display: flex; translate: 0 0; } /* The page dims as the sheet slides in, and back as it leaves */ [popover]::backdrop { background: rgb(0 0 0 / 0%); transition: background-color var(--gw-motion-normal) var(--gw-motion-easing), display var(--gw-motion-normal) allow-discrete, overlay var(--gw-motion-normal) allow-discrete; } [popover]:popover-open::backdrop { background: rgb(0 0 0 / 40%); } @starting-style { [popover]:popover-open::backdrop { background: rgb(0 0 0 / 0%); } } /* Full height from the start or end edge */ [data-side=\"start\"], [data-side=\"end\"] { inset: 0 auto; width: min(var(--gw-sheet-width, 20rem), 100vw); height: 100%; max-height: none; } [data-side=\"start\"] { inset-inline-start: 0; border-inline-end-width: max(var(--gw-border-width), 1px); translate: -100% 0; } [data-side=\"end\"] { inset-inline-end: 0; border-inline-start-width: max(var(--gw-border-width), 1px); translate: 100% 0; } :host(:dir(rtl)) [data-side=\"start\"] { translate: 100% 0; } :host(:dir(rtl)) [data-side=\"end\"] { translate: -100% 0; } /* Up from the bottom, with room for the phone's home bar */ [data-side=\"bottom\"] { inset: auto 0 0; width: 100%; max-width: none; max-height: var(--gw-sheet-height, 85vh); padding-block-end: env(safe-area-inset-bottom); border-block-start-width: max(var(--gw-border-width), 1px); border-start-start-radius: var(--gw-radius-panel); border-start-end-radius: var(--gw-radius-panel); translate: 0 100%; } @starting-style { [data-side=\"start\"]:popover-open { translate: -100% 0; } [data-side=\"end\"]:popover-open { translate: 100% 0; } [data-side=\"bottom\"]:popover-open { translate: 0 100%; } } header { display: flex; flex: none; gap: var(--gw-space-2); align-items: center; padding: var(--gw-space-2) var(--gw-space-3); border-block-end: var(--gw-border-width) solid var(--gw-color-border-quiet); } h2 { flex: 1; min-width: 0; margin: 0; font-size: var(--gw-font-size-m); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); } .body { display: flex; flex: 1; flex-direction: column; gap: var(--gw-space-3); min-height: 0; padding: var(--gw-space-4); /* It scrolls down only, so content reaching into its padding never makes it scroll sideways */ overflow: hidden auto; overscroll-behavior: contain; scrollbar-width: thin; } `, ]",
16678
+ "default": "[ base, css` [popover] { position: fixed; box-sizing: border-box; flex-direction: column; padding: 0; margin: 0; overflow: hidden; color: var(--gw-color-text-primary); background: var(--gw-color-surface-overlay); border: 0 solid var(--gw-color-border-normal); box-shadow: var(--gw-shadow-l); transition: translate var(--gw-motion-normal) var(--gw-motion-easing), display var(--gw-motion-normal) allow-discrete, overlay var(--gw-motion-normal) allow-discrete; } [popover]:popover-open { display: flex; translate: 0 0; } /* The page dims as the sheet slides in, and back as it leaves */ [popover]::backdrop { background: rgb(0 0 0 / 0%); transition: background-color var(--gw-motion-normal) var(--gw-motion-easing), display var(--gw-motion-normal) allow-discrete, overlay var(--gw-motion-normal) allow-discrete; } [popover]:popover-open::backdrop { background: rgb(0 0 0 / 40%); } @starting-style { [popover]:popover-open::backdrop { background: rgb(0 0 0 / 0%); } } /* Full height from the start or end edge */ [data-side=\"start\"], [data-side=\"end\"] { inset: 0 auto; width: min(var(--gw-sheet-width, 20rem), 100vw); height: 100%; max-height: none; } [data-side=\"start\"] { inset-inline-start: 0; border-inline-end-width: max(var(--gw-border-width), 1px); translate: -100% 0; } [data-side=\"end\"] { inset-inline-end: 0; border-inline-start-width: max(var(--gw-border-width), 1px); translate: 100% 0; } :host(:dir(rtl)) [data-side=\"start\"] { translate: 100% 0; } :host(:dir(rtl)) [data-side=\"end\"] { translate: -100% 0; } /* Up from the bottom, with room for the phone's home bar */ [data-side=\"bottom\"] { inset: auto 0 0; width: 100%; max-width: none; max-height: var(--gw-sheet-height, 85vh); padding-block-end: env(safe-area-inset-bottom); border-block-start-width: max(var(--gw-border-width), 1px); border-start-start-radius: var(--gw-radius-panel); border-start-end-radius: var(--gw-radius-panel); translate: 0 100%; } @starting-style { [data-side=\"start\"]:popover-open { translate: -100% 0; } [data-side=\"end\"]:popover-open { translate: 100% 0; } [data-side=\"bottom\"]:popover-open { translate: 0 100%; } } header { display: flex; flex: none; gap: var(--gw-space-2); align-items: center; padding: var(--gw-space-2) var(--gw-space-3); border-block-end: var(--gw-border-width) solid var(--gw-color-border-quiet); } h2 { flex: 1; min-width: 0; margin: 0; font-size: var(--gw-font-size-m); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); } .body { display: flex; flex: 1; flex-direction: column; gap: var(--gw-space-3); min-height: 0; padding: var(--gw-space-4); /* It scrolls down only, so content reaching into its padding never makes it scroll sideways */ overflow: hidden auto; overscroll-behavior: contain; } `, ]",
16679
16679
  "inheritedFrom": {
16680
16680
  "name": "GwElement",
16681
16681
  "module": "src/element.ts"
@@ -22859,7 +22859,7 @@
22859
22859
  {
22860
22860
  "kind": "variable",
22861
22861
  "name": "base",
22862
- "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; } } `",
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; } } `",
22863
22863
  "description": "What every component shares: box sizing, the focus ring, icons and the\ntones that set `--gw-tone` from a `tone` attribute."
22864
22864
  },
22865
22865
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timmo001/groundwork-ui",
3
- "version": "0.9.14",
3
+ "version": "0.9.15",
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
@@ -136,6 +136,43 @@ const toAttribute = (value: PropertyValue, type: PropertyOptions["type"]) => {
136
136
  const attributeName = (name: string, options: PropertyOptions) =>
137
137
  options.attribute === undefined ? name.toLowerCase() : options.attribute;
138
138
 
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
+
139
176
  /**
140
177
  * The base for every `gw-` element, with no framework underneath.
141
178
  *
@@ -182,6 +219,8 @@ export class GwElement extends HTMLElement {
182
219
  }
183
220
 
184
221
  if (!customElements.get(tag)) customElements.define(tag, this);
222
+
223
+ followPageScroll();
185
224
  }
186
225
 
187
226
  readonly #values = new Map<string, PropertyValue>();
package/src/gw-sheet.ts CHANGED
@@ -189,7 +189,6 @@ export class GwSheet extends GwElement {
189
189
  makes it scroll sideways */
190
190
  overflow: hidden auto;
191
191
  overscroll-behavior: contain;
192
- scrollbar-width: thin;
193
192
  }
194
193
  `,
195
194
  ];
package/src/styles.ts CHANGED
@@ -48,6 +48,105 @@ 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
+
51
150
  :host([hidden]),
52
151
  [hidden] {
53
152
  display: none !important;