feat(select): expose container and label as CSS parts (#27541)
Issue number: resolves #27112 --------- ## What is the current behavior? The select does not expose the label or the container for the value/placeholder as a CSS shadow part in order to style it. ## What is the new behavior? - Exposed `label` and `container` parts for custom styling - Added an e2e test to verify the parts are working - Renamed the existing screenshots for the custom tests to fix a typo from "custon" to "custom" ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> --------- Co-authored-by: ionitron <hi@ionicframework.com>
@ -1267,7 +1267,9 @@ ion-select,css-prop,--padding-top
|
||||
ion-select,css-prop,--placeholder-color
|
||||
ion-select,css-prop,--placeholder-opacity
|
||||
ion-select,css-prop,--ripple-color
|
||||
ion-select,part,container
|
||||
ion-select,part,icon
|
||||
ion-select,part,label
|
||||
ion-select,part,placeholder
|
||||
ion-select,part,text
|
||||
|
||||
|
||||
@ -35,6 +35,8 @@ import type { SelectChangeEventDetail, SelectInterface, SelectCompareFn } from '
|
||||
* @part placeholder - The text displayed in the select when there is no value.
|
||||
* @part text - The displayed value of the select.
|
||||
* @part icon - The select icon container.
|
||||
* @part container - The container for the selected text or placeholder.
|
||||
* @part label - The label text describing the select.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-select',
|
||||
@ -701,7 +703,7 @@ export class Select implements ComponentInterface {
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="label-text-wrapper">
|
||||
<div class="label-text-wrapper" part="label">
|
||||
<div class="label-text">{this.label}</div>
|
||||
</div>
|
||||
);
|
||||
@ -776,7 +778,7 @@ export class Select implements ComponentInterface {
|
||||
>
|
||||
<label class="select-wrapper" id="select-label">
|
||||
{this.renderLabelContainer()}
|
||||
<div class="native-wrapper" ref={(el) => (this.nativeWrapperEl = el)}>
|
||||
<div class="native-wrapper" ref={(el) => (this.nativeWrapperEl = el)} part="container">
|
||||
{this.renderSelectText()}
|
||||
{!hasFloatingOrStackedLabel && this.renderSelectIcon()}
|
||||
{this.renderListbox()}
|
||||
|
||||
@ -36,7 +36,41 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
);
|
||||
|
||||
const select = page.locator('ion-select');
|
||||
await expect(select).toHaveScreenshot(screenshot(`select-custon-diff`));
|
||||
await expect(select).toHaveScreenshot(screenshot(`select-custom-diff`));
|
||||
});
|
||||
test('should be able to customize select label, placeholder, and value using css parts', async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/ionic-team/ionic-framework/issues/27112',
|
||||
});
|
||||
|
||||
await page.setContent(
|
||||
`
|
||||
<div class="wrapper">
|
||||
<ion-select label="Select" label-placement="stacked" placeholder="Fruits">
|
||||
<ion-select-option value="a">Apple</ion-select-option>
|
||||
</ion-select>
|
||||
|
||||
<ion-select label="Select" label-placement="stacked" value="a">
|
||||
<ion-select-option value="a">Apple</ion-select-option>
|
||||
</ion-select>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
ion-select::part(container) {
|
||||
color: purple;
|
||||
}
|
||||
|
||||
ion-select::part(label) {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const wrapper = page.locator('.wrapper');
|
||||
await expect(wrapper).toHaveScreenshot(screenshot(`select-custom-parts-diff`));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 3.2 KiB |