@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.
- package/custom-elements.json +2 -2
- package/package.json +1 -1
- package/src/element.ts +39 -0
- package/src/gw-sheet.ts +0 -1
- package/src/styles.ts +99 -0
package/custom-elements.json
CHANGED
|
@@ -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;
|
|
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
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
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;
|