ropav 0.4.0 → 0.6.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/dist/components/autocomplete/autocomplete-root.js +3 -1
- package/dist/components/autocomplete/index.d.ts +3 -0
- package/dist/components/breadcrumbs/breadcrumbs-item.js +1 -0
- package/dist/components/breadcrumbs/index.d.ts +1 -0
- package/dist/components/calendar/index.d.ts +5 -3
- package/dist/components/calendar-year-picker/index.d.ts +4 -2
- package/dist/components/checkbox/checkbox-content.js +1 -1
- package/dist/components/color-field/index.d.ts +1 -0
- package/dist/components/color-input-group/color-input-group-root.js +2 -0
- package/dist/components/color-input-group/color-input-group.types.d.ts +2 -0
- package/dist/components/color-input-group/index.d.ts +2 -0
- package/dist/components/combo-box/combo-box-root.js +9 -2
- package/dist/components/combo-box/combo-box.types.d.ts +3 -0
- package/dist/components/combo-box/index.d.ts +3 -0
- package/dist/components/date-field/index.d.ts +1 -0
- package/dist/components/date-input-group/date-input-group-root.js +2 -0
- package/dist/components/date-input-group/date-input-group-segment.js +1 -1
- package/dist/components/date-input-group/date-input-group.types.d.ts +2 -0
- package/dist/{composables → components/date-input-group}/use-date-segment.d.ts +2 -2
- package/dist/{composables → components/date-input-group}/use-date-segment.js +9 -9
- package/dist/components/date-range-picker/date-range-picker-root.js +1 -1
- package/dist/components/date-range-picker/index.d.ts +15 -14
- package/dist/{composables → components/date-range-picker}/use-date-range-picker.d.ts +7 -7
- package/dist/{composables → components/date-range-picker}/use-date-range-picker.js +10 -10
- package/dist/components/drawer/drawer-dialog.js +1 -1
- package/dist/{composables → components/drawer}/use-drawer-drag.d.ts +1 -1
- package/dist/{composables → components/drawer}/use-drawer-drag.js +1 -1
- package/dist/components/drop-zone/drop-zone-root.d.ts +23 -0
- package/dist/components/drop-zone/drop-zone-root.js +153 -0
- package/dist/components/drop-zone/drop-zone-trigger.d.ts +21 -0
- package/dist/components/drop-zone/drop-zone-trigger.js +20 -0
- package/dist/components/drop-zone/drop-zone.accept.d.ts +19 -0
- package/dist/components/drop-zone/drop-zone.accept.js +28 -0
- package/dist/components/drop-zone/drop-zone.context.d.ts +6 -0
- package/dist/components/drop-zone/drop-zone.context.js +5 -0
- package/dist/components/drop-zone/drop-zone.types.d.ts +30 -0
- package/dist/components/drop-zone/index.d.ts +86 -0
- package/dist/components/drop-zone/index.js +11 -0
- package/dist/components/dropdown/dropdown-menu.js +1 -0
- package/dist/components/dropdown/dropdown-submenu-trigger.js +1 -1
- package/dist/components/dropdown/index.d.ts +4 -2
- package/dist/{composables → components/dropdown}/use-safely-mouse-to-submenu.js +1 -1
- package/dist/components/icons/icon-overlay-arrow.js +1 -1
- package/dist/components/index.d.ts +5 -0
- package/dist/components/input/index.d.ts +2 -0
- package/dist/components/input/input-root.js +3 -0
- package/dist/components/input/input.types.d.ts +5 -0
- package/dist/components/input-group/index.d.ts +2 -0
- package/dist/components/input-group/input-group-root.js +3 -0
- package/dist/components/input-group/input-group.types.d.ts +5 -0
- package/dist/components/input-otp/index.d.ts +6 -4
- package/dist/components/link/index.d.ts +2 -0
- package/dist/components/link/link-root.js +22 -5
- package/dist/components/link/link.types.d.ts +14 -3
- package/dist/{composables → components/list-box}/drag-collection.d.ts +2 -2
- package/dist/{composables → components/list-box}/drag-collection.js +1 -1
- package/dist/components/list-box/index.d.ts +4 -0
- package/dist/components/list-box/list-box-root.js +53 -32
- package/dist/components/list-box/list-box.types.d.ts +2 -0
- package/dist/components/menu/index.d.ts +2 -0
- package/dist/components/menu/menu-root.js +5 -1
- package/dist/components/menu/menu.types.d.ts +3 -0
- package/dist/components/number-field/index.d.ts +3 -0
- package/dist/components/number-field/number-field-root.js +2 -0
- package/dist/components/number-field/number-field.types.d.ts +2 -0
- package/dist/components/overlay/overlay-arrow.js +64 -11
- package/dist/components/progress-bar/index.d.ts +4 -0
- package/dist/components/progress-bar/progress-bar-root.js +4 -0
- package/dist/components/progress-bar/progress-bar.types.d.ts +7 -0
- package/dist/components/radio/radio-content.js +1 -1
- package/dist/components/range-calendar/index.d.ts +18 -15
- package/dist/components/router-provider/index.d.ts +5 -0
- package/dist/components/router-provider/index.js +3 -0
- package/dist/components/router-provider/router-provider.context.d.ts +40 -0
- package/dist/components/router-provider/router-provider.context.js +16 -0
- package/dist/components/router-provider/router-provider.d.ts +21 -0
- package/dist/components/router-provider/router-provider.js +22 -0
- package/dist/components/router-provider/router-provider.types.d.ts +23 -0
- package/dist/components/scroll-shadow/use-scroll-shadow.js +25 -1
- package/dist/components/search-field/index.d.ts +2 -0
- package/dist/components/search-field/search-field-root.js +3 -1
- package/dist/components/search-field/search-field.types.d.ts +2 -0
- package/dist/{composables → components/search-field}/use-search-field.d.ts +2 -2
- package/dist/{composables → components/search-field}/use-search-field.js +3 -3
- package/dist/components/segmented-control/index.d.ts +134 -0
- package/dist/components/segmented-control/index.js +15 -0
- package/dist/components/segmented-control/segmented-control-indicator.d.ts +19 -0
- package/dist/components/segmented-control/segmented-control-indicator.js +36 -0
- package/dist/components/segmented-control/segmented-control-item.d.ts +21 -0
- package/dist/components/segmented-control/segmented-control-item.js +96 -0
- package/dist/components/segmented-control/segmented-control-root.d.ts +25 -0
- package/dist/components/segmented-control/segmented-control-root.js +112 -0
- package/dist/components/segmented-control/segmented-control-separator.d.ts +19 -0
- package/dist/components/segmented-control/segmented-control-separator.js +18 -0
- package/dist/components/segmented-control/segmented-control.context.d.ts +17 -0
- package/dist/components/segmented-control/segmented-control.context.js +12 -0
- package/dist/components/segmented-control/segmented-control.types.d.ts +67 -0
- package/dist/components/select/index.d.ts +3 -0
- package/dist/components/select/select-hidden-select.js +1 -1
- package/dist/components/select/select-root.js +2 -0
- package/dist/components/select/select.types.d.ts +2 -0
- package/dist/components/sidebar/index.d.ts +546 -0
- package/dist/components/sidebar/index.js +47 -0
- package/dist/components/sidebar/sidebar-collapsible-trigger.d.ts +21 -0
- package/dist/components/sidebar/sidebar-collapsible-trigger.js +70 -0
- package/dist/components/sidebar/sidebar-collapsible.d.ts +24 -0
- package/dist/components/sidebar/sidebar-collapsible.js +78 -0
- package/dist/components/sidebar/sidebar-content.d.ts +21 -0
- package/dist/components/sidebar/sidebar-content.js +37 -0
- package/dist/components/sidebar/sidebar-footer.d.ts +21 -0
- package/dist/components/sidebar/sidebar-footer.js +24 -0
- package/dist/components/sidebar/sidebar-group-label.d.ts +21 -0
- package/dist/components/sidebar/sidebar-group-label.js +32 -0
- package/dist/components/sidebar/sidebar-group.d.ts +21 -0
- package/dist/components/sidebar/sidebar-group.js +48 -0
- package/dist/components/sidebar/sidebar-header.d.ts +21 -0
- package/dist/components/sidebar/sidebar-header.js +24 -0
- package/dist/components/sidebar/sidebar-inset.d.ts +21 -0
- package/dist/components/sidebar/sidebar-inset.js +24 -0
- package/dist/components/sidebar/sidebar-item-icon.d.ts +21 -0
- package/dist/components/sidebar/sidebar-item-icon.js +20 -0
- package/dist/components/sidebar/sidebar-item-indicator.d.ts +21 -0
- package/dist/components/sidebar/sidebar-item-indicator.js +48 -0
- package/dist/components/sidebar/sidebar-item-label.d.ts +21 -0
- package/dist/components/sidebar/sidebar-item-label.js +28 -0
- package/dist/components/sidebar/sidebar-item-tooltip.d.ts +21 -0
- package/dist/components/sidebar/sidebar-item-tooltip.js +38 -0
- package/dist/components/sidebar/sidebar-item-trailing.d.ts +21 -0
- package/dist/components/sidebar/sidebar-item-trailing.js +28 -0
- package/dist/components/sidebar/sidebar-item.d.ts +23 -0
- package/dist/components/sidebar/sidebar-item.js +160 -0
- package/dist/components/sidebar/sidebar-panel.d.ts +21 -0
- package/dist/components/sidebar/sidebar-panel.js +88 -0
- package/dist/components/sidebar/sidebar-rail.d.ts +21 -0
- package/dist/components/sidebar/sidebar-rail.js +210 -0
- package/dist/components/sidebar/sidebar-root.d.ts +31 -0
- package/dist/components/sidebar/sidebar-root.js +140 -0
- package/dist/components/sidebar/sidebar-separator.d.ts +19 -0
- package/dist/components/sidebar/sidebar-separator.js +16 -0
- package/dist/components/sidebar/sidebar-sub-menu.d.ts +23 -0
- package/dist/components/sidebar/sidebar-sub-menu.js +40 -0
- package/dist/components/sidebar/sidebar-trigger.d.ts +21 -0
- package/dist/components/sidebar/sidebar-trigger.js +69 -0
- package/dist/components/sidebar/sidebar.context.d.ts +75 -0
- package/dist/components/sidebar/sidebar.context.js +30 -0
- package/dist/components/sidebar/sidebar.state.d.ts +73 -0
- package/dist/components/sidebar/sidebar.state.js +76 -0
- package/dist/components/sidebar/sidebar.storage.d.ts +8 -0
- package/dist/components/sidebar/sidebar.storage.js +45 -0
- package/dist/components/sidebar/sidebar.types.d.ts +273 -0
- package/dist/components/splitter/index.d.ts +143 -0
- package/dist/components/splitter/index.js +13 -0
- package/dist/components/splitter/splitter-handle.d.ts +21 -0
- package/dist/components/splitter/splitter-handle.js +209 -0
- package/dist/components/splitter/splitter-panel.d.ts +21 -0
- package/dist/components/splitter/splitter-panel.js +70 -0
- package/dist/components/splitter/splitter-root.d.ts +31 -0
- package/dist/components/splitter/splitter-root.js +152 -0
- package/dist/components/splitter/splitter.context.d.ts +15 -0
- package/dist/components/splitter/splitter.context.js +5 -0
- package/dist/components/splitter/splitter.state.d.ts +87 -0
- package/dist/components/splitter/splitter.state.js +322 -0
- package/dist/components/splitter/splitter.storage.d.ts +15 -0
- package/dist/components/splitter/splitter.storage.js +56 -0
- package/dist/components/splitter/splitter.types.d.ts +98 -0
- package/dist/components/switch/switch-content.js +1 -1
- package/dist/components/table/index.d.ts +10 -9
- package/dist/components/table/table-body.js +13 -13
- package/dist/components/table/table-cell.js +49 -46
- package/dist/components/table/table-column-resizer.js +1 -1
- package/dist/components/table/table-column.js +1 -1
- package/dist/components/table/table-content.js +37 -18
- package/dist/{composables → components/table}/table-drag-collection.d.ts +1 -1
- package/dist/{composables → components/table}/table-drag-collection.js +1 -1
- package/dist/components/table/table-drop-indicator.js +3 -1
- package/dist/components/table/table-resizable-container.d.ts +4 -5
- package/dist/components/table/table-row.js +45 -14
- package/dist/components/table/table-virtualizer-item.d.ts +2 -7
- package/dist/components/table/table-virtualizer-item.js +20 -9
- package/dist/components/table/table.context.d.ts +11 -3
- package/dist/components/table/table.types.d.ts +1 -1
- package/dist/{composables → components/table}/use-grid-keyboard.d.ts +3 -3
- package/dist/{composables → components/table}/use-grid-keyboard.js +57 -55
- package/dist/{composables → components/table}/use-grid-selection-announcement.d.ts +2 -2
- package/dist/{composables → components/table}/use-grid-selection-announcement.js +2 -2
- package/dist/{composables → components/table}/use-table-collection.d.ts +2 -2
- package/dist/{composables → components/table}/use-table-collection.js +4 -4
- package/dist/{composables → components/table}/use-table-column-layout.d.ts +13 -20
- package/dist/components/table/use-table-column-layout.js +115 -0
- package/dist/components/textarea/index.d.ts +2 -0
- package/dist/components/textarea/textarea-root.js +3 -0
- package/dist/components/textarea/textarea.types.d.ts +5 -0
- package/dist/components/textfield/index.d.ts +2 -0
- package/dist/components/textfield/textfield-root.js +5 -1
- package/dist/components/textfield/textfield.context.d.ts +2 -0
- package/dist/components/textfield/textfield.types.d.ts +5 -0
- package/dist/components/time-field/index.d.ts +1 -0
- package/dist/components/toast/index.d.ts +1 -0
- package/dist/components/toast/toast-default-content.js +1 -1
- package/dist/components/toolbar/index.d.ts +3 -2
- package/dist/components/tooltip/index.js +1 -1
- package/dist/components/tooltip/tooltip-root.js +1 -1
- package/dist/components/virtualizer/index.d.ts +3 -1
- package/dist/components/virtualizer/index.js +2 -1
- package/dist/components/virtualizer/use-virtualizer-item.d.ts +23 -0
- package/dist/components/virtualizer/use-virtualizer-item.js +45 -0
- package/dist/components/virtualizer/virtualizer-item.js +7 -41
- package/dist/components/virtualizer/virtualizer-scrollbar-track.d.ts +20 -0
- package/dist/components/virtualizer/virtualizer-scrollbar-track.js +141 -0
- package/dist/components/virtualizer/virtualizer-scrollbar.d.ts +18 -0
- package/dist/components/virtualizer/virtualizer-scrollbar.js +55 -0
- package/dist/components/virtualizer/virtualizer.context.d.ts +17 -1
- package/dist/composables/drag-manager.js +1 -13
- package/dist/composables/index.d.ts +3 -70
- package/dist/composables/use-collection.d.ts +22 -3
- package/dist/composables/use-collection.js +67 -14
- package/dist/composables/use-color-area.js +2 -2
- package/dist/composables/use-color-field.js +1 -1
- package/dist/composables/use-combo-box.js +1 -1
- package/dist/composables/use-date-field.js +1 -1
- package/dist/composables/use-drag.d.ts +6 -5
- package/dist/composables/use-draggable-item.d.ts +2 -2
- package/dist/composables/use-droppable-collection.js +3 -3
- package/dist/composables/use-droppable-item.js +1 -1
- package/dist/composables/use-form-reset.d.ts +6 -2
- package/dist/composables/use-form-reset.js +9 -5
- package/dist/composables/use-list-keyboard.js +64 -62
- package/dist/composables/use-number-field.js +1 -1
- package/dist/composables/use-select.js +2 -2
- package/dist/composables/use-selection-manager.js +4 -4
- package/dist/composables/use-single-select-list-state.d.ts +37 -0
- package/dist/composables/use-single-select-list-state.js +110 -0
- package/dist/composables/use-slider-thumb.js +2 -2
- package/dist/composables/use-slider.js +1 -1
- package/dist/composables/use-tab-list-state.d.ts +10 -29
- package/dist/composables/use-tab-list-state.js +10 -99
- package/dist/composables/use-text-field.js +1 -1
- package/dist/composables/use-virtualizer-scroll.d.ts +52 -2
- package/dist/composables/use-virtualizer-scroll.js +79 -13
- package/dist/composables/use-virtualizer.d.ts +24 -4
- package/dist/composables/use-virtualizer.js +40 -6
- package/dist/index.js +60 -83
- package/dist/utils/document-order.d.ts +14 -0
- package/dist/utils/document-order.js +17 -0
- package/dist/utils/flex-sizing.d.ts +41 -0
- package/dist/utils/flex-sizing.js +140 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/open-link.d.ts +31 -0
- package/dist/utils/open-link.js +32 -0
- package/dist/utils/story-truncation.d.ts +20 -0
- package/dist/utils/story-users.d.ts +11 -0
- package/dist/utils/virtualizer-collection.d.ts +14 -4
- package/dist/utils/virtualizer-collection.js +9 -14
- package/dist/utils/virtualizer-layout-info.js +3 -2
- package/dist/utils/virtualizer-list-layout.d.ts +75 -29
- package/dist/utils/virtualizer-list-layout.js +182 -99
- package/dist/utils/virtualizer-offsets.d.ts +111 -0
- package/dist/utils/virtualizer-offsets.js +159 -0
- package/dist/utils/virtualizer-overscan.d.ts +9 -15
- package/dist/utils/virtualizer-overscan.js +14 -33
- package/dist/utils/virtualizer-table-layout.d.ts +50 -21
- package/dist/utils/virtualizer-table-layout.js +130 -89
- package/dist/version.js +1 -1
- package/package.json +25 -5
- package/dist/composables/use-table-column-layout.js +0 -214
- /package/dist/{composables → components/dropdown}/use-safely-mouse-to-submenu.d.ts +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** A size: pixels as a number or a `px` string, a percentage of the container, or a fraction of what is left. */
|
|
2
|
+
export type FlexSize = number | string;
|
|
3
|
+
export interface FlexSizeDefinition {
|
|
4
|
+
/** A size the caller controls. Set, it outranks everything below it. */
|
|
5
|
+
size?: FlexSize | null;
|
|
6
|
+
/** The size the item starts at, when the caller is not controlling it. */
|
|
7
|
+
defaultSize?: FlexSize | null;
|
|
8
|
+
minSize?: FlexSize | null;
|
|
9
|
+
maxSize?: FlexSize | null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Pixels and percentages are fixed; `fr` units and anything unrecognised flex.
|
|
13
|
+
*
|
|
14
|
+
* A bare number, a `px` string and a numeric string all count as pixels. Accepting the string
|
|
15
|
+
* forms is not cosmetic: a template attribute is always a string, so `size="240px"` is the only
|
|
16
|
+
* way most callers can express a pixel size at all.
|
|
17
|
+
*/
|
|
18
|
+
export declare const isStaticSize: (size?: FlexSize | null) => boolean;
|
|
19
|
+
/** The number in front of `fr`. Anything else counts as `1fr`, as React Aria has it. */
|
|
20
|
+
export declare const parseFractionalUnit: (size?: FlexSize | null) => number;
|
|
21
|
+
export declare const parseStaticSize: (size: FlexSize, availableSize: number) => number;
|
|
22
|
+
export declare const getMaxSize: (maxSize: FlexSize | null | undefined, availableSize: number) => number;
|
|
23
|
+
/**
|
|
24
|
+
* A minimum cannot be given in `fr`: knowing what a fraction comes to would need every other
|
|
25
|
+
* item's size, which is the very thing being solved for.
|
|
26
|
+
*/
|
|
27
|
+
export declare const getMinSize: (minSize: FlexSize | null | undefined, availableSize: number) => number;
|
|
28
|
+
/**
|
|
29
|
+
* Sizes for one container size, ported from react-stately's `calculateColumnSizes`.
|
|
30
|
+
*
|
|
31
|
+
* This is the CSS flexbox layout algorithm, cut down to the shape a single track needs: one line,
|
|
32
|
+
* a flex basis of zero unless the item asked for a static size, and grow and shrink both equal to
|
|
33
|
+
* the item's `fr`. It is deliberately **not** plain pixel sizing — `1fr` items have to share what
|
|
34
|
+
* the static and percentage items leave over, and a minimum or maximum on any one of them
|
|
35
|
+
* redistributes the rest.
|
|
36
|
+
*
|
|
37
|
+
* Keyless on purpose: a caller with overriding sizes of its own resolves them into `size` before
|
|
38
|
+
* calling, which is the same precedence a lookup here would have given and leaves the solver with
|
|
39
|
+
* nothing to know about how the caller identifies its items.
|
|
40
|
+
*/
|
|
41
|
+
export declare const calculateFlexSizes: (availableSize: number, definitions: FlexSizeDefinition[], getDefaultSize?: (index: number) => FlexSize | null | undefined, getDefaultMinSize?: (index: number) => FlexSize | null | undefined) => number[];
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
//#region src/utils/flex-sizing.ts
|
|
2
|
+
var PIXELS = /^(-?\d*\.?\d+)px$/;
|
|
3
|
+
var PERCENT = /^(-?\d*\.?\d+)%$/;
|
|
4
|
+
var NUMBER = /^-?\d*\.?\d+$/;
|
|
5
|
+
var FRACTION = /^(-?\d*\.?\d+)fr$/;
|
|
6
|
+
/**
|
|
7
|
+
* Pixels and percentages are fixed; `fr` units and anything unrecognised flex.
|
|
8
|
+
*
|
|
9
|
+
* A bare number, a `px` string and a numeric string all count as pixels. Accepting the string
|
|
10
|
+
* forms is not cosmetic: a template attribute is always a string, so `size="240px"` is the only
|
|
11
|
+
* way most callers can express a pixel size at all.
|
|
12
|
+
*/
|
|
13
|
+
var isStaticSize = (size) => {
|
|
14
|
+
if (size == null) return false;
|
|
15
|
+
if (typeof size === "number") return !isNaN(size);
|
|
16
|
+
return PIXELS.test(size) || PERCENT.test(size) || NUMBER.test(size);
|
|
17
|
+
};
|
|
18
|
+
/** The number in front of `fr`. Anything else counts as `1fr`, as React Aria has it. */
|
|
19
|
+
var parseFractionalUnit = (size) => {
|
|
20
|
+
if (!size || typeof size === "number") return 1;
|
|
21
|
+
const match = FRACTION.exec(size);
|
|
22
|
+
return match ? parseFloat(match[1]) : 1;
|
|
23
|
+
};
|
|
24
|
+
var parseStaticSize = (size, availableSize) => {
|
|
25
|
+
if (typeof size === "number") return size;
|
|
26
|
+
const percent = PERCENT.exec(size);
|
|
27
|
+
if (percent) return availableSize * (parseFloat(percent[1]) / 100);
|
|
28
|
+
const pixels = PIXELS.exec(size);
|
|
29
|
+
if (pixels) return parseFloat(pixels[1]);
|
|
30
|
+
if (NUMBER.test(size)) return parseFloat(size);
|
|
31
|
+
throw new Error("Only percentages or numbers are supported for static sizes");
|
|
32
|
+
};
|
|
33
|
+
var getMaxSize = (maxSize, availableSize) => maxSize != null ? parseStaticSize(maxSize, availableSize) : Number.MAX_SAFE_INTEGER;
|
|
34
|
+
/**
|
|
35
|
+
* A minimum cannot be given in `fr`: knowing what a fraction comes to would need every other
|
|
36
|
+
* item's size, which is the very thing being solved for.
|
|
37
|
+
*/
|
|
38
|
+
var getMinSize = (minSize, availableSize) => minSize != null ? parseStaticSize(minSize, availableSize) : 0;
|
|
39
|
+
/**
|
|
40
|
+
* Round an array of floats that sums to an integer, keeping the sum.
|
|
41
|
+
*
|
|
42
|
+
* Each item has to come out a whole number of pixels, and rounding them one by one would drift:
|
|
43
|
+
* the remainder is carried forward instead, so the total is preserved.
|
|
44
|
+
*/
|
|
45
|
+
var cascadeRounding = (items) => {
|
|
46
|
+
let floatTotal = 0;
|
|
47
|
+
let intTotal = 0;
|
|
48
|
+
return items.map((item) => {
|
|
49
|
+
const rounded = Math.round(item.targetMainSize + floatTotal) - intTotal;
|
|
50
|
+
floatTotal += item.targetMainSize;
|
|
51
|
+
intTotal += rounded;
|
|
52
|
+
return rounded;
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Sizes for one container size, ported from react-stately's `calculateColumnSizes`.
|
|
57
|
+
*
|
|
58
|
+
* This is the CSS flexbox layout algorithm, cut down to the shape a single track needs: one line,
|
|
59
|
+
* a flex basis of zero unless the item asked for a static size, and grow and shrink both equal to
|
|
60
|
+
* the item's `fr`. It is deliberately **not** plain pixel sizing — `1fr` items have to share what
|
|
61
|
+
* the static and percentage items leave over, and a minimum or maximum on any one of them
|
|
62
|
+
* redistributes the rest.
|
|
63
|
+
*
|
|
64
|
+
* Keyless on purpose: a caller with overriding sizes of its own resolves them into `size` before
|
|
65
|
+
* calling, which is the same precedence a lookup here would have given and leaves the solver with
|
|
66
|
+
* nothing to know about how the caller identifies its items.
|
|
67
|
+
*/
|
|
68
|
+
var calculateFlexSizes = (availableSize, definitions, getDefaultSize, getDefaultMinSize) => {
|
|
69
|
+
const originalSize = availableSize;
|
|
70
|
+
const flooredSize = Math.floor(availableSize);
|
|
71
|
+
const hasFractionalSize = availableSize - flooredSize > 0;
|
|
72
|
+
availableSize = flooredSize;
|
|
73
|
+
let hasNonFrozenItems = false;
|
|
74
|
+
const items = definitions.map((definition, index) => {
|
|
75
|
+
const size = definition.size ?? definition.defaultSize ?? getDefaultSize?.(index) ?? "1fr";
|
|
76
|
+
let frozen = false;
|
|
77
|
+
let baseSize = 0;
|
|
78
|
+
let flex = 0;
|
|
79
|
+
let targetMainSize = 0;
|
|
80
|
+
if (isStaticSize(size)) {
|
|
81
|
+
baseSize = parseStaticSize(size, availableSize);
|
|
82
|
+
frozen = true;
|
|
83
|
+
} else {
|
|
84
|
+
flex = parseFractionalUnit(size);
|
|
85
|
+
if (flex <= 0) frozen = true;
|
|
86
|
+
}
|
|
87
|
+
const min = getMinSize(definition.minSize ?? getDefaultMinSize?.(index) ?? 0, availableSize);
|
|
88
|
+
const max = getMaxSize(definition.maxSize, availableSize);
|
|
89
|
+
const hypotheticalMainSize = Math.max(min, Math.min(baseSize, max));
|
|
90
|
+
if (frozen) targetMainSize = hypotheticalMainSize;
|
|
91
|
+
else if (baseSize > hypotheticalMainSize) {
|
|
92
|
+
frozen = true;
|
|
93
|
+
targetMainSize = hypotheticalMainSize;
|
|
94
|
+
}
|
|
95
|
+
if (!frozen) hasNonFrozenItems = true;
|
|
96
|
+
return {
|
|
97
|
+
baseSize,
|
|
98
|
+
flex,
|
|
99
|
+
frozen,
|
|
100
|
+
hypotheticalMainSize,
|
|
101
|
+
max,
|
|
102
|
+
min,
|
|
103
|
+
targetMainSize,
|
|
104
|
+
violation: 0
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
while (hasNonFrozenItems) {
|
|
108
|
+
let usedSize = 0;
|
|
109
|
+
let flexFactors = 0;
|
|
110
|
+
for (const item of items) if (item.frozen) usedSize += item.targetMainSize;
|
|
111
|
+
else {
|
|
112
|
+
usedSize += item.baseSize;
|
|
113
|
+
flexFactors += item.flex;
|
|
114
|
+
}
|
|
115
|
+
const remainingFreeSpace = availableSize - usedSize;
|
|
116
|
+
if (remainingFreeSpace > 0) {
|
|
117
|
+
for (const item of items) if (!item.frozen) item.targetMainSize = item.baseSize + item.flex / flexFactors * remainingFreeSpace;
|
|
118
|
+
}
|
|
119
|
+
let totalViolation = 0;
|
|
120
|
+
for (const item of items) {
|
|
121
|
+
item.violation = 0;
|
|
122
|
+
if (item.frozen) continue;
|
|
123
|
+
const unclamped = item.targetMainSize;
|
|
124
|
+
item.targetMainSize = Math.max(item.min, Math.min(unclamped, item.max));
|
|
125
|
+
item.violation = item.targetMainSize - unclamped;
|
|
126
|
+
totalViolation += item.violation;
|
|
127
|
+
}
|
|
128
|
+
hasNonFrozenItems = false;
|
|
129
|
+
for (const item of items) if (totalViolation === 0 || Math.sign(totalViolation) === Math.sign(item.violation)) item.frozen = true;
|
|
130
|
+
else if (!item.frozen) hasNonFrozenItems = true;
|
|
131
|
+
}
|
|
132
|
+
const sizes = cascadeRounding(items);
|
|
133
|
+
if (hasFractionalSize && sizes.length > 0) {
|
|
134
|
+
const fraction = originalSize.toString().split(".")[1];
|
|
135
|
+
sizes[sizes.length - 1] = Number(`${sizes.at(-1)}.${fraction}`);
|
|
136
|
+
}
|
|
137
|
+
return sizes;
|
|
138
|
+
};
|
|
139
|
+
//#endregion
|
|
140
|
+
export { calculateFlexSizes, getMaxSize, getMinSize, isStaticSize, parseFractionalUnit, parseStaticSize };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export * from "./form-value.js";
|
|
|
22
22
|
export * from "./incomplete-date.js";
|
|
23
23
|
export * from "./locale.js";
|
|
24
24
|
export * from "./number.js";
|
|
25
|
+
export * from "./open-link.js";
|
|
25
26
|
export * from "./platform.js";
|
|
26
27
|
export * from "./position.js";
|
|
27
28
|
export * from "./text-value.js";
|
|
@@ -30,6 +31,7 @@ export * from "./virtualizer-geometry.js";
|
|
|
30
31
|
export * from "./virtualizer-layout.js";
|
|
31
32
|
export * from "./virtualizer-layout-info.js";
|
|
32
33
|
export * from "./virtualizer-list-layout.js";
|
|
34
|
+
export * from "./virtualizer-offsets.js";
|
|
33
35
|
export * from "./virtualizer-overscan.js";
|
|
34
36
|
export * from "./virtualizer-table-layout.js";
|
|
35
37
|
export * from "./visually-hidden.js";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { RouterContext } from "../components/router-provider/router-provider.context.js";
|
|
2
|
+
/** The modifier keys a click carries, which is all `shouldClientNavigate` reads off the event. */
|
|
3
|
+
export interface OpenLinkModifiers {
|
|
4
|
+
altKey: boolean;
|
|
5
|
+
ctrlKey: boolean;
|
|
6
|
+
metaKey: boolean;
|
|
7
|
+
shiftKey: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface OpenLinkOptions {
|
|
10
|
+
/** The href as the link declared it, before `resolveHref` rewrote it for the DOM. */
|
|
11
|
+
href?: string;
|
|
12
|
+
router: RouterContext | null;
|
|
13
|
+
/** Passed straight through to `navigate`, for whatever the application's router accepts. */
|
|
14
|
+
routerOptions?: unknown;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Whether the application's router should take this activation rather than the browser.
|
|
18
|
+
*
|
|
19
|
+
* Ported from React Aria's `shouldClientNavigate`. Every case below asks the browser for
|
|
20
|
+
* something a client-side router cannot do, so letting the event through is the whole point.
|
|
21
|
+
*/
|
|
22
|
+
export declare const shouldClientNavigate: (link: HTMLAnchorElement, modifiers: OpenLinkModifiers) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Give a click on an anchor to the application's router, when it is a click the router can serve.
|
|
25
|
+
*
|
|
26
|
+
* Called after the press machinery, from a link's own click handler. Every activation path
|
|
27
|
+
* converges there: a pointer press completes on the click, Enter on an anchor produces a native
|
|
28
|
+
* click because `usePress` carves anchors out of its keyboard default handling, and a screen
|
|
29
|
+
* reader arrives as a virtual click.
|
|
30
|
+
*/
|
|
31
|
+
export declare const openLink: (event: MouseEvent, options: OpenLinkOptions) => void;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/utils/open-link.ts
|
|
2
|
+
/**
|
|
3
|
+
* Whether the application's router should take this activation rather than the browser.
|
|
4
|
+
*
|
|
5
|
+
* Ported from React Aria's `shouldClientNavigate`. Every case below asks the browser for
|
|
6
|
+
* something a client-side router cannot do, so letting the event through is the whole point.
|
|
7
|
+
*/
|
|
8
|
+
var shouldClientNavigate = (link, modifiers) => {
|
|
9
|
+
const target = link.getAttribute("target");
|
|
10
|
+
return (!target || target === "_self") && link.origin === window.location.origin && !link.hasAttribute("download") && !modifiers.metaKey && !modifiers.ctrlKey && !modifiers.altKey && !modifiers.shiftKey;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Give a click on an anchor to the application's router, when it is a click the router can serve.
|
|
14
|
+
*
|
|
15
|
+
* Called after the press machinery, from a link's own click handler. Every activation path
|
|
16
|
+
* converges there: a pointer press completes on the click, Enter on an anchor produces a native
|
|
17
|
+
* click because `usePress` carves anchors out of its keyboard default handling, and a screen
|
|
18
|
+
* reader arrives as a virtual click.
|
|
19
|
+
*/
|
|
20
|
+
var openLink = (event, options) => {
|
|
21
|
+
const { href, router, routerOptions } = options;
|
|
22
|
+
if (!router || !href) return;
|
|
23
|
+
if (event.defaultPrevented) return;
|
|
24
|
+
if (event.button !== 0) return;
|
|
25
|
+
const link = event.currentTarget;
|
|
26
|
+
if (!(link instanceof HTMLAnchorElement)) return;
|
|
27
|
+
if (!shouldClientNavigate(link, event)) return;
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
router.navigate(href, routerOptions);
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { openLink, shouldClientNavigate };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CollectionKey } from "../composables/use-collection.js";
|
|
2
|
+
/**
|
|
3
|
+
* Which of a collection's labels are clipped, for the stories that pair truncation with a tooltip.
|
|
4
|
+
*
|
|
5
|
+
* A tooltip on every option is noise: the ones that fit already say everything they have to say, and
|
|
6
|
+
* a tooltip repeating a label the user can read is one more thing moving under the pointer. So the
|
|
7
|
+
* label reports whether it is actually clipped, and only those get one.
|
|
8
|
+
*
|
|
9
|
+
* `scrollWidth > clientWidth` is the only reliable read of that — CSS truncates without telling
|
|
10
|
+
* anyone, and the width a label wants depends on the font, the container and the text at once, none
|
|
11
|
+
* of which a story can know in advance. A `ResizeObserver` keeps the answer current: the popover is
|
|
12
|
+
* measured the moment it opens, and again whenever it is resized under a label that then fits, or
|
|
13
|
+
* stops fitting.
|
|
14
|
+
*
|
|
15
|
+
* Story-only, so it is deliberately not re-exported from `utils/index.ts`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const useClippedLabels: () => {
|
|
18
|
+
clipped: import("vue").ShallowRef<ReadonlySet<CollectionKey>, ReadonlySet<CollectionKey>>;
|
|
19
|
+
measure: (key: CollectionKey, element: unknown) => void;
|
|
20
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Story-only, like the rest of the `story-*` helpers, so deliberately not re-exported. */
|
|
2
|
+
export interface User {
|
|
3
|
+
id: number;
|
|
4
|
+
image_url: string;
|
|
5
|
+
name: string;
|
|
6
|
+
role: string;
|
|
7
|
+
status: "Active" | "Inactive" | "On Leave";
|
|
8
|
+
email: string;
|
|
9
|
+
}
|
|
10
|
+
/** The same rows in the same order as the React story, so the two can be compared row by row. */
|
|
11
|
+
export declare const generateUsers: (count: number) => User[];
|
|
@@ -34,7 +34,12 @@ export interface VirtualizerTableCollection extends VirtualizerCollection {
|
|
|
34
34
|
loaderKey: VirtualizerKey | null;
|
|
35
35
|
/** The columns, in order. A cell's position among them is what pairs it with a width. */
|
|
36
36
|
columnKeys: VirtualizerKey[];
|
|
37
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* The key of the cell where a row and a column meet.
|
|
39
|
+
*
|
|
40
|
+
* A cell is not a node of this collection — this is what stands in for one, so the layout can
|
|
41
|
+
* name a cell it is about to place and a rendered cell can look its own geometry back up.
|
|
42
|
+
*/
|
|
38
43
|
cellKey: (rowKey: VirtualizerKey, columnKey: VirtualizerKey) => VirtualizerKey;
|
|
39
44
|
/**
|
|
40
45
|
* The same nodes seen as a flat list of rows.
|
|
@@ -65,12 +70,17 @@ export interface CreateTableCollectionOptions<T> {
|
|
|
65
70
|
}
|
|
66
71
|
/**
|
|
67
72
|
* The two-dimensional collection a table layout walks: a header holding one row of columns, and a
|
|
68
|
-
* body holding a row per item
|
|
73
|
+
* body holding a row per item.
|
|
69
74
|
*
|
|
70
75
|
* React Aria gets this shape from its hidden render pass, where every cell a row rendered is a
|
|
71
76
|
* node of the collection. There is no such pass here, so the cells are **derived**: a virtualized
|
|
72
|
-
* table renders one cell per column, so the cell where row `r` meets column `c` is known
|
|
73
|
-
* anyone having rendered it. That is what lets
|
|
77
|
+
* table renders one cell per column, so the cell where row `r` meets column `c` is known from
|
|
78
|
+
* {@link VirtualizerTableCollection.cellKey} without anyone having rendered it. That is what lets
|
|
79
|
+
* the layout place a row that is nowhere in the DOM.
|
|
80
|
+
*
|
|
81
|
+
* Nothing here holds a cell, and deliberately: a cell per column per row is the one count that
|
|
82
|
+
* grows with the data rather than with the window, and it would be paid in full before the first
|
|
83
|
+
* paint. The layout builds the cells of the rows it places, and drops them with those rows.
|
|
74
84
|
*
|
|
75
85
|
* Consequently a `colSpan` is not expressible — every cell is exactly one column wide.
|
|
76
86
|
*/
|
|
@@ -36,12 +36,17 @@ var createListCollection = (options) => {
|
|
|
36
36
|
};
|
|
37
37
|
/**
|
|
38
38
|
* The two-dimensional collection a table layout walks: a header holding one row of columns, and a
|
|
39
|
-
* body holding a row per item
|
|
39
|
+
* body holding a row per item.
|
|
40
40
|
*
|
|
41
41
|
* React Aria gets this shape from its hidden render pass, where every cell a row rendered is a
|
|
42
42
|
* node of the collection. There is no such pass here, so the cells are **derived**: a virtualized
|
|
43
|
-
* table renders one cell per column, so the cell where row `r` meets column `c` is known
|
|
44
|
-
* anyone having rendered it. That is what lets
|
|
43
|
+
* table renders one cell per column, so the cell where row `r` meets column `c` is known from
|
|
44
|
+
* {@link VirtualizerTableCollection.cellKey} without anyone having rendered it. That is what lets
|
|
45
|
+
* the layout place a row that is nowhere in the DOM.
|
|
46
|
+
*
|
|
47
|
+
* Nothing here holds a cell, and deliberately: a cell per column per row is the one count that
|
|
48
|
+
* grows with the data rather than with the window, and it would be paid in full before the first
|
|
49
|
+
* paint. The layout builds the cells of the rows it places, and drops them with those rows.
|
|
45
50
|
*
|
|
46
51
|
* Consequently a `colSpan` is not expressible — every cell is exactly one column wide.
|
|
47
52
|
*/
|
|
@@ -93,11 +98,10 @@ var createTableCollection = (options) => {
|
|
|
93
98
|
});
|
|
94
99
|
items.forEach((item, index) => {
|
|
95
100
|
const rowKey = getKey(item, index);
|
|
96
|
-
const cellKeys = columnKeys.map((columnKey) => cellKey(rowKey, columnKey));
|
|
97
101
|
rowKeys.push(rowKey);
|
|
98
102
|
bodyChildKeys.push(rowKey);
|
|
99
103
|
add({
|
|
100
|
-
childKeys:
|
|
104
|
+
childKeys: [],
|
|
101
105
|
content: item,
|
|
102
106
|
index,
|
|
103
107
|
isDisabled: isDisabled?.(item) ?? false,
|
|
@@ -106,15 +110,6 @@ var createTableCollection = (options) => {
|
|
|
106
110
|
textValue: getTextValue?.(item),
|
|
107
111
|
type: "row"
|
|
108
112
|
});
|
|
109
|
-
cellKeys.forEach((key, columnIndex) => {
|
|
110
|
-
add({
|
|
111
|
-
childKeys: [],
|
|
112
|
-
index: columnIndex,
|
|
113
|
-
key,
|
|
114
|
-
parentKey: rowKey,
|
|
115
|
-
type: "cell"
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
113
|
});
|
|
119
114
|
if (loaderKey != null) {
|
|
120
115
|
bodyChildKeys.push(loaderKey);
|
|
@@ -68,10 +68,11 @@ var px = (value) => Number.isFinite(value) ? `${value}px` : void 0;
|
|
|
68
68
|
*/
|
|
69
69
|
var layoutInfoToStyle = (layoutInfo, parent) => {
|
|
70
70
|
const offsetParent = Boolean(parent && !(parent.allowOverflow && layoutInfo.isSticky)) ? parent : null;
|
|
71
|
+
const isEstimated = layoutInfo.estimatedSize;
|
|
71
72
|
return {
|
|
72
|
-
contain: "size layout style",
|
|
73
|
+
contain: isEstimated ? "layout style" : "size layout style",
|
|
73
74
|
display: layoutInfo.isSticky ? "inline-block" : void 0,
|
|
74
|
-
height: px(layoutInfo.rect.height),
|
|
75
|
+
height: isEstimated ? "auto" : px(layoutInfo.rect.height),
|
|
75
76
|
left: px(layoutInfo.rect.x - (offsetParent?.rect.x ?? 0)),
|
|
76
77
|
opacity: layoutInfo.opacity,
|
|
77
78
|
overflow: layoutInfo.allowOverflow ? "visible" : "hidden",
|
|
@@ -4,6 +4,7 @@ import type { VirtualizerKey } from "./virtualizer-layout-info.js";
|
|
|
4
4
|
import { Rect, Size } from "./virtualizer-geometry.js";
|
|
5
5
|
import { Layout } from "./virtualizer-layout.js";
|
|
6
6
|
import { LayoutInfo } from "./virtualizer-layout-info.js";
|
|
7
|
+
import { RowOffsets } from "./virtualizer-offsets.js";
|
|
7
8
|
export interface ListLayoutOptions {
|
|
8
9
|
/** The fixed size of a row, in px. */
|
|
9
10
|
rowSize?: number;
|
|
@@ -21,23 +22,11 @@ export interface ListLayoutOptions {
|
|
|
21
22
|
padding?: number;
|
|
22
23
|
/** How thick the line marking a gap between two items is, in px. @default 2 */
|
|
23
24
|
dropIndicatorThickness?: number;
|
|
24
|
-
/** @deprecated Use `rowSize`. Accepted because React Aria still does. */
|
|
25
|
-
rowHeight?: number;
|
|
26
|
-
/** @deprecated Use `estimatedRowSize`. */
|
|
27
|
-
estimatedRowHeight?: number;
|
|
28
|
-
/** @deprecated Use `headingSize`. */
|
|
29
|
-
headingHeight?: number;
|
|
30
|
-
/** @deprecated Use `estimatedHeadingSize`. */
|
|
31
|
-
estimatedHeadingHeight?: number;
|
|
32
|
-
/** @deprecated Use `loaderSize`. */
|
|
33
|
-
loaderHeight?: number;
|
|
34
25
|
}
|
|
35
26
|
/** A layout info plus the hierarchy around it, which a table needs and a list does not. */
|
|
36
27
|
export interface LayoutNode {
|
|
37
28
|
layoutInfo: LayoutInfo;
|
|
38
29
|
children: LayoutNode[];
|
|
39
|
-
/** The part of the layout info that has been computed against real data. */
|
|
40
|
-
validRect: Rect;
|
|
41
30
|
node?: VirtualizerNode;
|
|
42
31
|
index?: number;
|
|
43
32
|
}
|
|
@@ -53,21 +42,27 @@ export declare class ListLayout<Options extends ListLayoutOptions = ListLayoutOp
|
|
|
53
42
|
protected layoutNodes: Map<VirtualizerKey, LayoutNode>;
|
|
54
43
|
protected rootNodes: LayoutNode[];
|
|
55
44
|
protected contentSize: Size;
|
|
56
|
-
/**
|
|
57
|
-
protected
|
|
58
|
-
/** The
|
|
59
|
-
protected
|
|
45
|
+
/** Where every root sits, whether or not it has ever been built. */
|
|
46
|
+
protected offsets: RowOffsets;
|
|
47
|
+
/** The window the rendered set was built for, in content coordinates. */
|
|
48
|
+
protected window: Rect;
|
|
60
49
|
protected lastCollection: VirtualizerCollection | null;
|
|
61
50
|
private invalidateEverything;
|
|
62
51
|
constructor(options?: ListLayoutOptions);
|
|
63
52
|
getContentSize(): Size;
|
|
64
53
|
getLayoutInfo(key: VirtualizerKey): LayoutInfo | null;
|
|
54
|
+
/** Where every root sits, for a caller that needs an offset rather than a rendered node. */
|
|
55
|
+
getRowOffsets(): RowOffsets;
|
|
65
56
|
/**
|
|
66
57
|
* The rectangle grown to whole rows.
|
|
67
58
|
*
|
|
68
59
|
* Without this a one-pixel scroll would change which rows fall inside the rectangle, and the set
|
|
69
|
-
* of rendered elements would churn on every frame.
|
|
70
|
-
*
|
|
60
|
+
* of rendered elements would churn on every frame.
|
|
61
|
+
*
|
|
62
|
+
* The stride has to be the one rows are actually placed at, gap included, and the height has to
|
|
63
|
+
* absorb however far the top edge moved. Upstream's table snaps by the bare row height and lets
|
|
64
|
+
* the bottom edge fall wherever it lands, which costs a gap of coverage per screen — so a window
|
|
65
|
+
* arrived at by scrolling ends one gap short of where it was asked to reach.
|
|
71
66
|
*/
|
|
72
67
|
protected snapVisibleRect(rect: Rect): Rect;
|
|
73
68
|
/** Every layout info inside `rect`, snapped to whole rows, parents before children. */
|
|
@@ -77,21 +72,72 @@ export declare class ListLayout<Options extends ListLayoutOptions = ListLayoutOp
|
|
|
77
72
|
/**
|
|
78
73
|
* Records a row's measured size.
|
|
79
74
|
*
|
|
80
|
-
* Returns whether anything moved, which is the virtualizer's cue to lay out again. The
|
|
81
|
-
*
|
|
82
|
-
*
|
|
75
|
+
* Returns whether anything moved, which is the virtualizer's cue to lay out again. The size goes
|
|
76
|
+
* to the index rather than only onto the rendered node, so the rows below it move even though
|
|
77
|
+
* none of them is in the window, and so the row keeps its height when the window comes back.
|
|
83
78
|
*/
|
|
84
79
|
updateItemSize(key: VirtualizerKey, size: Size): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Hands a measurement to the index, when it is a root that the index places.
|
|
82
|
+
*
|
|
83
|
+
* A table's cell is measured too, but a cell does not sit among the roots — its row does, and
|
|
84
|
+
* the row is measured by its tallest cell, so the row's own measurement is the one that lands.
|
|
85
|
+
*/
|
|
86
|
+
protected recordMeasuredSize(layoutNode: LayoutNode, height: number): void;
|
|
85
87
|
protected shouldInvalidateEverything(context: InvalidationContext<Options>): boolean;
|
|
86
|
-
/** Extends the computed region to cover `rect`, and to cover every persisted key. */
|
|
87
|
-
protected layoutIfNeeded(rect: Rect): void;
|
|
88
88
|
/**
|
|
89
|
-
*
|
|
89
|
+
* The estimated size of a root, which is what the index places it at until it is measured.
|
|
90
|
+
*/
|
|
91
|
+
protected estimatedSizeAt(index: number): number;
|
|
92
|
+
/** How many things the index places. The roots for a list; the body's children for a table. */
|
|
93
|
+
protected get placedCount(): number;
|
|
94
|
+
/** Points the index at the collection as it stands, which is what makes every offset answerable. */
|
|
95
|
+
protected configureOffsets(start?: number): void;
|
|
96
|
+
/**
|
|
97
|
+
* The roots that are rendered wherever the window is.
|
|
98
|
+
*
|
|
99
|
+
* Loaders, because a sentinel that is not in the DOM can never report that it came into view,
|
|
100
|
+
* so the next page would never be asked for. Persisted keys, because the roving tab stop lives
|
|
101
|
+
* on the focused row and losing its element drops focus to the document.
|
|
102
|
+
*/
|
|
103
|
+
protected indicesPlacedOutsideTheWindow(): Set<number>;
|
|
104
|
+
/**
|
|
105
|
+
* Where the persisted keys sit among `keys`.
|
|
106
|
+
*
|
|
107
|
+
* A persisted key can be a cell as easily as a row — the roving tab stop lives on whichever
|
|
108
|
+
* element holds focus — and a cell needs its row placed or it has nowhere to live. So a key
|
|
109
|
+
* that is not one of these walks up until it finds the ancestor that is.
|
|
110
|
+
*/
|
|
111
|
+
protected persistedIndices(keys: readonly VirtualizerKey[]): Set<number>;
|
|
112
|
+
/** Where the row at `index` sits. A lookup, for a row nobody has rendered as much as for one. */
|
|
113
|
+
protected rowOffset(index: number): number;
|
|
114
|
+
/**
|
|
115
|
+
* The root indices the pass places, in order.
|
|
116
|
+
*
|
|
117
|
+
* The window plus whatever has to exist outside it. There is nothing to walk to and nothing to
|
|
118
|
+
* account for afterwards: a row's offset is a lookup, so the rows above and below the window
|
|
119
|
+
* cost the pass nothing at all.
|
|
120
|
+
*/
|
|
121
|
+
protected windowedIndices(rect: Rect): number[];
|
|
122
|
+
/** Builds the rendered set for a window, and drops what that window has left behind. */
|
|
123
|
+
protected layoutFor(rect: Rect): void;
|
|
124
|
+
/**
|
|
125
|
+
* Drops the rows the window has moved away from.
|
|
126
|
+
*
|
|
127
|
+
* Only rows and their cells: a table's header, its columns and its body are placed once and
|
|
128
|
+
* read by everything else, and a row that something still depends on — the one holding the
|
|
129
|
+
* roving tab stop — has to keep its element.
|
|
130
|
+
*/
|
|
131
|
+
protected pruneLayoutNodes(): void;
|
|
132
|
+
/**
|
|
133
|
+
* Places a key the windowed pass never reached.
|
|
90
134
|
*
|
|
91
|
-
* Pressing End, or restoring focus to a selected row, asks about a key at an arbitrary offset
|
|
92
|
-
*
|
|
135
|
+
* Pressing End, or restoring focus to a selected row, asks about a key at an arbitrary offset.
|
|
136
|
+
* That offset is a lookup whatever the rows are, so the one row is placed and nothing else is.
|
|
93
137
|
*/
|
|
94
138
|
private ensureLayoutInfo;
|
|
139
|
+
/** Where the index puts a node, or `null` for one it does not place. */
|
|
140
|
+
protected indexedOffset(node: VirtualizerNode): number | null;
|
|
95
141
|
private replaceLayoutInfo;
|
|
96
142
|
protected buildCollection(offset?: number): LayoutNode[];
|
|
97
143
|
protected buildChild(node: VirtualizerNode, x: number, y: number, parentKey: VirtualizerKey | null): LayoutNode;
|
|
@@ -100,9 +146,9 @@ export declare class ListLayout<Options extends ListLayoutOptions = ListLayoutOp
|
|
|
100
146
|
/**
|
|
101
147
|
* Whether a cached row can be reused as it stands.
|
|
102
148
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
149
|
+
* Three things: nothing global was invalidated, the datum is the same object, and the row is
|
|
150
|
+
* still at the same offset. There is no region to be inside of any more — a row's offset comes
|
|
151
|
+
* from the index, so being at the offset the index gives it *is* the whole of being current.
|
|
106
152
|
*/
|
|
107
153
|
protected isValid(node: VirtualizerNode, y: number): boolean;
|
|
108
154
|
protected buildLoader(node: VirtualizerNode, x: number, y: number): LayoutNode;
|