feat(select-option): pass class from the option to the interface for individual styling (#21304)

Co-authored-by: Robb Wright <audaxion@gmail.com>
This commit is contained in:
Brandy Carney
2020-05-27 12:12:01 -04:00
committed by GitHub
parent 2dac12c577
commit 5285824da5
12 changed files with 1465 additions and 13 deletions

View File

@ -32,6 +32,7 @@ export interface AlertInput {
handler?: (input: AlertInput) => void;
min?: string | number;
max?: string | number;
cssClass?: string | string[];
}
export interface AlertButton {

View File

@ -159,6 +159,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
label: i.label,
checked: !!i.checked,
disabled: !!i.disabled,
cssClass: i.cssClass || '',
id: i.id || `alert-input-${this.overlayIndex}-${index}`,
handler: i.handler,
min: i.min,
@ -334,6 +335,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
tabIndex={0}
role="checkbox"
class={{
...getClassMap(i.cssClass),
'alert-tappable': true,
'alert-checkbox': true,
'alert-checkbox-button': true,
@ -372,6 +374,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
id={i.id}
tabIndex={0}
class={{
...getClassMap(i.cssClass),
'alert-radio-button': true,
'alert-tappable': true,
'alert-radio': true,
@ -411,6 +414,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
disabled={i.disabled}
tabIndex={0}
class={{
...getClassMap(i.cssClass),
'alert-input': true,
'alert-input-disabled': i.disabled || false
}}
@ -431,6 +435,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
disabled={i.disabled}
tabIndex={0}
class={{
...getClassMap(i.cssClass),
'alert-input': true,
'alert-input-disabled': i.disabled || false
}}

View File

@ -1,11 +1,657 @@
# ion-select-option
SelectOption is a component that is a child element of Select. For more information, see the [Select docs](../select).
Select Options are components that are child elements of a Select. Each option defined is passed and displayed in the Select dialog. For more information, see the [Select docs](../select).
## Customization
Each `ion-select-option` component that is added as a child of an `ion-select` is passed to the interface to display it in the dialog. It's important to note that the `ion-select-option` element itself is hidden from the view. This means that attempting to style it will not have any effect on the option in the dialog:
```css
/* DOES NOT work */
ion-select-option {
color: red;
}
```
Instead, each interface option has the class `.select-interface-option` which can be styled. Keep in mind that due to the overlays being scoped components the selector by itself will not work and a custom `cssClass` is recommended to be passed to the interface.
```css
/* This will NOT work on its own */
.select-interface-option {
color: red;
}
/*
* "my-custom-interface" needs to be passed in through
* the cssClass of the interface options for this to work
*/
.my-custom-interface .select-interface-option {
color: red;
}
```
> Note: Some interfaces require more in depth styling due to how the options are rendered. See usage for expanded information on this.
The options can be styled individually by adding your own class on the `ion-select-option` which gets passed to the interface option. See the [Usage](#usage) section below for examples of styling and setting individual classes on options.
<!-- Auto Generated Below -->
## Usage
### Javascript
```html
<ion-item>
<ion-label>Select</ion-label>
<ion-select>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
```
### Customizing Options
```html
<ion-item>
<ion-label>Select: Alert Interface</ion-label>
<ion-select class="custom-options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Alert Interface (Multiple Selection)</ion-label>
<ion-select class="custom-options" multiple="true">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Popover Interface</ion-label>
<ion-select interface="popover" class="custom-options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Action Sheet Interface</ion-label>
<ion-select interface="action-sheet" class="custom-options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .select-interface-option {
--color: #971e49;
--color-hover: #79193b;
}
/* Action Sheet Interface: set color for the action sheet using its button CSS variables */
.my-custom-interface .select-interface-option {
--button-color: #971e49;
--button-color-hover: #79193b;
}
/* Alert Interface: set color for alert options (single selection) */
.my-custom-interface .select-interface-option .alert-radio-label {
color: #971e49;
}
/* Alert Interface: set color for alert options (multiple selection) */
.my-custom-interface .select-interface-option .alert-checkbox-label {
color: #971e49;
}
/* Alert Interface: set color for checked alert options (single selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-radio-label {
color: #79193b;
}
/* Alert Interface: set color for checked alert options (multiple selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-checkbox-label {
color: #79193b;
}
```
```javascript
// Pass a custom class to each select interface for styling
const selects = document.querySelectorAll('.custom-options');
for (var i = 0; i < selects.length; i++) {
selects[i].interfaceOptions = {
cssClass: 'my-custom-interface'
};
};
```
> Note: In the CSS examples, some of the selectors could be combined together, but are separated out in order to better explain what each selector is for.
### Customizing Individual Options
To customize an individual option, set a class on the `ion-select-option`:
```html
<ion-item>
<ion-label>Select</ion-label>
<ion-select class="custom-options" interface="popover">
<ion-select-option value="brown" class="brown-option">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .brown-option {
--color: #5e3e2c;
--color-hover: #362419;
}
```
```javascript
// Pass a custom class to each select interface for styling
const select = document.querySelector('.custom-options');
select.interfaceOptions = {
cssClass: 'my-custom-interface'
};
```
### React
```tsx
import React from 'react';
import { IonContent, IonItem, IonLabel, IonSelect, IonSelectOption, IonPage } from '@ionic/react';
export const SelectOptionExample: React.FC = () => {
return (
<IonPage>
<IonContent>
<IonItem>
<IonLabel>Select</IonLabel>
<IonSelect>
<IonSelectOption value="brown">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
</IonContent>
</IonPage>
);
};
```
### Customizing Options
```tsx
import React from 'react';
import { IonContent, IonItem, IonLabel, IonSelect, IonSelectOption, IonPage } from '@ionic/react';
const options = {
cssClass: 'my-custom-interface'
};
export const SelectOptionExample: React.FC = () => {
return (
<IonPage>
<IonContent>
<IonItem>
<IonLabel>Select: Alert Interface</IonLabel>
<IonSelect interfaceOptions={options}>
<IonSelectOption value="brown">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
<IonItem>
<IonLabel>Select: Alert Interface (Multiple Selection)</IonLabel>
<IonSelect interfaceOptions={options} multiple={true}>
<IonSelectOption value="brown">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
<IonItem>
<IonLabel>Select: Popover Interface</IonLabel>
<IonSelect interface="popover" interfaceOptions={options}>
<IonSelectOption value="brown">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
<IonItem>
<IonLabel>Select: Action Sheet Interface</IonLabel>
<IonSelect interface="action-sheet" interfaceOptions={options}>
<IonSelectOption value="brown">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
</IonContent>
</IonPage>
);
};
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .select-interface-option {
--color: #971e49;
--color-hover: #79193b;
}
/* Action Sheet Interface: set color for the action sheet using its button CSS variables */
.my-custom-interface .select-interface-option {
--button-color: #971e49;
--button-color-hover: #79193b;
}
/* Alert Interface: set color for alert options (single selection) */
.my-custom-interface .select-interface-option .alert-radio-label {
color: #971e49;
}
/* Alert Interface: set color for alert options (multiple selection) */
.my-custom-interface .select-interface-option .alert-checkbox-label {
color: #971e49;
}
/* Alert Interface: set color for checked alert options (single selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-radio-label {
color: #79193b;
}
/* Alert Interface: set color for checked alert options (multiple selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-checkbox-label {
color: #79193b;
}
```
> Note: In the CSS examples, some of the selectors could be combined together, but are separated out in order to better explain what each selector is for.
### Customizing Individual Options
To customize an individual option, set a class on the `ion-select-option`:
```tsx
import React from 'react';
import { IonContent, IonItem, IonLabel, IonSelect, IonSelectOption, IonPage } from '@ionic/react';
const options = {
cssClass: 'my-custom-interface'
};
export const SelectOptionExample: React.FC = () => {
return (
<IonPage>
<IonContent>
<IonItem>
<IonLabel>Select</IonLabel>
<IonSelect interface="popover" interfaceOptions={options}>
<IonSelectOption value="brown" class="brown-option">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
</IonContent>
</IonPage>
);
};
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .brown-option {
--color: #5e3e2c;
--color-hover: #362419;
}
```
### Stencil
```tsx
import { Component, h } from '@stencil/core';
@Component({
tag: 'select-option-example',
styleUrl: 'select-option-example.css'
})
export class SelectOptionExample {
render() {
return [
<ion-item>
<ion-label>Select</ion-label>
<ion-select>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
];
}
}
```
### Customizing Options
```tsx
import { Component, h } from '@stencil/core';
@Component({
tag: 'select-option-example',
styleUrl: 'select-option-example.css'
})
export class SelectOptionExample {
options = {
cssClass: 'my-custom-interface'
};
render() {
return [
<ion-item>
<ion-label>Select: Alert Interface</ion-label>
<ion-select interfaceOptions={options}>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>,
<ion-item>
<ion-label>Select: Alert Interface (Multiple Selection)</ion-label>
<ion-select interfaceOptions={options} multiple={true}>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>,
<ion-item>
<ion-label>Select: Popover Interface</ion-label>
<ion-select interface="popover" interfaceOptions={options}>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>,
<ion-item>
<ion-label>Select: Action Sheet Interface</ion-label>
<ion-select interface="action-sheet" interfaceOptions={options}>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
];
}
}
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .select-interface-option {
--color: #971e49;
--color-hover: #79193b;
}
/* Action Sheet Interface: set color for the action sheet using its button CSS variables */
.my-custom-interface .select-interface-option {
--button-color: #971e49;
--button-color-hover: #79193b;
}
/* Alert Interface: set color for alert options (single selection) */
.my-custom-interface .select-interface-option .alert-radio-label {
color: #971e49;
}
/* Alert Interface: set color for alert options (multiple selection) */
.my-custom-interface .select-interface-option .alert-checkbox-label {
color: #971e49;
}
/* Alert Interface: set color for checked alert options (single selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-radio-label {
color: #79193b;
}
/* Alert Interface: set color for checked alert options (multiple selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-checkbox-label {
color: #79193b;
}
```
> Note: In the CSS examples, some of the selectors could be combined together, but are separated out in order to better explain what each selector is for.
### Customizing Individual Options
To customize an individual option, set a class on the `ion-select-option`:
```tsx
import { Component, h } from '@stencil/core';
@Component({
tag: 'select-option-example',
styleUrl: 'select-option-example.css'
})
export class SelectOptionExample {
options = {
cssClass: 'my-custom-interface'
};
render() {
return [
<ion-item>
<ion-label>Select</ion-label>
<ion-select interface="popover" interfaceOptions={options}>
<ion-select-option value="brown" class="brown-option">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
];
}
}
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .brown-option {
--color: #5e3e2c;
--color-hover: #362419;
}
```
### Vue
```html
<template>
<ion-item>
<ion-label>Select</ion-label>
<ion-select>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
</template>
```
### Customizing Options
```html
<template>
<ion-item>
<ion-label>Select: Alert Interface</ion-label>
<ion-select :interface-options="options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Alert Interface (Multiple Selection)</ion-label>
<ion-select :interface-options="options" multiple="true">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Popover Interface</ion-label>
<ion-select interface="popover" :interface-options="options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Action Sheet Interface</ion-label>
<ion-select interface="action-sheet" :interface-options="options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component()
export default class Example extends Vue {
options: any = {
cssClass: 'my-custom-interface'
};
}
</script>
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .select-interface-option {
--color: #971e49;
--color-hover: #79193b;
}
/* Action Sheet Interface: set color for the action sheet using its button CSS variables */
.my-custom-interface .select-interface-option {
--button-color: #971e49;
--button-color-hover: #79193b;
}
/* Alert Interface: set color for alert options (single selection) */
.my-custom-interface .select-interface-option .alert-radio-label {
color: #971e49;
}
/* Alert Interface: set color for alert options (multiple selection) */
.my-custom-interface .select-interface-option .alert-checkbox-label {
color: #971e49;
}
/* Alert Interface: set color for checked alert options (single selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-radio-label {
color: #79193b;
}
/* Alert Interface: set color for checked alert options (multiple selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-checkbox-label {
color: #79193b;
}
```
> Note: In the CSS examples, some of the selectors could be combined together, but are separated out in order to better explain what each selector is for.
### Customizing Individual Options
To customize an individual option, set a class on the `ion-select-option`:
```html
<template>
<ion-item>
<ion-label>Select</ion-label>
<ion-select interface="popover" :interface-options="options">
<ion-select-option value="brown" class="brown-option">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component()
export default class Example extends Vue {
options: any = {
cssClass: 'my-custom-interface'
};
}
</script>
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .brown-option {
--color: #5e3e2c;
--color-hover: #362419;
}
```
## Properties
| Property | Attribute | Description | Type | Default |

View File

@ -0,0 +1,134 @@
```html
<ion-item>
<ion-label>Select</ion-label>
<ion-select>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
```
### Customizing Options
```html
<ion-item>
<ion-label>Select: Alert Interface</ion-label>
<ion-select class="custom-options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Alert Interface (Multiple Selection)</ion-label>
<ion-select class="custom-options" multiple="true">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Popover Interface</ion-label>
<ion-select interface="popover" class="custom-options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Action Sheet Interface</ion-label>
<ion-select interface="action-sheet" class="custom-options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .select-interface-option {
--color: #971e49;
--color-hover: #79193b;
}
/* Action Sheet Interface: set color for the action sheet using its button CSS variables */
.my-custom-interface .select-interface-option {
--button-color: #971e49;
--button-color-hover: #79193b;
}
/* Alert Interface: set color for alert options (single selection) */
.my-custom-interface .select-interface-option .alert-radio-label {
color: #971e49;
}
/* Alert Interface: set color for alert options (multiple selection) */
.my-custom-interface .select-interface-option .alert-checkbox-label {
color: #971e49;
}
/* Alert Interface: set color for checked alert options (single selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-radio-label {
color: #79193b;
}
/* Alert Interface: set color for checked alert options (multiple selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-checkbox-label {
color: #79193b;
}
```
```javascript
// Pass a custom class to each select interface for styling
const selects = document.querySelectorAll('.custom-options');
for (var i = 0; i < selects.length; i++) {
selects[i].interfaceOptions = {
cssClass: 'my-custom-interface'
};
};
```
> Note: In the CSS examples, some of the selectors could be combined together, but are separated out in order to better explain what each selector is for.
### Customizing Individual Options
To customize an individual option, set a class on the `ion-select-option`:
```html
<ion-item>
<ion-label>Select</ion-label>
<ion-select class="custom-options" interface="popover">
<ion-select-option value="brown" class="brown-option">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .brown-option {
--color: #5e3e2c;
--color-hover: #362419;
}
```
```javascript
// Pass a custom class to each select interface for styling
const select = document.querySelector('.custom-options');
select.interfaceOptions = {
cssClass: 'my-custom-interface'
};
```

View File

@ -0,0 +1,157 @@
```tsx
import React from 'react';
import { IonContent, IonItem, IonLabel, IonSelect, IonSelectOption, IonPage } from '@ionic/react';
export const SelectOptionExample: React.FC = () => {
return (
<IonPage>
<IonContent>
<IonItem>
<IonLabel>Select</IonLabel>
<IonSelect>
<IonSelectOption value="brown">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
</IonContent>
</IonPage>
);
};
```
### Customizing Options
```tsx
import React from 'react';
import { IonContent, IonItem, IonLabel, IonSelect, IonSelectOption, IonPage } from '@ionic/react';
const options = {
cssClass: 'my-custom-interface'
};
export const SelectOptionExample: React.FC = () => {
return (
<IonPage>
<IonContent>
<IonItem>
<IonLabel>Select: Alert Interface</IonLabel>
<IonSelect interfaceOptions={options}>
<IonSelectOption value="brown">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
<IonItem>
<IonLabel>Select: Alert Interface (Multiple Selection)</IonLabel>
<IonSelect interfaceOptions={options} multiple={true}>
<IonSelectOption value="brown">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
<IonItem>
<IonLabel>Select: Popover Interface</IonLabel>
<IonSelect interface="popover" interfaceOptions={options}>
<IonSelectOption value="brown">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
<IonItem>
<IonLabel>Select: Action Sheet Interface</IonLabel>
<IonSelect interface="action-sheet" interfaceOptions={options}>
<IonSelectOption value="brown">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
</IonContent>
</IonPage>
);
};
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .select-interface-option {
--color: #971e49;
--color-hover: #79193b;
}
/* Action Sheet Interface: set color for the action sheet using its button CSS variables */
.my-custom-interface .select-interface-option {
--button-color: #971e49;
--button-color-hover: #79193b;
}
/* Alert Interface: set color for alert options (single selection) */
.my-custom-interface .select-interface-option .alert-radio-label {
color: #971e49;
}
/* Alert Interface: set color for alert options (multiple selection) */
.my-custom-interface .select-interface-option .alert-checkbox-label {
color: #971e49;
}
/* Alert Interface: set color for checked alert options (single selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-radio-label {
color: #79193b;
}
/* Alert Interface: set color for checked alert options (multiple selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-checkbox-label {
color: #79193b;
}
```
> Note: In the CSS examples, some of the selectors could be combined together, but are separated out in order to better explain what each selector is for.
### Customizing Individual Options
To customize an individual option, set a class on the `ion-select-option`:
```tsx
import React from 'react';
import { IonContent, IonItem, IonLabel, IonSelect, IonSelectOption, IonPage } from '@ionic/react';
const options = {
cssClass: 'my-custom-interface'
};
export const SelectOptionExample: React.FC = () => {
return (
<IonPage>
<IonContent>
<IonItem>
<IonLabel>Select</IonLabel>
<IonSelect interface="popover" interfaceOptions={options}>
<IonSelectOption value="brown" class="brown-option">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
</IonContent>
</IonPage>
);
};
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .brown-option {
--color: #5e3e2c;
--color-hover: #362419;
}
```

View File

@ -0,0 +1,159 @@
```tsx
import { Component, h } from '@stencil/core';
@Component({
tag: 'select-option-example',
styleUrl: 'select-option-example.css'
})
export class SelectOptionExample {
render() {
return [
<ion-item>
<ion-label>Select</ion-label>
<ion-select>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
];
}
}
```
### Customizing Options
```tsx
import { Component, h } from '@stencil/core';
@Component({
tag: 'select-option-example',
styleUrl: 'select-option-example.css'
})
export class SelectOptionExample {
options = {
cssClass: 'my-custom-interface'
};
render() {
return [
<ion-item>
<ion-label>Select: Alert Interface</ion-label>
<ion-select interfaceOptions={options}>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>,
<ion-item>
<ion-label>Select: Alert Interface (Multiple Selection)</ion-label>
<ion-select interfaceOptions={options} multiple={true}>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>,
<ion-item>
<ion-label>Select: Popover Interface</ion-label>
<ion-select interface="popover" interfaceOptions={options}>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>,
<ion-item>
<ion-label>Select: Action Sheet Interface</ion-label>
<ion-select interface="action-sheet" interfaceOptions={options}>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
];
}
}
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .select-interface-option {
--color: #971e49;
--color-hover: #79193b;
}
/* Action Sheet Interface: set color for the action sheet using its button CSS variables */
.my-custom-interface .select-interface-option {
--button-color: #971e49;
--button-color-hover: #79193b;
}
/* Alert Interface: set color for alert options (single selection) */
.my-custom-interface .select-interface-option .alert-radio-label {
color: #971e49;
}
/* Alert Interface: set color for alert options (multiple selection) */
.my-custom-interface .select-interface-option .alert-checkbox-label {
color: #971e49;
}
/* Alert Interface: set color for checked alert options (single selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-radio-label {
color: #79193b;
}
/* Alert Interface: set color for checked alert options (multiple selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-checkbox-label {
color: #79193b;
}
```
> Note: In the CSS examples, some of the selectors could be combined together, but are separated out in order to better explain what each selector is for.
### Customizing Individual Options
To customize an individual option, set a class on the `ion-select-option`:
```tsx
import { Component, h } from '@stencil/core';
@Component({
tag: 'select-option-example',
styleUrl: 'select-option-example.css'
})
export class SelectOptionExample {
options = {
cssClass: 'my-custom-interface'
};
render() {
return [
<ion-item>
<ion-label>Select</ion-label>
<ion-select interface="popover" interfaceOptions={options}>
<ion-select-option value="brown" class="brown-option">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
];
}
}
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .brown-option {
--color: #5e3e2c;
--color-hover: #362419;
}
```

View File

@ -0,0 +1,145 @@
```html
<template>
<ion-item>
<ion-label>Select</ion-label>
<ion-select>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
</template>
```
### Customizing Options
```html
<template>
<ion-item>
<ion-label>Select: Alert Interface</ion-label>
<ion-select :interface-options="options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Alert Interface (Multiple Selection)</ion-label>
<ion-select :interface-options="options" multiple="true">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Popover Interface</ion-label>
<ion-select interface="popover" :interface-options="options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Select: Action Sheet Interface</ion-label>
<ion-select interface="action-sheet" :interface-options="options">
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component()
export default class Example extends Vue {
options: any = {
cssClass: 'my-custom-interface'
};
}
</script>
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .select-interface-option {
--color: #971e49;
--color-hover: #79193b;
}
/* Action Sheet Interface: set color for the action sheet using its button CSS variables */
.my-custom-interface .select-interface-option {
--button-color: #971e49;
--button-color-hover: #79193b;
}
/* Alert Interface: set color for alert options (single selection) */
.my-custom-interface .select-interface-option .alert-radio-label {
color: #971e49;
}
/* Alert Interface: set color for alert options (multiple selection) */
.my-custom-interface .select-interface-option .alert-checkbox-label {
color: #971e49;
}
/* Alert Interface: set color for checked alert options (single selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-radio-label {
color: #79193b;
}
/* Alert Interface: set color for checked alert options (multiple selection) */
.my-custom-interface .select-interface-option[aria-checked=true] .alert-checkbox-label {
color: #79193b;
}
```
> Note: In the CSS examples, some of the selectors could be combined together, but are separated out in order to better explain what each selector is for.
### Customizing Individual Options
To customize an individual option, set a class on the `ion-select-option`:
```html
<template>
<ion-item>
<ion-label>Select</ion-label>
<ion-select interface="popover" :interface-options="options">
<ion-select-option value="brown" class="brown-option">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component()
export default class Example extends Vue {
options: any = {
cssClass: 'my-custom-interface'
};
}
</script>
```
```css
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .brown-option {
--color: #5e3e2c;
--color-hover: #362419;
}
```

View File

@ -4,5 +4,6 @@ export interface SelectPopoverOption {
value: string;
disabled: boolean;
checked: boolean;
cssClass?: string | string[];
handler?: () => void;
}

View File

@ -3,6 +3,7 @@ import { Component, ComponentInterface, Host, Listen, Prop, h } from '@stencil/c
import { getIonMode } from '../../global/ionic-global';
import { SelectPopoverOption } from '../../interface';
import { safeCall } from '../../utils/overlays';
import { getClassMap } from '../../utils/theme';
/**
* @internal
@ -51,7 +52,7 @@ export class SelectPopover implements ComponentInterface {
}
<ion-radio-group value={checkedValue}>
{this.options.map(option =>
<ion-item>
<ion-item class={getClassMap(option.cssClass)}>
<ion-label>
{option.text}
</ion-label>

View File

@ -43,6 +43,83 @@ See the [ion-alert docs](../alert), [ion-action-sheet docs](../action-sheet), an
Note: `interfaceOptions` will not override `inputs` or `buttons` with the `alert` interface.
## Customization
There are two units that make up the Select component and each need to be styled separately. The `ion-select` element is represented on the view by the selected value(s), or placeholder if there is none, and dropdown icon. The interface, which is defined in the [Interfaces](#interfaces) section above, is the dialog that opens when clicking on the `ion-select`. The interface contains all of the options defined by adding `ion-select-option` elements. The following sections will go over the differences between styling these.
### Styling Select Element
As mentioned, the `ion-select` element consists only of the value(s), or placeholder, and icon that is displayed on the view. To customize this, style using a combination of CSS and any of the [CSS custom properties](#css-custom-properties):
```css
ion-select {
/* Applies to the value and placeholder color */
color: #545ca7;
/* Set a different placeholder color */
--placeholder-color: #971e49;
/* Set full opacity on the placeholder */
--placeholder-opacity: 1;
}
```
Alternatively, depending on the [browser support](https://caniuse.com/#feat=mdn-css_selectors_part) needed, CSS shadow parts can be used to style the select:
```css
/* Set the width to the full container and center the content */
ion-select {
width: 100%;
justify-content: center;
}
/* Set the flex in order to size the text width to its content */
ion-select::part(placeholder),
ion-select::part(text) {
flex: 0 0 auto;
}
/* Set the placeholder color and opacity */
ion-select::part(placeholder) {
color: #20a08a;
opacity: 1;
}
/*
* Set the font of the first letter of the placeholder
* Shadow parts work with pseudo-elements, too!
* https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements
*/
ion-select::part(placeholder)::first-letter {
font-size: 24px;
font-weight: 500;
}
/* Set the text color */
ion-select::part(text) {
color: #545ca7;
}
/* Set the icon color and opacity */
ion-select::part(icon) {
color: #971e49;
opacity: 1;
}
```
Notice that by using `::part`, any CSS property on the element can be targeted.
### Styling Select Interface
Customizing the interface dialog should be done by following the Customization section in that interface's documentation:
- [Alert Customization](../alert#customization)
- [Action Sheet Customization](../action-sheet#customization)
- [Popover Customization](../popover#customization)
However, the Select Option does set a class for easier styling and allows for the ability to pass a class to the overlay option, see the [Select Options documentation](./select-option) for usage examples of customizing options.
<!-- Auto Generated Below -->

View File

@ -229,9 +229,15 @@ export class Select implements ComponentInterface {
private createActionSheetButtons(data: HTMLIonSelectOptionElement[], selectValue: any): ActionSheetButton[] {
const actionSheetButtons = data.map(option => {
const value = getOptionValue(option);
// Remove hydrated before copying over classes
const copyClasses = Array.from(option.classList).filter(cls => cls !== 'hydrated').join(' ');
const optClass = `${OPTION_CLASS} ${copyClasses}`;
return {
role: (isOptionSelected(value, selectValue, this.compareWith) ? 'selected' : ''),
text: option.textContent,
cssClass: optClass,
handler: () => {
this.value = value;
}
@ -251,32 +257,48 @@ export class Select implements ComponentInterface {
}
private createAlertInputs(data: HTMLIonSelectOptionElement[], inputType: 'checkbox' | 'radio', selectValue: any): AlertInput[] {
return data.map(o => {
const value = getOptionValue(o);
const alertInputs = data.map(option => {
const value = getOptionValue(option);
// Remove hydrated before copying over classes
const copyClasses = Array.from(option.classList).filter(cls => cls !== 'hydrated').join(' ');
const optClass = `${OPTION_CLASS} ${copyClasses}`;
return {
type: inputType,
label: o.textContent || '',
cssClass: optClass,
label: option.textContent || '',
value,
checked: isOptionSelected(value, selectValue, this.compareWith),
disabled: o.disabled
disabled: option.disabled
};
});
return alertInputs;
}
private createPopoverOptions(data: HTMLIonSelectOptionElement[], selectValue: any): SelectPopoverOption[] {
return data.map(o => {
const value = getOptionValue(o);
const popoverOptions = data.map(option => {
const value = getOptionValue(option);
// Remove hydrated before copying over classes
const copyClasses = Array.from(option.classList).filter(cls => cls !== 'hydrated').join(' ');
const optClass = `${OPTION_CLASS} ${copyClasses}`;
return {
text: o.textContent || '',
text: option.textContent || '',
cssClass: optClass,
value,
checked: isOptionSelected(value, selectValue, this.compareWith),
disabled: o.disabled,
disabled: option.disabled,
handler: () => {
this.value = value;
this.close();
}
};
});
return popoverOptions;
}
private async openPopover(ev: UIEvent) {
@ -529,3 +551,5 @@ const textForValue = (opts: HTMLIonSelectOptionElement[], value: any, compareWit
};
let selectIds = 0;
const OPTION_CLASS = 'select-interface-option';

View File

@ -65,8 +65,64 @@
</ion-select>
</ion-item>
</ion-list>
<ion-list>
<ion-list-header>
<ion-label>Custom Options</ion-label>
</ion-list-header>
<ion-item>
<ion-label>Default Interface (Alert)</ion-label>
<ion-select placeholder="Styled Options" class="custom-options">
<ion-select-option class="select-option-custom-red" value="madison">Madison, WI</ion-select-option>
<ion-select-option class="select-option-custom-red" value="austin">Austin, TX</ion-select-option>
<ion-select-option class="select-option-custom-purple" value="chicago">Chicago, IL</ion-select-option>
<ion-select-option class="select-option-custom-red" value="seattle">Seattle, WA</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Action Sheet Interface</ion-label>
<ion-select placeholder="Styled Options" interface="action-sheet" class="custom-options">
<ion-select-option class="select-option-custom-red" value="madison">Madison, WI</ion-select-option>
<ion-select-option class="select-option-custom-red" value="austin">Austin, TX</ion-select-option>
<ion-select-option class="select-option-custom-purple" value="chicago">Chicago, IL</ion-select-option>
<ion-select-option class="select-option-custom-red" value="seattle">Seattle, WA</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Popover Interface</ion-label>
<ion-select placeholder="Styled Options" interface="popover" class="custom-options">
<ion-select-option class="select-option-custom-red" value="madison">Madison, WI</ion-select-option>
<ion-select-option class="select-option-custom-red" value="austin">Austin, TX</ion-select-option>
<ion-select-option class="select-option-custom-purple" value="chicago">Chicago, IL</ion-select-option>
<ion-select-option class="select-option-custom-red" value="seattle">Seattle, WA</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Default Interface (Alert): Multiple</ion-label>
<ion-select multiple="true" placeholder="Styled Options" class="custom-options">
<ion-select-option class="select-option-custom-red" value="madison">Madison, WI</ion-select-option>
<ion-select-option class="select-option-custom-red" value="austin">Austin, TX</ion-select-option>
<ion-select-option class="select-option-custom-purple" value="chicago">Chicago, IL</ion-select-option>
<ion-select-option class="select-option-custom-red" value="seattle">Seattle, WA</ion-select-option>
</ion-select>
</ion-item>
</ion-list>
</ion-content>
<script>
const selects = document.querySelectorAll('.custom-options');
for (var i = 0; i < selects.length; i++) {
selects[i].interfaceOptions = {
cssClass: 'select-interface-custom'
};
};
</script>
<style>
.custom-part-colors {
text-align: center;
@ -86,18 +142,64 @@
}
.custom-part-colors::part(placeholder) {
color: green;
color: #20a08a;
opacity: 1;
}
.custom-part-colors::part(text) {
color: blue;
color: #545ca7;
}
.custom-part-colors::part(icon) {
color: red;
color: #971e49;
opacity: 1;
}
/* Alert Interface [Selector 1]: set color for alert options (single selection) */
/* Alert Interface [Selector 2]: set color for checked alert options (single selection) */
/* Alert Interface [Selector 3]: set color for alert options (multi selection) */
/* Alert Interface [Selector 4]: set color for checked alert options (multi selection) */
.select-interface-custom .select-option-custom-red .alert-radio-label,
.select-interface-custom .select-option-custom-red[aria-checked=true] .alert-radio-label,
.select-interface-custom .select-option-custom-red .alert-checkbox-label,
.select-interface-custom .select-option-custom-red[aria-checked=true] .alert-checkbox-label {
color: #971e49;
}
/* Alert Interface [Selector 1]: set color for alert options (single selection) */
/* Alert Interface [Selector 2]: set color for checked alert options (single selection) */
/* Alert Interface [Selector 3]: set color for alert options (multi selection) */
/* Alert Interface [Selector 4]: set color for checked alert options (multi selection) */
.select-interface-custom .select-option-custom-purple .alert-radio-label,
.select-interface-custom .select-option-custom-purple[aria-checked=true] .alert-radio-label,
.select-interface-custom .select-option-custom-purple .alert-checkbox-label,
.select-interface-custom .select-option-custom-purple[aria-checked=true] .alert-checkbox-label {
color: #545ca7;
}
/* Popover Interface: set color for the popover using Item's CSS variables */
.select-interface-custom .select-option-custom-red {
--color: #971e49;
--color-hover: #79193b;
}
/* Popover Interface: set color for the popover using Item's CSS variables */
.select-interface-custom .select-option-custom-purple {
--color: #545ca7;
--color-hover: #414ba1;
}
/* Action Sheet Interface: set color for the action sheet using its button CSS variables */
.select-interface-custom .select-option-custom-red {
--button-color: #971e49;
--button-color-hover: #79193b;
}
/* Action Sheet Interface: set color for the action sheet using its button CSS variables */
.select-interface-custom .select-option-custom-purple {
--button-color: #545ca7;
--button-color-hover: #414ba1;
}
</style>
</ion-app>