@patternfly/react-core 4.236.5 → 4.236.8
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 +27 -0
- package/dist/esm/components/ApplicationLauncher/ApplicationLauncher.d.ts +2 -0
- package/dist/esm/components/ApplicationLauncher/ApplicationLauncher.d.ts.map +1 -1
- package/dist/esm/components/ApplicationLauncher/ApplicationLauncher.js +4 -3
- package/dist/esm/components/ApplicationLauncher/ApplicationLauncher.js.map +1 -1
- package/dist/esm/components/BackToTop/BackToTop.d.ts +1 -1
- package/dist/esm/components/ContextSelector/ContextSelector.d.ts +2 -0
- package/dist/esm/components/ContextSelector/ContextSelector.d.ts.map +1 -1
- package/dist/esm/components/ContextSelector/ContextSelector.js +4 -3
- package/dist/esm/components/ContextSelector/ContextSelector.js.map +1 -1
- package/dist/esm/components/Dropdown/Dropdown.d.ts +2 -0
- package/dist/esm/components/Dropdown/Dropdown.d.ts.map +1 -1
- package/dist/esm/components/Dropdown/Dropdown.js +2 -2
- package/dist/esm/components/Dropdown/Dropdown.js.map +1 -1
- package/dist/esm/components/Dropdown/DropdownWithContext.d.ts.map +1 -1
- package/dist/esm/components/Dropdown/DropdownWithContext.js +2 -2
- package/dist/esm/components/Dropdown/DropdownWithContext.js.map +1 -1
- package/dist/esm/components/DualListSelector/DualListSelectorControl.d.ts +1 -1
- package/dist/esm/components/DualListSelector/DualListSelectorControlsWrapper.d.ts +1 -1
- package/dist/esm/components/DualListSelector/DualListSelectorListItem.d.ts +1 -1
- package/dist/esm/components/DualListSelector/DualListSelectorListWrapper.d.ts +1 -1
- package/dist/esm/components/Menu/MenuContent.d.ts +1 -1
- package/dist/esm/components/Menu/MenuGroup.d.ts +1 -1
- package/dist/esm/components/Menu/MenuInput.d.ts +1 -1
- package/dist/esm/components/Menu/MenuItem.d.ts +1 -1
- package/dist/esm/components/Nav/NavItem.d.ts +2 -0
- package/dist/esm/components/Nav/NavItem.d.ts.map +1 -1
- package/dist/esm/components/Nav/NavItem.js +2 -2
- package/dist/esm/components/Nav/NavItem.js.map +1 -1
- package/dist/esm/components/NotificationDrawer/NotificationDrawer.d.ts +1 -1
- package/dist/esm/components/OptionsMenu/OptionsMenu.d.ts +2 -0
- package/dist/esm/components/OptionsMenu/OptionsMenu.d.ts.map +1 -1
- package/dist/esm/components/OptionsMenu/OptionsMenu.js +2 -2
- package/dist/esm/components/OptionsMenu/OptionsMenu.js.map +1 -1
- package/dist/esm/components/Page/Page.d.ts.map +1 -1
- package/dist/esm/components/Page/Page.js +11 -2
- package/dist/esm/components/Page/Page.js.map +1 -1
- package/dist/esm/components/Panel/Panel.d.ts +1 -1
- package/dist/esm/components/Popover/Popover.d.ts +2 -0
- package/dist/esm/components/Popover/Popover.d.ts.map +1 -1
- package/dist/esm/components/Popover/Popover.js +2 -2
- package/dist/esm/components/Popover/Popover.js.map +1 -1
- package/dist/esm/components/Popover/PopoverCloseButton.d.ts.map +1 -1
- package/dist/esm/components/Popover/PopoverCloseButton.js +2 -11
- package/dist/esm/components/Popover/PopoverCloseButton.js.map +1 -1
- package/dist/esm/components/SearchInput/SearchInput.d.ts +2 -0
- package/dist/esm/components/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/esm/components/SearchInput/SearchInput.js +2 -2
- package/dist/esm/components/SearchInput/SearchInput.js.map +1 -1
- package/dist/esm/components/Select/Select.d.ts +2 -0
- package/dist/esm/components/Select/Select.d.ts.map +1 -1
- package/dist/esm/components/Select/Select.js +4 -3
- package/dist/esm/components/Select/Select.js.map +1 -1
- package/dist/esm/components/Tabs/OverflowTab.d.ts +2 -0
- package/dist/esm/components/Tabs/OverflowTab.d.ts.map +1 -1
- package/dist/esm/components/Tabs/OverflowTab.js +2 -2
- package/dist/esm/components/Tabs/OverflowTab.js.map +1 -1
- package/dist/esm/components/Tabs/Tab.d.ts +1 -1
- package/dist/esm/components/TimePicker/TimePicker.d.ts +3 -0
- package/dist/esm/components/TimePicker/TimePicker.d.ts.map +1 -1
- package/dist/esm/components/TimePicker/TimePicker.js +5 -4
- package/dist/esm/components/TimePicker/TimePicker.js.map +1 -1
- package/dist/esm/components/Tooltip/Tooltip.d.ts +2 -0
- package/dist/esm/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/esm/components/Tooltip/Tooltip.js +2 -2
- package/dist/esm/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/esm/helpers/FocusTrap/FocusTrap.d.ts +5 -19
- package/dist/esm/helpers/FocusTrap/FocusTrap.d.ts.map +1 -1
- package/dist/esm/helpers/FocusTrap/FocusTrap.js +10 -6
- package/dist/esm/helpers/FocusTrap/FocusTrap.js.map +1 -1
- package/dist/esm/helpers/Popper/Popper.d.ts +5 -0
- package/dist/esm/helpers/Popper/Popper.d.ts.map +1 -1
- package/dist/esm/helpers/Popper/Popper.js +42 -7
- package/dist/esm/helpers/Popper/Popper.js.map +1 -1
- package/dist/esm/helpers/resizeObserver.d.ts +8 -1
- package/dist/esm/helpers/resizeObserver.d.ts.map +1 -1
- package/dist/esm/helpers/resizeObserver.js +18 -3
- package/dist/esm/helpers/resizeObserver.js.map +1 -1
- package/dist/js/components/ApplicationLauncher/ApplicationLauncher.d.ts +2 -0
- package/dist/js/components/ApplicationLauncher/ApplicationLauncher.d.ts.map +1 -1
- package/dist/js/components/ApplicationLauncher/ApplicationLauncher.js +4 -3
- package/dist/js/components/ApplicationLauncher/ApplicationLauncher.js.map +1 -1
- package/dist/js/components/BackToTop/BackToTop.d.ts +1 -1
- package/dist/js/components/ContextSelector/ContextSelector.d.ts +2 -0
- package/dist/js/components/ContextSelector/ContextSelector.d.ts.map +1 -1
- package/dist/js/components/ContextSelector/ContextSelector.js +4 -3
- package/dist/js/components/ContextSelector/ContextSelector.js.map +1 -1
- package/dist/js/components/Dropdown/Dropdown.d.ts +2 -0
- package/dist/js/components/Dropdown/Dropdown.d.ts.map +1 -1
- package/dist/js/components/Dropdown/Dropdown.js +2 -2
- package/dist/js/components/Dropdown/Dropdown.js.map +1 -1
- package/dist/js/components/Dropdown/DropdownWithContext.d.ts.map +1 -1
- package/dist/js/components/Dropdown/DropdownWithContext.js +2 -2
- package/dist/js/components/Dropdown/DropdownWithContext.js.map +1 -1
- package/dist/js/components/DualListSelector/DualListSelectorControl.d.ts +1 -1
- package/dist/js/components/DualListSelector/DualListSelectorControlsWrapper.d.ts +1 -1
- package/dist/js/components/DualListSelector/DualListSelectorListItem.d.ts +1 -1
- package/dist/js/components/DualListSelector/DualListSelectorListWrapper.d.ts +1 -1
- package/dist/js/components/Menu/MenuContent.d.ts +1 -1
- package/dist/js/components/Menu/MenuGroup.d.ts +1 -1
- package/dist/js/components/Menu/MenuInput.d.ts +1 -1
- package/dist/js/components/Menu/MenuItem.d.ts +1 -1
- package/dist/js/components/Nav/NavItem.d.ts +2 -0
- package/dist/js/components/Nav/NavItem.d.ts.map +1 -1
- package/dist/js/components/Nav/NavItem.js +2 -2
- package/dist/js/components/Nav/NavItem.js.map +1 -1
- package/dist/js/components/NotificationDrawer/NotificationDrawer.d.ts +1 -1
- package/dist/js/components/OptionsMenu/OptionsMenu.d.ts +2 -0
- package/dist/js/components/OptionsMenu/OptionsMenu.d.ts.map +1 -1
- package/dist/js/components/OptionsMenu/OptionsMenu.js +2 -2
- package/dist/js/components/OptionsMenu/OptionsMenu.js.map +1 -1
- package/dist/js/components/Page/Page.d.ts.map +1 -1
- package/dist/js/components/Page/Page.js +11 -2
- package/dist/js/components/Page/Page.js.map +1 -1
- package/dist/js/components/Panel/Panel.d.ts +1 -1
- package/dist/js/components/Popover/Popover.d.ts +2 -0
- package/dist/js/components/Popover/Popover.d.ts.map +1 -1
- package/dist/js/components/Popover/Popover.js +2 -2
- package/dist/js/components/Popover/Popover.js.map +1 -1
- package/dist/js/components/Popover/PopoverCloseButton.d.ts.map +1 -1
- package/dist/js/components/Popover/PopoverCloseButton.js +2 -11
- package/dist/js/components/Popover/PopoverCloseButton.js.map +1 -1
- package/dist/js/components/SearchInput/SearchInput.d.ts +2 -0
- package/dist/js/components/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/js/components/SearchInput/SearchInput.js +2 -2
- package/dist/js/components/SearchInput/SearchInput.js.map +1 -1
- package/dist/js/components/Select/Select.d.ts +2 -0
- package/dist/js/components/Select/Select.d.ts.map +1 -1
- package/dist/js/components/Select/Select.js +4 -3
- package/dist/js/components/Select/Select.js.map +1 -1
- package/dist/js/components/Tabs/OverflowTab.d.ts +2 -0
- package/dist/js/components/Tabs/OverflowTab.d.ts.map +1 -1
- package/dist/js/components/Tabs/OverflowTab.js +2 -2
- package/dist/js/components/Tabs/OverflowTab.js.map +1 -1
- package/dist/js/components/Tabs/Tab.d.ts +1 -1
- package/dist/js/components/TimePicker/TimePicker.d.ts +3 -0
- package/dist/js/components/TimePicker/TimePicker.d.ts.map +1 -1
- package/dist/js/components/TimePicker/TimePicker.js +5 -4
- package/dist/js/components/TimePicker/TimePicker.js.map +1 -1
- package/dist/js/components/Tooltip/Tooltip.d.ts +2 -0
- package/dist/js/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/js/components/Tooltip/Tooltip.js +2 -2
- package/dist/js/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/js/helpers/FocusTrap/FocusTrap.d.ts +5 -19
- package/dist/js/helpers/FocusTrap/FocusTrap.d.ts.map +1 -1
- package/dist/js/helpers/FocusTrap/FocusTrap.js +10 -7
- package/dist/js/helpers/FocusTrap/FocusTrap.js.map +1 -1
- package/dist/js/helpers/Popper/Popper.d.ts +5 -0
- package/dist/js/helpers/Popper/Popper.d.ts.map +1 -1
- package/dist/js/helpers/Popper/Popper.js +42 -7
- package/dist/js/helpers/Popper/Popper.js.map +1 -1
- package/dist/js/helpers/resizeObserver.d.ts +8 -1
- package/dist/js/helpers/resizeObserver.d.ts.map +1 -1
- package/dist/js/helpers/resizeObserver.js +18 -3
- package/dist/js/helpers/resizeObserver.js.map +1 -1
- package/dist/umd/react-core.min.css +39 -39
- package/dist/umd/react-core.min.js +5 -5
- package/package.json +5 -5
- package/src/components/ApplicationLauncher/ApplicationLauncher.tsx +6 -1
- package/src/components/ApplicationLauncher/__tests__/ApplicationLauncher.test.tsx +10 -1
- package/src/components/ApplicationLauncher/__tests__/__snapshots__/ApplicationLauncher.test.tsx.snap +153 -7
- package/src/components/ContextSelector/ContextSelector.tsx +6 -1
- package/src/components/ContextSelector/__tests__/ContextSelector.test.tsx +18 -1
- package/src/components/ContextSelector/__tests__/__snapshots__/ContextSelector.test.tsx.snap +144 -0
- package/src/components/Dropdown/Dropdown.tsx +9 -1
- package/src/components/Dropdown/DropdownWithContext.tsx +2 -0
- package/src/components/Dropdown/__tests__/Dropdown.test.tsx +16 -0
- package/src/components/Dropdown/__tests__/__snapshots__/Dropdown.test.tsx.snap +131 -7
- package/src/components/Nav/NavItem.tsx +4 -0
- package/src/components/Nav/__tests__/Nav.test.tsx +19 -0
- package/src/components/Nav/__tests__/__snapshots__/Nav.test.tsx.snap +111 -42
- package/src/components/OptionsMenu/OptionsMenu.tsx +4 -0
- package/src/components/OptionsMenu/__tests__/OptionsMenu.test.tsx +17 -0
- package/src/components/OptionsMenu/__tests__/__snapshots__/OptionsMenu.test.tsx.snap +216 -20
- package/src/components/Page/Page.tsx +11 -2
- package/src/components/Popover/Popover.tsx +4 -0
- package/src/components/Popover/PopoverCloseButton.tsx +6 -17
- package/src/components/Popover/__tests__/Popover.test.tsx +25 -0
- package/src/components/Popover/__tests__/__snapshots__/Popover.test.tsx.snap +10 -0
- package/src/components/SearchInput/SearchInput.tsx +4 -0
- package/src/components/SearchInput/__tests__/SearchInput.test.tsx +27 -1
- package/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap +130 -6
- package/src/components/Select/Select.tsx +6 -1
- package/src/components/Select/__tests__/Select.test.tsx +23 -7
- package/src/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +152 -46
- package/src/components/Tabs/OverflowTab.tsx +4 -0
- package/src/components/Tabs/__tests__/OverflowTab.test.tsx +31 -7
- package/src/components/Tabs/__tests__/__snapshots__/OverflowTab.test.tsx.snap +89 -0
- package/src/components/TimePicker/TimePicker.tsx +6 -1
- package/src/components/TimePicker/__tests__/TimePicker.test.tsx +16 -1
- package/src/components/Tooltip/Tooltip.tsx +4 -0
- package/src/components/Tooltip/__tests__/Tooltip.test.tsx +21 -0
- package/src/components/Tooltip/__tests__/__snapshots__/Tooltip.test.tsx.snap +10 -0
- package/src/helpers/FocusTrap/FocusTrap.tsx +21 -5
- package/src/helpers/Popper/Popper.tsx +54 -12
- package/src/helpers/resizeObserver.tsx +21 -3
|
@@ -6,6 +6,21 @@ import userEvent from '@testing-library/user-event';
|
|
|
6
6
|
import { TimePicker, TimePickerProps } from '../TimePicker';
|
|
7
7
|
|
|
8
8
|
describe('TimePicker', () => {
|
|
9
|
+
test('Renders in strict mode', () => {
|
|
10
|
+
const validateTime = (_time: string) => {
|
|
11
|
+
return true;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const consoleError = jest.spyOn(console, 'error');
|
|
15
|
+
const { asFragment } = render(
|
|
16
|
+
<React.StrictMode>
|
|
17
|
+
<TimePicker removeFindDomNode value={'00:00'} validateTime={validateTime} aria-label="time picker" />
|
|
18
|
+
</React.StrictMode>
|
|
19
|
+
);
|
|
20
|
+
expect(consoleError).not.toHaveBeenCalled();
|
|
21
|
+
expect(screen.getByLabelText('time picker')).not.toHaveClass('pf-m-error');
|
|
22
|
+
});
|
|
23
|
+
|
|
9
24
|
describe('test timepicker onChange method with valid values', () => {
|
|
10
25
|
const testOnChange = async ({
|
|
11
26
|
inputProps,
|
|
@@ -20,7 +35,7 @@ describe('TimePicker', () => {
|
|
|
20
35
|
render(<TimePicker onChange={onChange} {...inputProps} aria-label="time picker" />);
|
|
21
36
|
|
|
22
37
|
await user.type(screen.getByLabelText('time picker'), String(inputProps.value));
|
|
23
|
-
expect(onChange).toHaveBeenCalledWith(inputProps.value, expects.hour, expects.minutes, expects.seconds, true)
|
|
38
|
+
expect(onChange).toHaveBeenCalledWith(inputProps.value, expects.hour, expects.minutes, expects.seconds, true);
|
|
24
39
|
};
|
|
25
40
|
|
|
26
41
|
test('should return the correct value using the AM/PM pattern - midnight', async () => {
|
|
@@ -138,6 +138,8 @@ export interface TooltipProps extends Omit<React.HTMLProps<HTMLDivElement>, 'con
|
|
|
138
138
|
isAppLauncher?: boolean;
|
|
139
139
|
/** @deprecated - no longer used */
|
|
140
140
|
tippyProps?: Partial<TippyProps>;
|
|
141
|
+
/** @beta Opt-in for updated popper that does not use findDOMNode. */
|
|
142
|
+
removeFindDomNode?: boolean;
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
// id for associating trigger with the content aria-describedby or aria-labelledby
|
|
@@ -168,6 +170,7 @@ export const Tooltip: React.FunctionComponent<TooltipProps> = ({
|
|
|
168
170
|
boundary,
|
|
169
171
|
isAppLauncher,
|
|
170
172
|
tippyProps,
|
|
173
|
+
removeFindDomNode = false,
|
|
171
174
|
...rest
|
|
172
175
|
}: TooltipProps) => {
|
|
173
176
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -331,6 +334,7 @@ export const Tooltip: React.FunctionComponent<TooltipProps> = ({
|
|
|
331
334
|
enableFlip={enableFlip}
|
|
332
335
|
zIndex={zIndex}
|
|
333
336
|
flipBehavior={flipBehavior}
|
|
337
|
+
removeFindDomNode={removeFindDomNode}
|
|
334
338
|
/>
|
|
335
339
|
);
|
|
336
340
|
};
|
|
@@ -17,3 +17,24 @@ test('tooltip renders', () => {
|
|
|
17
17
|
);
|
|
18
18
|
expect(asFragment()).toMatchSnapshot();
|
|
19
19
|
});
|
|
20
|
+
|
|
21
|
+
test('tooltip renders in strict mode', () => {
|
|
22
|
+
const consoleError = jest.spyOn(console, 'error');
|
|
23
|
+
const { asFragment } = render(
|
|
24
|
+
<React.StrictMode>
|
|
25
|
+
<Tooltip
|
|
26
|
+
removeFindDomNode
|
|
27
|
+
position="top"
|
|
28
|
+
content={
|
|
29
|
+
<div>
|
|
30
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.
|
|
31
|
+
</div>
|
|
32
|
+
}
|
|
33
|
+
>
|
|
34
|
+
<div>Toggle tooltip</div>
|
|
35
|
+
</Tooltip>
|
|
36
|
+
</React.StrictMode>
|
|
37
|
+
);
|
|
38
|
+
expect(consoleError).not.toHaveBeenCalled();
|
|
39
|
+
expect(asFragment()).toMatchSnapshot();
|
|
40
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { createFocusTrap, Options as FocusTrapOptions, FocusTrap as IFocusTrap } from 'focus-trap';
|
|
3
3
|
|
|
4
|
-
interface FocusTrapProps extends React.HTMLProps<HTMLDivElement> {
|
|
4
|
+
interface FocusTrapProps extends Omit<React.HTMLProps<HTMLDivElement>, 'ref'> {
|
|
5
5
|
children: React.ReactNode;
|
|
6
6
|
className?: string;
|
|
7
7
|
active?: boolean;
|
|
@@ -9,13 +9,15 @@ interface FocusTrapProps extends React.HTMLProps<HTMLDivElement> {
|
|
|
9
9
|
focusTrapOptions?: FocusTrapOptions;
|
|
10
10
|
/** Prevent from scrolling to the previously focused element on deactivation */
|
|
11
11
|
preventScrollOnDeactivate?: boolean;
|
|
12
|
+
/** @hide Forwarded ref */
|
|
13
|
+
innerRef?: React.Ref<HTMLDivElement>;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
class FocusTrapBase extends React.Component<FocusTrapProps> {
|
|
15
17
|
static displayName = 'FocusTrap';
|
|
16
18
|
previouslyFocusedElement: HTMLElement;
|
|
17
19
|
focusTrap: IFocusTrap;
|
|
18
|
-
divRef = React.createRef<HTMLDivElement>();
|
|
20
|
+
divRef = (this.props.innerRef as React.RefObject<HTMLDivElement>) || React.createRef<HTMLDivElement>();
|
|
19
21
|
|
|
20
22
|
static defaultProps = {
|
|
21
23
|
active: true,
|
|
@@ -76,8 +78,18 @@ export class FocusTrap extends React.Component<FocusTrapProps> {
|
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
render() {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
const {
|
|
82
|
+
children,
|
|
83
|
+
className,
|
|
84
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
85
|
+
focusTrapOptions,
|
|
86
|
+
active,
|
|
87
|
+
paused,
|
|
88
|
+
preventScrollOnDeactivate,
|
|
89
|
+
innerRef,
|
|
90
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
91
|
+
...rest
|
|
92
|
+
} = this.props;
|
|
81
93
|
return (
|
|
82
94
|
<div ref={this.divRef} className={className} {...rest}>
|
|
83
95
|
{children}
|
|
@@ -85,3 +97,7 @@ export class FocusTrap extends React.Component<FocusTrapProps> {
|
|
|
85
97
|
);
|
|
86
98
|
}
|
|
87
99
|
}
|
|
100
|
+
|
|
101
|
+
export const FocusTrap = React.forwardRef((props: FocusTrapProps, ref: React.Ref<any>) => (
|
|
102
|
+
<FocusTrapBase innerRef={ref} {...props} />
|
|
103
|
+
));
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import * as ReactDOM from 'react-dom';
|
|
3
|
-
import { FindRefWrapper } from './FindRefWrapper';
|
|
4
3
|
import { usePopper } from './thirdparty/react-popper/usePopper';
|
|
5
4
|
import { Placement, BasePlacement, Modifier } from './thirdparty/popper-core';
|
|
6
5
|
import { css } from '@patternfly/react-styles';
|
|
6
|
+
import { FindRefWrapper } from './FindRefWrapper';
|
|
7
7
|
import '@patternfly/react-styles/css/components/Popper/Popper.css';
|
|
8
8
|
|
|
9
9
|
const hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
|
|
@@ -38,6 +38,7 @@ export interface PopperProps {
|
|
|
38
38
|
/**
|
|
39
39
|
* The reference element to which the Popover is relatively placed to.
|
|
40
40
|
* Use either trigger or reference, not both.
|
|
41
|
+
* Passing this property or the removeFindDomNode property, will bypass the use of findDOMNode for the trigger in react strict mode.
|
|
41
42
|
*/
|
|
42
43
|
reference?: HTMLElement | (() => HTMLElement) | React.RefObject<any>;
|
|
43
44
|
/** The popper (menu/tooltip/popover) element */
|
|
@@ -122,6 +123,10 @@ export interface PopperProps {
|
|
|
122
123
|
| 'right-start'
|
|
123
124
|
| 'right-end'
|
|
124
125
|
)[];
|
|
126
|
+
/** @beta Bypasses the use of findDOMNode for both the popper and trigger in react strict mode. Without this flag, the trigger and popper will require passed references via the reference property (trigger) and popperRef property (popper) for strict mode. */
|
|
127
|
+
removeFindDomNode?: boolean;
|
|
128
|
+
/** @beta Reference to the popper (menu/tooltip/popover) element. Passing this property or the removeFindDomNode property, will bypass the use of findDOMNode for the popper in react strict mode. The popper property is still required. */
|
|
129
|
+
popperRef?: HTMLElement | (() => HTMLElement) | React.RefObject<any>;
|
|
125
130
|
}
|
|
126
131
|
|
|
127
132
|
export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
@@ -149,11 +154,13 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
|
149
154
|
onDocumentKeyDown,
|
|
150
155
|
enableFlip = true,
|
|
151
156
|
flipBehavior = 'flip',
|
|
152
|
-
reference
|
|
157
|
+
reference,
|
|
158
|
+
removeFindDomNode = false,
|
|
159
|
+
popperRef
|
|
153
160
|
}) => {
|
|
154
161
|
const [triggerElement, setTriggerElement] = React.useState(null);
|
|
155
162
|
const [refElement, setRefElement] = React.useState<HTMLElement>(null);
|
|
156
|
-
const [popperElement, setPopperElement] = React.useState(null);
|
|
163
|
+
const [popperElement, setPopperElement] = React.useState<HTMLElement>(null);
|
|
157
164
|
const [ready, setReady] = React.useState(false);
|
|
158
165
|
const refOrTrigger = refElement || triggerElement;
|
|
159
166
|
const onDocumentClickCallback = React.useCallback(
|
|
@@ -173,6 +180,16 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
|
173
180
|
}
|
|
174
181
|
}
|
|
175
182
|
}, [reference]);
|
|
183
|
+
React.useEffect(() => {
|
|
184
|
+
// When the popperRef is defined or the popper visiblity changes, ensure the popper element is up to date
|
|
185
|
+
if (popperRef) {
|
|
186
|
+
if ((popperRef as React.RefObject<any>).current) {
|
|
187
|
+
setPopperElement((popperRef as React.RefObject<any>).current);
|
|
188
|
+
} else if (typeof popperRef === 'function') {
|
|
189
|
+
setPopperElement(popperRef());
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}, [isVisible, popperRef]);
|
|
176
193
|
const addEventListener = (listener: any, element: Document | HTMLElement, event: string) => {
|
|
177
194
|
if (listener && element) {
|
|
178
195
|
element.addEventListener(event, listener);
|
|
@@ -305,7 +322,7 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
|
305
322
|
return positionModifiers.top;
|
|
306
323
|
};
|
|
307
324
|
|
|
308
|
-
const
|
|
325
|
+
const options = {
|
|
309
326
|
className: css(popper.props && popper.props.className, positionModifiers && modifierFromPopperPosition()),
|
|
310
327
|
style: {
|
|
311
328
|
...((popper.props && popper.props.style) || {}),
|
|
@@ -313,7 +330,9 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
|
313
330
|
zIndex
|
|
314
331
|
},
|
|
315
332
|
...attributes.popper
|
|
316
|
-
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const menuWithPopper = React.cloneElement(popper, options);
|
|
317
336
|
|
|
318
337
|
const getTarget: () => HTMLElement = () => {
|
|
319
338
|
if (typeof appendTo === 'function') {
|
|
@@ -322,17 +341,40 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
|
322
341
|
return appendTo;
|
|
323
342
|
};
|
|
324
343
|
|
|
344
|
+
/**
|
|
345
|
+
* To enable strict mode, the popper must either have its reference defined via the popperRef property,
|
|
346
|
+
* or the removeFindDomNode flag must be present. Even if the reference is passed in, unlike the trigger,
|
|
347
|
+
* the popper property must still be passed.
|
|
348
|
+
* The trigger must similarly have either its reference defined via the reference property, or the
|
|
349
|
+
* removeFindDomNode flag must be present. The trigger property is not required when the reference is passed.
|
|
350
|
+
*
|
|
351
|
+
* Strict mode may be enabled by passing both reference properties to Popper, or by passing the
|
|
352
|
+
* removeFindDomNode flag with either reference property, or by solely passing the removeFindDomNode
|
|
353
|
+
* flag.
|
|
354
|
+
*/
|
|
355
|
+
let popperPortal;
|
|
356
|
+
if (removeFindDomNode) {
|
|
357
|
+
// If removeFindDomNode is passed, use the removeFindDomNode method of wrapping divs
|
|
358
|
+
popperPortal = <div ref={node => setPopperElement(node?.firstElementChild as HTMLElement)}>{menuWithPopper}</div>;
|
|
359
|
+
} else if (popperRef) {
|
|
360
|
+
// If removeFindDomNode is not passed and popperRef is passed, use the popperRef method
|
|
361
|
+
popperPortal = menuWithPopper;
|
|
362
|
+
} else {
|
|
363
|
+
// If neither removeFindDomNode and popperRef exist, use the old method of FindRefWrapper
|
|
364
|
+
popperPortal = (
|
|
365
|
+
<FindRefWrapper onFoundRef={(foundRef: any) => setPopperElement(foundRef)}>{menuWithPopper}</FindRefWrapper>
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
325
369
|
return (
|
|
326
370
|
<>
|
|
327
|
-
{!reference && trigger && (
|
|
371
|
+
{!reference && trigger && React.isValidElement(trigger) && !removeFindDomNode && (
|
|
328
372
|
<FindRefWrapper onFoundRef={(foundRef: any) => setTriggerElement(foundRef)}>{trigger}</FindRefWrapper>
|
|
329
373
|
)}
|
|
330
|
-
{
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
getTarget()
|
|
335
|
-
)}
|
|
374
|
+
{!reference && trigger && React.isValidElement(trigger) && removeFindDomNode && (
|
|
375
|
+
<div ref={node => setTriggerElement(node?.firstElementChild as HTMLElement)}>{trigger}</div>
|
|
376
|
+
)}
|
|
377
|
+
{ready && isVisible && ReactDOM.createPortal(popperPortal, getTarget())}
|
|
336
378
|
</>
|
|
337
379
|
);
|
|
338
380
|
};
|
|
@@ -56,11 +56,22 @@ import { canUseDOM } from './util';
|
|
|
56
56
|
* );
|
|
57
57
|
* }
|
|
58
58
|
*
|
|
59
|
+
* Example 3 - With debounced method passed in:
|
|
60
|
+
*
|
|
61
|
+
* public componentDidMount() {
|
|
62
|
+
* this.observer = getResizeObserver(this.inputRef.current, debounce(this.handleResize, 250), false);
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
59
65
|
* @param {Element} containerRefElement The container reference to observe
|
|
60
66
|
* @param {Function} handleResize The function to call for resize events
|
|
67
|
+
* @param {boolean} useRequestAnimationFrame Whether to pass the handleResize function as a callback to requestAnimationFrame. Pass in false when the function passed in is debounced. Defaults to true.
|
|
61
68
|
* @return {Function} The function used to unobserve resize events
|
|
62
69
|
*/
|
|
63
|
-
export const getResizeObserver = (
|
|
70
|
+
export const getResizeObserver = (
|
|
71
|
+
containerRefElement: Element,
|
|
72
|
+
handleResize: () => void,
|
|
73
|
+
useRequestAnimationFrame: boolean = true
|
|
74
|
+
) => {
|
|
64
75
|
let unobserve: any;
|
|
65
76
|
|
|
66
77
|
if (canUseDOM) {
|
|
@@ -69,11 +80,18 @@ export const getResizeObserver = (containerRefElement: Element, handleResize: ()
|
|
|
69
80
|
if (containerRefElement && ResizeObserver) {
|
|
70
81
|
const resizeObserver = new ResizeObserver((entries: any) => {
|
|
71
82
|
// Wrap resize function in requestAnimationFrame to avoid "ResizeObserver loop limit exceeded" errors
|
|
72
|
-
|
|
83
|
+
if (useRequestAnimationFrame) {
|
|
84
|
+
window.requestAnimationFrame(() => {
|
|
85
|
+
if (Array.isArray(entries) && entries.length > 0) {
|
|
86
|
+
handleResize();
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
// Avoid wrapping function in requestAnimationFrame if the function is debounced
|
|
90
|
+
} else {
|
|
73
91
|
if (Array.isArray(entries) && entries.length > 0) {
|
|
74
92
|
handleResize();
|
|
75
93
|
}
|
|
76
|
-
}
|
|
94
|
+
}
|
|
77
95
|
});
|
|
78
96
|
resizeObserver.observe(containerRefElement);
|
|
79
97
|
unobserve = () => resizeObserver.unobserve(containerRefElement);
|