UNPKG

@zoff-tech/zt-bottom-drawer

Version:
168 lines (165 loc) 6.23 kB
import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client'; import { renderHiddenInput } from '@utils/helpers'; import { g as getIonMode } from './ionic-global.js'; const RadioGroup = /*@__PURE__*/ proxyCustomElement(class RadioGroup extends HTMLElement { constructor() { super(); this.__registerHost(); this.ionChange = createEvent(this, "ionChange", 7); this.ionValueChange = createEvent(this, "ionValueChange", 7); this.inputId = `ion-rg-${radioGroupIds++}`; this.labelId = `${this.inputId}-lbl`; this.setRadioTabindex = (value) => { const radios = this.getRadios(); // Get the first radio that is not disabled and the checked one const first = radios.find((radio) => !radio.disabled); const checked = radios.find((radio) => radio.value === value && !radio.disabled); if (!first && !checked) { return; } // If an enabled checked radio exists, set it to be the focusable radio // otherwise we default to focus the first radio const focusable = checked || first; for (const radio of radios) { const tabindex = radio === focusable ? 0 : -1; radio.setButtonTabindex(tabindex); } }; this.onClick = (ev) => { ev.preventDefault(); /** * The Radio Group component mandates that only one radio button * within the group can be selected at any given time. Since `ion-radio` * is a shadow DOM component, it cannot natively perform this behavior * using the `name` attribute. */ const selectedRadio = ev.target && ev.target.closest('ion-radio'); if (selectedRadio) { const currentValue = this.value; const newValue = selectedRadio.value; if (newValue !== currentValue) { this.value = newValue; this.emitValueChange(ev); } else if (this.allowEmptySelection) { this.value = undefined; this.emitValueChange(ev); } } }; this.allowEmptySelection = false; this.name = this.inputId; this.value = undefined; } valueChanged(value) { this.setRadioTabindex(value); this.ionValueChange.emit({ value }); } componentDidLoad() { this.setRadioTabindex(this.value); } async connectedCallback() { // Get the list header if it exists and set the id // this is used to set aria-labelledby const header = this.el.querySelector('ion-list-header') || this.el.querySelector('ion-item-divider'); if (header) { const label = (this.label = header.querySelector('ion-label')); if (label) { this.labelId = label.id = this.name + '-lbl'; } } } getRadios() { return Array.from(this.el.querySelectorAll('ion-radio')); } /** * Emits an `ionChange` event. * * This API should be called for user committed changes. * This API should not be used for external value changes. */ emitValueChange(event) { const { value } = this; this.ionChange.emit({ value, event }); } onKeydown(ev) { const inSelectPopover = !!this.el.closest('ion-select-popover'); if (ev.target && !this.el.contains(ev.target)) { return; } // Get all radios inside of the radio group and then // filter out disabled radios since we need to skip those const radios = this.getRadios().filter((radio) => !radio.disabled); // Only move the radio if the current focus is in the radio group if (ev.target && radios.includes(ev.target)) { const index = radios.findIndex((radio) => radio === ev.target); const current = radios[index]; let next; // If hitting arrow down or arrow right, move to the next radio // If we're on the last radio, move to the first radio if (['ArrowDown', 'ArrowRight'].includes(ev.key)) { next = index === radios.length - 1 ? radios[0] : radios[index + 1]; } // If hitting arrow up or arrow left, move to the previous radio // If we're on the first radio, move to the last radio if (['ArrowUp', 'ArrowLeft'].includes(ev.key)) { next = index === 0 ? radios[radios.length - 1] : radios[index - 1]; } if (next && radios.includes(next)) { next.setFocus(ev); if (!inSelectPopover) { this.value = next.value; this.emitValueChange(ev); } } // Update the radio group value when a user presses the // space bar on top of a selected radio if ([' '].includes(ev.key)) { const previousValue = this.value; this.value = this.allowEmptySelection && this.value !== undefined ? undefined : current.value; if (previousValue !== this.value || this.allowEmptySelection) { /** * Value change should only be emitted if the value is different, * such as selecting a new radio with the space bar or if * the radio group allows for empty selection and the user * is deselecting a checked radio. */ this.emitValueChange(ev); } // Prevent browsers from jumping // to the bottom of the screen ev.preventDefault(); } } } render() { const { label, labelId, el, name, value } = this; const mode = getIonMode(this); renderHiddenInput(true, el, name, value, false); return h(Host, { role: "radiogroup", "aria-labelledby": label ? labelId : null, onClick: this.onClick, class: mode }); } get el() { return this; } static get watchers() { return { "value": ["valueChanged"] }; } }, [0, "ion-radio-group", { "allowEmptySelection": [4, "allow-empty-selection"], "name": [1], "value": [1032] }, [[4, "keydown", "onKeydown"]]]); let radioGroupIds = 0; function defineCustomElement() { if (typeof customElements === "undefined") { return; } const components = ["ion-radio-group"]; components.forEach(tagName => { switch (tagName) { case "ion-radio-group": if (!customElements.get(tagName)) { customElements.define(tagName, RadioGroup); } break; } }); } export { RadioGroup as R, defineCustomElement as d }; //# sourceMappingURL=radio-group.js.map