@simplybusiness/mobius 4.1.0 → 4.1.2
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 +15 -1
- package/dist/cjs/components/Accordion/Accordion.js.map +1 -1
- package/dist/cjs/components/Button/Button.js.map +1 -1
- package/dist/cjs/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/cjs/components/Checkbox/CheckboxGroup.js.map +1 -1
- package/dist/cjs/components/Drawer/Content.js.map +1 -1
- package/dist/cjs/components/Drawer/Drawer.js.map +1 -1
- package/dist/cjs/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/cjs/components/DropdownMenu/DropdownMenu.stories.d.ts +1 -1
- package/dist/cjs/components/Fieldset/Fieldset.js.map +1 -1
- package/dist/cjs/components/Grid/Grid.stories.d.ts +1 -1
- package/dist/cjs/components/Icon/Icon.js.map +1 -1
- package/dist/cjs/components/Icon/IconStyle.js.map +1 -1
- package/dist/cjs/components/LinkButton/LinkButton.js.map +1 -1
- package/dist/cjs/components/LinkButton/LinkButton.test.js.map +1 -1
- package/dist/cjs/components/List/List.js.map +1 -1
- package/dist/cjs/components/List/ListItem.js.map +1 -1
- package/dist/cjs/components/Modal/Content.js.map +1 -1
- package/dist/cjs/components/Modal/Modal.js.map +1 -1
- package/dist/cjs/components/NumberField/NumberField.js.map +1 -1
- package/dist/cjs/components/Popover/Popover.d.ts +1 -2
- package/dist/cjs/components/Popover/Popover.js +40 -47
- package/dist/cjs/components/Popover/Popover.js.map +1 -1
- package/dist/cjs/components/Popover/Popover.stories.d.ts +3 -10
- package/dist/cjs/components/Popover/Popover.stories.js +4 -16
- package/dist/cjs/components/Popover/Popover.stories.js.map +1 -1
- package/dist/cjs/components/Popover/Popover.test.js +25 -26
- package/dist/cjs/components/Popover/Popover.test.js.map +1 -1
- package/dist/cjs/components/Progress/Progress.js.map +1 -1
- package/dist/cjs/components/Radio/Radio.js.map +1 -1
- package/dist/cjs/components/Radio/RadioGroup.js.map +1 -1
- package/dist/cjs/components/Select/Select.js.map +1 -1
- package/dist/cjs/components/Slider/Slider.js.map +1 -1
- package/dist/cjs/components/Slider/helpers.js.map +1 -1
- package/dist/cjs/components/Text/Text.js.map +1 -1
- package/dist/cjs/hooks/useBodyScrollLock/useBodyScrollLock.js.map +1 -1
- package/dist/cjs/hooks/useBreakpoint/useBreakpoint.js.map +1 -1
- package/dist/cjs/hooks/useButton/useButton.js.map +1 -1
- package/dist/cjs/hooks/useLabel/useLabel.js.map +1 -1
- package/dist/cjs/hooks/useOnClickOutside/useOnClickOutside.js.map +1 -1
- package/dist/cjs/hooks/useWindowEvent/useWindowEvent.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils/changeCSS.js.map +1 -1
- package/dist/cjs/utils/mergeRefs.js.map +1 -1
- package/dist/cjs/utils/sizeClasses.js.map +1 -1
- package/dist/esm/components/Accordion/Accordion.js.map +1 -1
- package/dist/esm/components/Button/Button.js.map +1 -1
- package/dist/esm/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/esm/components/Checkbox/CheckboxGroup.js.map +1 -1
- package/dist/esm/components/Drawer/Content.js.map +1 -1
- package/dist/esm/components/Drawer/Drawer.js.map +1 -1
- package/dist/esm/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/esm/components/Fieldset/Fieldset.js.map +1 -1
- package/dist/esm/components/Icon/Icon.js.map +1 -1
- package/dist/esm/components/Icon/IconStyle.js.map +1 -1
- package/dist/esm/components/LinkButton/LinkButton.js.map +1 -1
- package/dist/esm/components/List/List.js.map +1 -1
- package/dist/esm/components/List/ListItem.js.map +1 -1
- package/dist/esm/components/Modal/Content.js.map +1 -1
- package/dist/esm/components/Modal/Modal.js.map +1 -1
- package/dist/esm/components/NumberField/NumberField.js.map +1 -1
- package/dist/esm/components/Popover/Popover.js +41 -48
- package/dist/esm/components/Popover/Popover.js.map +1 -1
- package/dist/esm/components/Progress/Progress.js.map +1 -1
- package/dist/esm/components/Radio/Radio.js.map +1 -1
- package/dist/esm/components/Radio/RadioGroup.js.map +1 -1
- package/dist/esm/components/Select/Select.js.map +1 -1
- package/dist/esm/components/Slider/Slider.js.map +1 -1
- package/dist/esm/components/Slider/helpers.js.map +1 -1
- package/dist/esm/components/Text/Text.js.map +1 -1
- package/dist/esm/hooks/useBodyScrollLock/useBodyScrollLock.js.map +1 -1
- package/dist/esm/hooks/useBreakpoint/useBreakpoint.js.map +1 -1
- package/dist/esm/hooks/useButton/useButton.js.map +1 -1
- package/dist/esm/hooks/useLabel/useLabel.js.map +1 -1
- package/dist/esm/hooks/useOnClickOutside/useOnClickOutside.js.map +1 -1
- package/dist/esm/hooks/useWindowEvent/useWindowEvent.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/utils/changeCSS.js.map +1 -1
- package/dist/esm/utils/mergeRefs.js.map +1 -1
- package/dist/esm/utils/sizeClasses.js.map +1 -1
- package/dist/mobius.d.ts +0 -1
- package/package.json +24 -24
- package/src/components/Popover/Popover.mdx +19 -27
- package/src/components/Popover/Popover.stories.tsx +18 -28
- package/src/components/Popover/Popover.story.styles.css +3 -2
- package/src/components/Popover/Popover.test.tsx +39 -38
- package/src/components/Popover/Popover.tsx +66 -66
|
@@ -8,9 +8,9 @@ import { Popover } from "./Popover";
|
|
|
8
8
|
|
|
9
9
|
The `Popover` component is used to display popup tooltips with additional information for users. Children of the Popover become tooltip contents and `trigger` is a render prop for the element that will present the Popover when clicked.
|
|
10
10
|
|
|
11
|
-
When presented, the Popover will align
|
|
11
|
+
When presented, the Popover will align horizontally with the centre of the trigger element, and by default it will appear below.
|
|
12
12
|
|
|
13
|
-
You can dismiss a Popover by clicking the close icon or by pressing `Enter` or `Escape` keys.
|
|
13
|
+
You can dismiss a Popover by clicking the close icon, clicking outside, or by pressing `Enter` or `Escape` keys.
|
|
14
14
|
|
|
15
15
|
Focus always remains on the element that triggers the Popover; its content should not accept focus.
|
|
16
16
|
|
|
@@ -38,40 +38,32 @@ return (
|
|
|
38
38
|
|
|
39
39
|
<Story of={PopoverStories.Normal} />
|
|
40
40
|
|
|
41
|
-
##
|
|
41
|
+
## Custom Trigger
|
|
42
42
|
|
|
43
|
-
This is a customised trigger as used in the Quote Comparison Page, which has a large, clickable
|
|
44
|
-
|
|
45
|
-
To achieve this, you need to control `isOpen` state with the clickable element and only use Popover to wrap the element you want to align with.
|
|
43
|
+
This is a customised trigger as used in the Quote Comparison Page, which has a large, clickable link (text and icon).
|
|
46
44
|
|
|
47
45
|
```jsx
|
|
48
46
|
import { Popover, Button, Flex } from "@simplybusiness/mobius";
|
|
49
47
|
|
|
50
|
-
const [isOpen, setIsOpen] = useState<boolean>(false);
|
|
51
|
-
const handleClick = () => setIsOpen(!isOpen);
|
|
52
|
-
|
|
53
|
-
// Component passed to trigger prop must be wrapped with forwardRef()
|
|
54
|
-
const Icon = forwardRef(
|
|
55
|
-
(props: IconProps, ref: Ref<SVGSVGElement>) => (
|
|
56
|
-
<svg ref={ref} {...props}>...</svg>
|
|
57
|
-
),
|
|
58
|
-
);
|
|
59
|
-
|
|
60
48
|
return (
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
</
|
|
69
|
-
|
|
70
|
-
|
|
49
|
+
<Popover
|
|
50
|
+
trigger={
|
|
51
|
+
<Button variant="ghost">
|
|
52
|
+
<Flex>
|
|
53
|
+
<span>Occurrence Limit</span>
|
|
54
|
+
<QuestionIcon />
|
|
55
|
+
</Flex>
|
|
56
|
+
</Button>
|
|
57
|
+
}
|
|
58
|
+
>
|
|
59
|
+
This is the maximum amount of money you'll get to cover a single
|
|
60
|
+
incident that occurs during the policy period, regardless of when it's
|
|
61
|
+
reported.
|
|
62
|
+
</Popover>
|
|
71
63
|
);
|
|
72
64
|
```
|
|
73
65
|
|
|
74
|
-
<Canvas of={PopoverStories.
|
|
66
|
+
<Canvas of={PopoverStories.CustomTrigger} />
|
|
75
67
|
|
|
76
68
|
## Props
|
|
77
69
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Meta } from "@storybook/react";
|
|
2
|
-
import { Ref, forwardRef
|
|
2
|
+
import { Ref, forwardRef } from "react";
|
|
3
3
|
import { Button, Flex, Popover, PopoverProps } from "..";
|
|
4
4
|
import { excludeControls } from "../../utils/excludeControls";
|
|
5
5
|
|
|
@@ -7,9 +7,6 @@ export default {
|
|
|
7
7
|
title: "Components/Popover",
|
|
8
8
|
component: Popover,
|
|
9
9
|
argTypes: {
|
|
10
|
-
isOpen: {
|
|
11
|
-
control: { type: "boolean" },
|
|
12
|
-
},
|
|
13
10
|
...excludeControls(
|
|
14
11
|
"className",
|
|
15
12
|
"children",
|
|
@@ -17,6 +14,7 @@ export default {
|
|
|
17
14
|
"id",
|
|
18
15
|
"onOpen",
|
|
19
16
|
"onClose",
|
|
17
|
+
"anchor",
|
|
20
18
|
),
|
|
21
19
|
},
|
|
22
20
|
decorators: [
|
|
@@ -70,36 +68,28 @@ const QuestionIcon = forwardRef(
|
|
|
70
68
|
export const Normal: Meta<typeof Popover> = {
|
|
71
69
|
render: (args: PopoverProps) => <Popover {...args} />,
|
|
72
70
|
args: {
|
|
73
|
-
isOpen: undefined,
|
|
74
71
|
children: <>No way! Now I know everything I need to 🚀.</>,
|
|
75
72
|
trigger: <Button variant="primary">If only I had more information</Button>,
|
|
76
73
|
},
|
|
77
74
|
};
|
|
78
75
|
|
|
79
|
-
export const
|
|
80
|
-
render: (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
</div>
|
|
93
|
-
);
|
|
94
|
-
},
|
|
95
|
-
args: {
|
|
96
|
-
trigger: <QuestionIcon />,
|
|
97
|
-
children: (
|
|
98
|
-
<>
|
|
76
|
+
export const CustomTrigger: Meta<typeof Popover> = {
|
|
77
|
+
render: () => (
|
|
78
|
+
<div className="popover-example">
|
|
79
|
+
<Popover
|
|
80
|
+
trigger={
|
|
81
|
+
<Button variant="ghost">
|
|
82
|
+
<Flex>
|
|
83
|
+
<span>Occurrence Limit</span>
|
|
84
|
+
<QuestionIcon />
|
|
85
|
+
</Flex>
|
|
86
|
+
</Button>
|
|
87
|
+
}
|
|
88
|
+
>
|
|
99
89
|
This is the maximum amount of money you'll get to cover a single
|
|
100
90
|
incident that occurs during the policy period, regardless of when
|
|
101
91
|
it's reported.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
92
|
+
</Popover>
|
|
93
|
+
</div>
|
|
94
|
+
),
|
|
105
95
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
.popover-example {
|
|
2
2
|
max-width: 500px;
|
|
3
|
+
min-height: 220px;
|
|
3
4
|
margin: 0 auto;
|
|
4
5
|
}
|
|
5
6
|
|
|
6
|
-
.popover-example .mobius\/Button {
|
|
7
|
+
.popover-example > .mobius\/Button {
|
|
7
8
|
border: none;
|
|
8
9
|
padding: 0;
|
|
9
10
|
font-weight: var(--font-weight-normal);
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
margin-bottom: 6px;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
.popover-example .mobius\/PopoverToggle {
|
|
23
|
+
.popover-example .mobius\/PopoverToggle svg {
|
|
23
24
|
width: 16px;
|
|
24
25
|
margin-left: 4px;
|
|
25
26
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
2
2
|
import { Popover } from ".";
|
|
3
3
|
|
|
4
|
-
const CONTAINER_ID = "react-tiny-popover-container";
|
|
5
4
|
const CONTAINER_CLASS_NAME = "mobius/PopoverContainer";
|
|
6
5
|
const TOGGLE_CLASS_NAME = "mobius/PopoverToggle";
|
|
7
6
|
const POPOVER_CLASS_NAME = "mobius/Popover";
|
|
@@ -63,8 +62,7 @@ describe("Popover", () => {
|
|
|
63
62
|
|
|
64
63
|
fireEvent.click(button);
|
|
65
64
|
|
|
66
|
-
const popoverContainer =
|
|
67
|
-
?.firstChild;
|
|
65
|
+
const popoverContainer = button.nextSibling;
|
|
68
66
|
|
|
69
67
|
await waitFor(() => {
|
|
70
68
|
expect(popoverContainer).toHaveClass("mobius");
|
|
@@ -99,39 +97,38 @@ describe("Popover", () => {
|
|
|
99
97
|
|
|
100
98
|
fireEvent.click(button);
|
|
101
99
|
|
|
102
|
-
const popoverContainer =
|
|
100
|
+
const popoverContainer = button.nextSibling;
|
|
103
101
|
|
|
104
102
|
await waitFor(() => {
|
|
105
|
-
expect(popoverContainer
|
|
103
|
+
expect(popoverContainer).toHaveClass(customClassName);
|
|
106
104
|
});
|
|
107
105
|
});
|
|
108
|
-
});
|
|
109
106
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
expect(onClose).not.toHaveBeenCalled();
|
|
131
|
-
});
|
|
107
|
+
it("passes trigger class names", () => {
|
|
108
|
+
const sampleText = "Sample Text";
|
|
109
|
+
const triggerText = "Click me";
|
|
110
|
+
const customClassName = "custom-trigger-class-name";
|
|
111
|
+
|
|
112
|
+
render(
|
|
113
|
+
<Popover
|
|
114
|
+
trigger={
|
|
115
|
+
<button type="button" className={customClassName}>
|
|
116
|
+
{triggerText}
|
|
117
|
+
</button>
|
|
118
|
+
}
|
|
119
|
+
>
|
|
120
|
+
{sampleText}
|
|
121
|
+
</Popover>,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const button = screen.getByText(triggerText);
|
|
125
|
+
|
|
126
|
+
expect(button).toHaveClass(customClassName);
|
|
132
127
|
});
|
|
128
|
+
});
|
|
133
129
|
|
|
134
|
-
|
|
130
|
+
describe("events", () => {
|
|
131
|
+
it("calls onOpen when Popover is opened", async () => {
|
|
135
132
|
const sampleText = "Sample Text";
|
|
136
133
|
const triggerText = "Click me";
|
|
137
134
|
const onOpen = jest.fn();
|
|
@@ -147,15 +144,17 @@ describe("Popover", () => {
|
|
|
147
144
|
</Popover>,
|
|
148
145
|
);
|
|
149
146
|
|
|
150
|
-
const
|
|
147
|
+
const toggle = screen.getByText(triggerText);
|
|
151
148
|
|
|
152
|
-
fireEvent.click(
|
|
149
|
+
fireEvent.click(toggle);
|
|
153
150
|
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
await waitFor(() => {
|
|
152
|
+
expect(onOpen).toHaveBeenCalled();
|
|
153
|
+
expect(onClose).not.toHaveBeenCalled();
|
|
154
|
+
});
|
|
156
155
|
});
|
|
157
156
|
|
|
158
|
-
it("calls onClose when Popover is closed", () => {
|
|
157
|
+
it("calls onClose when Popover is closed", async () => {
|
|
159
158
|
const sampleText = "Sample Text";
|
|
160
159
|
const triggerText = "Click me";
|
|
161
160
|
const onOpen = jest.fn();
|
|
@@ -171,16 +170,18 @@ describe("Popover", () => {
|
|
|
171
170
|
</Popover>,
|
|
172
171
|
);
|
|
173
172
|
|
|
174
|
-
const
|
|
173
|
+
const toggle = screen.getByText(triggerText);
|
|
175
174
|
|
|
176
|
-
fireEvent.click(
|
|
175
|
+
fireEvent.click(toggle);
|
|
177
176
|
|
|
178
177
|
const closeButton = screen.getByLabelText("Close");
|
|
179
178
|
|
|
180
179
|
fireEvent.click(closeButton);
|
|
181
180
|
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
await waitFor(() => {
|
|
182
|
+
expect(onClose).toHaveBeenCalled();
|
|
183
|
+
expect(onOpen).toHaveBeenCalledTimes(1);
|
|
184
|
+
});
|
|
184
185
|
});
|
|
185
186
|
});
|
|
186
187
|
});
|
|
@@ -1,19 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FloatingArrow,
|
|
3
|
+
arrow,
|
|
4
|
+
autoUpdate,
|
|
5
|
+
offset,
|
|
6
|
+
useDismiss,
|
|
7
|
+
useFloating,
|
|
8
|
+
useInteractions,
|
|
9
|
+
} from "@floating-ui/react";
|
|
1
10
|
import { cross } from "@simplybusiness/icons";
|
|
11
|
+
import classNames from "classnames";
|
|
2
12
|
import {
|
|
3
13
|
ReactElement,
|
|
4
14
|
ReactNode,
|
|
5
15
|
Ref,
|
|
6
16
|
RefAttributes,
|
|
7
17
|
cloneElement,
|
|
8
|
-
useCallback,
|
|
9
|
-
useEffect,
|
|
10
18
|
useRef,
|
|
11
19
|
useState,
|
|
12
20
|
} from "react";
|
|
13
|
-
import classNames from "classnames";
|
|
14
|
-
import { Popover as TinyPopover } from "react-tiny-popover";
|
|
15
21
|
import { useWindowEvent } from "../../hooks";
|
|
16
|
-
import { DOMProps } from "../../types
|
|
22
|
+
import { DOMProps } from "../../types";
|
|
17
23
|
import { Button } from "../Button";
|
|
18
24
|
import { Icon } from "../Icon";
|
|
19
25
|
|
|
@@ -24,7 +30,6 @@ export interface PopoverProps
|
|
|
24
30
|
RefAttributes<PopoverElementType> {
|
|
25
31
|
children?: ReactNode;
|
|
26
32
|
trigger: ReactElement;
|
|
27
|
-
isOpen?: boolean;
|
|
28
33
|
/** Callback that fires each time the accordion is opened */
|
|
29
34
|
onOpen?: () => void;
|
|
30
35
|
/** Callback that fires each time the accordion is closed */
|
|
@@ -35,87 +40,83 @@ export interface PopoverProps
|
|
|
35
40
|
|
|
36
41
|
export type PopoverRef = Ref<PopoverElementType>;
|
|
37
42
|
|
|
43
|
+
const OFFSET_FROM_CONTENT_DEFAULT = 10;
|
|
44
|
+
|
|
38
45
|
export const Popover = (props: PopoverProps) => {
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
const { trigger, children, onOpen, onClose, className } = props;
|
|
47
|
+
const arrowRef = useRef(null);
|
|
48
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
49
|
+
const { refs, floatingStyles, context } = useFloating({
|
|
50
|
+
open: isOpen,
|
|
51
|
+
onOpenChange: setIsOpen,
|
|
52
|
+
whileElementsMounted: autoUpdate,
|
|
53
|
+
middleware: [
|
|
54
|
+
arrow({
|
|
55
|
+
element: arrowRef,
|
|
56
|
+
}),
|
|
57
|
+
offset(OFFSET_FROM_CONTENT_DEFAULT),
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
const dismiss = useDismiss(context, {
|
|
61
|
+
bubbles: true,
|
|
62
|
+
outsidePress: (event: MouseEvent) => {
|
|
63
|
+
// Prevent 'onClose' from firing when clicking the toggle to close
|
|
64
|
+
const toggle = refs.reference.current as HTMLElement;
|
|
65
|
+
const isToggleClick = !toggle?.contains(event.target as HTMLElement);
|
|
66
|
+
if (isToggleClick) {
|
|
67
|
+
onClose?.();
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
const { getReferenceProps, getFloatingProps } = useInteractions([dismiss]);
|
|
73
|
+
|
|
45
74
|
const containerClasses = classNames(
|
|
46
75
|
"mobius",
|
|
47
76
|
"mobius/PopoverContainer",
|
|
48
77
|
className,
|
|
49
78
|
);
|
|
50
|
-
const noop = () => {};
|
|
51
|
-
|
|
52
|
-
const openPopover = useCallback(() => {
|
|
53
|
-
setOpen(true);
|
|
54
|
-
|
|
55
|
-
if (onOpen) {
|
|
56
|
-
onOpen();
|
|
57
|
-
}
|
|
58
|
-
}, [onOpen]);
|
|
59
|
-
|
|
60
|
-
const closePopover = useCallback(() => {
|
|
61
|
-
setOpen(false);
|
|
62
|
-
|
|
63
|
-
if (onClose) {
|
|
64
|
-
onClose();
|
|
65
|
-
}
|
|
66
|
-
}, [onClose]);
|
|
67
79
|
|
|
68
|
-
const
|
|
69
|
-
if (
|
|
70
|
-
|
|
80
|
+
const toggleVisibility = () => {
|
|
81
|
+
if (isOpen) {
|
|
82
|
+
setIsOpen(false);
|
|
83
|
+
onClose?.();
|
|
71
84
|
return;
|
|
72
85
|
}
|
|
73
86
|
|
|
74
|
-
|
|
87
|
+
setIsOpen(true);
|
|
88
|
+
onOpen?.();
|
|
75
89
|
};
|
|
76
90
|
|
|
77
91
|
const triggerComponent = cloneElement(trigger, {
|
|
78
|
-
|
|
79
|
-
|
|
92
|
+
ref: refs.setReference,
|
|
93
|
+
className: classNames(trigger.props.className, "mobius/PopoverToggle"),
|
|
94
|
+
onClick: toggleVisibility,
|
|
95
|
+
...getReferenceProps(),
|
|
80
96
|
});
|
|
81
97
|
|
|
82
98
|
useWindowEvent("keydown", e => {
|
|
83
|
-
if (
|
|
84
|
-
|
|
99
|
+
if (e.key === "Escape") {
|
|
100
|
+
onClose?.();
|
|
85
101
|
}
|
|
86
102
|
});
|
|
87
103
|
|
|
88
|
-
useEffect(() => {
|
|
89
|
-
if (isOpen) {
|
|
90
|
-
openPopover();
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Prevent 'onClose' being called when
|
|
95
|
-
// 'isOpen === false' on initial render
|
|
96
|
-
if (previousIsOpen.current === isOpen) {
|
|
97
|
-
previousIsOpen.current = undefined;
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (!isOpen) {
|
|
102
|
-
closePopover();
|
|
103
|
-
}
|
|
104
|
-
}, [isOpen, closePopover, openPopover]);
|
|
105
|
-
|
|
106
104
|
return (
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
105
|
+
<>
|
|
106
|
+
{triggerComponent}
|
|
107
|
+
{isOpen && (
|
|
108
|
+
<div
|
|
109
|
+
className={containerClasses}
|
|
110
|
+
ref={refs.setFloating}
|
|
111
|
+
style={floatingStyles}
|
|
112
|
+
{...getFloatingProps()}
|
|
113
|
+
>
|
|
113
114
|
<div className="mobius/Popover">
|
|
114
115
|
<header className="mobius/PopoverHeader">
|
|
115
116
|
<Button
|
|
116
117
|
type="button"
|
|
117
118
|
className="mobius/PopoverCloseButton"
|
|
118
|
-
onClick={
|
|
119
|
+
onClick={toggleVisibility}
|
|
119
120
|
aria-label="Close"
|
|
120
121
|
variant="ghost"
|
|
121
122
|
>
|
|
@@ -128,10 +129,9 @@ export const Popover = (props: PopoverProps) => {
|
|
|
128
129
|
</header>
|
|
129
130
|
<div className="mobius/PopoverBody">{children}</div>
|
|
130
131
|
</div>
|
|
132
|
+
<FloatingArrow ref={arrowRef} context={context} width={20} />
|
|
131
133
|
</div>
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
{triggerComponent}
|
|
135
|
-
</TinyPopover>
|
|
134
|
+
)}
|
|
135
|
+
</>
|
|
136
136
|
);
|
|
137
137
|
};
|