Skip to content

Commit c63d07b

Browse files
fix(many): do not grow slotted checkboxes, radios, selects and toggles (#29501)
Issue number: resolves #29423 --------- ## What is the current behavior? I fixed a bug where icon was collapsing its width when next to a checkbox, radio or toggle to match the styles of select in #29328. This caused a regression for checkboxes, radios, and toggles when slotted inside of an item. Our test coverage for this was not great, as the slotted inputs test in item had so many elements that it was not apparent that this bug was introduced. In addition, the select itself presented the same issue before my PR and this is a regression from the v7 behavior. See the following Codepens to see the regression: - [Ionic v7](https://codepen.io/brandyscarney/pen/jOoPzoL) - [Ionic v8](https://codepen.io/brandyscarney/pen/KKLpoLX) ## What is the new behavior? - Updates the checkbox, radio, select, and toggle to reset the flex property when slotted. - Adds test coverage for the previous fix I did in #29328 where icons were collapsing their width next to checkboxes, radios and toggles. This was reproducible with a div and easier to see in a test so I used a div with a background instead of an icon. - Adds better test coverage for this fix which separates each component (checkbox, radio, select, toggle) into their own screenshot test to make sure the width is shrinking or expanding properly based on where it is located in an item. ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information | Before fix 9b59138 | After | | ---| ---| | ![before fix](https://github.com/ionic-team/ionic-framework/assets/6577830/e27c6e3c-3d3a-4889-a44b-5f4a9a6ba552) | ![after fix](https://github.com/ionic-team/ionic-framework/assets/6577830/a05829d6-f776-4f0d-b7eb-cb8177449c90) | <table width="100%"> <tr align="center"> <td width="50%"><b>Before regression fix</b></td> <td width="50%"><b>After</b></td> </tr> <tr> <td width="50%"><img alt="before-regression-fix" src="https://github.com/ionic-team/ionic-framework/assets/6577830/bb1aea84-6c83-4fbe-96ad-855c1c9cca95"></td> <td width="50%"><img alt="after-regression-fix" src="https://github.com/ionic-team/ionic-framework/assets/6577830/655dab88-55a9-4961-a7fb-2a3233aa0004"></td> </tr> </table>
1 parent 44e1977 commit c63d07b

File tree

48 files changed

+234
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+234
-0
lines changed

core/src/components/checkbox/checkbox.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@
5252
*/
5353
:host([slot="start"]),
5454
:host([slot="end"]) {
55+
// Reset the flex property when the checkbox
56+
// is slotted to avoid growing the element larger
57+
// than its content.
58+
flex: initial;
59+
5560
width: auto;
5661
}
5762

core/src/components/item/test/inputs/item.e2e.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,57 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
200200
});
201201
});
202202
});
203+
204+
/**
205+
* This behavior does not vary across directions
206+
*/
207+
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
208+
test.describe(title('item: inputs'), () => {
209+
test('should not shrink the width of a div next to a checkbox, radio, select or toggle', async ({
210+
page,
211+
}, testInfo) => {
212+
testInfo.annotations.push({
213+
type: 'issue',
214+
description: 'https://github.com/ionic-team/ionic-framework/issues/29319',
215+
});
216+
await page.setContent(
217+
`
218+
<style>
219+
.box {
220+
background: lightgreen;
221+
222+
width: 60px;
223+
height: 60px;
224+
}
225+
</style>
226+
227+
<ion-list lines="none">
228+
<ion-item>
229+
<div class="box"></div>
230+
<ion-checkbox>Checkbox</ion-checkbox>
231+
</ion-item>
232+
<ion-item>
233+
<div class="box"></div>
234+
<ion-radio>Radio</ion-radio>
235+
</ion-item>
236+
<ion-item>
237+
<div class="box"></div>
238+
<ion-select label="Select">
239+
<ion-select-option>Option</ion-select-option>
240+
</ion-select>
241+
</ion-item>
242+
<ion-item>
243+
<div class="box"></div>
244+
<ion-toggle>Toggle</ion-toggle>
245+
</ion-item>
246+
</ion-list>
247+
`,
248+
config
249+
);
250+
251+
const list = page.locator('ion-list');
252+
253+
await expect(list).toHaveScreenshot(screenshot(`item-inputs-div-with-inputs`));
254+
});
255+
});
256+
});

core/src/components/item/test/slotted-inputs/item.e2e.ts

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,163 @@ configs().forEach(({ title, screenshot, config }) => {
1212
});
1313
});
1414
});
15+
16+
/**
17+
* This behavior does not vary across directions
18+
*/
19+
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
20+
test.describe(title('item: slotted inputs'), () => {
21+
test.describe('checkbox', () => {
22+
test('should not expand the slotted checkbox width larger than its content', async ({ page }, testInfo) => {
23+
testInfo.annotations.push({
24+
type: 'issue',
25+
description: 'https://github.com/ionic-team/ionic-framework/issues/29423',
26+
});
27+
28+
await page.setContent(
29+
`
30+
<ion-list>
31+
<ion-item>
32+
<ion-checkbox slot="start"></ion-checkbox>
33+
<ion-label>Label</ion-label>
34+
</ion-item>
35+
<ion-item>
36+
<ion-label>Label</ion-label>
37+
<ion-checkbox slot="end"></ion-checkbox>
38+
</ion-item>
39+
<ion-item>
40+
<ion-checkbox slot="start">Start</ion-checkbox>
41+
<ion-label>Label</ion-label>
42+
</ion-item>
43+
<ion-item>
44+
<ion-label>Label</ion-label>
45+
<ion-checkbox slot="end">End</ion-checkbox>
46+
</ion-item>
47+
</ion-list>
48+
`,
49+
config
50+
);
51+
52+
const list = page.locator('ion-list');
53+
54+
await expect(list).toHaveScreenshot(screenshot(`item-slotted-inputs-checkbox`));
55+
});
56+
});
57+
test.describe('radio', () => {
58+
test('should not expand the slotted radio width larger than its content', async ({ page }, testInfo) => {
59+
testInfo.annotations.push({
60+
type: 'issue',
61+
description: 'https://github.com/ionic-team/ionic-framework/issues/29423',
62+
});
63+
64+
await page.setContent(
65+
`
66+
<ion-list>
67+
<ion-item>
68+
<ion-radio slot="start"></ion-radio>
69+
<ion-label>Label</ion-label>
70+
</ion-item>
71+
<ion-item>
72+
<ion-label>Label</ion-label>
73+
<ion-radio slot="end"></ion-radio>
74+
</ion-item>
75+
<ion-item>
76+
<ion-radio slot="start">Start</ion-radio>
77+
<ion-label>Label</ion-label>
78+
</ion-item>
79+
<ion-item>
80+
<ion-label>Label</ion-label>
81+
<ion-radio slot="end">End</ion-radio>
82+
</ion-item>
83+
</ion-list>
84+
`,
85+
config
86+
);
87+
88+
const list = page.locator('ion-list');
89+
90+
await expect(list).toHaveScreenshot(screenshot(`item-slotted-inputs-radio`));
91+
});
92+
});
93+
test.describe('select', () => {
94+
test('should not expand the slotted select width larger than its content', async ({ page }, testInfo) => {
95+
testInfo.annotations.push({
96+
type: 'issue',
97+
description: 'https://github.com/ionic-team/ionic-framework/issues/29423',
98+
});
99+
100+
await page.setContent(
101+
`
102+
<ion-list>
103+
<ion-item>
104+
<ion-select slot="start">
105+
<ion-select-option>Option</ion-select-option>
106+
</ion-select>
107+
<ion-label>Label</ion-label>
108+
</ion-item>
109+
<ion-item>
110+
<ion-label>Label</ion-label>
111+
<ion-select slot="end">
112+
<ion-select-option>Option</ion-select-option>
113+
</ion-select>
114+
</ion-item>
115+
<ion-item>
116+
<ion-select slot="start" label="Start">
117+
<ion-select-option>Option</ion-select-option>
118+
</ion-select>
119+
<ion-label>Label</ion-label>
120+
</ion-item>
121+
<ion-item>
122+
<ion-label>Label</ion-label>
123+
<ion-select slot="end" label="End">
124+
<ion-select-option>Option</ion-select-option>
125+
</ion-select>
126+
</ion-item>
127+
</ion-list>
128+
`,
129+
config
130+
);
131+
132+
const list = page.locator('ion-list');
133+
134+
await expect(list).toHaveScreenshot(screenshot(`item-slotted-inputs-select`));
135+
});
136+
});
137+
test.describe('toggle', () => {
138+
test('should not expand the slotted toggle width larger than its content', async ({ page }, testInfo) => {
139+
testInfo.annotations.push({
140+
type: 'issue',
141+
description: 'https://github.com/ionic-team/ionic-framework/issues/29423',
142+
});
143+
144+
await page.setContent(
145+
`
146+
<ion-list>
147+
<ion-item>
148+
<ion-toggle slot="start"></ion-toggle>
149+
<ion-label>Label</ion-label>
150+
</ion-item>
151+
<ion-item>
152+
<ion-label>Label</ion-label>
153+
<ion-toggle slot="end"></ion-toggle>
154+
</ion-item>
155+
<ion-item>
156+
<ion-toggle slot="start">Start</ion-toggle>
157+
<ion-label>Label</ion-label>
158+
</ion-item>
159+
<ion-item>
160+
<ion-label>Label</ion-label>
161+
<ion-toggle slot="end">End</ion-toggle>
162+
</ion-item>
163+
</ion-list>
164+
`,
165+
config
166+
);
167+
168+
const list = page.locator('ion-list');
169+
170+
await expect(list).toHaveScreenshot(screenshot(`item-slotted-inputs-toggle`));
171+
});
172+
});
173+
});
174+
});

0 commit comments

Comments
 (0)