fix(checkbox): align checkbox properly in item using start alignment (#29850)
Issue number: resolves #29837 --------- ## What is the current behavior? The checkbox is not aligned properly to the top when using a long label with `alignment="start"` inside of an `ion-item`: ```html <ion-item> <ion-checkbox justify="start" alignment="start"> <ion-label class="ion-text-wrap"> Enable Notifications Enable Notifications Enable Notifications </ion-label> </ion-checkbox> </ion-item> ``` ## What is the new behavior? - Applies the same margin to the `.native-wrapper` (checkbox) as the label. - Adds a screenshot test to verify the alignment ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information | Before | After | | --- | --- | |  |  | |  |  | - [Label Preview](https://ionic-framework-git-rou-11163-ionic1.vercel.app/src/components/checkbox/test/label) - [Item Preview](https://ionic-framework-git-rou-11163-ionic1.vercel.app/src/components/checkbox/test/item) > [!NOTE] > The alignment on the Material Design checkbox is still slightly off. I could add margin directly to its checkbox but then it would change the margin of the checkbox in all use cases.
@ -87,7 +87,10 @@
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
:host(.in-item) .label-text-wrapper {
 | 
			
		||||
// Checkboxes that are not slotted inside an item and are not used with a
 | 
			
		||||
// stacked label should have margins equal to those of the label.
 | 
			
		||||
:host(.in-item) .label-text-wrapper,
 | 
			
		||||
:host(.in-item:not(.checkbox-label-placement-stacked):not([slot])) .native-wrapper {
 | 
			
		||||
  @include margin($checkbox-item-label-margin-top, null, $checkbox-item-label-margin-bottom, null);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -51,7 +51,7 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, screenshot, config }) => {
 | 
			
		||||
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
 | 
			
		||||
  test.describe(title('checkbox: long label in item'), () => {
 | 
			
		||||
    test('should render margins correctly when using long label in item', async ({ page }) => {
 | 
			
		||||
      await page.setContent(
 | 
			
		||||
@ -69,6 +69,28 @@ configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, screenshot, co
 | 
			
		||||
      const list = page.locator('ion-list');
 | 
			
		||||
      await expect(list).toHaveScreenshot(screenshot(`checkbox-long-label-in-item`));
 | 
			
		||||
    });
 | 
			
		||||
    test('should render margins correctly when using long label in item with start alignment', async ({
 | 
			
		||||
      page,
 | 
			
		||||
    }, testInfo) => {
 | 
			
		||||
      testInfo.annotations.push({
 | 
			
		||||
        type: 'issue',
 | 
			
		||||
        description: 'https://github.com/ionic-team/ionic-framework/issues/29837',
 | 
			
		||||
      });
 | 
			
		||||
      await page.setContent(
 | 
			
		||||
        `
 | 
			
		||||
          <ion-list>
 | 
			
		||||
            <ion-item>
 | 
			
		||||
              <ion-checkbox justify="start" alignment="start">
 | 
			
		||||
                <ion-label class="ion-text-wrap">Enable Notifications Enable Notifications Enable Notifications</ion-label>
 | 
			
		||||
              </ion-checkbox>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
          </ion-list>
 | 
			
		||||
        `,
 | 
			
		||||
        config
 | 
			
		||||
      );
 | 
			
		||||
      const list = page.locator('ion-list');
 | 
			
		||||
      await expect(list).toHaveScreenshot(screenshot(`checkbox-long-label-in-item-align-start`));
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  test.describe(title('checkbox: stacked label in item'), () => {
 | 
			
		||||
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.3 KiB  | 
| 
		 After Width: | Height: | Size: 5.6 KiB  | 
| 
		 After Width: | Height: | Size: 3.3 KiB  | 
| 
		 After Width: | Height: | Size: 2.9 KiB  | 
| 
		 After Width: | Height: | Size: 6.5 KiB  | 
| 
		 After Width: | Height: | Size: 2.6 KiB  | 
| 
		 After Width: | Height: | Size: 3.4 KiB  | 
| 
		 After Width: | Height: | Size: 5.7 KiB  | 
| 
		 After Width: | Height: | Size: 3.4 KiB  | 
| 
		 After Width: | Height: | Size: 2.4 KiB  | 
| 
		 After Width: | Height: | Size: 3.5 KiB  | 
| 
		 After Width: | Height: | Size: 2.4 KiB  | 
@ -181,6 +181,15 @@
 | 
			
		||||
              </ion-checkbox>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="grid-item">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
              <ion-checkbox justify="start" alignment="start">
 | 
			
		||||
                <ion-label class="ion-text-wrap">
 | 
			
		||||
                  Enable Notifications Enable Notifications Enable Notifications
 | 
			
		||||
                </ion-label>
 | 
			
		||||
              </ion-checkbox>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </ion-content>
 | 
			
		||||
    </ion-app>
 | 
			
		||||
 | 
			
		||||
@ -113,6 +113,24 @@
 | 
			
		||||
            <ion-checkbox label-placement="stacked" alignment="center">Enable Notifications</ion-checkbox>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <h1>Multiline Label</h1>
 | 
			
		||||
        <div class="grid">
 | 
			
		||||
          <div class="grid-item">
 | 
			
		||||
            <ion-checkbox justify="start">
 | 
			
		||||
              <ion-label class="ion-text-wrap">
 | 
			
		||||
                Enable Notifications Enable Notifications Enable Notifications
 | 
			
		||||
              </ion-label>
 | 
			
		||||
            </ion-checkbox>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="grid-item">
 | 
			
		||||
            <ion-checkbox justify="start" alignment="start">
 | 
			
		||||
              <ion-label class="ion-text-wrap">
 | 
			
		||||
                Enable Notifications Enable Notifications Enable Notifications
 | 
			
		||||
              </ion-label>
 | 
			
		||||
            </ion-checkbox>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </ion-content>
 | 
			
		||||
    </ion-app>
 | 
			
		||||
  </body>
 | 
			
		||||
 | 
			
		||||