@weft-js/scroll 0.0.0-stage → 0.1.4

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.
@@ -0,0 +1,199 @@
1
+ /* @weft-js/scroll: the root, viewport and bars. Every look is a custom property, so a theme or the `bar` options
2
+ restyle DOM bars and canvas bars alike. Nothing here declares them, so any layer or theme may: the defaults are the
3
+ fallbacks. Before the script runs the viewport scrolls natively, with its own bars; in native mode it keeps
4
+ scrolling natively after, with those bars hidden. */
5
+ :where([data-scroll]) {
6
+ position: relative;
7
+ overflow: hidden;
8
+ box-sizing: border-box;
9
+ }
10
+ :where([data-scroll] > [data-part='viewport']) {
11
+ block-size: 100%;
12
+ inline-size: 100%;
13
+ overflow: auto;
14
+ box-sizing: border-box;
15
+ outline-offset: -2px;
16
+ scroll-behavior: auto;
17
+ }
18
+ :where([data-scroll][data-axes='y'] > [data-part='viewport']) {
19
+ overflow-x: hidden;
20
+ }
21
+ :where([data-scroll][data-axes='x'] > [data-part='viewport']) {
22
+ overflow-y: hidden;
23
+ }
24
+ :where([data-scroll][data-ready][data-mode='engine'] > [data-part='viewport']) {
25
+ overflow: hidden;
26
+ overscroll-behavior: contain;
27
+ }
28
+ :where([data-scroll][data-ready][data-mode='engine'] > [data-part='viewport'][data-touch='js']) {
29
+ touch-action: pinch-zoom;
30
+ }
31
+ :where([data-scroll][data-ready][data-mode='native'] > [data-part='viewport']) {
32
+ scrollbar-width: none;
33
+ }
34
+ :where([data-scroll][data-ready][data-mode='native'] > [data-part='viewport'])::-webkit-scrollbar {
35
+ display: none;
36
+ }
37
+ :where([data-scroll][data-ready][data-mode='native'][data-chain='contain'] > [data-part='viewport']) {
38
+ overscroll-behavior: contain;
39
+ }
40
+ :where([data-scroll] [data-part='viewport']:focus:not(:focus-visible)) {
41
+ outline: none;
42
+ }
43
+
44
+ /* gutter: room is kept beside the content for each axis that scrolls, as `scrollbar-gutter: stable` does. */
45
+ :where([data-scroll][data-layout='gutter']:not([data-axes='x'])) {
46
+ padding-inline-end: calc(
47
+ max(var(--scroll-width, 6px), var(--scroll-hover-width, 10px)) + 2 * var(--scroll-inset, 2px)
48
+ );
49
+ }
50
+ :where([data-scroll][data-layout='gutter']:not([data-axes='y'])) {
51
+ padding-block-end: calc(
52
+ max(var(--scroll-width, 6px), var(--scroll-hover-width, 10px)) + 2 * var(--scroll-inset, 2px)
53
+ );
54
+ }
55
+
56
+ :where([data-scroll] > [data-part='scrollbar']) {
57
+ position: absolute;
58
+ z-index: 1;
59
+ opacity: 0;
60
+ transition:
61
+ opacity var(--scroll-fade, 200ms) ease-out,
62
+ background-color var(--scroll-fade, 200ms);
63
+ background: var(--scroll-track, transparent);
64
+ touch-action: none;
65
+ user-select: none;
66
+ -webkit-user-select: none;
67
+ }
68
+ :where([data-scroll] > [data-part='scrollbar'][data-orientation='vertical']) {
69
+ inset-block: 0;
70
+ inset-inline-end: 0;
71
+ inline-size: calc(
72
+ max(var(--scroll-width, 6px), var(--scroll-hover-width, 10px)) + 2 * var(--scroll-inset, 2px)
73
+ );
74
+ }
75
+ :where([data-scroll] > [data-part='scrollbar'][data-orientation='horizontal']) {
76
+ inset-inline: 0;
77
+ inset-block-end: 0;
78
+ block-size: calc(
79
+ max(var(--scroll-width, 6px), var(--scroll-hover-width, 10px)) + 2 * var(--scroll-inset, 2px)
80
+ );
81
+ }
82
+ :where(
83
+ [data-scroll][data-overflow-x][data-overflow-y]
84
+ > [data-part='scrollbar'][data-orientation='vertical']
85
+ ) {
86
+ inset-block-end: calc(
87
+ max(var(--scroll-width, 6px), var(--scroll-hover-width, 10px)) + 2 * var(--scroll-inset, 2px)
88
+ );
89
+ }
90
+ :where(
91
+ [data-scroll][data-overflow-x][data-overflow-y]
92
+ > [data-part='scrollbar'][data-orientation='horizontal']
93
+ ) {
94
+ inset-inline-end: calc(
95
+ max(var(--scroll-width, 6px), var(--scroll-hover-width, 10px)) + 2 * var(--scroll-inset, 2px)
96
+ );
97
+ }
98
+ :where([data-scroll] > [data-part='scrollbar'][data-visible]) {
99
+ opacity: 1;
100
+ transition-duration: calc(var(--scroll-fade, 200ms) / 2);
101
+ }
102
+ :where([data-scroll] > [data-part='scrollbar'][data-none]),
103
+ :where([data-scroll][data-show='never'] > [data-part='scrollbar']) {
104
+ visibility: hidden;
105
+ pointer-events: none;
106
+ }
107
+ :where([data-scroll]:not([data-ready]) > [data-part='scrollbar']) {
108
+ display: none;
109
+ }
110
+ :where([data-scroll] > [data-part='scrollbar']:is([data-hover], [data-active])) {
111
+ background: var(--scroll-hover-track, color-mix(in srgb, currentColor 8%, transparent));
112
+ }
113
+
114
+ :where([data-scroll] [data-part='scrollbar'] > [data-part='thumb']) {
115
+ position: absolute;
116
+ inset-block-start: 0;
117
+ inset-inline-start: 0;
118
+ border-radius: var(--scroll-radius, 999px);
119
+ background: var(--scroll-color, color-mix(in srgb, currentColor 32%, transparent));
120
+ will-change: transform;
121
+ transition:
122
+ inline-size var(--scroll-fade, 200ms) ease-out,
123
+ block-size var(--scroll-fade, 200ms) ease-out,
124
+ background-color var(--scroll-fade, 200ms);
125
+ }
126
+ :where([data-scroll] [data-part='scrollbar'][data-orientation='vertical'] > [data-part='thumb']) {
127
+ inset-inline-start: auto;
128
+ inset-inline-end: var(--scroll-inset, 2px);
129
+ inline-size: var(--scroll-width, 6px);
130
+ transition-property: inline-size, background-color;
131
+ }
132
+ :where([data-scroll] [data-part='scrollbar'][data-orientation='horizontal'] > [data-part='thumb']) {
133
+ inset-block-start: auto;
134
+ inset-block-end: var(--scroll-inset, 2px);
135
+ left: 0;
136
+ right: auto;
137
+ block-size: var(--scroll-width, 6px);
138
+ transition-property: block-size, background-color;
139
+ }
140
+ :where(
141
+ [data-scroll]
142
+ [data-part='scrollbar']:is([data-hover], [data-active])[data-orientation='vertical']
143
+ > [data-part='thumb']
144
+ ) {
145
+ inline-size: var(--scroll-hover-width, 10px);
146
+ }
147
+ :where(
148
+ [data-scroll]
149
+ [data-part='scrollbar']:is([data-hover], [data-active])[data-orientation='horizontal']
150
+ > [data-part='thumb']
151
+ ) {
152
+ block-size: var(--scroll-hover-width, 10px);
153
+ }
154
+ :where([data-scroll] [data-part='scrollbar'][data-hover] > [data-part='thumb']) {
155
+ background: var(--scroll-hover-color, color-mix(in srgb, currentColor 48%, transparent));
156
+ }
157
+ :where([data-scroll] [data-part='scrollbar'][data-active] > [data-part='thumb']) {
158
+ background: var(--scroll-active-color, color-mix(in srgb, currentColor 60%, transparent));
159
+ }
160
+ /* Native mode with DOM bars: the viewport's scroll position drives each thumb through a scroll timeline, which the
161
+ browser runs on the compositor, so the thumb keeps up while the main thread is busy. The script sets the two ends
162
+ and only sets `data-timeline` where the browser supports it; elsewhere it moves the thumb itself. */
163
+ :where([data-scroll][data-timeline]) {
164
+ timeline-scope: --scroll-timeline-y, --scroll-timeline-x;
165
+ }
166
+ :where([data-scroll][data-timeline] > [data-part='viewport']) {
167
+ scroll-timeline-name: --scroll-timeline-y, --scroll-timeline-x;
168
+ scroll-timeline-axis: y, x;
169
+ }
170
+ :where([data-scroll][data-timeline] > [data-part='scrollbar'][data-orientation='vertical'] > [data-part='thumb']) {
171
+ animation: scroll-thumb-y linear both;
172
+ animation-timeline: --scroll-timeline-y;
173
+ }
174
+ :where([data-scroll][data-timeline] > [data-part='scrollbar'][data-orientation='horizontal'] > [data-part='thumb']) {
175
+ animation: scroll-thumb-x linear both;
176
+ animation-timeline: --scroll-timeline-x;
177
+ }
178
+ @keyframes scroll-thumb-y {
179
+ from {
180
+ transform: translate3d(0, var(--scroll-thumb-start, 0px), 0);
181
+ }
182
+ to {
183
+ transform: translate3d(0, var(--scroll-thumb-end, 0px), 0);
184
+ }
185
+ }
186
+ @keyframes scroll-thumb-x {
187
+ from {
188
+ transform: translate3d(var(--scroll-thumb-start, 0px), 0, 0);
189
+ }
190
+ to {
191
+ transform: translate3d(var(--scroll-thumb-end, 0px), 0, 0);
192
+ }
193
+ }
194
+
195
+ @media (prefers-reduced-motion: reduce) {
196
+ :where([data-scroll]) {
197
+ --scroll-fade: 0ms;
198
+ }
199
+ }