Skip to content

Commit 7f23cc0

Browse files
author
Nicolas Naso
committed
feat(select): allow to pass custom close button text
Add a new property to customize the close button in the select when the interface is Modal.
1 parent 21f49b0 commit 7f23cc0

22 files changed

+155
-6
lines changed

core/api.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,6 +1695,7 @@ ion-select,part,supporting-text
16951695
ion-select,part,text
16961696

16971697
ion-select-modal,scoped
1698+
ion-select-modal,prop,closeText,string | undefined,undefined,false,false
16981699
ion-select-modal,prop,header,string | undefined,undefined,false,false
16991700
ion-select-modal,prop,multiple,boolean | undefined,undefined,false,false
17001701
ion-select-modal,prop,options,SelectModalOption[],[],false,false

core/src/components.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,6 +2862,7 @@ export namespace Components {
28622862
"value"?: any | null;
28632863
}
28642864
interface IonSelectModal {
2865+
"closeText"?: string;
28652866
"header"?: string;
28662867
"multiple"?: boolean;
28672868
"options": SelectModalOption[];
@@ -7742,6 +7743,7 @@ declare namespace LocalJSX {
77427743
"value"?: any | null;
77437744
}
77447745
interface IonSelectModal {
7746+
"closeText"?: string;
77457747
"header"?: string;
77467748
"multiple"?: boolean;
77477749
"options"?: SelectModalOption[];

core/src/components/select-modal/select-modal.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export class SelectModal implements ComponentInterface {
2323

2424
@Prop() header?: string;
2525

26+
@Prop() closeText?: string;
27+
2628
@Prop() multiple?: boolean;
2729

2830
@Prop() options: SelectModalOption[] = [];
@@ -149,7 +151,7 @@ export class SelectModal implements ComponentInterface {
149151
{this.header !== undefined && <ion-title>{this.header}</ion-title>}
150152

151153
<ion-buttons slot="end">
152-
<ion-button onClick={() => this.closeModal()}>Close</ion-button>
154+
<ion-button onClick={() => this.closeModal()}>{this.closeText || 'Close'}</ion-button>
153155
</ion-buttons>
154156
</ion-toolbar>
155157
</ion-header>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!DOCTYPE html>
2+
<html lang="en" dir="ltr">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Select - Modal</title>
6+
<meta
7+
name="viewport"
8+
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
9+
/>
10+
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
11+
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
12+
<script src="../../../../../scripts/testing/scripts.js"></script>
13+
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
14+
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
15+
</head>
16+
17+
<body>
18+
<ion-app>
19+
<ion-header>
20+
<ion-toolbar>
21+
<ion-title>Select Modal - Custom Close Text</ion-title>
22+
</ion-toolbar>
23+
</ion-header>
24+
25+
<ion-content>
26+
<ion-modal is-open="true">
27+
<ion-select-modal multiple="false" close-text="Close me"></ion-select-modal>
28+
</ion-modal>
29+
</ion-content>
30+
</ion-app>
31+
32+
<script>
33+
const selectModal = document.querySelector('ion-select-modal');
34+
selectModal.options = [
35+
{ value: 'apple', text: 'Apple', disabled: false, checked: true },
36+
{ value: 'banana', text: 'Banana', disabled: false, checked: false },
37+
];
38+
</script>
39+
</body>
40+
</html>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { expect } from '@playwright/test';
2+
import { configs, test } from '@utils/test/playwright';
3+
4+
import type { SelectModalOption } from '../../select-modal-interface';
5+
import { SelectModalPage } from '../fixtures';
6+
7+
const options: SelectModalOption[] = [
8+
{ value: 'apple', text: 'Apple', disabled: false, checked: false },
9+
{ value: 'banana', text: 'Banana', disabled: false, checked: false },
10+
];
11+
12+
const checkedOptions: SelectModalOption[] = [
13+
{ value: 'apple', text: 'Apple', disabled: false, checked: true },
14+
{ value: 'banana', text: 'Banana', disabled: false, checked: false },
15+
];
16+
17+
/**
18+
* This behavior does not vary across modes/directions.
19+
*/
20+
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
21+
test.describe(title('select-modal: custom-close-text'), () => {
22+
test.beforeEach(({ browserName }) => {
23+
test.skip(browserName === 'webkit', 'ROU-5437');
24+
});
25+
26+
test.describe('single selection', () => {
27+
let selectModalPage: SelectModalPage;
28+
29+
test.beforeEach(async ({ page }) => {
30+
selectModalPage = new SelectModalPage(page);
31+
});
32+
33+
test('clicking an unselected option should dismiss the modal', async () => {
34+
await selectModalPage.setup(config, options, false);
35+
36+
await selectModalPage.clickOption('apple');
37+
await selectModalPage.ionModalDidDismiss.next();
38+
await expect(selectModalPage.modal).not.toBeVisible();
39+
});
40+
41+
test('clicking a selected option should dismiss the modal', async () => {
42+
await selectModalPage.setup(config, checkedOptions, false);
43+
44+
await selectModalPage.clickOption('apple');
45+
await selectModalPage.ionModalDidDismiss.next();
46+
await expect(selectModalPage.modal).not.toBeVisible();
47+
});
48+
49+
test('pressing Space on an unselected option should dismiss the modal', async () => {
50+
await selectModalPage.setup(config, options, false);
51+
52+
await selectModalPage.pressSpaceOnOption('apple');
53+
await selectModalPage.ionModalDidDismiss.next();
54+
await expect(selectModalPage.modal).not.toBeVisible();
55+
});
56+
57+
test('pressing Space on a selected option should dismiss the modal', async ({ browserName }) => {
58+
test.skip(browserName === 'firefox', 'Same behavior as ROU-5437');
59+
60+
await selectModalPage.setup(config, checkedOptions, false);
61+
62+
await selectModalPage.pressSpaceOnOption('apple');
63+
await selectModalPage.ionModalDidDismiss.next();
64+
await expect(selectModalPage.modal).not.toBeVisible();
65+
});
66+
67+
test('clicking the close button should dismiss the modal', async () => {
68+
await selectModalPage.setup(config, options, false);
69+
70+
const closeButton = selectModalPage.modal.locator('ion-header ion-toolbar ion-button');
71+
await closeButton.click();
72+
await selectModalPage.ionModalDidDismiss.next();
73+
await expect(selectModalPage.modal).not.toBeVisible();
74+
});
75+
});
76+
});
77+
});
78+
79+
/**
80+
* This behavior does not vary across directions.
81+
* The components used inside of `ion-select-modal`
82+
* do have RTL logic, but those are tested in their
83+
* respective component test files.
84+
*/
85+
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
86+
test.describe(title('select-modal: rendering'), () => {
87+
let selectModalPage: SelectModalPage;
88+
89+
test.beforeEach(async ({ page }) => {
90+
selectModalPage = new SelectModalPage(page);
91+
});
92+
test('should not have visual regressions with single selection', async () => {
93+
await selectModalPage.setup(config, checkedOptions, false);
94+
await selectModalPage.screenshot(screenshot, 'select-modal-diff');
95+
});
96+
test('should not have visual regressions with multiple selection', async () => {
97+
await selectModalPage.setup(config, checkedOptions, true);
98+
await selectModalPage.screenshot(screenshot, 'select-modal-multiple-diff');
99+
});
100+
});
101+
});
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)