UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

95 lines (94 loc) • 5.53 kB
/*! All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://github.com/Esri/calcite-design-system/blob/dev/LICENSE.md for details. v3.2.1 */ import { c as customElement } from "../../chunks/runtime.js"; import { html } from "lit"; import { LitElement, createEvent, stringOrBoolean, safeClassMap } from "@arcgis/lumina"; import { c as createObserver } from "../../chunks/observers.js"; import { c as componentFocusable } from "../../chunks/component.js"; import { V as Validation } from "../../chunks/Validation.js"; import { h as focusFirstTabbable } from "../../chunks/dom.js"; import { css } from "@lit/reactive-element/css-tag.js"; const CSS = { itemWrapper: "item-wrapper" }; const IDS = { validationMessage: "radioButtonGroupValidationMessage" }; const styles = css`:host{display:flex;flex-direction:column}:host>.item-wrapper{display:flex;max-inline-size:100vw}:host([layout=horizontal])>.item-wrapper{flex-direction:row;flex-wrap:wrap}:host([layout=horizontal][scale=s])>.item-wrapper{column-gap:var(--calcite-radio-button-group-gap, var(--calcite-spacing-lg))}:host([layout=horizontal][scale=m])>.item-wrapper{column-gap:var(--calcite-radio-button-group-gap, var(--calcite-spacing-xl))}:host([layout=horizontal][scale=l])>.item-wrapper{column-gap:var(--calcite-radio-button-group-gap, var(--calcite-spacing-xxl))}:host([layout=vertical])>.item-wrapper{flex-direction:column;inline-size:fit-content}:host([scale=s]) calcite-input-message{--calcite-input-message-spacing: var( --calcite-radio-button-input-message-spacing, calc(var(--calcite-spacing-xxs) * -1) )}:host([scale=m]) calcite-input-message{--calcite-input-message-spacing: var( --calcite-radio-button-input-message-spacing, calc(var(--calcite-spacing-sm) * -1) )}:host([scale=l]) calcite-input-message{--calcite-input-message-spacing: var( --calcite-radio-button-input-message-spacing, calc(var(--calcite-spacing-md) * -1) )}.validation-container{display:flex;flex-direction:column;align-items:flex-start;align-self:stretch}:host([scale=m]) .validation-container,:host([scale=l]) .validation-container{padding-block-start:.5rem}:host([scale=s]) .validation-container{padding-block-start:.25rem}:host([hidden]){display:none}[hidden]{display:none}`; class RadioButtonGroup extends LitElement { constructor() { super(); this.mutationObserver = createObserver("mutation", () => this.passPropsToRadioButtons()); this.radioButtons = []; this.disabled = false; this.layout = "horizontal"; this.required = false; this.scale = "m"; this.selectedItem = null; this.status = "idle"; this.calciteRadioButtonGroupChange = createEvent({ cancelable: false }); this.listen("calciteRadioButtonChange", this.radioButtonChangeHandler); } static { this.properties = { radioButtons: [16, {}, { state: true }], disabled: [7, {}, { reflect: true, type: Boolean }], layout: [3, {}, { reflect: true }], name: [3, {}, { reflect: true }], required: [7, {}, { reflect: true, type: Boolean }], scale: [3, {}, { reflect: true }], selectedItem: [0, {}, { attribute: false }], status: [3, {}, { reflect: true }], validationIcon: [3, { converter: stringOrBoolean }, { reflect: true }], validationMessage: 1 }; } static { this.styles = styles; } async setFocus() { await componentFocusable(this); if (this.selectedItem && !this.selectedItem.disabled) { focusFirstTabbable(this.selectedItem); } if (this.radioButtons.length > 0) { focusFirstTabbable(this.getFocusableRadioButton()); } } connectedCallback() { super.connectedCallback(); this.passPropsToRadioButtons(); this.mutationObserver?.observe(this.el, { childList: true, subtree: true }); } willUpdate(changes) { if (changes.has("disabled") && (this.hasUpdated || this.disabled !== false) || changes.has("layout") && (this.hasUpdated || this.layout !== "horizontal") || changes.has("scale") && (this.hasUpdated || this.scale !== "m")) { this.passPropsToRadioButtons(); } } loaded() { this.passPropsToRadioButtons(); } disconnectedCallback() { super.disconnectedCallback(); this.mutationObserver?.disconnect(); } passPropsToRadioButtons() { this.radioButtons = Array.from(this.el.querySelectorAll("calcite-radio-button")); this.selectedItem = Array.from(this.radioButtons).reverse().find((radioButton) => radioButton.checked) || null; if (this.radioButtons.length > 0) { this.radioButtons.forEach((radioButton) => { if (this.hasUpdated) { radioButton.disabled = this.disabled || radioButton.disabled; } radioButton.name = this.name; radioButton.required = this.required; radioButton.scale = this.scale; }); } } getFocusableRadioButton() { return this.radioButtons.find((radiobutton) => !radiobutton.disabled) ?? null; } radioButtonChangeHandler(event) { this.selectedItem = event.target; this.calciteRadioButtonGroupChange.emit(); } render() { this.el.role = "radiogroup"; return html`<div aria-errormessage=${IDS.validationMessage} .ariaInvalid=${this.status === "invalid"} class=${safeClassMap(CSS.itemWrapper)}><slot></slot></div>${this.validationMessage && this.status === "invalid" ? Validation({ icon: this.validationIcon, id: IDS.validationMessage, message: this.validationMessage, scale: this.scale, status: this.status }) : null}`; } } customElement("calcite-radio-button-group", RadioButtonGroup); export { RadioButtonGroup };