import { Component, ComponentInterface, Host, Listen, Prop, h } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import { SelectPopoverOption } from '../../interface';
import { safeCall } from '../../utils/overlays';
import { getClassMap } from '../../utils/theme';
/**
* @internal
*/
@Component({
tag: 'ion-select-popover',
styleUrls: {
ios: 'select-popover.ios.scss',
md: 'select-popover.md.scss'
},
scoped: true
})
export class SelectPopover implements ComponentInterface {
/**
* The header text of the popover
*/
@Prop() header?: string;
/**
* The subheader text of the popover
*/
@Prop() subHeader?: string;
/**
* The text content of the popover body
*/
@Prop() message?: string;
/**
* If true, the select accepts multiple values
*/
@Prop() multiple?: boolean;
/**
* An array of options for the popover
*/
@Prop() options: SelectPopoverOption[] = [];
@Listen('ionChange')
onSelect(ev: any) {
this.setChecked(ev);
this.callOptionHandler(ev);
}
private findOptionFromEvent(ev: any) {
const { options } = this;
return options.find(o => o.value === ev.target.value);
}
/**
* When an option is selected we need to get the value(s)
* of the selected option(s) and return it in the option
* handler
*/
private callOptionHandler(ev: any) {
const option = this.findOptionFromEvent(ev);
const values = this.getValues(ev);
if (option && option.handler) {
safeCall(option.handler, values);
}
}
/**
* This is required when selecting a radio that is already
* selected because it will not trigger the ionChange event
* but we still want to close the popover
*/
private rbClick(ev: any) {
this.callOptionHandler(ev);
}
private setChecked(ev: any): void {
const { multiple } = this;
const option = this.findOptionFromEvent(ev);
// this is a popover with checkboxes (multiple value select)
// we need to set the checked value for this option
if (multiple && option) {
option.checked = ev.detail.checked;
}
}
private getValues(ev: any): any | any[] | null {
const { multiple, options } = this;
if (multiple) {
// this is a popover with checkboxes (multiple value select)
// return an array of all the checked values
return options.filter(o => o.checked).map(o => o.value);
}
// this is a popover with radio buttons (single value select)
// return the value that was clicked, otherwise undefined
const option = this.findOptionFromEvent(ev);
return option ? option.value : undefined;
}
renderOptions(options: SelectPopoverOption[]) {
const { multiple } = this;
switch (multiple) {
case true: return this.renderCheckboxOptions(options);
default: return this.renderRadioOptions(options);
}
}
renderCheckboxOptions(options: SelectPopoverOption[]) {
return (
options.map(option =>
{option.text}
)
)
}
renderRadioOptions(options: SelectPopoverOption[]) {
const checked = options.filter(o => o.checked).map(o => o.value)[0];
return (
{options.map(option =>
{option.text}
this.rbClick(ev)}
>
)}
)
}
render() {
const { header, message, options, subHeader } = this;
const hasSubHeaderOrMessage = subHeader !== undefined || message !== undefined;
return (
{header !== undefined && {header}}
{ hasSubHeaderOrMessage &&
{subHeader !== undefined && {subHeader}
}
{message !== undefined && {message}
}
}
{this.renderOptions(options)}
);
}
}