Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,8 @@ ion-item-option,css-prop,--background,ios
ion-item-option,css-prop,--background,md
ion-item-option,css-prop,--color,ios
ion-item-option,css-prop,--color,md
ion-item-option,part,container
ion-item-option,part,inner
ion-item-option,part,native

ion-item-options,none
Expand Down
6 changes: 4 additions & 2 deletions core/src/components/item-option/item-option.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import type { Color } from '../../interface';
* @slot end - Content is placed to the right of the option text in LTR, and to the left in RTL.
*
* @part native - The native HTML button or anchor element that wraps all child elements.
* @part inner - The inner container element that wraps the option content.
* @part container - The container element that wraps the start, icon-only, default, and end slots.
*/
@Component({
tag: 'ion-item-option',
Expand Down Expand Up @@ -109,9 +111,9 @@ export class ItemOption implements ComponentInterface, AnchorInterface, ButtonIn
})}
>
<TagType {...attrs} class="button-native" part="native" disabled={disabled}>
<span class="button-inner">
<span class="button-inner" part="inner">
<slot name="top"></slot>
<div class="horizontal-wrapper">
<div class="horizontal-wrapper" part="container">
<slot name="start"></slot>
<slot name="icon-only"></slot>
<slot></slot>
Expand Down
80 changes: 80 additions & 0 deletions core/src/components/item-option/test/custom/item-option.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
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-option: custom'), () => {
test.describe(title('CSS shadow parts'), () => {
test('should be able to customize native part', async ({ page }) => {
await page.setContent(
`
<style>
ion-item-option::part(native) {
background-color: red;
}
</style>

<ion-item-option>Option</ion-item-option>
`,
config
);

const itemOption = page.locator('ion-item-option');
const backgroundColor = await itemOption.evaluate((el) => {
const shadowRoot = el.shadowRoot;
const native = shadowRoot?.querySelector('.button-native');
return native ? window.getComputedStyle(native).backgroundColor : '';
});
expect(backgroundColor).toBe('rgb(255, 0, 0)');
});

test('should be able to customize inner part', async ({ page }) => {
await page.setContent(
`
<style>
ion-item-option::part(inner) {
background-color: green;
}
</style>

<ion-item-option>Option</ion-item-option>
`,
config
);

const itemOption = page.locator('ion-item-option');
const backgroundColor = await itemOption.evaluate((el) => {
const shadowRoot = el.shadowRoot;
const inner = shadowRoot?.querySelector('.button-inner');
return inner ? window.getComputedStyle(inner).backgroundColor : '';
});
expect(backgroundColor).toBe('rgb(0, 128, 0)');
});

test('should be able to customize container part', async ({ page }) => {
await page.setContent(
`
<style>
ion-item-option::part(container) {
background-color: blue;
}
</style>

<ion-item-option>Option</ion-item-option>
`,
config
);

const itemOption = page.locator('ion-item-option');
const backgroundColor = await itemOption.evaluate((el) => {
const shadowRoot = el.shadowRoot;
const container = shadowRoot?.querySelector('.horizontal-wrapper');
return container ? window.getComputedStyle(container).backgroundColor : '';
});
expect(backgroundColor).toBe('rgb(0, 0, 255)');
});
});
});
});
Loading