@telekom/scale-components
Version:
Scale is the digital design system for Telekom products and experiences.
468 lines (467 loc) • 13.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, Event, Method, } from '@stencil/core';
import classNames from 'classnames';
import { emitEvent } from '../../utils/utils';
let i = 0;
export class Segment {
constructor() {
/** (optional) The size of the segment */
this.size = 'small';
/** (optional) If `true`, the segment is selected */
this.selected = false;
/** (optional) If `true`, the segment is disabled */
this.disabled = false;
/** (optional) translation of 'selected */
this.ariaLangSelected = 'selected';
/** (optional) translation of 'deselected */
this.ariaLangDeselected = 'deselected';
/** a11y text for getting meaningful value. `$buttonNumber` and `$selected` are template variables and will be replaces by their corresponding properties. */
this.ariaDescriptionTranslation = '$selected';
this.handleClick = (event) => {
if (parseInt(this.selectedIndex, 10) + 1 === this.position) {
return;
}
event.preventDefault();
this.selected = !this.selected;
emitEvent(this, 'scaleClick', {
id: this.segmentId,
selected: this.selected,
});
};
}
async setFocus() {
this.focusableElement.focus();
}
componentWillLoad() {
if (this.segmentId == null) {
this.segmentId = 'segment-' + i++;
}
}
componentDidUpdate() {
this.handleIcon();
}
getAriaDescriptionTranslation() {
const replaceSelected = this.selected
? this.ariaLangSelected
: this.ariaLangDeselected;
const filledText = this.ariaDescriptionTranslation
.replace(/\$position/g, `${this.position}`)
.replace(/\$selected/g, `${replaceSelected}`);
return filledText;
}
handleIcon() {
Array.from(this.hostElement.childNodes).forEach((child) => {
if (child.nodeType === 1 &&
child.nodeName.substr(0, 10) === 'SCALE-ICON') {
const icon = this.hostElement.querySelector(child.nodeName);
switch (this.size) {
case 'small':
icon.setAttribute('size', '14');
break;
case 'medium':
icon.setAttribute('size', '16');
break;
case 'large':
icon.setAttribute('size', '20');
break;
}
icon.style.display = 'inline-flex';
icon.style.marginRight = '4px';
this.hasIcon = true;
}
if (child.nodeType === 3 && this.hostElement.childNodes.length === 1) {
this.textOnly = true;
const span = document.createElement('span');
child.parentNode.insertBefore(span, child);
span.appendChild(child);
}
if (child.nodeType === 1 &&
child.nodeName.substr(0, 10) === 'SCALE-ICON' &&
this.hostElement.childNodes.length === 1) {
this.iconOnly = true;
this.hostElement.setAttribute('icon-only', 'true');
const icon = this.hostElement.querySelector(child.nodeName);
icon.style.marginRight = '0px';
this.selected
? icon.setAttribute('selected', '')
: icon.removeAttribute('selected');
}
});
}
render() {
return (h(Host, null,
this.styles && h("style", null, this.styles),
h("button", { ref: (el) => (this.focusableElement = el), class: this.getCssClassMap(), id: this.segmentId, onClick: this.handleClick, disabled: this.disabled, type: "button", style: { width: this.width }, "aria-label": this.ariaLabelSegment, "aria-pressed": this.selected, part: this.getBasePartMap(), "aria-description": this.getAriaDescriptionTranslation() },
h("div", { class: "segment--mask" },
!this.iconOnly && (h("div", { class: "success-icon-container" },
h("scale-icon-action-checkmark", { size: this.size === 'small'
? 14
: this.size === 'medium'
? 16
: 20, class: "scale-icon-action-checkmark", "aria-hidden": "true", selected: true }))),
h("div", { class: "icon-container" },
h("slot", { name: "segment-icon" })),
h("slot", null)))));
}
getBasePartMap() {
return this.getCssOrBasePartMap('basePart');
}
getCssClassMap() {
return this.getCssOrBasePartMap('css');
}
getCssOrBasePartMap(mode) {
const prefix = mode === 'basePart' ? '' : 'segment--';
return classNames('segment', this.size && `${prefix}${this.size}`, this.selected && `${prefix}selected`, this.disabled && `${prefix}disabled`, this.adjacentSiblings &&
`${prefix}${this.adjacentSiblings.replace(/ /g, '-')}-sibling-selected`, this.hasIcon && `${prefix}has-icon`, this.iconOnly && `${prefix}icon-only`);
}
static get is() { return "scale-segment"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() { return {
"$": ["segment.css"]
}; }
static get styleUrls() { return {
"$": ["segment.css"]
}; }
static get properties() { return {
"size": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'small' | 'medium' | 'large'",
"resolved": "\"large\" | \"medium\" | \"small\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) The size of the segment"
},
"attribute": "size",
"reflect": false,
"defaultValue": "'small'"
},
"selected": {
"type": "boolean",
"mutable": true,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) If `true`, the segment is selected"
},
"attribute": "selected",
"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 segment is disabled"
},
"attribute": "disabled",
"reflect": false,
"defaultValue": "false"
},
"segmentId": {
"type": "string",
"mutable": true,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) segment's id"
},
"attribute": "segment-id",
"reflect": true
},
"ariaLabelSegment": {
"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 segments"
},
"attribute": "aria-label-segment",
"reflect": false
},
"width": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Segment width set to ensure that all segments have the same width"
},
"attribute": "width",
"reflect": false
},
"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
},
"adjacentSiblings": {
"type": "string",
"mutable": true,
"complexType": {
"original": "| 'left'\n | 'right'\n | 'leftright'",
"resolved": "\"left\" | \"leftright\" | \"right\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": ""
},
"attribute": "adjacent-siblings",
"reflect": true
},
"ariaLangSelected": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) translation of 'selected"
},
"attribute": "aria-lang-selected",
"reflect": false,
"defaultValue": "'selected'"
},
"ariaLangDeselected": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) translation of 'deselected"
},
"attribute": "aria-lang-deselected",
"reflect": false,
"defaultValue": "'deselected'"
},
"ariaDescriptionTranslation": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "a11y text for getting meaningful value. `$buttonNumber` and `$selected` are template variables and will be replaces by their corresponding properties."
},
"attribute": "aria-description-translation",
"reflect": false,
"defaultValue": "'$selected'"
},
"position": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) position within group"
},
"attribute": "position",
"reflect": false
},
"hasIcon": {
"type": "boolean",
"mutable": true,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) position within group"
},
"attribute": "has-icon",
"reflect": false
},
"textOnly": {
"type": "boolean",
"mutable": true,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) position within group"
},
"attribute": "text-only",
"reflect": false
},
"iconOnly": {
"type": "boolean",
"mutable": true,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) position within group"
},
"attribute": "icon-only",
"reflect": false
},
"selectedIndex": {
"type": "string",
"mutable": true,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) the index of the currently selected segment in the segmented-button"
},
"attribute": "selected-index",
"reflect": false
}
}; }
static get events() { return [{
"method": "scaleClick",
"name": "scale-click",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted when button is clicked"
},
"complexType": {
"original": "{\n id: string;\n selected: boolean;\n }",
"resolved": "{ id: string; selected: boolean; }",
"references": {}
}
}, {
"method": "scaleClickLegacy",
"name": "scaleClick",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [{
"name": "deprecated",
"text": "in v3 in favor of kebab-case event names"
}],
"text": ""
},
"complexType": {
"original": "{\n id: string;\n selected: boolean;\n }",
"resolved": "{ id: string; selected: boolean; }",
"references": {}
}
}]; }
static get methods() { return {
"setFocus": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "",
"tags": []
}
}
}; }
static get elementRef() { return "hostElement"; }
}