UNPKG

@limetech/lime-elements

Version:
207 lines (206 loc) • 6.52 kB
import { h, } from '@stencil/core'; import { createRandomString } from '../../util/random-string'; /** * A button group control is a linear set of two or more buttons. * * ## Usage * * Button groups are often used to display different views of the same thing. A * common example of this component is when you switch between [ Map | Transit * | Satellite ] views to look at an area on the map. * * In some cases, button groups may serve as quick filters as well. For example * a list of contacts, in which the user can switch to [ All | Favorites * | Frequently contacted ] can incorporate a button group to quickly filter out * items and display subsets of them. * * ## Layout * * The button groups are usually placed in top headers and action bars, * sometimes with other elements. Since the group items will always be rendered * in a row, you must make sure not to have too many buttons in the group. * Because if the container of your button group does not get enough space to * fit in all its buttons, they will have to truncate their text and may appear * very cramped together. Always think about how your button group will appear * on a small screen such as phones. * :::note * Button can contain text or icons, but not both simultaneously! * ::: * * Within the group, icon buttons will all have the same width, while each text button * inherits its width from its content. * * @exampleComponent limel-example-button-group-icons * @exampleComponent limel-example-button-group * @exampleComponent limel-example-button-group-mix * @exampleComponent limel-example-button-group-badges * @exampleComponent limel-example-button-group-composite */ export class ButtonGroup { constructor() { this.radioGroupName = createRandomString(); this.setSelectedButton = () => { var _a; this.selectedButtonId = (_a = this.value.find((button) => { return button.selected; })) === null || _a === void 0 ? void 0 : _a.id; }; this.value = []; this.disabled = false; this.selectedButtonId = undefined; this.renderButton = this.renderButton.bind(this); this.onChange = this.onChange.bind(this); this.renderContent = this.renderContent.bind(this); } componentWillLoad() { this.setSelectedButton(); } render() { const classes = { 'mdc-chip-set': true, disabled: this.disabled, 'mdc-chip-set--choice': true, }; return (h("div", { class: classes, role: "grid" }, this.value.map(this.renderButton))); } renderButton(button) { // Prefix with 'b' because html IDs cannot start with a digit, // and we need to differentiate from the ID on the limel-icon. /Ads const buttonId = `b${button.id}`; const classes = { 'mdc-chip': true, 'mdc-chip--selected': this.isButtonChecked(button), }; return (h("div", { class: classes, role: "row" }, h("span", { role: "gridcell" }, h("input", { type: "radio", name: this.radioGroupName, checked: this.isButtonChecked(button), id: buttonId, onChange: this.onChange }), h("label", { htmlFor: buttonId }, this.renderContent(button), this.renderBadge(button))))); } renderContent(button) { if (button.icon) { return this.renderIcon(button); } return this.renderLabel(button); } isButtonChecked(button) { return button.id === this.selectedButtonId; } renderLabel(button) { return h("span", { class: "mdc-chip__text" }, button.title); } renderIcon(button) { // Prefix with 'i' because html IDs cannot start with a digit, // and we need to differentiate from the "buttonId". /Ads const iconId = `i${button.id}`; return [ h("limel-icon", { id: iconId, class: "mdc-chip__icon", "aria-label": button.title, name: button.icon, size: "small", badge: true }), h("limel-tooltip", { elementId: iconId, label: button.title }), ]; } renderBadge(button) { if (!button.badge) { return; } return h("limel-badge", { label: button.badge }); } onChange(event) { event.stopPropagation(); const target = event.target; // The ID is prefixed with `b` in the HTML, remember? /Ads this.selectedButtonId = target.id.slice(1); const button = this.value.find((item) => { return item.id === this.selectedButtonId; }); this.change.emit(button); } valueChanged() { this.setSelectedButton(); } static get is() { return "limel-button-group"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["button-group.scss"] }; } static get styleUrls() { return { "$": ["button-group.css"] }; } static get properties() { return { "value": { "type": "unknown", "mutable": false, "complexType": { "original": "Button[]", "resolved": "Button[]", "references": { "Button": { "location": "import", "path": "../button/button.types" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "List of buttons for the group" }, "defaultValue": "[]" }, "disabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "True if the button-group should be disabled" }, "attribute": "disabled", "reflect": true, "defaultValue": "false" } }; } static get states() { return { "selectedButtonId": {} }; } static get events() { return [{ "method": "change", "name": "change", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Dispatched when a button is selected/deselected" }, "complexType": { "original": "Button", "resolved": "Button", "references": { "Button": { "location": "import", "path": "../button/button.types" } } } }]; } static get watchers() { return [{ "propName": "value", "methodName": "valueChanged" }]; } } //# sourceMappingURL=button-group.js.map