Skip to content

Commit 4ccd15e

Browse files
feat(checkbox): display as block when justify or alignment properties are defined (#29783)
- Change the checkbox's `display` property to `block` when the `justify` or `alignment` property is set. - Set the default `justify-content` style to `space-between` so that a checkbox with `width: 100%` set without `justify` or `alignment` set will still have the same default - Modifies the `label` e2e test to remove the explicit width as setting the property will make them full-width - Adds two examples to the `label` e2e test of labels that do not have `justify` set but use `width: 100%` to ensure they are working as expected without it
1 parent d737ec1 commit 4ccd15e

File tree

194 files changed

+97
-47
lines changed

Some content is hidden

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

194 files changed

+97
-47
lines changed

core/api.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -393,12 +393,12 @@ ion-card-title,css-prop,--color,ios
393393
ion-card-title,css-prop,--color,md
394394

395395
ion-checkbox,shadow
396-
ion-checkbox,prop,alignment,"center" | "start",'center',false,false
396+
ion-checkbox,prop,alignment,"center" | "start" | undefined,undefined,false,false
397397
ion-checkbox,prop,checked,boolean,false,false,false
398398
ion-checkbox,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
399399
ion-checkbox,prop,disabled,boolean,false,false,false
400400
ion-checkbox,prop,indeterminate,boolean,false,false,false
401-
ion-checkbox,prop,justify,"end" | "space-between" | "start",'space-between',false,false
401+
ion-checkbox,prop,justify,"end" | "space-between" | "start" | undefined,undefined,false,false
402402
ion-checkbox,prop,labelPlacement,"end" | "fixed" | "stacked" | "start",'start',false,false
403403
ion-checkbox,prop,mode,"ios" | "md",undefined,false,false
404404
ion-checkbox,prop,name,string,this.inputId,false,false

core/src/components.d.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,9 @@ export namespace Components {
601601
}
602602
interface IonCheckbox {
603603
/**
604-
* How to control the alignment of the checkbox and label on the cross axis. `"start"`: The label and control will appear on the left of the cross axis in LTR, and on the right side in RTL. `"center"`: The label and control will appear at the center of the cross axis in both LTR and RTL.
604+
* How to control the alignment of the checkbox and label on the cross axis. `"start"`: The label and control will appear on the left of the cross axis in LTR, and on the right side in RTL. `"center"`: The label and control will appear at the center of the cross axis in both LTR and RTL. Setting this property will change the checkbox `display` to `block`.
605605
*/
606-
"alignment": 'start' | 'center';
606+
"alignment"?: 'start' | 'center';
607607
/**
608608
* If `true`, the checkbox is selected.
609609
*/
@@ -621,9 +621,9 @@ export namespace Components {
621621
*/
622622
"indeterminate": boolean;
623623
/**
624-
* How to pack the label and checkbox within a line. `"start"`: The label and checkbox will appear on the left in LTR and on the right in RTL. `"end"`: The label and checkbox will appear on the right in LTR and on the left in RTL. `"space-between"`: The label and checkbox will appear on opposite ends of the line with space between the two elements.
624+
* How to pack the label and checkbox within a line. `"start"`: The label and checkbox will appear on the left in LTR and on the right in RTL. `"end"`: The label and checkbox will appear on the right in LTR and on the left in RTL. `"space-between"`: The label and checkbox will appear on opposite ends of the line with space between the two elements. Setting this property will change the checkbox `display` to `block`.
625625
*/
626-
"justify": 'start' | 'end' | 'space-between';
626+
"justify"?: 'start' | 'end' | 'space-between';
627627
/**
628628
* Where to place the label relative to the checkbox. `"start"`: The label will appear to the left of the checkbox in LTR and to the right in RTL. `"end"`: The label will appear to the right of the checkbox in LTR and to the left in RTL. `"fixed"`: The label has the same behavior as `"start"` except it also has a fixed width. Long text will be truncated with ellipses ("..."). `"stacked"`: The label will appear above the checkbox regardless of the direction. The alignment of the label can be controlled with the `alignment` property.
629629
*/
@@ -5321,7 +5321,7 @@ declare namespace LocalJSX {
53215321
}
53225322
interface IonCheckbox {
53235323
/**
5324-
* How to control the alignment of the checkbox and label on the cross axis. `"start"`: The label and control will appear on the left of the cross axis in LTR, and on the right side in RTL. `"center"`: The label and control will appear at the center of the cross axis in both LTR and RTL.
5324+
* How to control the alignment of the checkbox and label on the cross axis. `"start"`: The label and control will appear on the left of the cross axis in LTR, and on the right side in RTL. `"center"`: The label and control will appear at the center of the cross axis in both LTR and RTL. Setting this property will change the checkbox `display` to `block`.
53255325
*/
53265326
"alignment"?: 'start' | 'center';
53275327
/**
@@ -5341,7 +5341,7 @@ declare namespace LocalJSX {
53415341
*/
53425342
"indeterminate"?: boolean;
53435343
/**
5344-
* How to pack the label and checkbox within a line. `"start"`: The label and checkbox will appear on the left in LTR and on the right in RTL. `"end"`: The label and checkbox will appear on the right in LTR and on the left in RTL. `"space-between"`: The label and checkbox will appear on opposite ends of the line with space between the two elements.
5344+
* How to pack the label and checkbox within a line. `"start"`: The label and checkbox will appear on the left in LTR and on the right in RTL. `"end"`: The label and checkbox will appear on the right in LTR and on the left in RTL. `"space-between"`: The label and checkbox will appear on opposite ends of the line with space between the two elements. Setting this property will change the checkbox `display` to `block`.
53455345
*/
53465346
"justify"?: 'start' | 'end' | 'space-between';
53475347
/**

core/src/components/checkbox/checkbox.scss

+15
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
flex-grow: 1;
7373

7474
align-items: center;
75+
justify-content: space-between;
7576

7677
height: inherit;
7778

@@ -170,6 +171,20 @@ input {
170171
align-items: center;
171172
}
172173

174+
// Justify Content & Align Items
175+
// ---------------------------------------------
176+
177+
// The checkbox should be displayed as block when either justify
178+
// or alignment is set; otherwise, these properties will have no
179+
// visible effect.
180+
:host(.checkbox-justify-space-between),
181+
:host(.checkbox-justify-start),
182+
:host(.checkbox-justify-end),
183+
:host(.checkbox-alignment-start),
184+
:host(.checkbox-alignment-center) {
185+
display: block;
186+
}
187+
173188
// Label Placement - Start
174189
// ----------------------------------------------------------------
175190

core/src/components/checkbox/checkbox.tsx

+6-4
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,17 @@ export class Checkbox implements ComponentInterface {
8686
* on the left in RTL.
8787
* `"space-between"`: The label and checkbox will appear on opposite
8888
* ends of the line with space between the two elements.
89+
* Setting this property will change the checkbox `display` to `block`.
8990
*/
90-
@Prop() justify: 'start' | 'end' | 'space-between' = 'space-between';
91+
@Prop() justify?: 'start' | 'end' | 'space-between';
9192

9293
/**
9394
* How to control the alignment of the checkbox and label on the cross axis.
9495
* `"start"`: The label and control will appear on the left of the cross axis in LTR, and on the right side in RTL.
9596
* `"center"`: The label and control will appear at the center of the cross axis in both LTR and RTL.
97+
* Setting this property will change the checkbox `display` to `block`.
9698
*/
97-
@Prop() alignment: 'start' | 'center' = 'center';
99+
@Prop() alignment?: 'start' | 'center';
98100

99101
/**
100102
* Emitted when the checked property has changed as a result of a user action such as a click.
@@ -194,8 +196,8 @@ export class Checkbox implements ComponentInterface {
194196
'checkbox-disabled': disabled,
195197
'checkbox-indeterminate': indeterminate,
196198
interactive: true,
197-
[`checkbox-justify-${justify}`]: true,
198-
[`checkbox-alignment-${alignment}`]: true,
199+
[`checkbox-justify-${justify}`]: justify !== undefined,
200+
[`checkbox-alignment-${alignment}`]: alignment !== undefined,
199201
[`checkbox-label-placement-${labelPlacement}`]: true,
200202
})}
201203
onClick={this.onClick}

core/src/components/checkbox/test/a11y/checkbox.e2e.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ configs({ directions: ['ltr'] }).forEach(({ title, config, screenshot }) => {
3636
font-size: 310%;
3737
}
3838
</style>
39-
<ion-checkbox justify="start" checked>Checked</ion-checkbox>
39+
<ion-checkbox checked>Checked</ion-checkbox>
4040
`,
4141
config
4242
);

core/src/components/checkbox/test/basic/index.html

+17-10
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@
1515
</head>
1616
<style>
1717
ion-checkbox {
18-
display: block;
1918
margin-bottom: 8px;
2019
}
2120

2221
ion-checkbox.checkbox-part::part(mark) {
2322
transform: scale(0.5);
2423
transform-origin: center;
2524
}
25+
26+
hr {
27+
background: #ddd;
28+
}
2629
</style>
2730
<body>
2831
<ion-app>
@@ -33,15 +36,19 @@
3336
</ion-header>
3437

3538
<ion-content class="ion-padding">
36-
<div id="checkboxes">
37-
<ion-checkbox justify="start">Unchecked</ion-checkbox>
38-
<ion-checkbox justify="start" checked>Checked</ion-checkbox>
39-
<ion-checkbox justify="start" disabled>Disabled</ion-checkbox>
40-
<ion-checkbox justify="start" disabled checked>Disabled, Checked</ion-checkbox>
41-
<ion-checkbox justify="start" checked style="--checkmark-width: 7">Checkmark Width</ion-checkbox>
42-
<ion-checkbox justify="start" checked class="checkbox-part">Checkmark Shadow Part</ion-checkbox>
43-
<ion-checkbox justify="start" checked style="--size: 100px">--size</ion-checkbox>
44-
</div>
39+
<ion-checkbox>Unchecked</ion-checkbox><br />
40+
<ion-checkbox checked>Checked</ion-checkbox><br />
41+
<ion-checkbox disabled>Disabled</ion-checkbox><br />
42+
<ion-checkbox disabled checked>Disabled, Checked</ion-checkbox><br />
43+
<ion-checkbox checked style="--checkmark-width: 7">Checkmark Width</ion-checkbox><br />
44+
<ion-checkbox checked class="checkbox-part">Checkmark Shadow Part</ion-checkbox><br />
45+
<ion-checkbox checked style="--size: 100px">--size</ion-checkbox><br />
46+
47+
<hr />
48+
49+
<ion-checkbox checked>Default width</ion-checkbox><br />
50+
<ion-checkbox checked style="width: 200px">Specified width</ion-checkbox><br />
51+
<ion-checkbox checked style="width: 100%">Full-width</ion-checkbox><br />
4552
</ion-content>
4653
</ion-app>
4754
</body>

core/src/components/checkbox/test/label/checkbox.e2e.ts

+50-20
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,50 @@ import { expect } from '@playwright/test';
22
import { configs, test } from '@utils/test/playwright';
33

44
/**
5-
* By default ion-checkbox only takes up
6-
* as much space as it needs. Justification is
7-
* used for when the checkbox takes up the full
8-
* line (such as in an ion-item). As a result,
9-
* we set the width of the checkbox so we can
10-
* see the justification results.
5+
* By default ion-checkbox only takes up as much space
6+
* as it needs. Justification is used for when the
7+
* checkbox should take up the full line (such as in an
8+
* ion-item or when it has 100% width).
119
*/
1210
configs().forEach(({ title, screenshot, config }) => {
1311
test.describe(title('checkbox: label'), () => {
12+
test.describe('checkbox: default placement', () => {
13+
test('should render a space between justification with a full width checkbox', async ({ page }) => {
14+
await page.setContent(
15+
`
16+
<ion-checkbox style="width: 100%">
17+
Label
18+
</ion-checkbox>
19+
`,
20+
config
21+
);
22+
23+
const checkbox = page.locator('ion-checkbox');
24+
await expect(checkbox).toHaveScreenshot(screenshot(`checkbox-label-full-width`));
25+
});
26+
27+
test('should truncate long labels with ellipses', async ({ page }) => {
28+
// Checkbox needs to be full width to truncate properly
29+
// because it is not inside of an `ion-app` in tests
30+
await page.setContent(
31+
`
32+
<ion-checkbox style="width: 100%">
33+
Long Label Long Label Long Label Long Label Long Label Long Label
34+
</ion-checkbox>
35+
`,
36+
config
37+
);
38+
39+
const checkbox = page.locator('ion-checkbox');
40+
await expect(checkbox).toHaveScreenshot(screenshot(`checkbox-label-long-label`));
41+
});
42+
});
43+
1444
test.describe('checkbox: start placement', () => {
1545
test('should render a start justification with label in the start position', async ({ page }) => {
1646
await page.setContent(
1747
`
18-
<ion-checkbox label-placement="start" justify="start" style="width: 200px">Label</ion-checkbox>
48+
<ion-checkbox label-placement="start" justify="start">Label</ion-checkbox>
1949
`,
2050
config
2151
);
@@ -27,7 +57,7 @@ configs().forEach(({ title, screenshot, config }) => {
2757
test('should render an end justification with label in the start position', async ({ page }) => {
2858
await page.setContent(
2959
`
30-
<ion-checkbox label-placement="start" justify="end" style="width: 200px">Label</ion-checkbox>
60+
<ion-checkbox label-placement="start" justify="end">Label</ion-checkbox>
3161
`,
3262
config
3363
);
@@ -39,7 +69,7 @@ configs().forEach(({ title, screenshot, config }) => {
3969
test('should render a space between justification with label in the start position', async ({ page }) => {
4070
await page.setContent(
4171
`
42-
<ion-checkbox label-placement="start" justify="space-between" style="width: 200px">Label</ion-checkbox>
72+
<ion-checkbox label-placement="start" justify="space-between">Label</ion-checkbox>
4373
`,
4474
config
4575
);
@@ -51,23 +81,23 @@ configs().forEach(({ title, screenshot, config }) => {
5181
test('should truncate long labels with ellipses', async ({ page }) => {
5282
await page.setContent(
5383
`
54-
<ion-checkbox label-placement="start" justify="start" style="width: 200px">
84+
<ion-checkbox label-placement="start" justify="start">
5585
Long Label Long Label Long Label Long Label Long Label Long Label
5686
</ion-checkbox>
5787
`,
5888
config
5989
);
6090

6191
const checkbox = page.locator('ion-checkbox');
62-
await expect(checkbox).toHaveScreenshot(screenshot(`checkbox-long-label`));
92+
await expect(checkbox).toHaveScreenshot(screenshot(`checkbox-label-start-justify-start-long-label`));
6393
});
6494
});
6595

6696
test.describe('checkbox: end placement', () => {
6797
test('should render a start justification with label in the end position', async ({ page }) => {
6898
await page.setContent(
6999
`
70-
<ion-checkbox label-placement="end" justify="start" style="width: 200px">Label</ion-checkbox>
100+
<ion-checkbox label-placement="end" justify="start">Label</ion-checkbox>
71101
`,
72102
config
73103
);
@@ -79,7 +109,7 @@ configs().forEach(({ title, screenshot, config }) => {
79109
test('should render an end justification with label in the end position', async ({ page }) => {
80110
await page.setContent(
81111
`
82-
<ion-checkbox label-placement="end" justify="end" style="width: 200px">Label</ion-checkbox>
112+
<ion-checkbox label-placement="end" justify="end">Label</ion-checkbox>
83113
`,
84114
config
85115
);
@@ -91,7 +121,7 @@ configs().forEach(({ title, screenshot, config }) => {
91121
test('should render a space between justification with label in the end position', async ({ page }) => {
92122
await page.setContent(
93123
`
94-
<ion-checkbox label-placement="end" justify="space-between" style="width: 200px">Label</ion-checkbox>
124+
<ion-checkbox label-placement="end" justify="space-between">Label</ion-checkbox>
95125
`,
96126
config
97127
);
@@ -105,7 +135,7 @@ configs().forEach(({ title, screenshot, config }) => {
105135
test('should render a start justification with label in the fixed position', async ({ page }) => {
106136
await page.setContent(
107137
`
108-
<ion-checkbox label-placement="fixed" justify="start" style="width: 200px">This is a long label</ion-checkbox>
138+
<ion-checkbox label-placement="fixed" justify="start">This is a long label</ion-checkbox>
109139
`,
110140
config
111141
);
@@ -117,7 +147,7 @@ configs().forEach(({ title, screenshot, config }) => {
117147
test('should render an end justification with label in the fixed position', async ({ page }) => {
118148
await page.setContent(
119149
`
120-
<ion-checkbox label-placement="fixed" justify="end" style="width: 200px">This is a long label</ion-checkbox>
150+
<ion-checkbox label-placement="fixed" justify="end">This is a long label</ion-checkbox>
121151
`,
122152
config
123153
);
@@ -129,7 +159,7 @@ configs().forEach(({ title, screenshot, config }) => {
129159
test('should render a space between justification with label in the fixed position', async ({ page }) => {
130160
await page.setContent(
131161
`
132-
<ion-checkbox label-placement="fixed" justify="space-between" style="width: 200px">This is a long label</ion-checkbox>
162+
<ion-checkbox label-placement="fixed" justify="space-between">This is a long label</ion-checkbox>
133163
`,
134164
config
135165
);
@@ -143,7 +173,7 @@ configs().forEach(({ title, screenshot, config }) => {
143173
test('should align the label to the start of the container in the stacked position', async ({ page }) => {
144174
await page.setContent(
145175
`
146-
<ion-checkbox label-placement="stacked" alignment="start" style="width: 200px">This is a long label</ion-checkbox>
176+
<ion-checkbox label-placement="stacked" alignment="start">This is a long label</ion-checkbox>
147177
`,
148178
config
149179
);
@@ -155,7 +185,7 @@ configs().forEach(({ title, screenshot, config }) => {
155185
test('should align the label to the center of the container in the stacked position', async ({ page }) => {
156186
await page.setContent(
157187
`
158-
<ion-checkbox label-placement="stacked" alignment="center" style="width: 200px">This is a long label</ion-checkbox>
188+
<ion-checkbox label-placement="stacked" alignment="center">This is a long label</ion-checkbox>
159189
`,
160190
config
161191
);
@@ -172,7 +202,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config, screen
172202
test('long label should truncate', async ({ page }) => {
173203
await page.setContent(
174204
`
175-
<ion-checkbox label-placement="stacked" alignment="start" style="width: 200px">Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable Notifications</ion-checkbox>
205+
<ion-checkbox label-placement="stacked" alignment="start">Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable Notifications</ion-checkbox>
176206
`,
177207
config
178208
);

core/src/components/checkbox/test/label/index.html

-4
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@
3535
padding: 0;
3636
}
3737
}
38-
39-
ion-checkbox {
40-
width: 100%;
41-
}
4238
</style>
4339
</head>
4440

0 commit comments

Comments
 (0)