UNPKG

@govbr-ds/webcomponents

Version:

Biblioteca de Web Components baseado no GovBR-DS

365 lines (364 loc) 14.3 kB
/*! * Construído por SERPRO * © https://serpro.gov.br/ - MIT License. */ import { h, Host } from "@stencil/core"; /** * Para uma descrição detalhada, consulte a [documentação do GovBR-DS](https://www.gov.br/ds/components/radio?tab=designer). * * @slot default - O texto descritivo pode ser passado por propriedade (label) ou por slot. */ export class Radio { /** * Referência ao elemento host do componente. * Utilize esta propriedade para acessar e manipular o elemento do DOM associado ao componente. */ el; elementInternals; /** * Define o estado de seleção do radio. * Se definido como verdadeiro, o radio estará marcado. Caso contrário, estará desmarcado. */ checked = false; /** * Desativa o radio, tornando-o não interativo. */ disabled = false; /** * Indica a validade do radio. * Valores possíveis: * - 'valid': O radio é considerado válido. * - 'invalid': O radio é considerado inválido. * Se não for especificado, o valor padrão é `null`, indicando que a validade não foi definida. */ state; /** * Define se o label associado ao radio deve ser oculto. * Se definido como verdadeiro, o texto do label será oculto, mas o radio ainda estará visível e funcional. */ hasHiddenLabel = false; /** * Identificador único. * Caso não seja fornecido, um ID gerado automaticamente será usado. */ customId = `br-radio-${radioId++}`; /** * Define o nome do radio, que é utilizado para agrupar radios em formulários e identificar o campo. * O valor é obrigatório e deve ser fornecido para garantir o correto funcionamento em formulários. */ name; /** * Texto descritivo exibido à direita do radio. * Caso um slot seja utilizado para fornecer um texto alternativo, o valor desta propriedade será ignorado. */ label; /** * Define o valor associado ao radio quando ele faz parte de um formulário nativo (`<form>`). * Esse valor é enviado com o formulário quando o radio está selecionado. * **Nota:** Esta propriedade não deve ser utilizada para determinar se o radio está selecionado; para verificar o estado de seleção, use a propriedade `checked`. */ value; /** * Disparado depois que o valor do `checked` foi alterado */ checkedChange; handleCheckedChange(event) { if (event.target.customId !== this.customId && event.target.name === this.name) { this.checked = false; } } /** * Navega e seleciona o próximo/anterior rádio habilitado no grupo via teclas de seta. * Ativado por 'keydown', move a seleção entre rádios do mesmo 'name' * usando as setas, partindo do rádio atualmente checado. * @param {KeyboardEvent} event O evento de teclado. * @listens keydown */ handleKeyDown(event) { if (this.disabled || !this.checked) return; const isArrowKey = ['ArrowRight', 'ArrowDown', 'ArrowLeft', 'ArrowUp'].includes(event.key); if (!isArrowKey) return; event.preventDefault(); const radios = Array.from(document.querySelectorAll('br-radio')).filter((el) => el.name === this.name && !el.disabled); const currentIndex = radios.findIndex((radio) => radio.customId === this.customId); if (currentIndex === -1) return; let nextIndex = currentIndex; if (event.key === 'ArrowRight' || event.key === 'ArrowDown') { nextIndex = (currentIndex + 1) % radios.length; } else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') { nextIndex = (currentIndex - 1 + radios.length) % radios.length; } const nextRadio = radios[nextIndex]; nextRadio?.toggleChecked?.(); nextRadio?.shadowRoot?.querySelector('input')?.focus(); } /** * Inverte o valor da prop `checked` */ async toggleChecked() { this.checked = !this.checked; this.checkedChange.emit(this.checked); } getCssClassMap() { return { 'br-radio': true, valid: this.state === 'valid', invalid: this.state === 'invalid', disabled: this.disabled, 'hidden-label': this.hasHiddenLabel, }; } /** * Handler para o event `click` * @param event Objeto Event */ onClick = (event) => { event.stopPropagation(); this.checked = event.target.checked; }; /** * Handler para o evento `change` */ onChange = () => { this.checkedChange.emit(this.checked); }; render() { return (h(Host, { key: '0893a6f83c0ec5fac62c79fa58e67723181939c4', "aria-disabled": this.disabled ? 'true' : null }, h("div", { key: 'ec1441be271e548a0e10fb2f6633134d163f849f', class: this.getCssClassMap() }, h("input", { key: '77b75006291a77464856c392c485ed3b7dc1aadd', part: "radio-input", "aria-label": this.hasHiddenLabel && this.label ? this.label : null, type: "radio", id: this.customId, name: this.name, checked: this.checked, disabled: this.disabled, value: this.value, onClick: this.onClick, onChange: this.onChange }), h("label", { key: 'a7db34096f038cd0886f8a4d6b0212622cc5c648', part: "radio-label", htmlFor: this.customId }, h("slot", { key: '52ae8520d66a87458afd1f47c84181f1780ec0e1' }, this.label))))); } static get is() { return "br-radio"; } static get encapsulation() { return "shadow"; } static get formAssociated() { return true; } static get originalStyleUrls() { return { "$": ["radio.scss"] }; } static get styleUrls() { return { "$": ["radio.css"] }; } static get properties() { return { "checked": { "type": "boolean", "mutable": true, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Define o estado de sele\u00E7\u00E3o do radio.\nSe definido como verdadeiro, o radio estar\u00E1 marcado. Caso contr\u00E1rio, estar\u00E1 desmarcado." }, "getter": false, "setter": false, "attribute": "checked", "reflect": true, "defaultValue": "false" }, "disabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Desativa o radio, tornando-o n\u00E3o interativo." }, "getter": false, "setter": false, "attribute": "disabled", "reflect": true, "defaultValue": "false" }, "state": { "type": "string", "mutable": false, "complexType": { "original": "'valid' | 'invalid'", "resolved": "\"invalid\" | \"valid\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Indica a validade do radio.\nValores poss\u00EDveis:\n- 'valid': O radio \u00E9 considerado v\u00E1lido.\n- 'invalid': O radio \u00E9 considerado inv\u00E1lido.\nSe n\u00E3o for especificado, o valor padr\u00E3o \u00E9 `null`, indicando que a validade n\u00E3o foi definida." }, "getter": false, "setter": false, "attribute": "state", "reflect": true }, "hasHiddenLabel": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Define se o label associado ao radio deve ser oculto.\nSe definido como verdadeiro, o texto do label ser\u00E1 oculto, mas o radio ainda estar\u00E1 vis\u00EDvel e funcional." }, "getter": false, "setter": false, "attribute": "has-hidden-label", "reflect": true, "defaultValue": "false" }, "customId": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Identificador \u00FAnico.\nCaso n\u00E3o seja fornecido, um ID gerado automaticamente ser\u00E1 usado." }, "getter": false, "setter": false, "attribute": "custom-id", "reflect": true, "defaultValue": "`br-radio-${radioId++}`" }, "name": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": true, "optional": false, "docs": { "tags": [], "text": "Define o nome do radio, que \u00E9 utilizado para agrupar radios em formul\u00E1rios e identificar o campo.\nO valor \u00E9 obrigat\u00F3rio e deve ser fornecido para garantir o correto funcionamento em formul\u00E1rios." }, "getter": false, "setter": false, "attribute": "name", "reflect": true }, "label": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Texto descritivo exibido \u00E0 direita do radio.\nCaso um slot seja utilizado para fornecer um texto alternativo, o valor desta propriedade ser\u00E1 ignorado." }, "getter": false, "setter": false, "attribute": "label", "reflect": true }, "value": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Define o valor associado ao radio quando ele faz parte de um formul\u00E1rio nativo (`<form>`).\nEsse valor \u00E9 enviado com o formul\u00E1rio quando o radio est\u00E1 selecionado.\n**Nota:** Esta propriedade n\u00E3o deve ser utilizada para determinar se o radio est\u00E1 selecionado; para verificar o estado de sele\u00E7\u00E3o, use a propriedade `checked`." }, "getter": false, "setter": false, "attribute": "value", "reflect": true } }; } static get events() { return [{ "method": "checkedChange", "name": "checkedChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Disparado depois que o valor do `checked` foi alterado" }, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} } }]; } static get methods() { return { "toggleChecked": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global", "id": "global::Promise" } }, "return": "Promise<void>" }, "docs": { "text": "Inverte o valor da prop `checked`", "tags": [] } } }; } static get elementRef() { return "el"; } static get listeners() { return [{ "name": "checkedChange", "method": "handleCheckedChange", "target": "window", "capture": false, "passive": false }, { "name": "keydown", "method": "handleKeyDown", "target": undefined, "capture": false, "passive": false }]; } static get attachInternalsMemberName() { return "elementInternals"; } } let radioId = 0; //# sourceMappingURL=radio.js.map