diff --git a/core/src/components/alert/alert-interface.ts b/core/src/components/alert/alert-interface.ts index 21f33c0dcb..ae80cd17b1 100644 --- a/core/src/components/alert/alert-interface.ts +++ b/core/src/components/alert/alert-interface.ts @@ -32,6 +32,7 @@ export interface AlertInput { handler?: (input: AlertInput) => void; min?: string | number; max?: string | number; + cssClass?: string | string[]; } export interface AlertButton { diff --git a/core/src/components/alert/alert.tsx b/core/src/components/alert/alert.tsx index d9daeecd4d..20452d223d 100644 --- a/core/src/components/alert/alert.tsx +++ b/core/src/components/alert/alert.tsx @@ -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 }} diff --git a/core/src/components/select-option/readme.md b/core/src/components/select-option/readme.md index c0d4e33ad8..a4136576cf 100644 --- a/core/src/components/select-option/readme.md +++ b/core/src/components/select-option/readme.md @@ -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. +## Usage + +### Javascript + +```html + + Select + + Brown + Blonde + Black + Red + + +``` + +### Customizing Options + +```html + + Select: Alert Interface + + Brown + Blonde + Black + Red + + + + + Select: Alert Interface (Multiple Selection) + + Brown + Blonde + Black + Red + + + + + Select: Popover Interface + + Brown + Blonde + Black + Red + + + + + Select: Action Sheet Interface + + Brown + Blonde + Black + Red + + +``` + +```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 + + Select + + Brown + Blonde + Black + Red + + +``` + +```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 ( + + + + Select + + Brown + Blonde + Black + Red + + + + + ); +}; +``` + +### 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 ( + + + + Select: Alert Interface + + Brown + Blonde + Black + Red + + + + + Select: Alert Interface (Multiple Selection) + + Brown + Blonde + Black + Red + + + + + Select: Popover Interface + + Brown + Blonde + Black + Red + + + + + Select: Action Sheet Interface + + Brown + Blonde + Black + Red + + + + + ); +}; +``` + +```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 ( + + + + Select + + Brown + Blonde + Black + Red + + + + + ); +}; +``` + +```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 [ + + Select + + Brown + Blonde + Black + Red + + + ]; + } +} +``` + +### 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 [ + + Select: Alert Interface + + Brown + Blonde + Black + Red + + , + + + Select: Alert Interface (Multiple Selection) + + Brown + Blonde + Black + Red + + , + + + Select: Popover Interface + + Brown + Blonde + Black + Red + + , + + + Select: Action Sheet Interface + + Brown + Blonde + Black + Red + + + ]; + } +} +``` + +```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 [ + + Select + + Brown + Blonde + Black + Red + + + ]; + } +} +``` + +```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 + +``` + +### Customizing Options + +```html + + + + +``` + +```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 + + + +``` + +```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 | diff --git a/core/src/components/select-option/usage/javascript.md b/core/src/components/select-option/usage/javascript.md new file mode 100644 index 0000000000..02b75dcc2b --- /dev/null +++ b/core/src/components/select-option/usage/javascript.md @@ -0,0 +1,134 @@ +```html + + Select + + Brown + Blonde + Black + Red + + +``` + +### Customizing Options + +```html + + Select: Alert Interface + + Brown + Blonde + Black + Red + + + + + Select: Alert Interface (Multiple Selection) + + Brown + Blonde + Black + Red + + + + + Select: Popover Interface + + Brown + Blonde + Black + Red + + + + + Select: Action Sheet Interface + + Brown + Blonde + Black + Red + + +``` + +```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 + + Select + + Brown + Blonde + Black + Red + + +``` + +```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' +}; +``` \ No newline at end of file diff --git a/core/src/components/select-option/usage/react.md b/core/src/components/select-option/usage/react.md new file mode 100644 index 0000000000..f3d09aa332 --- /dev/null +++ b/core/src/components/select-option/usage/react.md @@ -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 ( + + + + Select + + Brown + Blonde + Black + Red + + + + + ); +}; +``` + +### 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 ( + + + + Select: Alert Interface + + Brown + Blonde + Black + Red + + + + + Select: Alert Interface (Multiple Selection) + + Brown + Blonde + Black + Red + + + + + Select: Popover Interface + + Brown + Blonde + Black + Red + + + + + Select: Action Sheet Interface + + Brown + Blonde + Black + Red + + + + + ); +}; +``` + +```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 ( + + + + Select + + Brown + Blonde + Black + Red + + + + + ); +}; +``` + +```css +/* Popover Interface: set color for the popover using Item's CSS variables */ +.my-custom-interface .brown-option { + --color: #5e3e2c; + --color-hover: #362419; +} +``` \ No newline at end of file diff --git a/core/src/components/select-option/usage/stencil.md b/core/src/components/select-option/usage/stencil.md new file mode 100644 index 0000000000..a17f0edd72 --- /dev/null +++ b/core/src/components/select-option/usage/stencil.md @@ -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 [ + + Select + + Brown + Blonde + Black + Red + + + ]; + } +} +``` + +### 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 [ + + Select: Alert Interface + + Brown + Blonde + Black + Red + + , + + + Select: Alert Interface (Multiple Selection) + + Brown + Blonde + Black + Red + + , + + + Select: Popover Interface + + Brown + Blonde + Black + Red + + , + + + Select: Action Sheet Interface + + Brown + Blonde + Black + Red + + + ]; + } +} +``` + +```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 [ + + Select + + Brown + Blonde + Black + Red + + + ]; + } +} +``` + +```css +/* Popover Interface: set color for the popover using Item's CSS variables */ +.my-custom-interface .brown-option { + --color: #5e3e2c; + --color-hover: #362419; +} +``` \ No newline at end of file diff --git a/core/src/components/select-option/usage/vue.md b/core/src/components/select-option/usage/vue.md new file mode 100644 index 0000000000..be7696b1b0 --- /dev/null +++ b/core/src/components/select-option/usage/vue.md @@ -0,0 +1,145 @@ +```html + +``` + +### Customizing Options + +```html + + + + +``` + +```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 + + + +``` + +```css +/* Popover Interface: set color for the popover using Item's CSS variables */ +.my-custom-interface .brown-option { + --color: #5e3e2c; + --color-hover: #362419; +} +``` diff --git a/core/src/components/select-popover/select-popover-interface.ts b/core/src/components/select-popover/select-popover-interface.ts index 43dc6481bb..194f1e0645 100644 --- a/core/src/components/select-popover/select-popover-interface.ts +++ b/core/src/components/select-popover/select-popover-interface.ts @@ -4,5 +4,6 @@ export interface SelectPopoverOption { value: string; disabled: boolean; checked: boolean; + cssClass?: string | string[]; handler?: () => void; } diff --git a/core/src/components/select-popover/select-popover.tsx b/core/src/components/select-popover/select-popover.tsx index 612e9d8789..4ff4b70a6f 100644 --- a/core/src/components/select-popover/select-popover.tsx +++ b/core/src/components/select-popover/select-popover.tsx @@ -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 { } {this.options.map(option => - + {option.text} diff --git a/core/src/components/select/readme.md b/core/src/components/select/readme.md index 529474b135..a0c9cb80c2 100644 --- a/core/src/components/select/readme.md +++ b/core/src/components/select/readme.md @@ -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. + diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index 01347586aa..e7193fc3c1 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -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'; diff --git a/core/src/components/select/test/custom/index.html b/core/src/components/select/test/custom/index.html index 28a515053b..3bffd39ae1 100644 --- a/core/src/components/select/test/custom/index.html +++ b/core/src/components/select/test/custom/index.html @@ -65,8 +65,64 @@ + + + + Custom Options + + + + Default Interface (Alert) + + Madison, WI + Austin, TX + Chicago, IL + Seattle, WA + + + + + Action Sheet Interface + + Madison, WI + Austin, TX + Chicago, IL + Seattle, WA + + + + + Popover Interface + + Madison, WI + Austin, TX + Chicago, IL + Seattle, WA + + + + + Default Interface (Alert): Multiple + + Madison, WI + Austin, TX + Chicago, IL + Seattle, WA + + + + +