@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
339 lines (338 loc) • 9.75 kB
JavaScript
/*!
* All material copyright ESRI, All Rights Reserved, unless otherwise specified.
* See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
* v1.5.0-next.4
*/
import { h, Host } from "@stencil/core";
import { createObserver } from "../../utils/observers";
import { componentLoaded, setComponentLoaded, setUpLoadableComponent } from "../../utils/loadable";
/**
* @slot - A slot for adding `calcite-radio-button`s.
*/
export class RadioButtonGroup {
constructor() {
// --------------------------------------------------------------------------
//
// Private Properties
//
// --------------------------------------------------------------------------
this.mutationObserver = createObserver("mutation", () => this.passPropsToRadioButtons());
//--------------------------------------------------------------------------
//
// Private Methods
//
//--------------------------------------------------------------------------
this.passPropsToRadioButtons = () => {
this.radioButtons = Array.from(this.el.querySelectorAll("calcite-radio-button"));
this.selectedItem =
Array.from(this.radioButtons).find((radioButton) => radioButton.checked) || null;
if (this.radioButtons.length > 0) {
this.radioButtons.forEach((radioButton) => {
radioButton.disabled = this.disabled || radioButton.disabled;
radioButton.hidden = this.hidden;
radioButton.name = this.name;
radioButton.required = this.required;
radioButton.scale = this.scale;
});
}
};
this.disabled = false;
this.hidden = false;
this.layout = "horizontal";
this.name = undefined;
this.required = false;
this.selectedItem = null;
this.scale = "m";
this.radioButtons = [];
}
onDisabledChange() {
this.passPropsToRadioButtons();
}
onHiddenChange() {
this.passPropsToRadioButtons();
}
onLayoutChange() {
this.passPropsToRadioButtons();
}
onScaleChange() {
this.passPropsToRadioButtons();
}
//--------------------------------------------------------------------------
//
// Lifecycle
//
//--------------------------------------------------------------------------
connectedCallback() {
this.passPropsToRadioButtons();
this.mutationObserver?.observe(this.el, { childList: true, subtree: true });
}
componentWillLoad() {
setUpLoadableComponent(this);
}
componentDidLoad() {
setComponentLoaded(this);
}
disconnectedCallback() {
this.mutationObserver?.disconnect();
}
getFocusableRadioButton() {
return this.radioButtons.find((radiobutton) => !radiobutton.disabled) ?? null;
}
//--------------------------------------------------------------------------
//
// Public Method
//
//--------------------------------------------------------------------------
/** Sets focus on the fist focusable `calcite-radio-button` element in the component. */
async setFocus() {
await componentLoaded(this);
if (this.selectedItem && !this.selectedItem.disabled) {
this.selectedItem.setFocus();
return;
}
if (this.radioButtons.length > 0) {
this.getFocusableRadioButton()?.setFocus();
}
}
//--------------------------------------------------------------------------
//
// Event Listeners
//
//--------------------------------------------------------------------------
radioButtonChangeHandler(event) {
this.selectedItem = event.target;
this.calciteRadioButtonGroupChange.emit();
}
// --------------------------------------------------------------------------
//
// Render Methods
//
// --------------------------------------------------------------------------
render() {
return (h(Host, { role: "radiogroup" }, h("slot", null)));
}
static get is() { return "calcite-radio-button-group"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["radio-button-group.scss"]
};
}
static get styleUrls() {
return {
"$": ["radio-button-group.css"]
};
}
static get properties() {
return {
"disabled": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "When `true`, interaction is prevented and the component is displayed with lower opacity."
},
"attribute": "disabled",
"reflect": true,
"defaultValue": "false"
},
"hidden": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "When `true`, the component is not displayed and its `calcite-radio-button`s are not focusable or checkable."
},
"attribute": "hidden",
"reflect": true,
"defaultValue": "false"
},
"layout": {
"type": "string",
"mutable": false,
"complexType": {
"original": "Layout",
"resolved": "\"grid\" | \"horizontal\" | \"vertical\"",
"references": {
"Layout": {
"location": "import",
"path": "../interfaces"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Defines the layout of the component."
},
"attribute": "layout",
"reflect": true,
"defaultValue": "\"horizontal\""
},
"name": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": true,
"optional": false,
"docs": {
"tags": [],
"text": "Specifies the name of the component on form submission. Must be unique to other component instances."
},
"attribute": "name",
"reflect": true
},
"required": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "When `true`, the component must have a value in order for the form to submit."
},
"attribute": "required",
"reflect": true,
"defaultValue": "false"
},
"selectedItem": {
"type": "unknown",
"mutable": true,
"complexType": {
"original": "HTMLCalciteRadioButtonElement",
"resolved": "HTMLCalciteRadioButtonElement",
"references": {
"HTMLCalciteRadioButtonElement": {
"location": "global"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [{
"name": "readonly",
"text": undefined
}],
"text": "Specifies the component's selected item."
},
"defaultValue": "null"
},
"scale": {
"type": "string",
"mutable": false,
"complexType": {
"original": "Scale",
"resolved": "\"l\" | \"m\" | \"s\"",
"references": {
"Scale": {
"location": "import",
"path": "../interfaces"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Specifies the size of the component."
},
"attribute": "scale",
"reflect": true,
"defaultValue": "\"m\""
}
};
}
static get states() {
return {
"radioButtons": {}
};
}
static get events() {
return [{
"method": "calciteRadioButtonGroupChange",
"name": "calciteRadioButtonGroupChange",
"bubbles": true,
"cancelable": false,
"composed": true,
"docs": {
"tags": [],
"text": "Fires when the component has changed."
},
"complexType": {
"original": "void",
"resolved": "void",
"references": {}
}
}];
}
static get methods() {
return {
"setFocus": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Sets focus on the fist focusable `calcite-radio-button` element in the component.",
"tags": []
}
}
};
}
static get elementRef() { return "el"; }
static get watchers() {
return [{
"propName": "disabled",
"methodName": "onDisabledChange"
}, {
"propName": "hidden",
"methodName": "onHiddenChange"
}, {
"propName": "layout",
"methodName": "onLayoutChange"
}, {
"propName": "scale",
"methodName": "onScaleChange"
}];
}
static get listeners() {
return [{
"name": "calciteRadioButtonChange",
"method": "radioButtonChangeHandler",
"target": undefined,
"capture": false,
"passive": false
}];
}
}