@box/blueprint-web 13.19.0 → 14.0.1
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/THIRD_PARTY_LICENSES +206 -27
- package/dist/lib-esm/button/button.d.ts +0 -2
- package/dist/lib-esm/button/button.js +2 -4
- package/dist/lib-esm/button/types.d.ts +0 -4
- package/dist/lib-esm/card-tooltip/card-tooltip.d.ts +3 -6
- package/dist/lib-esm/card-tooltip/card-tooltip.js +96 -42
- package/dist/lib-esm/card-tooltip/card-tooltip.module.js +1 -1
- package/dist/lib-esm/card-tooltip/types.d.ts +21 -36
- package/dist/lib-esm/combobox/chips-group.js +1 -5
- package/dist/lib-esm/combobox/combobox.js +64 -55
- package/dist/lib-esm/combobox/combobox.module.js +1 -1
- package/dist/lib-esm/combobox/types.d.ts +2 -2
- package/dist/lib-esm/combobox-group/combobox-group-combobox.js +0 -1
- package/dist/lib-esm/data-table/data-table-wrapper.js +2 -0
- package/dist/lib-esm/data-table/use-table-scroll-correction.d.ts +15 -0
- package/dist/lib-esm/data-table/use-table-scroll-correction.js +211 -0
- package/dist/lib-esm/empty-state/empty-state.d.ts +0 -2
- package/dist/lib-esm/guided-tooltip/guided-tooltip-footer.d.ts +0 -4
- package/dist/lib-esm/guided-tooltip/guided-tooltip.d.ts +0 -4
- package/dist/lib-esm/index.css +105 -289
- package/dist/lib-esm/index.d.ts +0 -3
- package/dist/lib-esm/index.js +0 -3
- package/dist/lib-esm/list-item/table-header-dropdown.js +1 -1
- package/dist/lib-esm/modal/alert-modal.d.ts +0 -4
- package/dist/lib-esm/modal/modal-footer.d.ts +0 -4
- package/dist/lib-esm/modal/modal.d.ts +0 -4
- package/dist/lib-esm/primitives/context-menu/context-menu.module.js +1 -1
- package/dist/lib-esm/primitives/select-menu-grid/select-menu-grid-option.js +0 -1
- package/dist/lib-esm/side-panel/side-panel-footer.d.ts +0 -4
- package/dist/lib-esm/side-panel/side-panel.d.ts +0 -4
- package/dist/lib-esm/tooltip/tooltip.d.ts +3 -2
- package/dist/lib-esm/tooltip/tooltip.js +2 -36
- package/dist/lib-esm/tooltip/types.d.ts +0 -9
- package/dist/lib-esm/util-components/base-grid-list-item/types.d.ts +2 -2
- package/dist/lib-esm/utils/useMedia.js +13 -1
- package/package.json +14 -14
- package/dist/lib-esm/card-tooltip-v2/card-tooltip-v2.d.ts +0 -10
- package/dist/lib-esm/card-tooltip-v2/card-tooltip-v2.js +0 -119
- package/dist/lib-esm/card-tooltip-v2/card-tooltip-v2.module.js +0 -4
- package/dist/lib-esm/card-tooltip-v2/index.d.ts +0 -2
- package/dist/lib-esm/card-tooltip-v2/types.d.ts +0 -30
- package/dist/lib-esm/content-field/content-field.d.ts +0 -4
- package/dist/lib-esm/content-field/content-field.js +0 -126
- package/dist/lib-esm/content-field/content-field.module.js +0 -4
- package/dist/lib-esm/content-field/index.d.ts +0 -2
- package/dist/lib-esm/content-field/messages.d.ts +0 -7
- package/dist/lib-esm/content-field/messages.js +0 -8
- package/dist/lib-esm/content-field/types.d.ts +0 -35
- package/dist/lib-esm/util-components/focus-trap/focus-trap.d.ts +0 -2
- package/dist/lib-esm/util-components/focus-trap/focus-trap.js +0 -52
- package/dist/lib-esm/util-components/focus-trap/index.d.ts +0 -1
- package/dist/lib-esm/util-components/focus-trap/types.d.ts +0 -8
- package/dist/lib-esm/utils/useIsTriggerInteractive.d.ts +0 -4
- package/dist/lib-esm/utils/useIsTriggerInteractive.js +0 -21
|
@@ -356,63 +356,68 @@ const RootInner = ({
|
|
|
356
356
|
hideLabel: hideLabel
|
|
357
357
|
}), jsx(PopoverAnchor, {
|
|
358
358
|
store: comboboxStore,
|
|
359
|
-
children:
|
|
359
|
+
children: jsx("div", {
|
|
360
360
|
ref: comboboxContainerRef,
|
|
361
361
|
className: clsx(styles.comboboxContainer, {
|
|
362
362
|
[styles.error]: hasError,
|
|
363
363
|
[styles.withChips]: showChipsGroup || showSingleSelectChip,
|
|
364
364
|
[styles.withComboboxButtons]: showComboboxCancelButton || Boolean(endComboboxIcon)
|
|
365
365
|
}),
|
|
366
|
-
"data-testid": "combobox-container",
|
|
367
366
|
onClick: handleFocusInputOnEvent,
|
|
368
|
-
|
|
367
|
+
"data-testid": "combobox-container",
|
|
368
|
+
children: jsxs("div", {
|
|
369
|
+
className: styles.comboboxContainerInner,
|
|
369
370
|
onClick: handleFocusInputOnEvent,
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
className: styles.textInput,
|
|
394
|
-
disabled: disabled,
|
|
395
|
-
id: comboboxId,
|
|
396
|
-
onBlur: composeEventHandlers(onBlur, handleOnBlur),
|
|
397
|
-
onFocus: handleOnFocus,
|
|
398
|
-
onKeyDown: handleKeyDown,
|
|
399
|
-
required: required,
|
|
400
|
-
store: comboboxStore
|
|
401
|
-
}), jsx("div", {
|
|
402
|
-
className: styles.comboboxButtons,
|
|
403
|
-
children: showComboboxCancelButton ? jsx(ComboboxCancel, {
|
|
404
|
-
onClick: resetSelectedValue,
|
|
405
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
406
|
-
render: cancelProps => jsx(IconButton, {
|
|
407
|
-
...cancelProps,
|
|
408
|
-
"aria-label": clearButtonAriaLabel,
|
|
409
|
-
icon: enableModernizedComponents ? XMark : XMark$1,
|
|
410
|
-
size: "x-small"
|
|
371
|
+
role: "presentation",
|
|
372
|
+
children: [showChipsGroup && jsx(ChipsGroup, {
|
|
373
|
+
onClick: handleFocusInputOnEvent,
|
|
374
|
+
children: selectedValue.map(selected => jsx(InputChip, {
|
|
375
|
+
avatar: getDisplayAvatarFromOptionValue(selected, options, displayAvatar),
|
|
376
|
+
label: getDisplayValueFromOptionValue(selected, options, displayValue),
|
|
377
|
+
onDelete: () => removeMultiSelectInputChip(selected),
|
|
378
|
+
tooltip: getTooltipValueFromOptionValue(selected, options, displayTooltip),
|
|
379
|
+
variant: getDisplayChipVariantFromOptionValue(selected, options, displayChipVariant)
|
|
380
|
+
}, selected))
|
|
381
|
+
}), showSingleSelectChip && jsx(InputChip, {
|
|
382
|
+
label: getDisplayValueFromOptionValue(selectedValue, options, displayValue),
|
|
383
|
+
onDelete: showComboboxCancelButton ? undefined : removeSingleSelectInputChip,
|
|
384
|
+
tooltip: getTooltipValueFromOptionValue(selectedValue, options, displayTooltip),
|
|
385
|
+
variant: getDisplayChipVariantFromOptionValue(selectedValue, options, displayChipVariant)
|
|
386
|
+
}), jsxs("div", {
|
|
387
|
+
className: styles.textInputWrapper,
|
|
388
|
+
children: [jsx(Combobox$1, {
|
|
389
|
+
...comboboxProps,
|
|
390
|
+
ref: reference,
|
|
391
|
+
"aria-describedby": ariaDescribedBy,
|
|
392
|
+
...(hasError && {
|
|
393
|
+
'aria-invalid': 'true'
|
|
411
394
|
}),
|
|
395
|
+
"aria-required": required,
|
|
396
|
+
autoSelect: false,
|
|
397
|
+
className: styles.textInput,
|
|
398
|
+
disabled: disabled,
|
|
399
|
+
id: comboboxId,
|
|
400
|
+
onBlur: composeEventHandlers(onBlur, handleOnBlur),
|
|
401
|
+
onFocus: handleOnFocus,
|
|
402
|
+
onKeyDown: handleKeyDown,
|
|
403
|
+
required: required,
|
|
412
404
|
store: comboboxStore
|
|
413
|
-
})
|
|
405
|
+
}), jsx("div", {
|
|
406
|
+
className: styles.comboboxButtons,
|
|
407
|
+
children: showComboboxCancelButton ? jsx(ComboboxCancel, {
|
|
408
|
+
onClick: resetSelectedValue,
|
|
409
|
+
// eslint-disable-next-line react/jsx-no-bind
|
|
410
|
+
render: cancelProps => jsx(IconButton, {
|
|
411
|
+
...cancelProps,
|
|
412
|
+
"aria-label": clearButtonAriaLabel,
|
|
413
|
+
icon: enableModernizedComponents ? XMark : XMark$1,
|
|
414
|
+
size: "x-small"
|
|
415
|
+
}),
|
|
416
|
+
store: comboboxStore
|
|
417
|
+
}) : endComboboxIcon
|
|
418
|
+
})]
|
|
414
419
|
})]
|
|
415
|
-
})
|
|
420
|
+
})
|
|
416
421
|
})
|
|
417
422
|
}), jsx(InlineError, {
|
|
418
423
|
className: styles.inlineError,
|
|
@@ -470,15 +475,19 @@ const RootInner = ({
|
|
|
470
475
|
sameWidth: true,
|
|
471
476
|
store: comboboxStore,
|
|
472
477
|
unmountOnHide: unmountOnHide,
|
|
473
|
-
children: jsx(
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
478
|
+
children: jsx("div", {
|
|
479
|
+
className: styles.popoverInner,
|
|
480
|
+
role: "presentation",
|
|
481
|
+
children: jsx(Collection, {
|
|
482
|
+
experimentalVirtualization: experimentalVirtualization,
|
|
483
|
+
inputValue: inputValue,
|
|
484
|
+
loadingAriaLabel: loadingAriaLabel,
|
|
485
|
+
noResultMessage: noResultMessage,
|
|
486
|
+
options: filteredOptions,
|
|
487
|
+
overscan: 2,
|
|
488
|
+
renderOptionFn: renderOptionFn,
|
|
489
|
+
showLoading: showLoading
|
|
490
|
+
})
|
|
482
491
|
})
|
|
483
492
|
}) : null]
|
|
484
493
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import '../index.css';
|
|
2
|
-
var styles = {"container":"bp_combobox_module_container--
|
|
2
|
+
var styles = {"container":"bp_combobox_module_container--c4fe7","label":"bp_combobox_module_label--c4fe7","textInput":"bp_combobox_module_textInput--c4fe7","popover":"bp_combobox_module_popover--c4fe7","disabled":"bp_combobox_module_disabled--c4fe7","hiddenLabel":"bp_combobox_module_hiddenLabel--c4fe7","comboboxContainer":"bp_combobox_module_comboboxContainer--c4fe7","comboboxContainerInner":"bp_combobox_module_comboboxContainerInner--c4fe7","withChips":"bp_combobox_module_withChips--c4fe7","error":"bp_combobox_module_error--c4fe7","withComboboxButtons":"bp_combobox_module_withComboboxButtons--c4fe7","textInputWrapper":"bp_combobox_module_textInputWrapper--c4fe7","comboboxButtons":"bp_combobox_module_comboboxButtons--c4fe7","inlineError":"bp_combobox_module_inlineError--c4fe7","popoverInner":"bp_combobox_module_popoverInner--c4fe7","option":"bp_combobox_module_option--c4fe7","indicator":"bp_combobox_module_indicator--c4fe7","indicatorIcon":"bp_combobox_module_indicatorIcon--c4fe7","optionWithIndicator":"bp_combobox_module_optionWithIndicator--c4fe7","loadingIndicator":"bp_combobox_module_loadingIndicator--c4fe7"};
|
|
3
3
|
|
|
4
4
|
export { styles as default };
|
|
@@ -15,7 +15,7 @@ export interface ComboboxBaseProps<Multiple extends boolean, FreeInput extends b
|
|
|
15
15
|
/**
|
|
16
16
|
* The list of values for the combobox items.
|
|
17
17
|
*/
|
|
18
|
-
options: T
|
|
18
|
+
options: ReadonlyArray<T>;
|
|
19
19
|
/**
|
|
20
20
|
* If set to `true`, the combobox input can contain any arbitrary value.
|
|
21
21
|
* In other words, options just behave as suggestions and the user input
|
|
@@ -291,7 +291,7 @@ export interface ComboboxOptionProps extends Pick<SelectItemProps, 'hideOnClick'
|
|
|
291
291
|
className?: string;
|
|
292
292
|
}
|
|
293
293
|
export interface CollectionProps<T> {
|
|
294
|
-
options:
|
|
294
|
+
options: ReadonlyArray<T>;
|
|
295
295
|
experimentalVirtualization: boolean;
|
|
296
296
|
inputValue: string;
|
|
297
297
|
renderOptionFn: (option: T) => React.ReactElement;
|
|
@@ -3,7 +3,6 @@ import clsx from 'clsx';
|
|
|
3
3
|
import { forwardRef, useCallback, useEffect } from 'react';
|
|
4
4
|
import '@box/blueprint-web-assets/tokens/px-tokens';
|
|
5
5
|
import '@radix-ui/react-tooltip';
|
|
6
|
-
import 'tabbable';
|
|
7
6
|
import { Combobox } from '../combobox/combobox.js';
|
|
8
7
|
import { useComboboxGroupContext } from './combobox-group-context.js';
|
|
9
8
|
import styles from './combobox-group.module.js';
|
|
@@ -4,6 +4,7 @@ import { forwardRef, useRef } from 'react';
|
|
|
4
4
|
import { useScroll, ScrollContext } from '../util-components/scrollable-container/scrollable-container.js';
|
|
5
5
|
import { useForkRef } from '../utils/useForkRef.js';
|
|
6
6
|
import styles from './data-table.module.js';
|
|
7
|
+
import { useTableScrollCorrection } from './use-table-scroll-correction.js';
|
|
7
8
|
|
|
8
9
|
const hideActionWrapperRightOffsetPx = 30;
|
|
9
10
|
const DataTableWrapper = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
|
@@ -17,6 +18,7 @@ const DataTableWrapper = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
|
|
17
18
|
value,
|
|
18
19
|
onScrollThrottled
|
|
19
20
|
} = useScroll(localRef);
|
|
21
|
+
useTableScrollCorrection(localRef);
|
|
20
22
|
const {
|
|
21
23
|
offsetTillEndX,
|
|
22
24
|
isScrolledX,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
export declare function getScrollableAncestors(element: HTMLElement): HTMLElement[];
|
|
3
|
+
/**
|
|
4
|
+
* corrects the scroll position of the ancestor element to make the element visible
|
|
5
|
+
*/
|
|
6
|
+
export declare function scrollElementIntoAncestor(ancestor: HTMLElement, element: HTMLElement): void;
|
|
7
|
+
/**
|
|
8
|
+
* Attaches a corrective scroll listener to the container referenced by
|
|
9
|
+
* `containerRef`. When keyboard focus moves to a descendant element,
|
|
10
|
+
* react-aria's Chrome-specific scroll path may leave the focused element
|
|
11
|
+
* partially or fully out of view. This hook schedules a corrective
|
|
12
|
+
* `scrollBy` in the animation frame after react-aria's own frame, ensuring
|
|
13
|
+
* the focused element is visible.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useTableScrollCorrection(containerRef: RefObject<HTMLDivElement | null>): void;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { getInteractionModality } from '@react-aria/interactions';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
const getElementPadding = element => {
|
|
5
|
+
const style = getComputedStyle(element);
|
|
6
|
+
return {
|
|
7
|
+
paddingTop: parseFloat(style.paddingTop) || 0,
|
|
8
|
+
paddingRight: parseFloat(style.paddingRight) || 0,
|
|
9
|
+
paddingBottom: parseFloat(style.paddingBottom) || 0,
|
|
10
|
+
paddingLeft: parseFloat(style.paddingLeft) || 0
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
const getViewportDimensions = () => {
|
|
14
|
+
const {
|
|
15
|
+
visualViewport
|
|
16
|
+
} = window;
|
|
17
|
+
if (!visualViewport) {
|
|
18
|
+
return {
|
|
19
|
+
top: 0,
|
|
20
|
+
right: window.innerWidth,
|
|
21
|
+
bottom: window.innerHeight,
|
|
22
|
+
left: 0
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
top: 0,
|
|
27
|
+
right: visualViewport.width,
|
|
28
|
+
bottom: visualViewport.height,
|
|
29
|
+
left: 0
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
function getScrollableAncestors(element) {
|
|
33
|
+
const ancestors = [];
|
|
34
|
+
let node = element.parentElement;
|
|
35
|
+
while (node) {
|
|
36
|
+
const {
|
|
37
|
+
overflowY,
|
|
38
|
+
overflowX
|
|
39
|
+
} = getComputedStyle(node);
|
|
40
|
+
const isScrollableY = /(auto|scroll|overlay)/.test(overflowY) && node.scrollHeight > node.clientHeight;
|
|
41
|
+
const isScrollableX = /(auto|scroll|overlay)/.test(overflowX) && node.scrollWidth > node.clientWidth;
|
|
42
|
+
if (isScrollableY || isScrollableX) {
|
|
43
|
+
ancestors.push(node);
|
|
44
|
+
}
|
|
45
|
+
node = node.parentElement;
|
|
46
|
+
}
|
|
47
|
+
const root = document.scrollingElement;
|
|
48
|
+
if (root && root instanceof HTMLElement) {
|
|
49
|
+
ancestors.push(root);
|
|
50
|
+
}
|
|
51
|
+
return ancestors;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* corrects the scroll position of the ancestor element to make the element visible
|
|
55
|
+
*/
|
|
56
|
+
function scrollElementIntoAncestor(ancestor, element) {
|
|
57
|
+
const {
|
|
58
|
+
paddingTop,
|
|
59
|
+
paddingRight,
|
|
60
|
+
paddingBottom,
|
|
61
|
+
paddingLeft
|
|
62
|
+
} = getElementPadding(ancestor);
|
|
63
|
+
const eRect = element.getBoundingClientRect();
|
|
64
|
+
const isRootScroller = ancestor === document.scrollingElement;
|
|
65
|
+
const aRect = isRootScroller ? getViewportDimensions() : ancestor.getBoundingClientRect();
|
|
66
|
+
let dy = 0;
|
|
67
|
+
if (eRect.top < aRect.top + paddingTop) {
|
|
68
|
+
dy = eRect.top - aRect.top - paddingTop;
|
|
69
|
+
} else if (eRect.bottom > aRect.bottom - paddingBottom) {
|
|
70
|
+
dy = eRect.bottom - aRect.bottom + paddingBottom;
|
|
71
|
+
}
|
|
72
|
+
let dx = 0;
|
|
73
|
+
if (eRect.left < aRect.left + paddingLeft) {
|
|
74
|
+
dx = eRect.left - aRect.left - paddingLeft;
|
|
75
|
+
} else if (eRect.right > aRect.right - paddingRight) {
|
|
76
|
+
dx = eRect.right - aRect.right + paddingRight;
|
|
77
|
+
}
|
|
78
|
+
if (dx !== 0 || dy !== 0) {
|
|
79
|
+
ancestor.scrollBy({
|
|
80
|
+
left: dx,
|
|
81
|
+
top: dy,
|
|
82
|
+
behavior: 'instant'
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Scrolls `element` into the visible area of `container`, respecting the
|
|
88
|
+
* container's CSS `scroll-padding`. Uses manual `scrollBy` instead of native
|
|
89
|
+
* `element.scrollIntoView` to work around Chromium bug #40074749, which causes
|
|
90
|
+
* `scrollIntoView` on `<td>` elements to skip the real scroll container.
|
|
91
|
+
*
|
|
92
|
+
* Horizontal correction is skipped for `<tr>` elements because rows span the
|
|
93
|
+
* full table width and would cause erroneous horizontal scrolling.
|
|
94
|
+
*/
|
|
95
|
+
function scrollElementIntoContainer(container, element) {
|
|
96
|
+
const {
|
|
97
|
+
paddingTop,
|
|
98
|
+
paddingRight,
|
|
99
|
+
paddingBottom,
|
|
100
|
+
paddingLeft
|
|
101
|
+
} = getElementPadding(container);
|
|
102
|
+
const cRect = container.getBoundingClientRect();
|
|
103
|
+
const eRect = element.getBoundingClientRect();
|
|
104
|
+
const stickyHeader = container.querySelector('table > thead > tr');
|
|
105
|
+
const stickyHeaderRect = stickyHeader instanceof HTMLElement ? stickyHeader.getBoundingClientRect() : null;
|
|
106
|
+
// Get the viewport dimensions to check if the element is completely visible
|
|
107
|
+
const {
|
|
108
|
+
top: viewportTop,
|
|
109
|
+
right: viewportRight,
|
|
110
|
+
bottom: viewportBottom,
|
|
111
|
+
left: viewportLeft
|
|
112
|
+
} = getViewportDimensions();
|
|
113
|
+
const visibleTop = Math.max(cRect.top, viewportTop);
|
|
114
|
+
const visibleRight = Math.min(cRect.right, viewportRight);
|
|
115
|
+
const visibleBottom = Math.min(cRect.bottom, viewportBottom);
|
|
116
|
+
const visibleLeft = Math.max(cRect.left, viewportLeft);
|
|
117
|
+
const isRow = element.tagName === 'TR';
|
|
118
|
+
const isInsideTableHead = element.closest('thead') !== null;
|
|
119
|
+
const stickyHeaderOverlayTopInset = stickyHeaderRect && !isInsideTableHead ? Math.max(0, stickyHeaderRect.bottom - visibleTop) : 0;
|
|
120
|
+
const topInset = paddingTop + stickyHeaderOverlayTopInset;
|
|
121
|
+
const row = element.closest('tr');
|
|
122
|
+
const firstRowCell = row?.firstElementChild instanceof HTMLElement ? row.firstElementChild : null;
|
|
123
|
+
const firstRowCellRect = firstRowCell?.getBoundingClientRect();
|
|
124
|
+
const firstRowCellStyle = firstRowCell ? getComputedStyle(firstRowCell) : null;
|
|
125
|
+
const isFirstCellSticky = firstRowCellStyle?.position === 'sticky';
|
|
126
|
+
const isWithinStickyFirstCell = Boolean(isFirstCellSticky && firstRowCell && (firstRowCell === element || firstRowCell.contains(element)));
|
|
127
|
+
const stickyFirstCellOverlayLeftInset = firstRowCellRect && isFirstCellSticky ? Math.max(0, firstRowCellRect.right - visibleLeft) : 0;
|
|
128
|
+
const leftInset = isWithinStickyFirstCell ? paddingLeft : paddingLeft + stickyFirstCellOverlayLeftInset;
|
|
129
|
+
let dy = 0;
|
|
130
|
+
if (eRect.top < visibleTop + topInset) {
|
|
131
|
+
dy = eRect.top - visibleTop - topInset;
|
|
132
|
+
} else if (eRect.bottom > visibleBottom - paddingBottom) {
|
|
133
|
+
dy = eRect.bottom - visibleBottom + paddingBottom;
|
|
134
|
+
}
|
|
135
|
+
let dx = 0;
|
|
136
|
+
if (!isRow) {
|
|
137
|
+
if (eRect.left < visibleLeft + leftInset) {
|
|
138
|
+
dx = eRect.left - visibleLeft - leftInset;
|
|
139
|
+
} else if (eRect.right > visibleRight - paddingRight) {
|
|
140
|
+
dx = eRect.right - visibleRight + paddingRight;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (dx !== 0 || dy !== 0) {
|
|
144
|
+
const prevScrollTop = container.scrollTop;
|
|
145
|
+
const prevScrollLeft = container.scrollLeft;
|
|
146
|
+
container.scrollBy({
|
|
147
|
+
left: dx,
|
|
148
|
+
top: dy,
|
|
149
|
+
behavior: 'instant'
|
|
150
|
+
});
|
|
151
|
+
const actualDy = container.scrollTop - prevScrollTop;
|
|
152
|
+
const actualDx = container.scrollLeft - prevScrollLeft;
|
|
153
|
+
const didNotFullyApply = Math.abs(actualDy - dy) > 0.5 || Math.abs(actualDx - dx) > 0.5;
|
|
154
|
+
// Check if scroll wrapper was able to correctly show focused element
|
|
155
|
+
// If not, change scroll position of the ancestor elements to make element visible
|
|
156
|
+
if (didNotFullyApply) {
|
|
157
|
+
const outerAncestors = getScrollableAncestors(container);
|
|
158
|
+
outerAncestors.forEach(ancestor => {
|
|
159
|
+
scrollElementIntoAncestor(ancestor, element);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Attaches a corrective scroll listener to the container referenced by
|
|
166
|
+
* `containerRef`. When keyboard focus moves to a descendant element,
|
|
167
|
+
* react-aria's Chrome-specific scroll path may leave the focused element
|
|
168
|
+
* partially or fully out of view. This hook schedules a corrective
|
|
169
|
+
* `scrollBy` in the animation frame after react-aria's own frame, ensuring
|
|
170
|
+
* the focused element is visible.
|
|
171
|
+
*/
|
|
172
|
+
function useTableScrollCorrection(containerRef) {
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
const container = containerRef.current;
|
|
175
|
+
if (!container) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
let raf1 = 0;
|
|
179
|
+
let raf2 = 0;
|
|
180
|
+
const onFocusIn = e => {
|
|
181
|
+
const modality = getInteractionModality();
|
|
182
|
+
const target = e.target;
|
|
183
|
+
const containsTarget = container.contains(target);
|
|
184
|
+
if (modality !== 'keyboard') {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (!containsTarget) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
cancelAnimationFrame(raf1);
|
|
191
|
+
cancelAnimationFrame(raf2);
|
|
192
|
+
// react-aria schedules its (broken) scroll in one rAF; we run in
|
|
193
|
+
// the following frame to override the incorrect final position.
|
|
194
|
+
raf1 = requestAnimationFrame(() => {
|
|
195
|
+
raf2 = requestAnimationFrame(() => {
|
|
196
|
+
scrollElementIntoContainer(container, target);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
container.addEventListener('focusin', onFocusIn);
|
|
201
|
+
// eslint-disable-next-line consistent-return
|
|
202
|
+
return () => {
|
|
203
|
+
container.removeEventListener('focusin', onFocusIn);
|
|
204
|
+
cancelAnimationFrame(raf1);
|
|
205
|
+
cancelAnimationFrame(raf2);
|
|
206
|
+
};
|
|
207
|
+
// since it is a ref, it will not trigger a re-render, however eslint still warns to add it to the dependency array
|
|
208
|
+
}, [containerRef]);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export { getScrollableAncestors, scrollElementIntoAncestor, useTableScrollCorrection };
|
|
@@ -11,12 +11,10 @@ export declare const EmptyState: import("react").ForwardRefExoticComponent<Empty
|
|
|
11
11
|
*/
|
|
12
12
|
PrimaryAction: import("react").ForwardRefExoticComponent<(Omit<import("../primitives/base-button").BaseButtonInterface & Required<Pick<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
13
13
|
children?: string | string[];
|
|
14
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
15
14
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
16
15
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
17
16
|
}, "ref"> | Omit<import("../primitives/base-button").BaseButtonInterface & Partial<Record<keyof import("../primitives/base-button").Loading, never>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
18
17
|
children?: string | string[];
|
|
19
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
20
18
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
21
19
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
22
20
|
}, "ref">) & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -11,23 +11,19 @@ export declare const GuidedTooltipFooter: (({ children, className, ...rest }: Gu
|
|
|
11
11
|
ActionsContainer: ({ children, className, ...rest }: GuidedTooltipActionsContainerProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
12
|
PrimaryAction: import("react").ForwardRefExoticComponent<(Omit<import("../primitives/base-button").BaseButtonInterface & Required<Pick<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
13
13
|
children?: string | string[];
|
|
14
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
15
14
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
16
15
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
17
16
|
}, "ref"> | Omit<import("../primitives/base-button").BaseButtonInterface & Partial<Record<keyof import("../primitives/base-button").Loading, never>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
18
17
|
children?: string | string[];
|
|
19
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
20
18
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
21
19
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
22
20
|
}, "ref">) & import("react").RefAttributes<HTMLButtonElement>>;
|
|
23
21
|
SecondaryAction: import("react").ForwardRefExoticComponent<(Omit<import("../primitives/base-button").BaseButtonInterface & Required<Pick<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
24
22
|
children?: string | string[];
|
|
25
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
26
23
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
27
24
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
28
25
|
}, "ref"> | Omit<import("../primitives/base-button").BaseButtonInterface & Partial<Record<keyof import("../primitives/base-button").Loading, never>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
29
26
|
children?: string | string[];
|
|
30
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
31
27
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
32
28
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
33
29
|
}, "ref">) & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -5,23 +5,19 @@ export declare const GuidedTooltip: (({ children, onOpenChange, open, container,
|
|
|
5
5
|
ActionsContainer: ({ children, className, ...rest }: import("./types").GuidedTooltipActionsContainerProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
PrimaryAction: import("react").ForwardRefExoticComponent<(Omit<import("../primitives/base-button").BaseButtonInterface & Required<Pick<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
7
7
|
children?: string | string[];
|
|
8
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
9
8
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
10
9
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
11
10
|
}, "ref"> | Omit<import("../primitives/base-button").BaseButtonInterface & Partial<Record<keyof import("../primitives/base-button").Loading, never>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
12
11
|
children?: string | string[];
|
|
13
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
14
12
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
15
13
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
16
14
|
}, "ref">) & import("react").RefAttributes<HTMLButtonElement>>;
|
|
17
15
|
SecondaryAction: import("react").ForwardRefExoticComponent<(Omit<import("../primitives/base-button").BaseButtonInterface & Required<Pick<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
18
16
|
children?: string | string[];
|
|
19
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
20
17
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
21
18
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
22
19
|
}, "ref"> | Omit<import("../primitives/base-button").BaseButtonInterface & Partial<Record<keyof import("../primitives/base-button").Loading, never>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
23
20
|
children?: string | string[];
|
|
24
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
25
21
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
26
22
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
27
23
|
}, "ref">) & import("react").RefAttributes<HTMLButtonElement>>;
|