@telekom/scale-components
Version:
Scale is the digital design system for Telekom products and experiences.
419 lines (418 loc) • 12.6 kB
JavaScript
/**
* @license
* Scale https://github.com/telekom/scale
*
* Copyright (c) 2021 Egor Kirpichev and contributors, Deutsche Telekom AG
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { Component, Prop, h, Host, Element, State, Listen, Event, Watch, } from '@stencil/core';
import classNames from 'classnames';
import { emitEvent } from '../../utils/utils';
import statusNote from '../../utils/status-note';
export class ToggleGroup {
constructor() {
/** toggle button position within group */
this.position = 0;
/** number of slotted toggle-buttons */
this.slottedButtons = 0;
/** state */
this.status = [];
/** (optional) The size of the button */
this.size = 'regular';
/** (optional) Button Group background */
this.background = 'white';
/** (optional) 100% width */
this.fullWidth = false;
/** (optional) If `true`, the button is disabled */
this.disabled = false;
/** (optional) If `true`, the group has a border */
this.hideBorder = false;
/** (optional) more than one button selected possible */
this.singleSelect = false;
/** (optional) aria-label attribute needed for icon-only buttons */
this.ariaLabelTranslation = `toggle button group with $slottedButtons buttons`;
/** @deprecated - variant should replace colorScheme */
this.colorScheme = 'color';
/** (optional) background variant of a selected toggle-button */
this.variant = 'color';
}
scaleClickHandler(ev) {
let tempState;
if (this.singleSelect) {
if (!ev.detail.selected) {
tempState = this.status.map((obj) => ev.detail.id === obj.id ? ev.detail : Object.assign({}, obj));
/* clicked button has now selected state */
}
else {
tempState = this.status.map((obj) => ev.detail.id === obj.id ? ev.detail : Object.assign(Object.assign({}, obj), { selected: false }));
}
}
else {
tempState = this.status.map((obj) => ev.detail.id === obj.id ? ev.detail : Object.assign({}, obj));
}
this.setNewState(tempState);
}
handlePropsChange() {
this.propagatePropsToChildren();
}
componentDidLoad() {
const tempState = [];
const toggleButtons = this.getAllToggleButtons();
this.slottedButtons = toggleButtons.length;
toggleButtons.forEach((toggleButton) => {
this.position++;
tempState.push({
id: toggleButton.getAttribute('toggle-button-id'),
selected: toggleButton.hasAttribute('selected'),
});
toggleButton.setAttribute('position', this.position.toString());
toggleButton.setAttribute('aria-description-translation', '$position $selected');
});
this.propagatePropsToChildren();
this.position = 0;
this.status = tempState;
}
getAllToggleButtons() {
return Array.from(this.hostElement.querySelectorAll('scale-toggle-button'));
}
/**
* Keep props, needed in children buttons, in sync
*/
propagatePropsToChildren() {
this.getAllToggleButtons().forEach((el) => {
el.setAttribute('size', this.size);
el.setAttribute('background', this.background);
el.setAttribute('disabled', this.disabled && 'disabled');
/** DEPRECATED */
// if attribute variant is set it overrides color-scheme
el.setAttribute('color-scheme', this.variant !== 'color' ? this.variant : this.colorScheme);
// if attribute color-scheme is set it overrides variant
el.setAttribute('variant', this.colorScheme !== 'color' ? this.colorScheme : this.variant);
el.setAttribute('hide-border', this.hideBorder ? 'true' : 'false');
});
}
getAriaLabelTranslation() {
const filledText = this.ariaLabelTranslation.replace(/\$slottedButtons/g, `${this.slottedButtons}`);
return filledText;
}
componentDidRender() {
if (this.fullWidth) {
this.setButtonWidth();
}
this.setChildrenCorners();
if (this.colorScheme !== 'color') {
statusNote({
tag: 'deprecated',
message: 'Property "colorScheme" is deprecated. Please use the "variant" property!',
type: 'warn',
source: this.hostElement,
});
}
}
setNewState(tempState) {
const toggleButtons = Array.from(this.hostElement.querySelectorAll('scale-toggle-button'));
toggleButtons.forEach((button, i) => {
button.setAttribute('selected', tempState[i].selected ? 'true' : 'false');
});
this.status = tempState;
emitEvent(this, 'scaleChange', this.status);
}
setButtonWidth() {
Array.from(this.hostElement.children).forEach((child) => {
const button = child.shadowRoot.querySelector('button');
button.style.width = '100%';
});
}
setChildrenCorners() {
const children = Array.from(this.hostElement.children);
if (children.length === 1) {
// set four border radius when there is only one child
children[0].setAttribute('radius', 'all');
}
else {
for (let i = 0; i < children.length; i++) {
if (i === 0) {
children[i].setAttribute('radius', 'left');
}
if (i > 0 && i < children.length - 1) {
children[i].setAttribute('radius', 'neither');
}
if (i === children.length - 1) {
children[i].setAttribute('radius', 'right');
}
}
}
}
render() {
return (h(Host, null,
this.styles && h("style", null, this.styles),
h("div", { class: this.getCssClassMap(), part: this.getBasePartMap(), "aria-label": this.getAriaLabelTranslation(), role: "group" },
h("slot", null))));
}
getBasePartMap() {
return this.getCssOrBasePartMap('basePart');
}
getCssClassMap() {
return this.getCssOrBasePartMap('css');
}
getCssOrBasePartMap(mode) {
const prefix = mode === 'basePart' ? '' : 'toggle-group--';
return classNames('toggle-group', this.fullWidth && `${prefix}block`, !this.fullWidth && `${prefix}inline`, this.disabled && `${prefix}disabled`);
}
static get is() { return "scale-toggle-group"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() { return {
"$": ["toggle-group.css"]
}; }
static get styleUrls() { return {
"$": ["toggle-group.css"]
}; }
static get properties() { return {
"size": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'large' | 'regular' | 'small' | 'xs'",
"resolved": "\"large\" | \"regular\" | \"small\" | \"xs\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) The size of the button"
},
"attribute": "size",
"reflect": false,
"defaultValue": "'regular'"
},
"background": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'grey' | 'white'",
"resolved": "\"grey\" | \"white\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Button Group background"
},
"attribute": "background",
"reflect": false,
"defaultValue": "'white'"
},
"fullWidth": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) 100% width"
},
"attribute": "full-width",
"reflect": false,
"defaultValue": "false"
},
"disabled": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) If `true`, the button is disabled"
},
"attribute": "disabled",
"reflect": false,
"defaultValue": "false"
},
"hideBorder": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) If `true`, the group has a border"
},
"attribute": "hide-border",
"reflect": false,
"defaultValue": "false"
},
"singleSelect": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "(optional) more than one button selected possible"
},
"attribute": "single-select",
"reflect": false,
"defaultValue": "false"
},
"ariaLabelTranslation": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "(optional) aria-label attribute needed for icon-only buttons"
},
"attribute": "aria-label-translation",
"reflect": false,
"defaultValue": "`toggle button group with $slottedButtons buttons`"
},
"colorScheme": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'monochrome' | 'color'",
"resolved": "\"color\" | \"monochrome\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "deprecated",
"text": "- variant should replace colorScheme"
}],
"text": ""
},
"attribute": "color-scheme",
"reflect": false,
"defaultValue": "'color'"
},
"variant": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'monochrome' | 'color'",
"resolved": "\"color\" | \"monochrome\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) background variant of a selected toggle-button"
},
"attribute": "variant",
"reflect": false,
"defaultValue": "'color'"
},
"styles": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Injected CSS styles"
},
"attribute": "styles",
"reflect": false
}
}; }
static get states() { return {
"status": {}
}; }
static get events() { return [{
"method": "scaleChange",
"name": "scale-change",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted when button is clicked"
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "scaleChangeLegacy",
"name": "scaleChange",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [{
"name": "deprecated",
"text": "in v3 in favor of kebab-case event names"
}],
"text": ""
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}]; }
static get elementRef() { return "hostElement"; }
static get watchers() { return [{
"propName": "background",
"methodName": "handlePropsChange"
}, {
"propName": "disabled",
"methodName": "handlePropsChange"
}, {
"propName": "hideBorder",
"methodName": "handlePropsChange"
}, {
"propName": "size",
"methodName": "handlePropsChange"
}, {
"propName": "variant",
"methodName": "handlePropsChange"
}]; }
static get listeners() { return [{
"name": "scaleClick",
"method": "scaleClickHandler",
"target": undefined,
"capture": false,
"passive": false
}]; }
}