@timmo001/groundwork-tokens 0.9.13 → 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.
@@ -60,6 +60,103 @@
60
60
  }
61
61
  }
62
62
 
63
+ @supports not selector(::-webkit-scrollbar) {
64
+ :where(:root, :root *) {
65
+ scrollbar-width: thin;
66
+ scrollbar-color: var(--gw-scrollbar-thumb, color-mix(in oklab, var(--gw-color-text-secondary, currentColor) 45%, transparent)) var(--gw-scrollbar-track, transparent);
67
+ }
68
+ }
69
+
70
+ :where(:root, :root *)::-webkit-scrollbar {
71
+ width: var(--gw-scrollbar-size, 0.4rem);
72
+ height: var(--gw-scrollbar-size, 0.4rem);
73
+ background: var(--gw-scrollbar-track, transparent);
74
+ }
75
+
76
+ :where(:root, :root *)::-webkit-scrollbar-thumb {
77
+ background: var(--gw-scrollbar-thumb, color-mix(in oklab, var(--gw-color-text-secondary, currentColor) 45%, transparent));
78
+ 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));
79
+ }
80
+
81
+ :where(:root, :root *)::-webkit-scrollbar-thumb:horizontal {
82
+ 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));
83
+ }
84
+
85
+ :where(:root, :root *)::-webkit-scrollbar-thumb:hover {
86
+ background: var(--gw-scrollbar-thumb, color-mix(in oklab, var(--gw-color-text-secondary, currentColor) 70%, transparent));
87
+ }
88
+
89
+ :where(:root, :root *)::-webkit-scrollbar-corner {
90
+ background: transparent;
91
+ }
92
+
93
+ @property --gw-scrollbar-top {
94
+ syntax: "<number>";
95
+ inherits: true;
96
+ initial-value: 1;
97
+ }
98
+
99
+ @property --gw-scrollbar-bottom {
100
+ syntax: "<number>";
101
+ inherits: true;
102
+ initial-value: 1;
103
+ }
104
+
105
+ @property --gw-scrollbar-left {
106
+ syntax: "<number>";
107
+ inherits: true;
108
+ initial-value: 1;
109
+ }
110
+
111
+ @property --gw-scrollbar-right {
112
+ syntax: "<number>";
113
+ inherits: true;
114
+ initial-value: 1;
115
+ }
116
+
117
+ @keyframes gw-scrollbar-edges-y {
118
+ 0% {
119
+ --gw-scrollbar-top: 0;
120
+ }
121
+
122
+ 1% {
123
+ --gw-scrollbar-top: 1;
124
+ }
125
+
126
+ 99% {
127
+ --gw-scrollbar-bottom: 1;
128
+ }
129
+
130
+ 100% {
131
+ --gw-scrollbar-bottom: 0;
132
+ }
133
+ }
134
+
135
+ @keyframes gw-scrollbar-edges-x {
136
+ 0% {
137
+ --gw-scrollbar-left: 0;
138
+ }
139
+
140
+ 1% {
141
+ --gw-scrollbar-left: 1;
142
+ }
143
+
144
+ 99% {
145
+ --gw-scrollbar-right: 1;
146
+ }
147
+
148
+ 100% {
149
+ --gw-scrollbar-right: 0;
150
+ }
151
+ }
152
+
153
+ :where(:root *) {
154
+ --gw-scrollbar-top: 1;
155
+ --gw-scrollbar-bottom: 1;
156
+ --gw-scrollbar-left: 1;
157
+ --gw-scrollbar-right: 1;
158
+ }
159
+
63
160
  gw-fade-in:not(:defined) {
64
161
  opacity: 0;
65
162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timmo001/groundwork-tokens",
3
- "version": "0.9.13",
3
+ "version": "0.9.15",
4
4
  "description": "Groundwork's design tokens: the theme schema, the OKLCH solver and every theme as CSS and JSON",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
package/src/generate.ts CHANGED
@@ -361,11 +361,87 @@ const preUpgradeCss = Object.entries(preUpgrade)
361
361
  })
362
362
  .join("\n\n");
363
363
 
364
+ /**
365
+ * Small scrollbars with a rounded, quiet thumb on a clear track and no arrow
366
+ * buttons, for the page and every element in it, at no specificity so any
367
+ * rule of a page's wins. `--gw-scrollbar-size`, `--gw-scrollbar-thumb` and
368
+ * `--gw-scrollbar-track` restyle them anywhere; `scrollbar-width: none` hides
369
+ * one. Firefox, without the WebKit pseudo-elements, gets its thin scrollbar.
370
+ */
371
+ const scrollbarCss = (scope: string) => {
372
+ const each = (pseudo = "") => `:where(${scope})${pseudo}`;
373
+
374
+ return `@supports not selector(::-webkit-scrollbar) {
375
+ ${each()} {
376
+ scrollbar-width: thin;
377
+ scrollbar-color: ${scrollbarThumb(45)} var(--gw-scrollbar-track, transparent);
378
+ }
379
+ }
380
+
381
+ ${each("::-webkit-scrollbar")} {
382
+ width: var(--gw-scrollbar-size, 0.4rem);
383
+ height: var(--gw-scrollbar-size, 0.4rem);
384
+ background: var(--gw-scrollbar-track, transparent);
385
+ }
386
+
387
+ ${each("::-webkit-scrollbar-thumb")} {
388
+ background: ${scrollbarThumb(45)};
389
+ border-radius: ${scrollbarRadius("top", "top", "bottom", "bottom")};
390
+ }
391
+
392
+ ${each("::-webkit-scrollbar-thumb:horizontal")} {
393
+ border-radius: ${scrollbarRadius("left", "right", "right", "left")};
394
+ }
395
+
396
+ ${each("::-webkit-scrollbar-thumb:hover")} {
397
+ background: ${scrollbarThumb(70)};
398
+ }
399
+
400
+ ${each("::-webkit-scrollbar-corner")} {
401
+ background: transparent;
402
+ }`;
403
+ };
404
+
405
+ const scrollbarThumb = (strength: number) =>
406
+ `var(--gw-scrollbar-thumb, color-mix(in oklab, var(--gw-color-text-secondary, currentColor) ${strength}%, transparent))`;
407
+
408
+ /**
409
+ * The thumb's corners, from top left: round, or square where it meets the end
410
+ * of its track. `--gw-scrollbar-top`, `-bottom`, `-left` and `-right` are 0 at
411
+ * that end and 1 elsewhere.
412
+ */
413
+ const scrollbarRadius = (...edges: readonly string[]) =>
414
+ edges
415
+ .map(
416
+ (edge) =>
417
+ `calc(var(--gw-scrollbar-size, 0.4rem) * var(--gw-scrollbar-${edge}, 1))`,
418
+ )
419
+ .join(" ");
420
+
421
+ /**
422
+ * Where a scroller is against each end, for the thumb's square ends. A
423
+ * scroller takes its own from the `gw-scrollbar-edges-y` and `-x` animations
424
+ * on its scroll timeline; everything else resets them, so a scroller without
425
+ * them never takes its parent's. The page's own come from the ui package,
426
+ * since an animation on the root doesn't repaint the window's scrollbar.
427
+ */
428
+ const scrollbarEdgesCss = [
429
+ ...["top", "bottom", "left", "right"].map(
430
+ (edge) =>
431
+ `@property --gw-scrollbar-${edge} {\n syntax: "<number>";\n inherits: true;\n initial-value: 1;\n}`,
432
+ ),
433
+ `@keyframes gw-scrollbar-edges-y {\n 0% {\n --gw-scrollbar-top: 0;\n }\n\n 1% {\n --gw-scrollbar-top: 1;\n }\n\n 99% {\n --gw-scrollbar-bottom: 1;\n }\n\n 100% {\n --gw-scrollbar-bottom: 0;\n }\n}`,
434
+ `@keyframes gw-scrollbar-edges-x {\n 0% {\n --gw-scrollbar-left: 0;\n }\n\n 1% {\n --gw-scrollbar-left: 1;\n }\n\n 99% {\n --gw-scrollbar-right: 1;\n }\n\n 100% {\n --gw-scrollbar-right: 0;\n }\n}`,
435
+ `:where(:root *) {\n --gw-scrollbar-top: 1;\n --gw-scrollbar-bottom: 1;\n --gw-scrollbar-left: 1;\n --gw-scrollbar-right: 1;\n}`,
436
+ ].join("\n\n");
437
+
364
438
  export const css = (themes: readonly ResolvedTheme[]) =>
365
439
  [
366
440
  `/* ${header} */`,
367
441
  `:root {\n${declarations(foundations)}\n}`,
368
442
  `@media (prefers-reduced-motion: reduce) {\n :root {\n --gw-motion-instant: 1ms;\n --gw-motion-fast: 1ms;\n --gw-motion-normal: 1ms;\n --gw-motion-slow: 1ms;\n }\n}`,
443
+ scrollbarCss(":root, :root *"),
444
+ scrollbarEdgesCss,
369
445
  preUpgradeCss,
370
446
  ...themes.map(themeCss),
371
447
  ].join("\n\n") + "\n";