@govbr-ds/webcomponents
Version:
Biblioteca de Web Components baseado no GovBR-DS
365 lines (364 loc) • 14.3 kB
JavaScript
/*!
* 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