@rcarls/rc-virtual-scroller 0.0.0 → 0.7.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 +96 -0
- package/README.md +164 -5
- package/dist/custom-elements.json +878 -0
- package/dist/rc-virtual-scroller-BA_t6Xkx.js +403 -0
- package/dist/rc-virtual-scroller-BA_t6Xkx.js.map +1 -0
- package/dist/rc-virtual-scroller-define.js +6 -0
- package/dist/rc-virtual-scroller-define.js.map +1 -0
- package/dist/rc-virtual-scroller.js +5 -0
- package/dist/rc-virtual-scroller.js.map +1 -0
- package/dist/types/packages/rc-virtual-scroller/src/define.d.ts +1 -0
- package/dist/types/packages/rc-virtual-scroller/src/index.d.ts +1 -0
- package/dist/types/packages/rc-virtual-scroller/src/range.d.ts +31 -0
- package/dist/types/packages/rc-virtual-scroller/src/rc-virtual-scroller.d.ts +211 -0
- package/dist/types/packages/rc-virtual-scroller/src/rc-virtual-scroller.styles.d.ts +2 -0
- package/dist/types/packages/rc-virtual-scroller/src/sample.d.ts +15 -0
- package/package.json +58 -7
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# @rcarls/rc-virtual-scroller
|
|
2
|
+
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- aed2034: Add `rc-virtual-scroller`, a headless virtualization wrapper.
|
|
8
|
+
|
|
9
|
+
Mounting a large collection as custom elements costs real time regardless of
|
|
10
|
+
`content-visibility: auto`: upgrade happens at parse and insertion, before
|
|
11
|
+
style resolves, so containment cannot prevent element construction. This
|
|
12
|
+
package stops the count of mounted elements from scaling with collection
|
|
13
|
+
size, without taking over rendering.
|
|
14
|
+
|
|
15
|
+
The element measures geometry against a slotted container and dispatches
|
|
16
|
+
`rc-virtual-scroller-range` with the visible `[start, end)` index range; the
|
|
17
|
+
consumer renders that slice into its own container with whatever it already
|
|
18
|
+
uses, and two spacer parts reserve the off-range scroll space. Items per line
|
|
19
|
+
and line pitch are measured from the container's own grid tracks rather than
|
|
20
|
+
configured, so `auto-fill` and container queries stay authoritative. The
|
|
21
|
+
focused item is never dropped from the reported range, so scrolling never
|
|
22
|
+
silently resets keyboard focus to `<body>`.
|
|
23
|
+
|
|
24
|
+
`axis="block|inline"` is logical: `block` windows stacked lines, `inline`
|
|
25
|
+
windows a row of items such as a horizontal shelf. Direction and writing mode
|
|
26
|
+
are read from computed style, so RTL pages and vertical text work without
|
|
27
|
+
configuration.
|
|
28
|
+
|
|
29
|
+
- 11ef1ad: Harden virtual scrolling for document and element scroll containers, viewport resizing,
|
|
30
|
+
shadow-root focus, hidden panes, and uniform spanning grids. Separate layout
|
|
31
|
+
sampling from range calculation and avoid repeating item measurements during
|
|
32
|
+
unchanged scroll frames. Scroll ancestor discovery now follows slots and shadow hosts.
|
|
33
|
+
|
|
34
|
+
Breaking: `first` and `last` are read-only computed outputs. Use `scrollToIndex()`
|
|
35
|
+
for navigation and read `range` for rendering instead of assigning output values.
|
|
36
|
+
Virtualization requires uniform line pitch and capacity in sequential DOM order;
|
|
37
|
+
detected unsupported layouts render the full collection. Set `items-per-line`
|
|
38
|
+
for ambiguous uniform grid capacity, or remove it to restore automatic inference.
|
|
39
|
+
Numeric inputs now normalize invalid values and floor integer configuration.
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- 5c006de: Ship component CSS minified. Package builds now run the CSS in Lit `css` styles
|
|
44
|
+
and light-DOM structural styles through Lightning CSS, removing comments and
|
|
45
|
+
whitespace while keeping source maps that resolve to each template. Rendered
|
|
46
|
+
styles are unchanged.
|
|
47
|
+
|
|
48
|
+
`@rcarls/rc-common` adds `cssText`, an identity tag that marks a plain CSS
|
|
49
|
+
string for minification. `rc-chip`, `rc-disclosure`, and `rc-accordion` now
|
|
50
|
+
depend on `@rcarls/rc-common` for it.
|
|
51
|
+
|
|
52
|
+
- 0c9d563: Re-resolve the writing direction when a `dir` attribute changes, and at the
|
|
53
|
+
start of every `scrollToIndex` call, so an inline-axis scroller keeps the
|
|
54
|
+
right range and scrolls to the right item after a page switches direction.
|
|
55
|
+
- 16420f9: Count items per line from where items render instead of from the grid's
|
|
56
|
+
track count, so a collection whose items span several tracks, such as a
|
|
57
|
+
shelf of cards aligned through subgrid across its rows, windows one item per
|
|
58
|
+
line instead of one per track.
|
|
59
|
+
- 7c1c7c4: Keep the rendered window on screen under CSS `zoom`, such as an app-wide
|
|
60
|
+
interface size set on the root. The view position, scrollport size, and line
|
|
61
|
+
pitch were read in viewport pixels but the spacers were written in the host's
|
|
62
|
+
own CSS pixels, so the window drifted off screen by the zoom error as the list
|
|
63
|
+
scrolled, leaving a growing blank gap. All geometry is now converted to host
|
|
64
|
+
pixels, and `scrollToIndex()` scrolls in the scroll container's own pixels.
|
|
65
|
+
- Updated dependencies [e3dfa59]
|
|
66
|
+
- Updated dependencies [50d5610]
|
|
67
|
+
- Updated dependencies [9ee769c]
|
|
68
|
+
- Updated dependencies [1179f24]
|
|
69
|
+
- Updated dependencies [595fe37]
|
|
70
|
+
- Updated dependencies [38cd00c]
|
|
71
|
+
- Updated dependencies [5c006de]
|
|
72
|
+
- Updated dependencies [a6553ff]
|
|
73
|
+
- Updated dependencies [2205478]
|
|
74
|
+
- Updated dependencies [4341311]
|
|
75
|
+
- Updated dependencies [899bb5e]
|
|
76
|
+
- Updated dependencies [25fcfe0]
|
|
77
|
+
- Updated dependencies [51f6403]
|
|
78
|
+
- Updated dependencies [9caca6b]
|
|
79
|
+
- Updated dependencies [b764a3c]
|
|
80
|
+
- Updated dependencies [54d9ead]
|
|
81
|
+
- Updated dependencies [b9175e9]
|
|
82
|
+
- Updated dependencies [c8b762b]
|
|
83
|
+
- Updated dependencies [55e1e7f]
|
|
84
|
+
- Updated dependencies [f1ca82d]
|
|
85
|
+
- Updated dependencies [b87f27b]
|
|
86
|
+
- Updated dependencies [32ebead]
|
|
87
|
+
- Updated dependencies [bfefedd]
|
|
88
|
+
- Updated dependencies [c130173]
|
|
89
|
+
- Updated dependencies [11680b6]
|
|
90
|
+
- Updated dependencies [223d36c]
|
|
91
|
+
- Updated dependencies [7b91a44]
|
|
92
|
+
- Updated dependencies [aa04ead]
|
|
93
|
+
- Updated dependencies [ac65b5b]
|
|
94
|
+
- Updated dependencies [afcfef8]
|
|
95
|
+
- Updated dependencies [11ef1ad]
|
|
96
|
+
- @rcarls/rc-common@0.7.0
|
package/README.md
CHANGED
|
@@ -1,8 +1,167 @@
|
|
|
1
1
|
# @rcarls/rc-virtual-scroller
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Headless virtualization wrapper that reports the visible index range for a
|
|
4
|
+
consumer-owned list or grid and reserves the off-range scroll space.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
```html
|
|
7
|
+
<rc-scroller>
|
|
8
|
+
<rc-virtual-scroller count="4000" item-size="288">
|
|
9
|
+
<ul class="cards">
|
|
10
|
+
<!-- only the items in the current range -->
|
|
11
|
+
</ul>
|
|
12
|
+
</rc-virtual-scroller>
|
|
13
|
+
</rc-scroller>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
const scroller = document.querySelector('rc-virtual-scroller');
|
|
18
|
+
|
|
19
|
+
const render = ({ start, end }) => renderItems(recipes.slice(start, end), start);
|
|
20
|
+
|
|
21
|
+
// The element may have measured before this listener existed.
|
|
22
|
+
if (scroller.range) render(scroller.range);
|
|
23
|
+
|
|
24
|
+
scroller.addEventListener('rc-virtual-scroller-range', (event) => render(event.detail));
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The element measures on its own schedule, which can be before your listener is
|
|
28
|
+
attached, and it never re-sends an unchanged range. Render once from the
|
|
29
|
+
read-only `range` property when you subscribe, then follow the event.
|
|
30
|
+
|
|
31
|
+
The element never creates, recycles, or positions item DOM. It measures
|
|
32
|
+
geometry, dispatches `rc-virtual-scroller-range`, and sizes two spacer parts
|
|
33
|
+
around the default slot. You slot one container element and render the reported
|
|
34
|
+
slice into it with whatever you already use.
|
|
35
|
+
|
|
36
|
+
That split is the whole point. The markup, the CSS layout, and the
|
|
37
|
+
accessibility semantics stay with the code that owns them, so a native
|
|
38
|
+
`grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr))` keeps working
|
|
39
|
+
untouched, `<ul>` still contains `<li>`, and a framework's keyed list still
|
|
40
|
+
reuses the nodes that stayed in range.
|
|
41
|
+
|
|
42
|
+
## Why not `content-visibility: auto`
|
|
43
|
+
|
|
44
|
+
CSS containment skips layout and paint for offscreen content, but a custom
|
|
45
|
+
element upgrades when it is parsed or inserted, before style is resolved.
|
|
46
|
+
Containment cannot prevent element construction, so a collection of a few
|
|
47
|
+
thousand custom elements still pays for all of them up front. Virtualization is
|
|
48
|
+
the only thing that avoids that cost.
|
|
49
|
+
|
|
50
|
+
## Axis, direction, and writing mode
|
|
51
|
+
|
|
52
|
+
`axis` is logical. `block`, the default, windows lines that stack the way
|
|
53
|
+
paragraphs do: top to bottom in horizontal text, right to left in
|
|
54
|
+
`vertical-rl`. `inline` windows items running the way text runs, such as a
|
|
55
|
+
horizontal shelf. For the inline axis, lay the container's items along it with
|
|
56
|
+
`display: flex` or a grid with `grid-auto-flow: column`.
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<rc-virtual-scroller axis="inline" count="500" item-size="160">
|
|
60
|
+
<ul class="shelf">
|
|
61
|
+
<!-- display: flex -->
|
|
62
|
+
</ul>
|
|
63
|
+
</rc-virtual-scroller>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Direction and writing mode come from the element's computed style, so RTL
|
|
67
|
+
pages and vertical text need no configuration. The visible range is measured
|
|
68
|
+
from where the scroll container's visible box sits relative to the element, in
|
|
69
|
+
the element's own flow, so it never depends on the sign conventions of
|
|
70
|
+
`scrollLeft` in RTL.
|
|
71
|
+
|
|
72
|
+
## Geometry
|
|
73
|
+
|
|
74
|
+
Virtualization supports sequential DOM-order collections with **uniform line
|
|
75
|
+
pitch and capacity**; the final line may be partial. Use ordinary lists,
|
|
76
|
+
shelves without wrapping, regular grids, or uniform numeric grid spans. Masonry,
|
|
77
|
+
variable-height lines, dense placement, and reordered collections are outside
|
|
78
|
+
this contract. When a sampled layout is demonstrably unsupported, the component
|
|
79
|
+
reports the whole collection, removes its spacers, and warns in development.
|
|
80
|
+
|
|
81
|
+
Automatic grid measurement reads resolved tracks and their gaps, so differently
|
|
82
|
+
aligned items in the same track do not become separate lines. Uniform spans,
|
|
83
|
+
including `1 / -1`, count as items rather than individual tracks. Container
|
|
84
|
+
queries and `auto-fill` remain authoritative.
|
|
85
|
+
|
|
86
|
+
For ambiguous uniform grid placement, set `items-per-line` to the number of
|
|
87
|
+
items in each line. The override controls capacity, not pitch or CSS placement;
|
|
88
|
+
it does not enable virtualization of variable-height layouts. Remove the attribute,
|
|
89
|
+
or assign `itemsPerLine = 0`, to restore automatic inference.
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<rc-virtual-scroller axis="inline" count="500" item-size="160" items-per-line="1">
|
|
93
|
+
<ul class="shelf">
|
|
94
|
+
<!-- One card per column, spanning named row tracks. -->
|
|
95
|
+
</ul>
|
|
96
|
+
</rc-virtual-scroller>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`count` is the true total. `item-size` estimates line pitch until it can be
|
|
100
|
+
measured; it never overrides measured geometry. `overscan` defaults to two
|
|
101
|
+
extra lines at each viewport edge. A one-line slice retains its established
|
|
102
|
+
geometry instead of reverting to a contradictory track-count estimate.
|
|
103
|
+
|
|
104
|
+
Numeric inputs are normalized: `count` and `items-per-line` are floored
|
|
105
|
+
nonnegative integers with a fallback of zero; `overscan` is floored with a
|
|
106
|
+
fallback of two for negative values, infinity, or NaN. Zero, negative, or invalid
|
|
107
|
+
`item-size` becomes zero. Without a usable pitch the full collection is
|
|
108
|
+
reported so it can be measured.
|
|
109
|
+
|
|
110
|
+
`rc-virtual-scroller-range` reports the effective `itemsPerLine`, `lineSize`,
|
|
111
|
+
and `measured` (whether pitch comes from real layout). `first`, `last`, and
|
|
112
|
+
`range` are read-only outputs. The `first` and `last` attributes report the
|
|
113
|
+
computed state; author writes do not control the window.
|
|
114
|
+
|
|
115
|
+
The nearest scrolling ancestor is found through slots and shadow hosts.
|
|
116
|
+
Document scrolling and viewport resizing are supported. Set `scrollTarget`
|
|
117
|
+
when the intended scrollport differs from the automatically resolved ancestor.
|
|
118
|
+
Resizing the scrollport fills newly visible space even when the host itself
|
|
119
|
+
does not resize. A pane hidden with `display: none` retains its mounted slice
|
|
120
|
+
and geometry until layout becomes available again.
|
|
121
|
+
|
|
122
|
+
Call `measure()` after changes that observers cannot see, such as a stylesheet
|
|
123
|
+
writing-mode change that preserves logical size, a font/theme change that only
|
|
124
|
+
affects item internals, or repositioning the collection without resizing it.
|
|
125
|
+
Consumers should commit the requested slice promptly; after an asynchronous
|
|
126
|
+
render commit, call `measure()` if the container's children and size did not
|
|
127
|
+
change.
|
|
128
|
+
|
|
129
|
+
`scrollToIndex(index, { align, behavior })` uses the current line pitch.
|
|
130
|
+
Alignment is `start` (default), `center`, `end`, or `nearest`. Finite
|
|
131
|
+
indices are floored and clamped; infinity and NaN are ignored.
|
|
132
|
+
`disabled` reports the full collection with zero spacers.
|
|
133
|
+
|
|
134
|
+
To migrate code that assigned `first` or `last`, use `scrollToIndex()`
|
|
135
|
+
for navigation and read `range` for rendering. Supply `items-per-line`
|
|
136
|
+
when a uniform grid's placement cannot be inferred.
|
|
137
|
+
|
|
138
|
+
## Accessibility
|
|
139
|
+
|
|
140
|
+
A virtualized set must still tell assistive technology how big it really is,
|
|
141
|
+
because the DOM no longer says so. The element does not write these for you:
|
|
142
|
+
the roles belong to your markup, and guessing at them would fight a container
|
|
143
|
+
that manages its own rows.
|
|
144
|
+
|
|
145
|
+
- For a list, put `aria-setsize` (the true `count`) and `aria-posinset` (the
|
|
146
|
+
item's real index, not its position in the rendered slice) on each item.
|
|
147
|
+
- For a grid, use `aria-rowcount` / `aria-rowindex`, and
|
|
148
|
+
`aria-colcount` / `aria-colindex` where columns are also virtualized.
|
|
149
|
+
- Set `aria-busy="true"` on the container while a batch is being swapped in, as
|
|
150
|
+
the [WAI-ARIA APG feed pattern](https://www.w3.org/WAI/ARIA/apg/patterns/feed/)
|
|
151
|
+
describes.
|
|
152
|
+
|
|
153
|
+
The one thing the element does handle is focus. Unmounting the focused element
|
|
154
|
+
moves focus to `<body>` with no error and no visible cause, which is how a
|
|
155
|
+
keyboard user silently loses their place. The reported range is always widened
|
|
156
|
+
to include the focused item, contiguously, so your render stays a plain slice;
|
|
157
|
+
it collapses again as soon as focus moves. Scrolling a long way while holding
|
|
158
|
+
focus therefore renders a larger range on purpose.
|
|
159
|
+
|
|
160
|
+
The element sets `overflow-anchor: none` on itself. Browser scroll anchoring
|
|
161
|
+
exists to hold the reading position when content above the viewport changes
|
|
162
|
+
size, which is what this element does every frame, so leaving it on makes the
|
|
163
|
+
two fight and the scroll position drift.
|
|
164
|
+
|
|
165
|
+
Import `@rcarls/rc-virtual-scroller` to use the class without registering it, or
|
|
166
|
+
import `@rcarls/rc-virtual-scroller/define` to register
|
|
167
|
+
`<rc-virtual-scroller>`.
|