@botiverse/raft-ui 0.59.1 → 0.60.0
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/CHANGELOG.md +47 -0
- package/dist/components/button/button.mjs +1 -1
- package/dist/components/composer/composer-attachment.recipe.mjs +2 -3
- package/dist/components/composer/composer-attachments-scroll-area.d.mts +6 -0
- package/dist/components/composer/composer-attachments-scroll-area.mjs +20 -31
- package/dist/components/composer/composer.d.mts +8 -2
- package/dist/components/composer/composer.mjs +7 -9
- package/dist/components/composer/composer.recipe.mjs +1 -0
- package/dist/components/context-menu/context-menu.d.mts +1 -1
- package/dist/components/dropdown-menu/dropdown-menu.d.mts +1 -1
- package/dist/components/dropdown-menu/dropdown-menu.mjs +1 -1
- package/dist/components/kbd/index.d.mts +5 -2
- package/dist/components/kbd/kbd-keys.d.mts +12 -0
- package/dist/components/kbd/kbd-keys.mjs +297 -0
- package/dist/components/kbd/kbd-shortcut.d.mts +34 -0
- package/dist/components/kbd/kbd-shortcut.mjs +79 -0
- package/dist/components/kbd/kbd.d.mts +55 -2
- package/dist/components/kbd/kbd.mjs +39 -15
- package/dist/components/markdown/markdown-parts.d.mts +7 -2
- package/dist/components/markdown/markdown-parts.mjs +8 -3
- package/dist/components/markdown/markdown.recipe.mjs +1 -5
- package/dist/components/message-list/message-list.mjs +9 -15
- package/dist/components/message-list/message-list.recipe.mjs +1 -1
- package/dist/components/scroll-area/class-names.mjs +19 -0
- package/dist/components/scroll-area/gutters-binding.mjs +4 -0
- package/dist/components/scroll-area/index.d.mts +6 -2
- package/dist/components/scroll-area/scroll-area-gutters.d.mts +15 -0
- package/dist/components/scroll-area/scroll-area-gutters.mjs +60 -0
- package/dist/components/scroll-area/scroll-area-textarea.d.mts +14 -0
- package/dist/components/scroll-area/scroll-area-textarea.mjs +50 -0
- package/dist/components/scroll-area/scroll-area.css +720 -0
- package/dist/components/scroll-area/scroll-area.d.mts +24 -15
- package/dist/components/scroll-area/scroll-area.mjs +67 -45
- package/dist/components/scroll-area/scroll-geometry.mjs +58 -0
- package/dist/components/scroll-area/scroll-to-element.mjs +67 -0
- package/dist/components/scroll-area/types.d.mts +224 -0
- package/dist/components/scroll-area/use-rail-pointer.mjs +93 -0
- package/dist/components/scroll-area/use-scroll-area-container.d.mts +26 -0
- package/dist/components/scroll-area/use-scroll-area-container.mjs +150 -0
- package/dist/components/scroll-area/use-scrollbars.mjs +480 -0
- package/dist/components/search/search-trigger.d.mts +1 -1
- package/dist/components/sidebar/sidebar.d.mts +1 -1
- package/dist/components/sidebar/sidebar.mjs +24 -20
- package/dist/components/sidebar/sidebar.recipe.mjs +1 -6
- package/dist/components/tooltip/tooltip.mjs +8 -5
- package/dist/components/virtual-list/VirtualList.mjs +1 -1
- package/dist/index.d.mts +7 -3
- package/dist/index.mjs +5 -2
- package/dist/lib/inline-part.mjs +13 -0
- package/dist/lib/use-merged-ref.mjs +73 -47
- package/dist/lib/use-platform.d.mts +13 -0
- package/dist/lib/use-platform.mjs +29 -0
- package/dist/styles.css +1 -0
- package/dist/wip.d.mts +5 -1
- package/dist/wip.mjs +3 -1
- package/package.json +1 -1
- package/dist/components/scroll-area/scroll-area.recipe.mjs +0 -23
|
@@ -0,0 +1,720 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ScrollArea, modelled on 07akioni/react-scroll-area-demo. The container is
|
|
3
|
+
* the element that scrolls (native scrolling, its native scrollbars hidden);
|
|
4
|
+
* the gutters are a layer that draws thin overlay scrollbars over it. Where
|
|
5
|
+
* the gutters go (`<ScrollArea>` is always sticky; `useScrollAreaContainer`
|
|
6
|
+
* takes either):
|
|
7
|
+
*
|
|
8
|
+
* sticky the root is the container; the gutters are its first child, a
|
|
9
|
+
* zero-height layer stuck to the top of the viewport and sized
|
|
10
|
+
* by --r-scroll-area-viewport-{height,width}.
|
|
11
|
+
* absolute the root is a positioned frame holding the container and,
|
|
12
|
+
* after it, the gutters, laid over the frame (`inset: 0`). For a
|
|
13
|
+
* container that can't hold children: a textarea.
|
|
14
|
+
*
|
|
15
|
+
* Plain CSS: every selector is written out, and every rule that reaches
|
|
16
|
+
* past the root names the position (`--sticky-gutters`,
|
|
17
|
+
* `--absolute-gutters`), so an area nested in another's container never
|
|
18
|
+
* matches the outer one's rules.
|
|
19
|
+
*
|
|
20
|
+
* Classes: `.r-scroll-area` (the root) with the modifiers
|
|
21
|
+
* `--small` / `--medium`, `--{hover,scroll,none}-trigger`,
|
|
22
|
+
* `--{vertical,horizontal,both}-orientation`, `--{sticky,absolute}-gutters`,
|
|
23
|
+
* `--{none,contain}-overscroll-{y,x}`, `--fade`, `--rtl`,
|
|
24
|
+
* `--overflow-{y,x}-{start,end}` (more content past that edge; `x` is
|
|
25
|
+
* inline; these and `--rtl` are set by the script with `classList`, never
|
|
26
|
+
* rendered) and `--textarea`; `__container` (with absolute gutters, the
|
|
27
|
+
* container), `__viewport` (ScrollArea's own `<div>` container: its
|
|
28
|
+
* overflow), `__content`, `__textarea`, `__gutters` (with `--scrolling`,
|
|
29
|
+
* from the first scroll until `hideDelay` after the last, and `--dragging`,
|
|
30
|
+
* both set by the script: on the layer, so toggling them restyles only the
|
|
31
|
+
* gutters, not the content under the root), `__gutter` (`--vertical`,
|
|
32
|
+
* `--horizontal`, `--shortened`, `--dragging`) and `__thumb`.
|
|
33
|
+
*
|
|
34
|
+
* In the `components` layer, so a utility in the caller's `className`
|
|
35
|
+
* (`h-*`, `max-h-*`, `absolute`) overrides these rules.
|
|
36
|
+
*
|
|
37
|
+
* Knobs, set on the root (or by a utility on it):
|
|
38
|
+
* --r-scroll-area-thumb-size-{small,medium} thumb thickness at rest
|
|
39
|
+
* --r-scroll-area-thumb-size-hover-{small,medium} while pointed at or dragged
|
|
40
|
+
* --r-scroll-area-thumb-min-length
|
|
41
|
+
* --r-scroll-area-thumb-color / -color-hover
|
|
42
|
+
* --r-scroll-area-rail-gap thumb to the root's edge
|
|
43
|
+
* --r-scroll-area-rail-inset-{top,bottom,left,right} room kept clear at the
|
|
44
|
+
* ends (`railInset`); they
|
|
45
|
+
* don't inherit
|
|
46
|
+
* --r-scroll-area-fade-size how far `fade` fades
|
|
47
|
+
*
|
|
48
|
+
* Written by React on the root:
|
|
49
|
+
* --r-scroll-area-timeline-{y,x} the names of the container's scroll
|
|
50
|
+
* timelines, unique to the ScrollArea
|
|
51
|
+
* What the script writes as inline styles (React never renders them):
|
|
52
|
+
* --r-scroll-area-viewport-{height,width} on the root: the container's
|
|
53
|
+
* client size (layout path only)
|
|
54
|
+
* --r-scroll-area-padding-{top,left,right} on a sticky root: its padding,
|
|
55
|
+
* which the gutters layer
|
|
56
|
+
* reaches over (layout path only)
|
|
57
|
+
* --r-scroll-area-thumb-length on each thumb: its length, px
|
|
58
|
+
* --r-scroll-area-thumb-travel on each thumb, with scroll-driven
|
|
59
|
+
* animations: gutter minus length
|
|
60
|
+
* (negative inline in RTL)
|
|
61
|
+
* transform on each thumb, without them:
|
|
62
|
+
* where it is along its gutter
|
|
63
|
+
* --r-scroll-area-overflow-{y,x}-{start,end} with `fade` only, where the
|
|
64
|
+
* mask is: px left past each edge
|
|
65
|
+
* Where scroll-driven animations work, the thumb is moved by one, on the
|
|
66
|
+
* container's named scroll timeline: the gutters are inside the container
|
|
67
|
+
* (sticky) and see it, or the root hoists it (`timeline-scope`, absolute).
|
|
68
|
+
* The script then writes only when a size changes. Elsewhere a scrolled
|
|
69
|
+
* frame changes the thumbs' transforms, and the length with them when the
|
|
70
|
+
* content's size changed. Never the root while scrolling, whose variables
|
|
71
|
+
* everything inside would inherit.
|
|
72
|
+
*
|
|
73
|
+
* The thumb is the label colour (`foreground`) made translucent, dark on
|
|
74
|
+
* light pages and light on dark ones, so it sits on any content; there is no
|
|
75
|
+
* visible track: pointing at the scrollbar only thickens the thumb. One look
|
|
76
|
+
* in every theme.
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
/*
|
|
80
|
+
* The px left past each edge change on every scrolled frame. Only `fade`
|
|
81
|
+
* reads them, on the element its mask is on (the content, or the container
|
|
82
|
+
* with absolute gutters), and they don't inherit: a change restyles that
|
|
83
|
+
* element, not everything inside it.
|
|
84
|
+
*/
|
|
85
|
+
@property --r-scroll-area-overflow-y-start {
|
|
86
|
+
syntax: "<length>";
|
|
87
|
+
inherits: false;
|
|
88
|
+
initial-value: 0px;
|
|
89
|
+
}
|
|
90
|
+
@property --r-scroll-area-overflow-y-end {
|
|
91
|
+
syntax: "<length>";
|
|
92
|
+
inherits: false;
|
|
93
|
+
initial-value: 0px;
|
|
94
|
+
}
|
|
95
|
+
@property --r-scroll-area-overflow-x-start {
|
|
96
|
+
syntax: "<length>";
|
|
97
|
+
inherits: false;
|
|
98
|
+
initial-value: 0px;
|
|
99
|
+
}
|
|
100
|
+
@property --r-scroll-area-overflow-x-end {
|
|
101
|
+
syntax: "<length>";
|
|
102
|
+
inherits: false;
|
|
103
|
+
initial-value: 0px;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/*
|
|
107
|
+
* Room kept clear at each end of the scrollbars, such as for a sticky header
|
|
108
|
+
* or footer inside the area (`railInset`). Set on the root itself; they don't
|
|
109
|
+
* inherit, so a scroll area nested inside doesn't take them.
|
|
110
|
+
*/
|
|
111
|
+
@property --r-scroll-area-rail-inset-top {
|
|
112
|
+
syntax: "<length>";
|
|
113
|
+
inherits: false;
|
|
114
|
+
initial-value: 0px;
|
|
115
|
+
}
|
|
116
|
+
@property --r-scroll-area-rail-inset-bottom {
|
|
117
|
+
syntax: "<length>";
|
|
118
|
+
inherits: false;
|
|
119
|
+
initial-value: 0px;
|
|
120
|
+
}
|
|
121
|
+
@property --r-scroll-area-rail-inset-left {
|
|
122
|
+
syntax: "<length>";
|
|
123
|
+
inherits: false;
|
|
124
|
+
initial-value: 0px;
|
|
125
|
+
}
|
|
126
|
+
@property --r-scroll-area-rail-inset-right {
|
|
127
|
+
syntax: "<length>";
|
|
128
|
+
inherits: false;
|
|
129
|
+
initial-value: 0px;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Along the gutter: from its start to `travel` px down (or along) it, driven by the scroll. */
|
|
133
|
+
@keyframes r-scroll-area-thumb-y {
|
|
134
|
+
from {
|
|
135
|
+
transform: translate3d(0, 0, 0);
|
|
136
|
+
}
|
|
137
|
+
to {
|
|
138
|
+
transform: translate3d(0, var(--r-scroll-area-thumb-travel), 0);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
@keyframes r-scroll-area-thumb-x {
|
|
142
|
+
from {
|
|
143
|
+
transform: translate3d(0, 0, 0);
|
|
144
|
+
}
|
|
145
|
+
to {
|
|
146
|
+
transform: translate3d(var(--r-scroll-area-thumb-travel), 0, 0);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@layer components {
|
|
151
|
+
.r-scroll-area {
|
|
152
|
+
--r-scroll-area-thumb-size-small: 5px;
|
|
153
|
+
--r-scroll-area-thumb-size-hover-small: 8px;
|
|
154
|
+
--r-scroll-area-thumb-size-medium: 7px;
|
|
155
|
+
--r-scroll-area-thumb-size-hover-medium: 10px;
|
|
156
|
+
--r-scroll-area-thumb-min-length: 24px;
|
|
157
|
+
--r-scroll-area-thumb-color: color-mix(in oklab, var(--foreground) 42%, transparent);
|
|
158
|
+
--r-scroll-area-thumb-color-hover: color-mix(in oklab, var(--foreground) 58%, transparent);
|
|
159
|
+
--r-scroll-area-rail-gap: 3px;
|
|
160
|
+
/* Room left for a textarea's resize grip in the bottom corner. */
|
|
161
|
+
--r-scroll-area-resize-grip-size: 16px;
|
|
162
|
+
--r-scroll-area-fade-size: 24px;
|
|
163
|
+
--r-scroll-area-duration-fade-in: 120ms;
|
|
164
|
+
--r-scroll-area-duration-fade-out: 400ms;
|
|
165
|
+
--r-scroll-area-duration: 150ms;
|
|
166
|
+
--r-scroll-area-easing: ease-out;
|
|
167
|
+
/* Unique per ScrollArea from its inline style; these only stand in for a root rendered without it. */
|
|
168
|
+
--r-scroll-area-timeline-y: --r-scroll-area-y;
|
|
169
|
+
--r-scroll-area-timeline-x: --r-scroll-area-x;
|
|
170
|
+
|
|
171
|
+
--r-scroll-area-thumb-size: var(--r-scroll-area-thumb-size-medium);
|
|
172
|
+
--r-scroll-area-thumb-size-hover: var(--r-scroll-area-thumb-size-hover-medium);
|
|
173
|
+
/*
|
|
174
|
+
* Until the first measurement, and again for a nested scroll area, which
|
|
175
|
+
* would otherwise inherit its parent's.
|
|
176
|
+
*/
|
|
177
|
+
--r-scroll-area-viewport-height: 100%;
|
|
178
|
+
--r-scroll-area-viewport-width: 100%;
|
|
179
|
+
--r-scroll-area-padding-top: 0px;
|
|
180
|
+
--r-scroll-area-padding-left: 0px;
|
|
181
|
+
--r-scroll-area-padding-right: 0px;
|
|
182
|
+
/* The gutter is as thick as the hovered thumb plus the gap on both sides. */
|
|
183
|
+
--r-scroll-area-rail-size: calc(
|
|
184
|
+
var(--r-scroll-area-thumb-size-hover) + 2 * var(--r-scroll-area-rail-gap)
|
|
185
|
+
);
|
|
186
|
+
/*
|
|
187
|
+
* Where each gutter starts and ends: the gap plus the room kept clear at
|
|
188
|
+
* that end. Read on the root, where the room is set (it doesn't inherit).
|
|
189
|
+
*/
|
|
190
|
+
--r-scroll-area-rail-top: calc(
|
|
191
|
+
var(--r-scroll-area-rail-gap) + var(--r-scroll-area-rail-inset-top)
|
|
192
|
+
);
|
|
193
|
+
--r-scroll-area-rail-bottom: calc(
|
|
194
|
+
var(--r-scroll-area-rail-gap) + var(--r-scroll-area-rail-inset-bottom)
|
|
195
|
+
);
|
|
196
|
+
--r-scroll-area-rail-left: calc(
|
|
197
|
+
var(--r-scroll-area-rail-gap) + var(--r-scroll-area-rail-inset-left)
|
|
198
|
+
);
|
|
199
|
+
--r-scroll-area-rail-right: calc(
|
|
200
|
+
var(--r-scroll-area-rail-gap) + var(--r-scroll-area-rail-inset-right)
|
|
201
|
+
);
|
|
202
|
+
/* With both gutters, the end at the corner: the other gutter plus the room kept clear there. */
|
|
203
|
+
--r-scroll-area-rail-bottom-shortened: calc(
|
|
204
|
+
var(--r-scroll-area-rail-size) + var(--r-scroll-area-rail-inset-bottom)
|
|
205
|
+
);
|
|
206
|
+
--r-scroll-area-rail-left-shortened: calc(
|
|
207
|
+
var(--r-scroll-area-rail-size) + var(--r-scroll-area-rail-inset-left)
|
|
208
|
+
);
|
|
209
|
+
--r-scroll-area-rail-right-shortened: calc(
|
|
210
|
+
var(--r-scroll-area-rail-size) + var(--r-scroll-area-rail-inset-right)
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
.r-scroll-area.r-scroll-area--small {
|
|
214
|
+
--r-scroll-area-thumb-size: var(--r-scroll-area-thumb-size-small);
|
|
215
|
+
--r-scroll-area-thumb-size-hover: var(--r-scroll-area-thumb-size-hover-small);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/*
|
|
219
|
+
* The container. Its own overflow, layout and focus are its own (a list,
|
|
220
|
+
* a textarea); the overlay scrollbars replace its native ones. With sticky
|
|
221
|
+
* gutters it is the root.
|
|
222
|
+
*/
|
|
223
|
+
.r-scroll-area.r-scroll-area--sticky-gutters,
|
|
224
|
+
.r-scroll-area.r-scroll-area--absolute-gutters > .r-scroll-area__container {
|
|
225
|
+
scrollbar-width: none;
|
|
226
|
+
}
|
|
227
|
+
.r-scroll-area.r-scroll-area--sticky-gutters::-webkit-scrollbar,
|
|
228
|
+
.r-scroll-area.r-scroll-area--absolute-gutters > .r-scroll-area__container::-webkit-scrollbar {
|
|
229
|
+
display: none;
|
|
230
|
+
}
|
|
231
|
+
/*
|
|
232
|
+
* Absolute gutters: the root is the frame the gutters are positioned in,
|
|
233
|
+
* and a column the container fills, so a height or a `max-height` on the
|
|
234
|
+
* root bounds the container, which then scrolls. The frame is what callers
|
|
235
|
+
* border and size, so its size includes its border whatever the page's
|
|
236
|
+
* preflight says (Tailwind's already does this).
|
|
237
|
+
*/
|
|
238
|
+
.r-scroll-area.r-scroll-area--absolute-gutters {
|
|
239
|
+
box-sizing: border-box;
|
|
240
|
+
display: flex;
|
|
241
|
+
flex-direction: column;
|
|
242
|
+
position: relative;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/* ScrollArea's own `<div>` container (always sticky) scrolls in the orientation. */
|
|
246
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area__viewport {
|
|
247
|
+
overflow: hidden auto;
|
|
248
|
+
position: relative;
|
|
249
|
+
}
|
|
250
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area--horizontal-orientation.r-scroll-area__viewport {
|
|
251
|
+
overflow: auto hidden;
|
|
252
|
+
}
|
|
253
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area--both-orientation.r-scroll-area__viewport {
|
|
254
|
+
overflow: auto;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/*
|
|
258
|
+
* A scroll that reaches the end stops there instead of scrolling the page:
|
|
259
|
+
* `none` also keeps Mac trackpads and iOS from bouncing the area (and its
|
|
260
|
+
* sticky parts) at the edge; `contain` lets them bounce it. Only on the axes
|
|
261
|
+
* that really scroll right now (the script adds each modifier while that
|
|
262
|
+
* axis has a gutter), so a strip that only overflows sideways never holds
|
|
263
|
+
* back the page's vertical scroll. Each sets one axis only and never `auto`,
|
|
264
|
+
* so it doesn't override a caller's own `overscroll-behavior` on the other
|
|
265
|
+
* axis. The modifiers are on the root; the container takes them.
|
|
266
|
+
*/
|
|
267
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area--contain-overscroll-y,
|
|
268
|
+
.r-scroll-area.r-scroll-area--absolute-gutters.r-scroll-area--contain-overscroll-y
|
|
269
|
+
> .r-scroll-area__container {
|
|
270
|
+
overscroll-behavior-y: contain;
|
|
271
|
+
}
|
|
272
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area--contain-overscroll-x,
|
|
273
|
+
.r-scroll-area.r-scroll-area--absolute-gutters.r-scroll-area--contain-overscroll-x
|
|
274
|
+
> .r-scroll-area__container {
|
|
275
|
+
overscroll-behavior-x: contain;
|
|
276
|
+
}
|
|
277
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area--none-overscroll-y,
|
|
278
|
+
.r-scroll-area.r-scroll-area--absolute-gutters.r-scroll-area--none-overscroll-y
|
|
279
|
+
> .r-scroll-area__container {
|
|
280
|
+
overscroll-behavior-y: none;
|
|
281
|
+
}
|
|
282
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area--none-overscroll-x,
|
|
283
|
+
.r-scroll-area.r-scroll-area--absolute-gutters.r-scroll-area--none-overscroll-x
|
|
284
|
+
> .r-scroll-area__container {
|
|
285
|
+
overscroll-behavior-x: none;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/*
|
|
289
|
+
* Keyboard focus only (--focus-ring is empty after a click or a tap,
|
|
290
|
+
* styles.css), on ScrollArea's own container. A frame with absolute
|
|
291
|
+
* gutters is the caller's, and so is its focus ring (`has-focus-visible:`).
|
|
292
|
+
*/
|
|
293
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area__viewport:focus-visible {
|
|
294
|
+
box-shadow: var(--focus-ring);
|
|
295
|
+
outline: none;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/* Wide content widens the content box instead of wrapping to it. */
|
|
299
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area--horizontal-orientation
|
|
300
|
+
> .r-scroll-area__content,
|
|
301
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area--both-orientation
|
|
302
|
+
> .r-scroll-area__content,
|
|
303
|
+
.r-scroll-area.r-scroll-area--absolute-gutters.r-scroll-area--horizontal-orientation
|
|
304
|
+
> .r-scroll-area__container
|
|
305
|
+
> .r-scroll-area__content,
|
|
306
|
+
.r-scroll-area.r-scroll-area--absolute-gutters.r-scroll-area--both-orientation
|
|
307
|
+
> .r-scroll-area__container
|
|
308
|
+
> .r-scroll-area__content {
|
|
309
|
+
inline-size: fit-content;
|
|
310
|
+
min-inline-size: 100%;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/*
|
|
314
|
+
* `fade`: the content fades out toward each edge with more past it, over
|
|
315
|
+
* the px left (at most --r-scroll-area-fade-size), so it fades in as it
|
|
316
|
+
* leaves an edge. A mask reads only alpha: `black` is opaque here, not a
|
|
317
|
+
* colour. The gutters never fade:
|
|
318
|
+
* sticky the mask is on the content, not the container that holds the
|
|
319
|
+
* gutters. The content scrolls, so the mask is one viewport
|
|
320
|
+
* large and moved to where the viewport is.
|
|
321
|
+
* absolute the mask is on the container, which doesn't move it when it
|
|
322
|
+
* scrolls; the gutters are its siblings.
|
|
323
|
+
*
|
|
324
|
+
* The mask repaints on every scrolled frame, so `fade` is meant for short
|
|
325
|
+
* areas, not long lists.
|
|
326
|
+
*/
|
|
327
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--sticky-gutters > .r-scroll-area__content,
|
|
328
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--absolute-gutters > .r-scroll-area__container {
|
|
329
|
+
--r-scroll-area-overflow-left: var(--r-scroll-area-overflow-x-start);
|
|
330
|
+
--r-scroll-area-overflow-right: var(--r-scroll-area-overflow-x-end);
|
|
331
|
+
--r-scroll-area-fade-top: min(
|
|
332
|
+
var(--r-scroll-area-overflow-y-start),
|
|
333
|
+
var(--r-scroll-area-fade-size)
|
|
334
|
+
);
|
|
335
|
+
--r-scroll-area-fade-bottom: min(
|
|
336
|
+
var(--r-scroll-area-overflow-y-end),
|
|
337
|
+
var(--r-scroll-area-fade-size)
|
|
338
|
+
);
|
|
339
|
+
--r-scroll-area-fade-left: min(
|
|
340
|
+
var(--r-scroll-area-overflow-left),
|
|
341
|
+
var(--r-scroll-area-fade-size)
|
|
342
|
+
);
|
|
343
|
+
--r-scroll-area-fade-right: min(
|
|
344
|
+
var(--r-scroll-area-overflow-right),
|
|
345
|
+
var(--r-scroll-area-fade-size)
|
|
346
|
+
);
|
|
347
|
+
--r-scroll-area-fade-y: linear-gradient(
|
|
348
|
+
to bottom,
|
|
349
|
+
transparent,
|
|
350
|
+
black var(--r-scroll-area-fade-top),
|
|
351
|
+
black calc(100% - var(--r-scroll-area-fade-bottom)),
|
|
352
|
+
transparent
|
|
353
|
+
);
|
|
354
|
+
--r-scroll-area-fade-x: linear-gradient(
|
|
355
|
+
to right,
|
|
356
|
+
transparent,
|
|
357
|
+
black var(--r-scroll-area-fade-left),
|
|
358
|
+
black calc(100% - var(--r-scroll-area-fade-right)),
|
|
359
|
+
transparent
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--sticky-gutters > .r-scroll-area__content {
|
|
363
|
+
mask-position: var(--r-scroll-area-overflow-left) var(--r-scroll-area-overflow-y-start);
|
|
364
|
+
mask-repeat: no-repeat;
|
|
365
|
+
mask-size: var(--r-scroll-area-viewport-width) var(--r-scroll-area-viewport-height);
|
|
366
|
+
}
|
|
367
|
+
/* In right-to-left layouts the inline start is the right edge. */
|
|
368
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--rtl.r-scroll-area--sticky-gutters
|
|
369
|
+
> .r-scroll-area__content,
|
|
370
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--rtl.r-scroll-area--absolute-gutters
|
|
371
|
+
> .r-scroll-area__container {
|
|
372
|
+
--r-scroll-area-overflow-left: var(--r-scroll-area-overflow-x-end);
|
|
373
|
+
--r-scroll-area-overflow-right: var(--r-scroll-area-overflow-x-start);
|
|
374
|
+
}
|
|
375
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--vertical-orientation.r-scroll-area--sticky-gutters
|
|
376
|
+
> .r-scroll-area__content,
|
|
377
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--vertical-orientation.r-scroll-area--absolute-gutters
|
|
378
|
+
> .r-scroll-area__container {
|
|
379
|
+
mask-image: var(--r-scroll-area-fade-y);
|
|
380
|
+
}
|
|
381
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--horizontal-orientation.r-scroll-area--sticky-gutters
|
|
382
|
+
> .r-scroll-area__content,
|
|
383
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--horizontal-orientation.r-scroll-area--absolute-gutters
|
|
384
|
+
> .r-scroll-area__container {
|
|
385
|
+
mask-image: var(--r-scroll-area-fade-x);
|
|
386
|
+
}
|
|
387
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--both-orientation.r-scroll-area--sticky-gutters
|
|
388
|
+
> .r-scroll-area__content,
|
|
389
|
+
.r-scroll-area.r-scroll-area--fade.r-scroll-area--both-orientation.r-scroll-area--absolute-gutters
|
|
390
|
+
> .r-scroll-area__container {
|
|
391
|
+
mask-composite: intersect;
|
|
392
|
+
mask-image: var(--r-scroll-area-fade-y), var(--r-scroll-area-fade-x);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/* ScrollAreaTextarea: absolute gutters, the textarea is the container and fills the frame. */
|
|
396
|
+
.r-scroll-area.r-scroll-area--textarea {
|
|
397
|
+
display: grid;
|
|
398
|
+
}
|
|
399
|
+
.r-scroll-area.r-scroll-area--textarea > .r-scroll-area__textarea {
|
|
400
|
+
box-sizing: border-box;
|
|
401
|
+
min-block-size: 0;
|
|
402
|
+
/* Drag the corner to make it taller; widening would outgrow the frame. */
|
|
403
|
+
resize: vertical;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/* The gutters layer: out of the way of the content, but for each gutter itself. */
|
|
407
|
+
.r-scroll-area > .r-scroll-area__gutters {
|
|
408
|
+
pointer-events: none;
|
|
409
|
+
user-select: none;
|
|
410
|
+
z-index: 1;
|
|
411
|
+
}
|
|
412
|
+
/*
|
|
413
|
+
* Sticky: a zero-height layer at the top of the viewport, the container's
|
|
414
|
+
* first child. In a container that lays its children out as a block or a
|
|
415
|
+
* flex column it stays a zero-height row of the full width, and nothing
|
|
416
|
+
* after it moves. It is in flow (a sticky box always is), so a grid, a flex
|
|
417
|
+
* row, `gap` and sibling selectors (`stack-y-*`, `rule-y`, `first:`) count
|
|
418
|
+
* it: lay the content out in a wrapper inside the container instead.
|
|
419
|
+
*
|
|
420
|
+
* It reaches over the container's padding, so the gutters are at the
|
|
421
|
+
* padding box's edges, not the content's: the negative inline margins
|
|
422
|
+
* widen it to the padding box. A sticky box sticks inside the scrollport
|
|
423
|
+
* less its padding, so `top: 0` holds it `padding-top` below the top of the
|
|
424
|
+
* viewport, where a translate lifts it back to the top. The translate moves
|
|
425
|
+
* nothing in flow, so the content stays where its padding puts it.
|
|
426
|
+
*/
|
|
427
|
+
.r-scroll-area.r-scroll-area--sticky-gutters > .r-scroll-area__gutters {
|
|
428
|
+
align-self: stretch;
|
|
429
|
+
block-size: 0;
|
|
430
|
+
flex-shrink: 0;
|
|
431
|
+
inset-block-start: 0;
|
|
432
|
+
inset-inline-start: 0;
|
|
433
|
+
margin-left: calc(-1 * var(--r-scroll-area-padding-left));
|
|
434
|
+
margin-right: calc(-1 * var(--r-scroll-area-padding-right));
|
|
435
|
+
position: sticky;
|
|
436
|
+
translate: 0 calc(-1 * var(--r-scroll-area-padding-top));
|
|
437
|
+
}
|
|
438
|
+
/*
|
|
439
|
+
* Scrolling sideways, it also sticks the inline-start padding in from that
|
|
440
|
+
* edge, and the translate lifts it back across (the other way right to left).
|
|
441
|
+
*/
|
|
442
|
+
.r-scroll-area.r-scroll-area--sticky-gutters:is(
|
|
443
|
+
.r-scroll-area--horizontal-orientation,
|
|
444
|
+
.r-scroll-area--both-orientation
|
|
445
|
+
)
|
|
446
|
+
> .r-scroll-area__gutters {
|
|
447
|
+
translate: calc(-1 * var(--r-scroll-area-padding-left))
|
|
448
|
+
calc(-1 * var(--r-scroll-area-padding-top));
|
|
449
|
+
}
|
|
450
|
+
.r-scroll-area.r-scroll-area--sticky-gutters.r-scroll-area--rtl:is(
|
|
451
|
+
.r-scroll-area--horizontal-orientation,
|
|
452
|
+
.r-scroll-area--both-orientation
|
|
453
|
+
)
|
|
454
|
+
> .r-scroll-area__gutters {
|
|
455
|
+
translate: var(--r-scroll-area-padding-right) calc(-1 * var(--r-scroll-area-padding-top));
|
|
456
|
+
}
|
|
457
|
+
/* Absolute: a layer over the frame's padding box, after the container. */
|
|
458
|
+
.r-scroll-area.r-scroll-area--absolute-gutters > .r-scroll-area__gutters {
|
|
459
|
+
border-radius: inherit;
|
|
460
|
+
inset: 0;
|
|
461
|
+
position: absolute;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/*
|
|
465
|
+
* A gutter is the thumb's travel, and the invisible target for hover and
|
|
466
|
+
* paging: it stops the gap short of both ends, plus any room kept clear
|
|
467
|
+
* there. Top and bottom room shortens the vertical gutter, left and right
|
|
468
|
+
* the horizontal one. Sticky gutters hang from the zero-height layer, so
|
|
469
|
+
* their length comes from the viewport's size; absolute ones from the
|
|
470
|
+
* frame's.
|
|
471
|
+
*/
|
|
472
|
+
.r-scroll-area > .r-scroll-area__gutters > .r-scroll-area__gutter {
|
|
473
|
+
opacity: 0;
|
|
474
|
+
pointer-events: auto;
|
|
475
|
+
position: absolute;
|
|
476
|
+
transition: opacity var(--r-scroll-area-duration-fade-out) var(--r-scroll-area-easing);
|
|
477
|
+
}
|
|
478
|
+
.r-scroll-area > .r-scroll-area__gutters > .r-scroll-area__gutter--vertical {
|
|
479
|
+
inline-size: var(--r-scroll-area-rail-size);
|
|
480
|
+
inset-block-start: var(--r-scroll-area-rail-top);
|
|
481
|
+
inset-inline-end: 0;
|
|
482
|
+
}
|
|
483
|
+
.r-scroll-area.r-scroll-area--sticky-gutters
|
|
484
|
+
> .r-scroll-area__gutters
|
|
485
|
+
> .r-scroll-area__gutter--vertical {
|
|
486
|
+
block-size: calc(
|
|
487
|
+
var(--r-scroll-area-viewport-height) - var(--r-scroll-area-rail-top) -
|
|
488
|
+
var(--r-scroll-area-rail-bottom)
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
.r-scroll-area.r-scroll-area--absolute-gutters
|
|
492
|
+
> .r-scroll-area__gutters
|
|
493
|
+
> .r-scroll-area__gutter--vertical {
|
|
494
|
+
inset-block-end: var(--r-scroll-area-rail-bottom);
|
|
495
|
+
}
|
|
496
|
+
.r-scroll-area > .r-scroll-area__gutters > .r-scroll-area__gutter--horizontal {
|
|
497
|
+
block-size: var(--r-scroll-area-rail-size);
|
|
498
|
+
left: var(--r-scroll-area-rail-left);
|
|
499
|
+
right: var(--r-scroll-area-rail-right);
|
|
500
|
+
}
|
|
501
|
+
.r-scroll-area.r-scroll-area--sticky-gutters
|
|
502
|
+
> .r-scroll-area__gutters
|
|
503
|
+
> .r-scroll-area__gutter--horizontal {
|
|
504
|
+
inset-block-start: calc(var(--r-scroll-area-viewport-height) - var(--r-scroll-area-rail-size));
|
|
505
|
+
}
|
|
506
|
+
.r-scroll-area.r-scroll-area--absolute-gutters
|
|
507
|
+
> .r-scroll-area__gutters
|
|
508
|
+
> .r-scroll-area__gutter--horizontal {
|
|
509
|
+
inset-block-end: 0;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/*
|
|
513
|
+
* With both gutters, each stops short of the other, like native scrollbars;
|
|
514
|
+
* room kept clear past the corner adds to it. The corner is at the inline
|
|
515
|
+
* end: the right, or the left in right-to-left layouts.
|
|
516
|
+
*/
|
|
517
|
+
.r-scroll-area.r-scroll-area--sticky-gutters
|
|
518
|
+
> .r-scroll-area__gutters
|
|
519
|
+
> .r-scroll-area__gutter--vertical.r-scroll-area__gutter--shortened {
|
|
520
|
+
block-size: calc(
|
|
521
|
+
var(--r-scroll-area-viewport-height) - var(--r-scroll-area-rail-top) -
|
|
522
|
+
var(--r-scroll-area-rail-bottom-shortened)
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
.r-scroll-area.r-scroll-area--absolute-gutters
|
|
526
|
+
> .r-scroll-area__gutters
|
|
527
|
+
> .r-scroll-area__gutter--vertical.r-scroll-area__gutter--shortened {
|
|
528
|
+
inset-block-end: var(--r-scroll-area-rail-bottom-shortened);
|
|
529
|
+
}
|
|
530
|
+
.r-scroll-area
|
|
531
|
+
> .r-scroll-area__gutters
|
|
532
|
+
> .r-scroll-area__gutter--horizontal.r-scroll-area__gutter--shortened {
|
|
533
|
+
right: var(--r-scroll-area-rail-right-shortened);
|
|
534
|
+
}
|
|
535
|
+
.r-scroll-area.r-scroll-area--rtl
|
|
536
|
+
> .r-scroll-area__gutters
|
|
537
|
+
> .r-scroll-area__gutter--horizontal.r-scroll-area__gutter--shortened {
|
|
538
|
+
left: var(--r-scroll-area-rail-left-shortened);
|
|
539
|
+
right: var(--r-scroll-area-rail-right);
|
|
540
|
+
}
|
|
541
|
+
/* The vertical gutter stops above the textarea's resize grip so the grip can be dragged. */
|
|
542
|
+
.r-scroll-area.r-scroll-area--absolute-gutters.r-scroll-area--textarea
|
|
543
|
+
> .r-scroll-area__gutters
|
|
544
|
+
> .r-scroll-area__gutter--vertical {
|
|
545
|
+
inset-block-end: var(--r-scroll-area-resize-grip-size);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/*
|
|
549
|
+
* The thumb sits at the start of its gutter and is moved along it by a
|
|
550
|
+
* transform (`translate3d`, its own compositor layer), so a scrolled frame
|
|
551
|
+
* moves it without a layout: a scroll-driven animation where the browser
|
|
552
|
+
* has them (below), the script's transform elsewhere. Its length, in px, is
|
|
553
|
+
* written by the script (at least --r-scroll-area-thumb-min-length). Only
|
|
554
|
+
* the thickness and the colour transition, on hover; the length and the
|
|
555
|
+
* place never do, so like a native scrollbar it always shows the current
|
|
556
|
+
* size.
|
|
557
|
+
*/
|
|
558
|
+
.r-scroll-area > .r-scroll-area__gutters > .r-scroll-area__gutter > .r-scroll-area__thumb {
|
|
559
|
+
background: var(--r-scroll-area-thumb-color);
|
|
560
|
+
border-radius: calc(var(--r-scroll-area-thumb-size-hover) / 2);
|
|
561
|
+
position: absolute;
|
|
562
|
+
touch-action: none;
|
|
563
|
+
will-change: transform;
|
|
564
|
+
}
|
|
565
|
+
.r-scroll-area
|
|
566
|
+
> .r-scroll-area__gutters
|
|
567
|
+
> .r-scroll-area__gutter--vertical
|
|
568
|
+
> .r-scroll-area__thumb {
|
|
569
|
+
block-size: var(--r-scroll-area-thumb-length, 0px);
|
|
570
|
+
inline-size: var(--r-scroll-area-thumb-size);
|
|
571
|
+
inset-block-start: 0;
|
|
572
|
+
inset-inline-end: var(--r-scroll-area-rail-gap);
|
|
573
|
+
transition:
|
|
574
|
+
background-color var(--r-scroll-area-duration) var(--r-scroll-area-easing),
|
|
575
|
+
inline-size var(--r-scroll-area-duration) var(--r-scroll-area-easing);
|
|
576
|
+
}
|
|
577
|
+
.r-scroll-area
|
|
578
|
+
> .r-scroll-area__gutters
|
|
579
|
+
> .r-scroll-area__gutter--horizontal
|
|
580
|
+
> .r-scroll-area__thumb {
|
|
581
|
+
block-size: var(--r-scroll-area-thumb-size);
|
|
582
|
+
inline-size: var(--r-scroll-area-thumb-length, 0px);
|
|
583
|
+
inset-block-end: var(--r-scroll-area-rail-gap);
|
|
584
|
+
inset-inline-start: 0;
|
|
585
|
+
transition:
|
|
586
|
+
background-color var(--r-scroll-area-duration) var(--r-scroll-area-easing),
|
|
587
|
+
block-size var(--r-scroll-area-duration) var(--r-scroll-area-easing);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/* Shown while hovered (trigger="hover"), always (trigger="none"), and while scrolling or dragging (every trigger). */
|
|
591
|
+
.r-scroll-area.r-scroll-area--hover-trigger:hover
|
|
592
|
+
> .r-scroll-area__gutters
|
|
593
|
+
> .r-scroll-area__gutter,
|
|
594
|
+
.r-scroll-area.r-scroll-area--none-trigger > .r-scroll-area__gutters > .r-scroll-area__gutter,
|
|
595
|
+
.r-scroll-area
|
|
596
|
+
> .r-scroll-area__gutters.r-scroll-area__gutters--scrolling
|
|
597
|
+
> .r-scroll-area__gutter,
|
|
598
|
+
.r-scroll-area
|
|
599
|
+
> .r-scroll-area__gutters.r-scroll-area__gutters--dragging
|
|
600
|
+
> .r-scroll-area__gutter {
|
|
601
|
+
opacity: 1;
|
|
602
|
+
transition-duration: var(--r-scroll-area-duration-fade-in);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/*
|
|
606
|
+
* trigger="scroll": a hidden gutter doesn't catch presses meant for the
|
|
607
|
+
* content under it. A gutter the pointer is already on (it was shown by
|
|
608
|
+
* scrolling) stays visible and usable after `hideDelay`, until the pointer
|
|
609
|
+
* leaves it; a hidden gutter can't become hovered, so it never shows on hover.
|
|
610
|
+
*/
|
|
611
|
+
.r-scroll-area.r-scroll-area--scroll-trigger
|
|
612
|
+
> .r-scroll-area__gutters
|
|
613
|
+
> .r-scroll-area__gutter:hover {
|
|
614
|
+
opacity: 1;
|
|
615
|
+
transition-duration: var(--r-scroll-area-duration-fade-in);
|
|
616
|
+
}
|
|
617
|
+
.r-scroll-area.r-scroll-area--scroll-trigger
|
|
618
|
+
> .r-scroll-area__gutters:not(.r-scroll-area__gutters--scrolling):not(
|
|
619
|
+
.r-scroll-area__gutters--dragging
|
|
620
|
+
)
|
|
621
|
+
> .r-scroll-area__gutter:not(:hover) {
|
|
622
|
+
pointer-events: none;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/* Pointed at, or while dragged: the thumb thickens and darkens. */
|
|
626
|
+
.r-scroll-area
|
|
627
|
+
> .r-scroll-area__gutters
|
|
628
|
+
> .r-scroll-area__gutter--vertical:hover
|
|
629
|
+
> .r-scroll-area__thumb,
|
|
630
|
+
.r-scroll-area
|
|
631
|
+
> .r-scroll-area__gutters
|
|
632
|
+
> .r-scroll-area__gutter--vertical.r-scroll-area__gutter--dragging
|
|
633
|
+
> .r-scroll-area__thumb {
|
|
634
|
+
background: var(--r-scroll-area-thumb-color-hover);
|
|
635
|
+
inline-size: var(--r-scroll-area-thumb-size-hover);
|
|
636
|
+
}
|
|
637
|
+
.r-scroll-area
|
|
638
|
+
> .r-scroll-area__gutters
|
|
639
|
+
> .r-scroll-area__gutter--horizontal:hover
|
|
640
|
+
> .r-scroll-area__thumb,
|
|
641
|
+
.r-scroll-area
|
|
642
|
+
> .r-scroll-area__gutters
|
|
643
|
+
> .r-scroll-area__gutter--horizontal.r-scroll-area__gutter--dragging
|
|
644
|
+
> .r-scroll-area__thumb {
|
|
645
|
+
background: var(--r-scroll-area-thumb-color-hover);
|
|
646
|
+
block-size: var(--r-scroll-area-thumb-size-hover);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/*
|
|
650
|
+
* Scroll-driven thumbs: the browser moves each thumb from the scroll itself,
|
|
651
|
+
* on the compositor, with no script per scroll. The container names its
|
|
652
|
+
* timelines with the ScrollArea's unique names. Sticky gutters are inside
|
|
653
|
+
* the container and see them, so they need only `animation-timeline`;
|
|
654
|
+
* absolute gutters are its siblings, so the frame hoists the names to
|
|
655
|
+
* itself (`timeline-scope`), and only gutters after a container are
|
|
656
|
+
* animated (`~`). `use-scrollbars.ts` checks the same conditions
|
|
657
|
+
* (`stickyScrollTimelineCondition`, `scrollTimelineCondition`) and the
|
|
658
|
+
* same arrangement; for any other the script moves the thumbs.
|
|
659
|
+
*/
|
|
660
|
+
@supports (animation-timeline: scroll()) {
|
|
661
|
+
.r-scroll-area.r-scroll-area--sticky-gutters {
|
|
662
|
+
scroll-timeline:
|
|
663
|
+
var(--r-scroll-area-timeline-y) block,
|
|
664
|
+
var(--r-scroll-area-timeline-x) inline;
|
|
665
|
+
}
|
|
666
|
+
.r-scroll-area.r-scroll-area--sticky-gutters
|
|
667
|
+
> .r-scroll-area__gutters
|
|
668
|
+
> .r-scroll-area__gutter--vertical
|
|
669
|
+
> .r-scroll-area__thumb {
|
|
670
|
+
animation: r-scroll-area-thumb-y linear both;
|
|
671
|
+
animation-timeline: var(--r-scroll-area-timeline-y);
|
|
672
|
+
}
|
|
673
|
+
.r-scroll-area.r-scroll-area--sticky-gutters
|
|
674
|
+
> .r-scroll-area__gutters
|
|
675
|
+
> .r-scroll-area__gutter--horizontal
|
|
676
|
+
> .r-scroll-area__thumb {
|
|
677
|
+
animation: r-scroll-area-thumb-x linear both;
|
|
678
|
+
animation-timeline: var(--r-scroll-area-timeline-x);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
@supports (animation-timeline: scroll()) and (timeline-scope: none) {
|
|
682
|
+
.r-scroll-area.r-scroll-area--absolute-gutters > .r-scroll-area__container {
|
|
683
|
+
scroll-timeline:
|
|
684
|
+
var(--r-scroll-area-timeline-y) block,
|
|
685
|
+
var(--r-scroll-area-timeline-x) inline;
|
|
686
|
+
}
|
|
687
|
+
.r-scroll-area.r-scroll-area--absolute-gutters {
|
|
688
|
+
timeline-scope: var(--r-scroll-area-timeline-y), var(--r-scroll-area-timeline-x);
|
|
689
|
+
}
|
|
690
|
+
.r-scroll-area.r-scroll-area--absolute-gutters
|
|
691
|
+
> .r-scroll-area__container
|
|
692
|
+
~ .r-scroll-area__gutters
|
|
693
|
+
> .r-scroll-area__gutter--vertical
|
|
694
|
+
> .r-scroll-area__thumb {
|
|
695
|
+
animation: r-scroll-area-thumb-y linear both;
|
|
696
|
+
animation-timeline: var(--r-scroll-area-timeline-y);
|
|
697
|
+
}
|
|
698
|
+
.r-scroll-area.r-scroll-area--absolute-gutters
|
|
699
|
+
> .r-scroll-area__container
|
|
700
|
+
~ .r-scroll-area__gutters
|
|
701
|
+
> .r-scroll-area__gutter--horizontal
|
|
702
|
+
> .r-scroll-area__thumb {
|
|
703
|
+
animation: r-scroll-area-thumb-x linear both;
|
|
704
|
+
animation-timeline: var(--r-scroll-area-timeline-x);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
@media print {
|
|
709
|
+
.r-scroll-area > .r-scroll-area__gutters {
|
|
710
|
+
display: none;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
@media (prefers-reduced-motion: reduce) {
|
|
715
|
+
.r-scroll-area > .r-scroll-area__gutters > .r-scroll-area__gutter,
|
|
716
|
+
.r-scroll-area > .r-scroll-area__gutters > .r-scroll-area__gutter > .r-scroll-area__thumb {
|
|
717
|
+
transition: none;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|