feat(item-divider): add inner and container parts (#30928)

Issue number: N/A

---------

## What is the current behavior?
The inner structural elements of item-divider are not exposed as shadow parts, preventing users from being able to customize their styles directly.

## What is the new behavior?
- Exposes `inner` and `container` shadow parts
- Adds e2e test coverage for customizing the shadow parts

## Does this introduce a breaking change?
- [ ] Yes
- [x] No

---------

Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
This commit is contained in:
Brandy Smith
2026-02-27 12:53:49 -05:00
committed by GitHub
parent a2c655923b
commit 5cdeb7fd35
3 changed files with 64 additions and 2 deletions

View File

@@ -968,6 +968,8 @@ ion-item-divider,css-prop,--padding-start,ios
ion-item-divider,css-prop,--padding-start,md
ion-item-divider,css-prop,--padding-top,ios
ion-item-divider,css-prop,--padding-top,md
ion-item-divider,part,container
ion-item-divider,part,inner
ion-item-group,none

View File

@@ -11,6 +11,9 @@ import type { Color } from '../../interface';
* @slot - Content is placed between the named slots if provided without a slot.
* @slot start - Content is placed to the left of the divider text in LTR, and to the right in RTL.
* @slot end - Content is placed to the right of the divider text in LTR, and to the left in RTL.
*
* @part inner - The inner wrapper element that arranges the divider content.
* @part container - The wrapper element that contains the default slot.
*/
@Component({
tag: 'ion-item-divider',
@@ -50,8 +53,8 @@ export class ItemDivider implements ComponentInterface {
})}
>
<slot name="start"></slot>
<div class="item-divider-inner">
<div class="item-divider-wrapper">
<div class="item-divider-inner" part="inner">
<div class="item-divider-wrapper" part="container">
<slot></slot>
</div>
<slot name="end"></slot>

View File

@@ -0,0 +1,57 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
/**
* This behavior does not vary across modes/directions
*/
configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, config }) => {
test.describe(title('item-divider: custom'), () => {
test.describe('CSS shadow parts', () => {
test('should be able to customize inner part', async ({ page }) => {
await page.setContent(
`
<style>
ion-item-divider::part(inner) {
background-color: red;
}
</style>
<ion-item-divider>Divider</ion-item-divider>
`,
config
);
const divider = page.locator('ion-item-divider');
const backgroundColor = await divider.evaluate((el) => {
const shadowRoot = el.shadowRoot;
const inner = shadowRoot?.querySelector('.item-divider-inner');
return inner ? window.getComputedStyle(inner).backgroundColor : '';
});
expect(backgroundColor).toBe('rgb(255, 0, 0)');
});
test('should be able to customize container part', async ({ page }) => {
await page.setContent(
`
<style>
ion-item-divider::part(container) {
background-color: green;
}
</style>
<ion-item-divider>Divider</ion-item-divider>
`,
config
);
const divider = page.locator('ion-item-divider');
const backgroundColor = await divider.evaluate((el) => {
const shadowRoot = el.shadowRoot;
const container = shadowRoot?.querySelector('.item-divider-wrapper');
return container ? window.getComputedStyle(container).backgroundColor : '';
});
expect(backgroundColor).toBe('rgb(0, 128, 0)');
});
});
});
});