@jsenv/navi 0.29.51 → 0.29.52
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/dist/jsenv_navi.js +66 -9
- package/dist/jsenv_navi.js.map +17 -4
- package/docs/scroll.md +5 -0
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -55587,10 +55587,13 @@ const ListFirstResolver = props => {
|
|
|
55587
55587
|
* thread read backwards — the last rows are the ones to show, and the ones
|
|
55588
55588
|
* asked for first. A number opens on that row of the collection. `{id,
|
|
55589
55589
|
* offset}` — what `onScrolledChange` hands out — opens on a NAMED row,
|
|
55590
|
-
* `offset` pixels below the
|
|
55591
|
-
* (see the range's own `around`), then put back by MEASURING it,
|
|
55592
|
-
* where it was even if rows were inserted before it, and whatever
|
|
55593
|
-
* it was saved on.
|
|
55590
|
+
* `offset` pixels below where the row would land on its own: the row is asked
|
|
55591
|
+
* for by name (see the range's own `around`), then put back by MEASURING it,
|
|
55592
|
+
* so it lands where it was even if rows were inserted before it, and whatever
|
|
55593
|
+
* the screen it was saved on. `offset: 0` is where a `scrollIntoView()` puts
|
|
55594
|
+
* it — in front of the fixed bar the scroller gives room for, below the
|
|
55595
|
+
* sticky header and the group label the row lives under — so nothing of that
|
|
55596
|
+
* room has to be restated as a number by whoever asks.
|
|
55594
55597
|
* @param {"start"|"end"|number|{id: string, offset?: number}} [props.scrolled]
|
|
55595
55598
|
* The same, but held: the list goes back there every time this changes, even
|
|
55596
55599
|
* after the user has scrolled — the caller owns where the list is (see
|
|
@@ -55604,7 +55607,8 @@ const ListFirstResolver = props => {
|
|
|
55604
55607
|
* user reaches for the list.
|
|
55605
55608
|
* @param {(scrolled: {id: string, index: number, offset: number}) => void} [props.onScrolledChange]
|
|
55606
55609
|
* Where the list is, as the user scrolls: the row at the top of the view and
|
|
55607
|
-
* how far below the
|
|
55610
|
+
* how far below the place a row lands on its own (see `defaultScrolled`) it
|
|
55611
|
+
* starts. Keep it to come back to it
|
|
55608
55612
|
* later through `scrolled`/`defaultScrolled` — an index would not do, since
|
|
55609
55613
|
* rows get inserted while a list is being read.
|
|
55610
55614
|
* @param {"self"|"parent"|"document"|Element|{current: Element}} [props.scroller="self"]
|
|
@@ -56215,7 +56219,7 @@ const useListScrollSync = ({
|
|
|
56215
56219
|
}
|
|
56216
56220
|
const viewportRect = getScrollerViewportRect(scrollerEl);
|
|
56217
56221
|
const rowRect = rowEl.getBoundingClientRect();
|
|
56218
|
-
const offsetWanted = resolveOpenOffset(openAt.offset || 0, horizontal ? viewportRect.width : viewportRect.height, horizontal ? rowRect.width : rowRect.height);
|
|
56222
|
+
const offsetWanted = resolveOpenOffset(getRowScrollInset(scrollerEl, rowEl, horizontal) + (openAt.offset || 0), horizontal ? viewportRect.width : viewportRect.height, horizontal ? rowRect.width : rowRect.height);
|
|
56219
56223
|
const offsetNow = horizontal ? rowRect.left - viewportRect.left : rowRect.top - viewportRect.top;
|
|
56220
56224
|
const delta = offsetNow - offsetWanted;
|
|
56221
56225
|
if (delta > -0.5 && delta < 0.5) {
|
|
@@ -56292,10 +56296,14 @@ const useListScrollSync = ({
|
|
|
56292
56296
|
return;
|
|
56293
56297
|
}
|
|
56294
56298
|
positionRef.current = position;
|
|
56295
|
-
onScrolledChangeRef.current
|
|
56299
|
+
if (!onScrolledChangeRef.current) {
|
|
56300
|
+
return;
|
|
56301
|
+
}
|
|
56302
|
+
const rowEl = findRowElement(getListEl(), position.id);
|
|
56303
|
+
onScrolledChangeRef.current({
|
|
56296
56304
|
id: position.id,
|
|
56297
56305
|
index: position.index,
|
|
56298
|
-
offset: position.offset
|
|
56306
|
+
offset: position.offset - getRowScrollInset(getScroller(), rowEl, horizontal)
|
|
56299
56307
|
});
|
|
56300
56308
|
};
|
|
56301
56309
|
|
|
@@ -56760,6 +56768,38 @@ const resolveOpenOffset = (offset, viewportSize, rowSize) => {
|
|
|
56760
56768
|
return offset;
|
|
56761
56769
|
};
|
|
56762
56770
|
|
|
56771
|
+
// The room a row must be given at the top (or left) of the view: the
|
|
56772
|
+
// scroller's own scroll-padding — where a fixed bar publishes the space it
|
|
56773
|
+
// takes — plus the row's scroll-margin, where the list puts its sticky header
|
|
56774
|
+
// and the height of the group label it lives under. `scrollIntoView()` on a row
|
|
56775
|
+
// lands past both; a position given as `{id, offset}` means the same place, so
|
|
56776
|
+
// `offset` is the caller's own few pixels and not a number restating what the
|
|
56777
|
+
// CSS already measures.
|
|
56778
|
+
const getRowScrollInset = (scrollerEl, rowEl, horizontal) => {
|
|
56779
|
+
if (!rowEl) {
|
|
56780
|
+
return 0;
|
|
56781
|
+
}
|
|
56782
|
+
const viewportRect = getScrollerViewportRect(scrollerEl);
|
|
56783
|
+
const viewportSize = horizontal ? viewportRect.width : viewportRect.height;
|
|
56784
|
+
const scrollerStyle = window.getComputedStyle(scrollerEl);
|
|
56785
|
+
const rowStyle = window.getComputedStyle(rowEl);
|
|
56786
|
+
const scrollPadding = resolveScrollInset(horizontal ? scrollerStyle.scrollPaddingLeft : scrollerStyle.scrollPaddingTop, viewportSize);
|
|
56787
|
+
const scrollMargin = resolveScrollInset(horizontal ? rowStyle.scrollMarginLeft : rowStyle.scrollMarginTop, viewportSize);
|
|
56788
|
+
return scrollPadding + scrollMargin;
|
|
56789
|
+
};
|
|
56790
|
+
// scroll-padding is a length, a percentage of the scrollport, or "auto" (the
|
|
56791
|
+
// browser decides, which for placing a row means nothing).
|
|
56792
|
+
const resolveScrollInset = (value, viewportSize) => {
|
|
56793
|
+
const number = parseFloat(value);
|
|
56794
|
+
if (!number) {
|
|
56795
|
+
return 0;
|
|
56796
|
+
}
|
|
56797
|
+
if (value.endsWith("%")) {
|
|
56798
|
+
return number * viewportSize / 100;
|
|
56799
|
+
}
|
|
56800
|
+
return number;
|
|
56801
|
+
};
|
|
56802
|
+
|
|
56763
56803
|
// The row with that id, IN THIS LIST. Not document.getElementById: an id is
|
|
56764
56804
|
// only ever unique within a list — two lists on the same page can be showing
|
|
56765
56805
|
// the same collection — and a list acting on a row that belongs to another one
|
|
@@ -57893,6 +57933,7 @@ const VISIBILITY_HIDDEN_STYLE = {
|
|
|
57893
57933
|
* count?: number,
|
|
57894
57934
|
* groupBy?: (item: any, index: number) => any,
|
|
57895
57935
|
* renderGroupLabel?: (item: any, index: number) => import("ignore:preact").ComponentChildren,
|
|
57936
|
+
* groupLabelProps?: (item: any, index: number) => object,
|
|
57896
57937
|
* pageSize?: number,
|
|
57897
57938
|
* memoryBudget?: number,
|
|
57898
57939
|
* renderSkeleton?: false | ((index: number) => import("ignore:preact").ComponentChildren),
|
|
@@ -57910,6 +57951,12 @@ const VISIBILITY_HIDDEN_STYLE = {
|
|
|
57910
57951
|
* the only way a list that discovers its rows page by page can have any.
|
|
57911
57952
|
* @param {(item: any, index: number) => any} [props.renderGroupLabel]
|
|
57912
57953
|
* The label of the group a row opens, given that row.
|
|
57954
|
+
* @param {(item: any, index: number) => object} [props.groupLabelProps]
|
|
57955
|
+
* The props the label of the group a row opens carries — `class`,
|
|
57956
|
+
* `data-*`, anything a `<span>` takes. For a label that says something about
|
|
57957
|
+
* its group (a day behind us, today, one ahead) rather than just naming it:
|
|
57958
|
+
* the state then sits on the element the CSS styles, instead of being read
|
|
57959
|
+
* back from a child.
|
|
57913
57960
|
* @param {number} [props.pageSize]
|
|
57914
57961
|
* How many rows to ask for at a time. A turn of the wheel opens a hole three
|
|
57915
57962
|
* rows wide; asking for exactly that would ask again at the next turn.
|
|
@@ -57937,6 +57984,7 @@ const ListItems = ({
|
|
|
57937
57984
|
memoryBudget,
|
|
57938
57985
|
groupBy,
|
|
57939
57986
|
renderGroupLabel,
|
|
57987
|
+
groupLabelProps,
|
|
57940
57988
|
renderSkeleton,
|
|
57941
57989
|
renderError
|
|
57942
57990
|
}) => {
|
|
@@ -58076,6 +58124,7 @@ const ListItems = ({
|
|
|
58076
58124
|
}
|
|
58077
58125
|
rows.push(jsx(ListItemGroup, {
|
|
58078
58126
|
label: group.label,
|
|
58127
|
+
labelProps: group.labelProps,
|
|
58079
58128
|
children: group.children
|
|
58080
58129
|
}, `${ownerId}_group_${group.key}`));
|
|
58081
58130
|
group = null;
|
|
@@ -58092,6 +58141,7 @@ const ListItems = ({
|
|
|
58092
58141
|
group = {
|
|
58093
58142
|
key: groupKey,
|
|
58094
58143
|
label: renderGroupLabel ? renderGroupLabel(item, rowIndex) : groupKey,
|
|
58144
|
+
labelProps: groupLabelProps ? groupLabelProps(item, rowIndex) : undefined,
|
|
58095
58145
|
children: []
|
|
58096
58146
|
};
|
|
58097
58147
|
}
|
|
@@ -58532,6 +58582,7 @@ const useItemStore = ({
|
|
|
58532
58582
|
*/
|
|
58533
58583
|
const ListItemGroup = ({
|
|
58534
58584
|
label,
|
|
58585
|
+
labelProps,
|
|
58535
58586
|
hiddenWhileEmpty,
|
|
58536
58587
|
children,
|
|
58537
58588
|
...rest
|
|
@@ -58557,6 +58608,11 @@ const ListItemGroup = ({
|
|
|
58557
58608
|
groupEl.style.setProperty("--list-group-label-height", `${rect.height}px`);
|
|
58558
58609
|
groupEl.style.setProperty("--list-group-label-width", `${rect.width}px`);
|
|
58559
58610
|
}, []);
|
|
58611
|
+
const {
|
|
58612
|
+
className: labelClassName,
|
|
58613
|
+
class: labelClass,
|
|
58614
|
+
...labelRest
|
|
58615
|
+
} = labelProps || {};
|
|
58560
58616
|
return jsxs(ListItem, {
|
|
58561
58617
|
...rest,
|
|
58562
58618
|
ref: groupRef,
|
|
@@ -58564,9 +58620,10 @@ const ListItemGroup = ({
|
|
|
58564
58620
|
role: "presentation",
|
|
58565
58621
|
"data-hidden-while-empty": hiddenWhileEmpty ? "" : undefined,
|
|
58566
58622
|
children: [jsx("span", {
|
|
58623
|
+
...labelRest,
|
|
58567
58624
|
ref: labelRef,
|
|
58568
58625
|
id: groupId,
|
|
58569
|
-
className: "navi_list_item_group_label",
|
|
58626
|
+
className: withPropsClassName("navi_list_item_group_label", labelClassName || labelClass),
|
|
58570
58627
|
role: "presentation",
|
|
58571
58628
|
"aria-hidden": labelHidden ? "true" : undefined,
|
|
58572
58629
|
inert: labelHidden ? true : undefined
|