Skip to content

Commit e647d41

Browse files
authored
feat(Modals): support auto-closing popovers sharing the same opener (#8149)
Closes #8147
1 parent a865429 commit e647d41

5 files changed

Lines changed: 350 additions & 91 deletions

File tree

packages/main/src/components/Modals/Modals.cy.tsx

Lines changed: 76 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,33 @@ describe('Modals - static helpers', () => {
4545
>
4646
Show Popover
4747
</Button>
48+
<br />
49+
<Button
50+
onClick={() => {
51+
Modals.showPopover(
52+
{
53+
opener: 'modals-show-popover',
54+
children: 'Popover 2',
55+
},
56+
{ autoClosePopovers: true },
57+
);
58+
}}
59+
>
60+
Show Popover 2
61+
</Button>
4862
</>
4963
);
64+
};
65+
cy.mount(<TestComp />);
5066

51-
cy.mount(<TestComp />);
67+
cy.findByText('Show Popover').click();
68+
cy.findByText('Popover Content').should('be.visible');
69+
cy.findByText('Show Popover').click();
70+
cy.get('[ui5-popover]').should('have.length', 2);
5271

53-
cy.findByText('Show Popover').click();
54-
cy.findByText('Popover Content').should('be.visible');
55-
cy.findByText('Close').click();
56-
cy.findByText('Dialog Content').should('not.exist');
57-
};
72+
cy.findByText('Show Popover 2').click();
73+
cy.findByText('Popover 2').should('be.visible');
74+
cy.get('[ui5-popover]').should('have.length', 1);
5875
});
5976

6077
it('showResponsivePopover', () => {
@@ -63,27 +80,43 @@ describe('Modals - static helpers', () => {
6380
<>
6481
<Modals />
6582
<Button
66-
id="modals-show-popover"
83+
id="modals-show-responsive-popover"
6784
onClick={() => {
68-
const { close } = Modals.showResponsivePopover({
69-
opener: 'modals-show-popover',
70-
children: 'Popover Content',
71-
footer: <Bar endContent={<Button onClick={() => close()}>Close</Button>} />,
85+
Modals.showResponsivePopover({
86+
opener: 'modals-show-responsive-popover',
87+
children: 'ResponsivePopover Content',
7288
});
7389
}}
7490
>
75-
Show Popover
91+
Show ResponsivePopover
92+
</Button>
93+
<br />
94+
<Button
95+
onClick={() => {
96+
Modals.showResponsivePopover(
97+
{
98+
opener: 'modals-show-responsive-popover',
99+
children: 'ResponsivePopover 2',
100+
},
101+
{ autoClosePopovers: true },
102+
);
103+
}}
104+
>
105+
Show ResponsivePopover 2
76106
</Button>
77107
</>
78108
);
109+
};
110+
cy.mount(<TestComp />);
79111

80-
cy.mount(<TestComp />);
112+
cy.findByText('Show ResponsivePopover').click();
113+
cy.findByText('ResponsivePopover Content').should('be.visible');
114+
cy.findByText('Show ResponsivePopover').click();
115+
cy.get('[ui5-responsive-popover]').should('have.length', 2);
81116

82-
cy.findByText('Show Popover').click();
83-
cy.findByText('Popover Content').should('be.visible');
84-
cy.findByText('Close').click();
85-
cy.findByText('Dialog Content').should('not.exist');
86-
};
117+
cy.findByText('Show ResponsivePopover 2').click();
118+
cy.findByText('ResponsivePopover 2').should('be.visible');
119+
cy.get('[ui5-responsive-popover]').should('have.length', 1);
87120
});
88121

89122
it('showMenu', () => {
@@ -92,26 +125,42 @@ describe('Modals - static helpers', () => {
92125
<>
93126
<Modals />
94127
<Button
95-
id="modals-show-popover"
128+
id="modals-show-menu"
96129
onClick={() => {
97130
Modals.showMenu({
98-
opener: 'modals-show-popover',
99-
children: <MenuItem text="MenuItem" />,
131+
opener: 'modals-show-menu',
132+
children: <MenuItem text="MenuItem 1" />,
100133
});
101134
}}
102135
>
103136
Show Menu
104137
</Button>
138+
<Button
139+
onClick={() => {
140+
Modals.showMenu(
141+
{
142+
opener: 'modals-show-menu',
143+
children: <MenuItem text="MenuItem 2" />,
144+
},
145+
{ autoClosePopovers: true },
146+
);
147+
}}
148+
>
149+
Show Menu 2
150+
</Button>
105151
</>
106152
);
153+
};
154+
cy.mount(<TestComp />);
107155

108-
cy.mount(<TestComp />);
156+
cy.findByText('Show Menu').click();
157+
cy.get('[ui5-menu-item][text="MenuItem 1"]').should('be.visible');
158+
cy.findByText('Show Menu').click();
159+
cy.get('[ui5-menu]').should('have.length', 2);
109160

110-
cy.findByText('Show Menu').click();
111-
cy.findByText('MenuItem').should('be.visible');
112-
cy.findByText('MenuItem').click();
113-
cy.findByText('MenuItem').should('not.exist');
114-
};
161+
cy.findByText('Show Menu 2').click();
162+
cy.get('[ui5-menu-item][text="MenuItem 2"]').should('be.visible');
163+
cy.get('[ui5-menu]').should('have.length', 1);
115164
});
116165

117166
it('showMessageBox', () => {

packages/main/src/components/Modals/Modals.mdx

Lines changed: 95 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,26 @@ root.render(
3939
```typescript
4040
import { Modals } from '@ui5/webcomponents-react/Modals';
4141

42+
// Recommended: using config object
43+
const { ref, close } = Modals.showDialog(props, config);
44+
45+
// Legacy: using container directly
4246
const { ref, close } = Modals.showDialog(props, container);
4347
```
4448

4549
**Parameters**
4650

47-
| Parameter | Description |
48-
| ------------- | ------------------------------------------------------------------------------------- |
49-
| `props` | All supported `Dialog` props (see table below). `open` will always be set to `true`. |
50-
| _`container`_ | Optional container where the `Dialog` should be mounted. Defaults to `document.body`. |
51+
| Parameter | Description |
52+
| ------------- | ------------------------------------------------------------------------------------------------------- |
53+
| `props` | All supported `Dialog` props (see table below). `open` will always be set to `true`. |
54+
| _`config`_ | Optional configuration object. See config options below. |
55+
| _`container`_ | _(deprecated)_ Optional container where the `Dialog` should be mounted. Use `config.container` instead. |
56+
57+
**Config Options** _(since 2.19.0)_
58+
59+
| Property | Description |
60+
| ----------- | -------------------------------------------------------------------------------------- |
61+
| `container` | Optional container where the component should be mounted. Defaults to `document.body`. |
5162

5263
**Return Value**
5364

@@ -71,15 +82,27 @@ The `showDialog` method returns an object with the following properties:
7182
```typescript
7283
import { Modals } from '@ui5/webcomponents-react/Modals';
7384

85+
// Recommended: using config object
86+
const { ref, close } = Modals.showPopover(props, config);
87+
88+
// Legacy: using container directly
7489
const { ref, close } = Modals.showPopover(props, container);
7590
```
7691

7792
**Parameters**
7893

79-
| Parameter | Description |
80-
| ------------- | -------------------------------------------------------------------------------------- |
81-
| `props` | All supported `Popover` props (see table below).`open` will always be set to `true`. |
82-
| _`container`_ | Optional container where the `Popover` should be mounted. Defaults to `document.body`. |
94+
| Parameter | Description |
95+
| ------------- | -------------------------------------------------------------------------------------------------------- |
96+
| `props` | All supported `Popover` props (see table below). `open` will always be set to `true`. |
97+
| _`config`_ | Optional configuration object. See config options below. |
98+
| _`container`_ | _(deprecated)_ Optional container where the `Popover` should be mounted. Use `config.container` instead. |
99+
100+
**Config Options** _(since 2.19.0)_
101+
102+
| Property | Description |
103+
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
104+
| `container` | Optional container where the component should be mounted. Defaults to `document.body`. |
105+
| `autoClosePopovers` | If set to `true`, opening a new Popover will automatically close all currently opened Popovers that share the same opener. Only affects Popover, Menu, and ResponsivePopover. |
83106

84107
**Return Value**
85108

@@ -103,15 +126,27 @@ The `showPopover` method returns an object with the following properties:
103126
```typescript
104127
import { Modals } from '@ui5/webcomponents-react/Modals';
105128

129+
// Recommended: using config object
130+
const { ref, close } = Modals.showResponsivePopover(props, config);
131+
132+
// Legacy: using container directly
106133
const { ref, close } = Modals.showResponsivePopover(props, container);
107134
```
108135

109136
**Parameters**
110137

111-
| Parameter | Description |
112-
| ------------- | ------------------------------------------------------------------------------------------------ |
113-
| `props` | All supported `ResponsivePopover` props (see table below). `open` will always be set to `true`. |
114-
| _`container`_ | Optional container where the `ResponsivePopover` should be mounted. Defaults to `document.body`. |
138+
| Parameter | Description |
139+
| ------------- | ------------------------------------------------------------------------------------------------------------------ |
140+
| `props` | All supported `ResponsivePopover` props (see table below). `open` will always be set to `true`. |
141+
| _`config`_ | Optional configuration object. See config options below. |
142+
| _`container`_ | _(deprecated)_ Optional container where the `ResponsivePopover` should be mounted. Use `config.container` instead. |
143+
144+
**Config Options** _(since 2.19.0)_
145+
146+
| Property | Description |
147+
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
148+
| `container` | Optional container where the component should be mounted. Defaults to `document.body`. |
149+
| `autoClosePopovers` | If set to `true`, opening a new Popover will automatically close all currently opened Popovers that share the same opener. Only affects Popover, Menu, and ResponsivePopover. |
115150

116151
**Return Value**
117152

@@ -137,19 +172,31 @@ The `showResponsivePopover` method returns an object with the following properti
137172
```typescript
138173
import { Modals } from '@ui5/webcomponents-react/Modals';
139174

175+
// Recommended: using config object
176+
const { ref, close } = Modals.showMenu(props, config);
177+
178+
// Legacy: using container directly
140179
const { ref, close } = Modals.showMenu(props, container);
141180
```
142181

143182
**Parameters**
144183

145-
| Parameter | Description |
146-
| ------------- | ----------------------------------------------------------------------------------- |
147-
| `props` | All supported `Menu` props (see table below). `open` will always be set to `true`. |
148-
| _`container`_ | Optional container where the `Menu` should be mounted. Defaults to `document.body`. |
184+
| Parameter | Description |
185+
| ------------- | ----------------------------------------------------------------------------------------------------- |
186+
| `props` | All supported `Menu` props (see table below). `open` will always be set to `true`. |
187+
| _`config`_ | Optional configuration object. See config options below. |
188+
| _`container`_ | _(deprecated)_ Optional container where the `Menu` should be mounted. Use `config.container` instead. |
189+
190+
**Config Options** _(since 2.19.0)_
191+
192+
| Property | Description |
193+
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
194+
| `container` | Optional container where the component should be mounted. Defaults to `document.body`. |
195+
| `autoClosePopovers` | If set to `true`, opening a new Popover will automatically close all currently opened Popovers that share the same opener. Only affects Popover, Menu, and ResponsivePopover. |
149196

150197
**Return Value**
151198

152-
The `Menu` method returns an object with the following properties:
199+
The `showMenu` method returns an object with the following properties:
153200

154201
| Property | Description |
155202
| --------- | ---------------------------------------------------------------- |
@@ -169,15 +216,26 @@ The `Menu` method returns an object with the following properties:
169216
```typescript
170217
import { Modals } from '@ui5/webcomponents-react/Modals';
171218

219+
// Recommended: using config object
220+
const { ref, close } = Modals.showMessageBox(props, config);
221+
222+
// Legacy: using container directly
172223
const { ref, close } = Modals.showMessageBox(props, container);
173224
```
174225

175226
**Parameters**
176227

177-
| Parameter | Description |
178-
| ------------- | ----------------------------------------------------------------------------------------- |
179-
| `props` | All supported `MessageBox` props (see table below). `open` will always be set to `true`. |
180-
| _`container`_ | Optional container where the `MessageBox` should be mounted. Defaults to `document.body`. |
228+
| Parameter | Description |
229+
| ------------- | ----------------------------------------------------------------------------------------------------------- |
230+
| `props` | All supported `MessageBox` props (see table below). `open` will always be set to `true`. |
231+
| _`config`_ | Optional configuration object. See config options below. |
232+
| _`container`_ | _(deprecated)_ Optional container where the `MessageBox` should be mounted. Use `config.container` instead. |
233+
234+
**Config Options** _(since 2.19.0)_
235+
236+
| Property | Description |
237+
| ----------- | -------------------------------------------------------------------------------------- |
238+
| `container` | Optional container where the component should be mounted. Defaults to `document.body`. |
181239

182240
**Return Value**
183241

@@ -201,19 +259,30 @@ The `showMessageBox` method returns an object with the following properties:
201259
```typescript
202260
import { Modals } from '@ui5/webcomponents-react/Modals';
203261

262+
// Recommended: using config object
263+
const { ref } = Modals.showToast(props, config);
264+
265+
// Legacy: using container directly
204266
const { ref } = Modals.showToast(props, container);
205267
```
206268

207269
**Parameters**
208270

209-
| Parameter | Description |
210-
| ------------- | ----------------------------------------------------------------------------------- |
211-
| `props` | All supported `Toast` props(see table below). |
212-
| _`container`_ | Optional container where the `Toast` should be mounted.Defaults to `document.body`. |
271+
| Parameter | Description |
272+
| ------------- | ------------------------------------------------------------------------------------------------------ |
273+
| `props` | All supported `Toast` props (see table below). |
274+
| _`config`_ | Optional configuration object. See config options below. |
275+
| _`container`_ | _(deprecated)_ Optional container where the `Toast` should be mounted. Use `config.container` instead. |
276+
277+
**Config Options** _(since 2.19.0)_
278+
279+
| Property | Description |
280+
| ----------- | -------------------------------------------------------------------------------------- |
281+
| `container` | Optional container where the component should be mounted. Defaults to `document.body`. |
213282

214283
**Return Value**
215284

216-
The`showToast` method returns an object with the following properties:
285+
The `showToast` method returns an object with the following properties:
217286

218287
| Property | Description |
219288
| -------- | ----------------------------------------------------------------- |

0 commit comments

Comments
 (0)