diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 134b699352..7f17407863 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -58,6 +58,7 @@ import { RouterOutletOptions, RouteWrite, SelectInputChangeEvent, + SelectInterface, SelectPopoverOption, StyleEvent, ToastOptions, @@ -5674,7 +5675,7 @@ declare global { /** * The interface the select should use: `action-sheet`, `popover` or `alert`. Default: `alert`. */ - 'interface': string; + 'interface': SelectInterface; /** * Any additional options that the `alert`, `action-sheet` or `popover` interface can take. See the [AlertController API docs](../../alert/AlertController/#create), the [ActionSheetController API docs](../../action-sheet/ActionSheetController/#create) and the [PopoverController API docs](../../popover/PopoverController/#create) for the create options for each interface. */ @@ -5736,7 +5737,7 @@ declare global { /** * The interface the select should use: `action-sheet`, `popover` or `alert`. Default: `alert`. */ - 'interface'?: string; + 'interface'?: SelectInterface; /** * Any additional options that the `alert`, `action-sheet` or `popover` interface can take. See the [AlertController API docs](../../alert/AlertController/#create), the [ActionSheetController API docs](../../action-sheet/ActionSheetController/#create) and the [PopoverController API docs](../../popover/PopoverController/#create) for the create options for each interface. */ diff --git a/core/src/components/action-sheet/action-sheet-interface.ts b/core/src/components/action-sheet/action-sheet-interface.ts index b4f322527f..c059d1bf60 100644 --- a/core/src/components/action-sheet/action-sheet-interface.ts +++ b/core/src/components/action-sheet/action-sheet-interface.ts @@ -2,7 +2,7 @@ export interface ActionSheetOptions { header?: string; subHeader?: string; - cssClass?: string; + cssClass?: string | string[]; buttons: (ActionSheetButton | string)[]; enableBackdropDismiss?: boolean; translucent?: boolean; @@ -12,7 +12,7 @@ export interface ActionSheetButton { text?: string; role?: 'cancel' | 'destructive' | 'selected' | string; icon?: string; - cssClass?: string; + cssClass?: string | string[]; handler?: () => boolean | void; } diff --git a/core/src/components/input/input-base.tsx b/core/src/components/input/input-base.tsx index 9d5f0db8e2..2e7d14fc3a 100644 --- a/core/src/components/input/input-base.tsx +++ b/core/src/components/input/input-base.tsx @@ -10,7 +10,6 @@ export interface InputBaseComponent { clearOnEdit: boolean; didBlurAfterEdit: boolean; - styleTmr?: number; // Shared Attributes autocapitalize?: string; diff --git a/core/src/components/select/select-interface.ts b/core/src/components/select/select-interface.ts new file mode 100644 index 0000000000..918a878e48 --- /dev/null +++ b/core/src/components/select/select-interface.ts @@ -0,0 +1 @@ +export type SelectInterface = 'action-sheet' | 'popover' | 'alert'; diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index a4fbea8b70..6199af209e 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -1,7 +1,8 @@ import { Component, Element, Event, EventEmitter, Listen, Prop, State, Watch } from '@stencil/core'; -import { ActionSheetButton, ActionSheetOptions, AlertOptions, CssClassMap, - Mode, PopoverOptions, SelectInputChangeEvent, SelectPopoverOption, StyleEvent +import { ActionSheetButton, ActionSheetOptions, AlertInput, AlertOptions, + CssClassMap, Mode, PopoverOptions, SelectInputChangeEvent, SelectInterface, SelectPopoverOption, StyleEvent } from '../../interface'; +import { deferEvent } from '../../utils/helpers'; @Component({ @@ -20,7 +21,7 @@ export class Select { private selectId = `ion-sel-${selectIds++}`; private labelId?: string; private overlay?: HTMLIonActionSheetElement | HTMLIonAlertElement | HTMLIonPopoverElement; - private styleTmr: any; + mode!: Mode; @Element() el!: HTMLIonSelectElement; @@ -71,7 +72,7 @@ export class Select { /** * The interface the select should use: `action-sheet`, `popover` or `alert`. Default: `alert`. */ - @Prop() interface = 'alert'; + @Prop() interface: SelectInterface = 'alert'; /** * Any additional options that the `alert`, `action-sheet` or `popover` interface @@ -231,6 +232,8 @@ export class Select { } componentDidLoad() { + this.ionStyle = deferEvent(this.ionStyle); + const label = this.getLabel(); if (label) { this.labelId = label.id = this.name + '-lbl'; @@ -292,9 +295,11 @@ export class Select { } private async openPopover(ev: UIEvent) { - const interfaceOptions = {...this.interfaceOptions}; + const interfaceOptions = this.interfaceOptions; + + const popoverOpts: PopoverOptions = { + ...interfaceOptions, - const popoverOpts: PopoverOptions = Object.assign(interfaceOptions, { component: 'ion-select-popover', componentProps: { header: interfaceOptions.header, @@ -314,9 +319,9 @@ export class Select { } as SelectPopoverOption; }) }, - cssClass: 'select-popover' + (interfaceOptions.cssClass ? ' ' + interfaceOptions.cssClass : ''), + cssClass: ['select-popover', interfaceOptions.cssClass], ev: ev - }); + }; const popover = this.overlay = await this.popoverCtrl.create(popoverOpts); await popover.present(); @@ -325,8 +330,6 @@ export class Select { } private async openActionSheet() { - const interfaceOptions = {...this.interfaceOptions}; - const actionSheetButtons = this.childOpts.map(option => { return { role: (option.selected ? 'selected' : ''), @@ -345,10 +348,13 @@ export class Select { } }); - const actionSheetOpts: ActionSheetOptions = Object.assign(interfaceOptions, { + const interfaceOptions = this.interfaceOptions; + const actionSheetOpts: ActionSheetOptions = { + ...interfaceOptions, + buttons: actionSheetButtons, - cssClass: 'select-action-sheet' + (interfaceOptions.cssClass ? ' ' + interfaceOptions.cssClass : '') - }); + cssClass: ['select-action-sheet', interfaceOptions.cssClass] + }; const actionSheet = this.overlay = await this.actionSheetCtrl.create(actionSheetOpts); await actionSheet.present(); @@ -358,12 +364,14 @@ export class Select { } private async openAlert() { - const interfaceOptions = {...this.interfaceOptions}; const label = this.getLabel(); const labelText = (label) ? label.textContent : null; - const alertOpts: AlertOptions = Object.assign(interfaceOptions, { + const interfaceOptions = this.interfaceOptions; + const alertOpts: AlertOptions = { + ...interfaceOptions, + header: interfaceOptions.header ? interfaceOptions.header : labelText, inputs: this.childOpts.map(o => { return { @@ -372,27 +380,23 @@ export class Select { value: o.value, checked: o.selected, disabled: o.disabled - }; + } as AlertInput; }), - buttons: [ - { - text: this.cancelText, - role: 'cancel', - handler: () => { - this.ionCancel.emit(); - } - }, - { - text: this.okText, - handler: (selectedValues: any) => { - this.value = selectedValues; - } + buttons: [{ + text: this.cancelText, + role: 'cancel', + handler: () => { + this.ionCancel.emit(); } - ], - cssClass: 'select-alert ' + - (this.multiple ? 'multiple-select-alert' : 'single-select-alert') + - (interfaceOptions.cssClass ? ' ' + interfaceOptions.cssClass : '') - }); + }, { + text: this.okText, + handler: (selectedValues: any) => { + this.value = selectedValues; + } + }], + cssClass: ['select-alert', interfaceOptions.cssClass, + (this.multiple ? 'multiple-select-alert' : 'single-select-alert')] + }; const alert = this.overlay = await this.alertCtrl.create(alertOpts); await alert.present(); @@ -412,7 +416,6 @@ export class Select { const overlay = this.overlay; this.overlay = undefined; - this.isExpanded = false; return overlay.dismiss(); @@ -439,14 +442,10 @@ export class Select { } private emitStyle() { - clearTimeout(this.styleTmr); - - this.styleTmr = setTimeout(() => { - this.ionStyle.emit({ - 'select': true, - 'select-disabled': this.disabled, - 'input-has-value': this.hasValue() - }); + this.ionStyle.emit({ + 'select': true, + 'select-disabled': this.disabled, + 'input-has-value': this.hasValue() }); } diff --git a/core/src/components/textarea/textarea.tsx b/core/src/components/textarea/textarea.tsx index 200c2ea829..af08b56e84 100644 --- a/core/src/components/textarea/textarea.tsx +++ b/core/src/components/textarea/textarea.tsx @@ -22,7 +22,6 @@ export class Textarea implements TextareaComponent { color!: string; didBlurAfterEdit = false; - styleTmr?: number; @Element() el!: HTMLElement; diff --git a/core/src/interface.d.ts b/core/src/interface.d.ts index 5d8b90bd3e..6ee9224262 100644 --- a/core/src/interface.d.ts +++ b/core/src/interface.d.ts @@ -12,6 +12,7 @@ export * from './components/loading/loading-interface'; export * from './components/popover/popover-interface'; export * from './components/nav/nav-interface'; export * from './components/router/utils/interface'; +export * from './components/select/select-interface'; export * from './components/select-popover/select-popover-interface'; export * from './components/toast/toast-interface'; diff --git a/core/src/utils/theme.ts b/core/src/utils/theme.ts index 0e9c4440b7..52afad3f2c 100644 --- a/core/src/utils/theme.ts +++ b/core/src/utils/theme.ts @@ -52,12 +52,11 @@ export function getButtonClassMap(buttonType: string, mode: Mode): CssClassMap { export function getClassList(classes: string | string[] | undefined): string[] { if (classes) { - if (Array.isArray(classes)) { - return classes; - } - return classes - .split(' ') - .filter(c => c.trim() !== ''); + const array = Array.isArray(classes) ? classes : classes.split(' '); + return array + .filter(c => c != null) + .map(c => c.trim()) + .filter(c => c !== ''); } return []; }