import type { ComponentInterface, EventEmitter } from '@stencil/core'; import { Component, Element, Event, Host, Prop, Watch, h } from '@stencil/core'; import { getIonMode } from '../../global/ionic-global'; import type { CheckboxChangeEventDetail, Color, StyleEventDetail } from '../../interface'; import { getAriaLabel, renderHiddenInput } from '../../utils/helpers'; import { createColorClasses, hostContext } from '../../utils/theme'; /** * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use. * * @part container - The container for the checkbox mark. * @part mark - The checkmark used to indicate the checked state. */ @Component({ tag: 'ion-checkbox', styleUrls: { ios: 'checkbox.ios.scss', md: 'checkbox.md.scss', }, shadow: true, }) export class Checkbox implements ComponentInterface { private inputId = `ion-cb-${checkboxIds++}`; private focusEl?: HTMLElement; @Element() el!: HTMLElement; /** * The color to use from your application's color palette. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information on colors, see [theming](/docs/theming/basics). */ @Prop({ reflect: true }) color?: Color; /** * The name of the control, which is submitted with the form data. */ @Prop() name: string = this.inputId; /** * If `true`, the checkbox is selected. */ @Prop({ mutable: true }) checked = false; /** * If `true`, the checkbox will visually appear as indeterminate. */ @Prop({ mutable: true }) indeterminate = false; /** * If `true`, the user cannot interact with the checkbox. */ @Prop() disabled = false; /** * The value of the checkbox does not mean if it's checked or not, use the `checked` * property for that. * * The value of a checkbox is analogous to the value of an ``, * it's only used when the checkbox participates in a native `
`. */ @Prop() value: any | null = 'on'; /** * Emitted when the checked property has changed. */ @Event() ionChange!: EventEmitter; /** * Emitted when the checkbox has focus. */ @Event() ionFocus!: EventEmitter; /** * Emitted when the checkbox loses focus. */ @Event() ionBlur!: EventEmitter; /** * Emitted when the styles change. * @internal */ @Event() ionStyle!: EventEmitter; componentWillLoad() { this.emitStyle(); } @Watch('checked') checkedChanged(isChecked: boolean) { this.ionChange.emit({ checked: isChecked, value: this.value, }); this.emitStyle(); } @Watch('disabled') disabledChanged() { this.emitStyle(); } private emitStyle() { this.ionStyle.emit({ 'checkbox-checked': this.checked, 'interactive-disabled': this.disabled, }); } private setFocus() { if (this.focusEl) { this.focusEl.focus(); } } private onClick = (ev: any) => { ev.preventDefault(); this.setFocus(); this.checked = !this.checked; this.indeterminate = false; }; private onFocus = () => { this.ionFocus.emit(); }; private onBlur = () => { this.ionBlur.emit(); }; render() { const { color, checked, disabled, el, indeterminate, inputId, name, value } = this; const mode = getIonMode(this); const { label, labelId, labelText } = getAriaLabel(el, inputId); renderHiddenInput(true, el, name, checked ? value : '', disabled); let path = indeterminate ? ( ) : ( ); if (mode === 'md') { path = indeterminate ? ( ) : ( ); } return ( {path} this.onFocus()} onBlur={() => this.onBlur()} ref={(focusEl) => (this.focusEl = focusEl)} /> ); } } let checkboxIds = 0;