@nectary/components 0.42.1 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/accordion/index.js +3 -3
- package/action-menu/index.js +1 -2
- package/card-container/index.js +1 -1
- package/color-menu/index.d.ts +3 -3
- package/color-menu/index.js +2 -3
- package/color-menu/types.d.ts +2 -2
- package/date-picker/index.js +173 -64
- package/date-picker/types.d.ts +6 -0
- package/date-picker/utils.d.ts +6 -3
- package/date-picker/utils.js +19 -4
- package/dialog/index.js +2 -2
- package/emoji/index.d.ts +11 -0
- package/emoji/index.js +47 -0
- package/emoji/types.d.ts +11 -0
- package/emoji/types.js +1 -0
- package/emoji/utils.d.ts +1 -0
- package/emoji/utils.js +46 -0
- package/emoji-picker/index.d.ts +28 -0
- package/emoji-picker/index.js +319 -0
- package/emoji-picker/types.d.ts +25 -0
- package/emoji-picker/types.js +1 -0
- package/file-drop/types.d.ts +2 -2
- package/file-picker/types.d.ts +1 -1
- package/icon/index.d.ts +11 -0
- package/icon/index.js +32 -0
- package/icon/types.d.ts +11 -0
- package/icon/types.js +1 -0
- package/icon-button/index.js +1 -1
- package/package.json +2 -2
- package/pop/index.js +1 -2
- package/popover/index.js +1 -2
- package/segment/index.js +1 -1
- package/segmented-icon-control/index.js +3 -3
- package/select-menu/index.js +3 -4
- package/stop-events/index.js +3 -3
- package/tabs/index.js +24 -76
- package/tabs/types.d.ts +9 -2
- package/tabs-icon-option/index.d.ts +11 -0
- package/tabs-icon-option/index.js +75 -0
- package/tabs-icon-option/types.d.ts +19 -0
- package/tabs-icon-option/types.js +1 -0
- package/tabs-option/index.d.ts +1 -0
- package/tabs-option/index.js +8 -15
- package/tabs-option/types.d.ts +13 -5
- package/theme/emoji.css +6 -0
- package/theme/fonts.css +9 -0
- package/theme/fonts.json +9 -0
- package/theme/icon.css +7 -0
- package/theme.css +2 -0
- package/tile-control/index.js +3 -3
- package/tooltip/index.js +78 -31
- package/utils/csv.d.ts +5 -0
- package/utils/csv.js +22 -0
- package/utils/dom.d.ts +30 -0
- package/utils/dom.js +143 -0
- package/utils/element.d.ts +12 -0
- package/utils/element.js +38 -0
- package/utils/get-react-event-handler.d.ts +1 -0
- package/utils/get-react-event-handler.js +8 -0
- package/utils/index.d.ts +8 -57
- package/utils/index.js +8 -301
- package/utils/rect.d.ts +4 -0
- package/utils/rect.js +29 -0
- package/utils/slot.d.ts +4 -0
- package/utils/slot.js +38 -0
- package/utils/throttle.d.ts +4 -0
- package/utils/throttle.js +25 -0
- /package/{utils/animation.d.ts → tooltip/tooltip-state.d.ts} +0 -0
- /package/{utils/animation.js → tooltip/tooltip-state.js} +0 -0
package/select-menu/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { attrValueToPixels, defineCustomElement, getAttribute, getBooleanAttribute,
|
|
2
|
-
import { dispatchContextConnectEvent, dispatchContextDisconnectEvent } from '../utils/context';
|
|
1
|
+
import { attrValueToPixels, defineCustomElement, dispatchContextConnectEvent, dispatchContextDisconnectEvent, getAttribute, getBooleanAttribute, unpackCsv, getFirstCsvValue, getIntegerAttribute, getReactEventHandler, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateCsv, updateExplicitBooleanAttribute, updateIntegerAttribute } from '../utils';
|
|
3
2
|
const templateHTML = '<style>:host{display:block;outline:0}#listbox{overflow-y:auto}</style><div id="listbox" role="presentation"><slot></slot></div>';
|
|
4
3
|
const ITEM_HEIGHT = 40;
|
|
5
4
|
const template = document.createElement('template');
|
|
@@ -160,9 +159,9 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
160
159
|
};
|
|
161
160
|
#onValueChange(csv) {
|
|
162
161
|
if (this.multiple) {
|
|
163
|
-
const values =
|
|
162
|
+
const values = unpackCsv(csv);
|
|
164
163
|
for (const $option of this.#getOptionElements()) {
|
|
165
|
-
const isChecked = !getBooleanAttribute($option, 'disabled') && values.
|
|
164
|
+
const isChecked = !getBooleanAttribute($option, 'disabled') && values.includes(getAttribute($option, 'value', ''));
|
|
166
165
|
updateBooleanAttribute($option, 'data-checked', isChecked);
|
|
167
166
|
}
|
|
168
167
|
} else {
|
package/stop-events/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { defineCustomElement,
|
|
1
|
+
import { defineCustomElement, unpackCsv } from '../utils';
|
|
2
2
|
defineCustomElement('sinch-stop-events', class extends HTMLElement {
|
|
3
3
|
constructor() {
|
|
4
4
|
super();
|
|
5
5
|
this.style.display = 'contents';
|
|
6
6
|
}
|
|
7
7
|
connectedCallback() {
|
|
8
|
-
const events =
|
|
8
|
+
const events = unpackCsv(this.getAttribute('events'));
|
|
9
9
|
for (const event of events) {
|
|
10
10
|
this.addEventListener(event, this.#stopEvent);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
disconnectedCallback() {
|
|
14
|
-
const events =
|
|
14
|
+
const events = unpackCsv(this.getAttribute('events'));
|
|
15
15
|
for (const event of events) {
|
|
16
16
|
this.removeEventListener(event, this.#stopEvent);
|
|
17
17
|
}
|
package/tabs/index.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { defineCustomElement, getAttribute, getBooleanAttribute, getReactEventHandler, NectaryElement, updateAttribute, updateBooleanAttribute } from '../utils';
|
|
2
|
-
const templateHTML = '<style>:host{display:block
|
|
3
|
-
const findSelectedOption = elements => {
|
|
4
|
-
return elements.find(el => el.checked) ?? null;
|
|
5
|
-
};
|
|
1
|
+
import { defineCustomElement, getAttribute, getBooleanAttribute, getReactEventHandler, getRect, NectaryElement, updateAttribute, updateBooleanAttribute } from '../utils';
|
|
2
|
+
const templateHTML = '<style>:host{display:block}#wrapper{display:flex;width:100%;border-bottom:1px solid var(--sinch-color-border-default)}</style><div id="wrapper"><slot></slot></div>';
|
|
6
3
|
const template = document.createElement('template');
|
|
7
4
|
template.innerHTML = templateHTML;
|
|
8
5
|
defineCustomElement('sinch-tabs', class extends NectaryElement {
|
|
9
6
|
#$slot;
|
|
7
|
+
#controller = null;
|
|
10
8
|
constructor() {
|
|
11
9
|
super();
|
|
12
10
|
const shadowRoot = this.attachShadow();
|
|
@@ -14,17 +12,23 @@ defineCustomElement('sinch-tabs', class extends NectaryElement {
|
|
|
14
12
|
this.#$slot = shadowRoot.querySelector('slot');
|
|
15
13
|
}
|
|
16
14
|
connectedCallback() {
|
|
15
|
+
this.#controller = new AbortController();
|
|
16
|
+
const {
|
|
17
|
+
signal
|
|
18
|
+
} = this.#controller;
|
|
17
19
|
this.setAttribute('role', 'tablist');
|
|
18
|
-
this.#$slot.addEventListener('
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
this.addEventListener('
|
|
20
|
+
this.#$slot.addEventListener('option-change', this.#onOptionChange, {
|
|
21
|
+
signal
|
|
22
|
+
});
|
|
23
|
+
this.#$slot.addEventListener('slotchange', this.#onSlotChange, {
|
|
24
|
+
signal
|
|
25
|
+
});
|
|
26
|
+
this.addEventListener('-change', this.#onChangeReactHandler, {
|
|
27
|
+
signal
|
|
28
|
+
});
|
|
22
29
|
}
|
|
23
30
|
disconnectedCallback() {
|
|
24
|
-
this
|
|
25
|
-
this.#$slot.removeEventListener('option-change', this.#onOptionChange);
|
|
26
|
-
this.#$slot.removeEventListener('slotchange', this.#onSlotChange);
|
|
27
|
-
this.removeEventListener('-change', this.#onChangeReactHandler);
|
|
31
|
+
this.#controller.abort();
|
|
28
32
|
}
|
|
29
33
|
static get observedAttributes() {
|
|
30
34
|
return ['value'];
|
|
@@ -47,32 +51,13 @@ defineCustomElement('sinch-tabs', class extends NectaryElement {
|
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
53
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{
|
|
55
|
-
e.preventDefault();
|
|
56
|
-
const $option = this.#getPrevOption();
|
|
57
|
-
if ($option !== null) {
|
|
58
|
-
$option.focus();
|
|
59
|
-
this.#dispatchChangeEvent($option.value);
|
|
60
|
-
}
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
case 'ArrowDown':
|
|
64
|
-
case 'ArrowRight':
|
|
65
|
-
{
|
|
66
|
-
e.preventDefault();
|
|
67
|
-
const $option = this.#getNextOption();
|
|
68
|
-
if ($option !== null) {
|
|
69
|
-
$option.focus();
|
|
70
|
-
this.#dispatchChangeEvent($option.value);
|
|
71
|
-
}
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
54
|
+
nthOptionRect(index) {
|
|
55
|
+
const $el = this.#$slot.assignedElements()[index];
|
|
56
|
+
if ($el != null) {
|
|
57
|
+
return getRect($el);
|
|
74
58
|
}
|
|
75
|
-
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
76
61
|
#onSlotChange = () => {
|
|
77
62
|
this.#onValueChange(this.value);
|
|
78
63
|
};
|
|
@@ -83,7 +68,7 @@ defineCustomElement('sinch-tabs', class extends NectaryElement {
|
|
|
83
68
|
#onValueChange(value) {
|
|
84
69
|
for (const $option of this.#$slot.assignedElements()) {
|
|
85
70
|
const isChecked = !getBooleanAttribute($option, 'disabled') && value === getAttribute($option, 'value', '');
|
|
86
|
-
updateBooleanAttribute($option, 'checked', isChecked);
|
|
71
|
+
updateBooleanAttribute($option, 'data-checked', isChecked);
|
|
87
72
|
}
|
|
88
73
|
}
|
|
89
74
|
#dispatchChangeEvent(value) {
|
|
@@ -95,43 +80,6 @@ defineCustomElement('sinch-tabs', class extends NectaryElement {
|
|
|
95
80
|
detail: value
|
|
96
81
|
}));
|
|
97
82
|
}
|
|
98
|
-
#getFirstOption() {
|
|
99
|
-
for (const $option of this.#$slot.assignedElements()) {
|
|
100
|
-
if ($option.disabled !== true) {
|
|
101
|
-
return $option;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
#getLastOption() {
|
|
107
|
-
for (const $option of this.#$slot.assignedElements().reverse()) {
|
|
108
|
-
if ($option.disabled !== true) {
|
|
109
|
-
return $option;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
#getNextOption() {
|
|
115
|
-
const $options = this.#getEnabledRadioElements();
|
|
116
|
-
const $selectedOption = findSelectedOption($options);
|
|
117
|
-
const currentIndex = $selectedOption !== null ? $options.indexOf($selectedOption) : -1;
|
|
118
|
-
if (currentIndex < 0) {
|
|
119
|
-
return this.#getFirstOption();
|
|
120
|
-
}
|
|
121
|
-
return $options[(currentIndex + 1) % $options.length];
|
|
122
|
-
}
|
|
123
|
-
#getPrevOption() {
|
|
124
|
-
const $options = this.#getEnabledRadioElements();
|
|
125
|
-
const $selectedOption = findSelectedOption($options);
|
|
126
|
-
const currentIndex = $selectedOption !== null ? $options.indexOf($selectedOption) : -1;
|
|
127
|
-
if (currentIndex < 0) {
|
|
128
|
-
return this.#getLastOption();
|
|
129
|
-
}
|
|
130
|
-
return $options[(currentIndex - 1 + $options.length) % $options.length];
|
|
131
|
-
}
|
|
132
|
-
#getEnabledRadioElements() {
|
|
133
|
-
return this.#$slot.assignedElements().filter(opt => opt.disabled !== true);
|
|
134
|
-
}
|
|
135
83
|
#onChangeReactHandler = e => {
|
|
136
84
|
getReactEventHandler(this, 'on-change')?.(e);
|
|
137
85
|
};
|
package/tabs/types.d.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
import type { TSinchElementReact } from '../types';
|
|
1
|
+
import type { TRect, TSinchElementReact } from '../types';
|
|
2
2
|
import type { SyntheticEvent } from 'react';
|
|
3
3
|
export declare type TSinchTabsElement = HTMLElement & {
|
|
4
|
+
/** Value */
|
|
4
5
|
value: string;
|
|
6
|
+
nthOptionRect(index: number): TRect | null;
|
|
7
|
+
/** Change value event */
|
|
5
8
|
addEventListener(type: '-change', listener: (e: CustomEvent<string>) => void): void;
|
|
9
|
+
/** Value */
|
|
6
10
|
setAttribute(name: 'value', value: string): void;
|
|
7
11
|
};
|
|
8
12
|
export declare type TSinchTabsReact = TSinchElementReact<TSinchTabsElement> & {
|
|
13
|
+
/** Value */
|
|
9
14
|
value: string;
|
|
15
|
+
/** Label that is used for a11y */
|
|
10
16
|
'aria-label': string;
|
|
11
|
-
/** @deprecated */
|
|
17
|
+
/** @deprecated Change value handler */
|
|
12
18
|
onChange?: (event: SyntheticEvent<TSinchTabsElement, CustomEvent<string>>) => void;
|
|
19
|
+
/** Change value event */
|
|
13
20
|
'on-change'?: (e: CustomEvent<string>) => void;
|
|
14
21
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TSinchTabsIconOptionElement, TSinchTabsIconOptionReact } from './types';
|
|
2
|
+
declare global {
|
|
3
|
+
namespace JSX {
|
|
4
|
+
interface IntrinsicElements {
|
|
5
|
+
'sinch-tabs-icon-option': TSinchTabsIconOptionReact;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
interface HTMLElementTagNameMap {
|
|
9
|
+
'sinch-tabs-icon-option': TSinchTabsIconOptionElement;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { defineCustomElement, getAttribute, getBooleanAttribute, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute } from '../utils';
|
|
2
|
+
const templateHTML = '<style>:host{display:block;outline:0}#button{all:initial;position:relative;display:flex;flex-direction:column;padding:12px 16px 0;box-sizing:border-box;cursor:pointer;border-top-left-radius:var(--sinch-shape-radius-l);border-top-right-radius:var(--sinch-shape-radius-l);height:40px;--sinch-color-icon:var(--sinch-color-stormy-300);--sinch-size-icon:16px}#button:hover{background-color:var(--sinch-color-tropical-100)}#button:focus-visible::before{content:"";position:absolute;inset:0;bottom:-3px;border:2px solid var(--sinch-color-border-focus);border-top-left-radius:var(--sinch-shape-radius-l);border-top-right-radius:var(--sinch-shape-radius-l);pointer-events:none}:host([data-checked]) #button{--sinch-color-icon:var(--sinch-color-tropical-500)}:host([data-checked]) #button::after{content:"";position:absolute;left:4px;right:4px;bottom:-1px;pointer-events:none;border-top:2px solid var(--sinch-color-tropical-500)}#button:disabled{cursor:unset;pointer-events:none;--sinch-color-icon:var(--sinch-color-border-default)}::slotted(*){display:block}</style><sinch-tooltip id="tooltip" inverted><button id="button"><slot name="icon"></slot></button></sinch-tooltip>';
|
|
3
|
+
const template = document.createElement('template');
|
|
4
|
+
template.innerHTML = templateHTML;
|
|
5
|
+
defineCustomElement('sinch-tabs-icon-option', class extends NectaryElement {
|
|
6
|
+
#$button;
|
|
7
|
+
#$tooltip;
|
|
8
|
+
constructor() {
|
|
9
|
+
super();
|
|
10
|
+
const shadowRoot = this.attachShadow();
|
|
11
|
+
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
12
|
+
this.#$button = shadowRoot.querySelector('#button');
|
|
13
|
+
this.#$tooltip = shadowRoot.querySelector('#tooltip');
|
|
14
|
+
}
|
|
15
|
+
connectedCallback() {
|
|
16
|
+
this.setAttribute('role', 'tab');
|
|
17
|
+
this.#$button.addEventListener('click', this.#onClick);
|
|
18
|
+
}
|
|
19
|
+
disconnectedCallback() {
|
|
20
|
+
this.#$button.removeEventListener('click', this.#onClick);
|
|
21
|
+
}
|
|
22
|
+
static get observedAttributes() {
|
|
23
|
+
return ['data-checked', 'disabled', 'aria-label'];
|
|
24
|
+
}
|
|
25
|
+
set value(value) {
|
|
26
|
+
updateAttribute(this, 'value', value);
|
|
27
|
+
}
|
|
28
|
+
get value() {
|
|
29
|
+
return getAttribute(this, 'value', '');
|
|
30
|
+
}
|
|
31
|
+
set disabled(isDisabled) {
|
|
32
|
+
updateBooleanAttribute(this, 'disabled', isDisabled);
|
|
33
|
+
}
|
|
34
|
+
get disabled() {
|
|
35
|
+
return getBooleanAttribute(this, 'disabled');
|
|
36
|
+
}
|
|
37
|
+
attributeChangedCallback(name, oldVal, newVal) {
|
|
38
|
+
if (oldVal === newVal) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
switch (name) {
|
|
42
|
+
case 'data-checked':
|
|
43
|
+
{
|
|
44
|
+
updateExplicitBooleanAttribute(this, 'aria-selected', isAttrTrue(newVal));
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case 'disabled':
|
|
48
|
+
{
|
|
49
|
+
this.#$button.disabled = isAttrTrue(newVal);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case 'aria-label':
|
|
53
|
+
{
|
|
54
|
+
updateAttribute(this.#$tooltip, 'text', newVal);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
get focusable() {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
focus() {
|
|
63
|
+
this.#$button.focus();
|
|
64
|
+
}
|
|
65
|
+
blur() {
|
|
66
|
+
this.#$button.blur();
|
|
67
|
+
}
|
|
68
|
+
#onClick = e => {
|
|
69
|
+
e.stopPropagation();
|
|
70
|
+
this.dispatchEvent(new CustomEvent('option-change', {
|
|
71
|
+
bubbles: true,
|
|
72
|
+
detail: this.value
|
|
73
|
+
}));
|
|
74
|
+
};
|
|
75
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TSinchElementReact } from '../types';
|
|
2
|
+
export declare type TSinchTabsIconOptionElement = HTMLElement & {
|
|
3
|
+
/** Value */
|
|
4
|
+
value: string;
|
|
5
|
+
/** Disabled */
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
/** Value */
|
|
8
|
+
setAttribute(name: 'value', value: string): void;
|
|
9
|
+
/** Disabled */
|
|
10
|
+
setAttribute(name: 'disabled', value: ''): void;
|
|
11
|
+
};
|
|
12
|
+
export declare type TSinchTabsIconOptionReact = TSinchElementReact<TSinchTabsIconOptionElement> & {
|
|
13
|
+
/** Value */
|
|
14
|
+
value: string;
|
|
15
|
+
/** Label that is used for a11y */
|
|
16
|
+
'aria-label': string;
|
|
17
|
+
/** Disabled */
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/tabs-option/index.d.ts
CHANGED
package/tabs-option/index.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
import '../text';
|
|
1
2
|
import { defineCustomElement, getAttribute, getBooleanAttribute, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute } from '../utils';
|
|
2
|
-
const templateHTML = '<style>:host{display:block
|
|
3
|
+
const templateHTML = '<style>:host{display:block}#button{all:initial;position:relative;display:flex;align-items:center;justify-content:center;gap:8px;width:100%;padding:12px 16px;box-sizing:border-box;cursor:pointer;border-top-left-radius:var(--sinch-shape-radius-l);border-top-right-radius:var(--sinch-shape-radius-l);height:40px;color:var(--sinch-color-stormy-300);--sinch-color-icon:var(--sinch-color-stormy-300);--sinch-size-icon:16px}#button:hover{background-color:var(--sinch-color-tropical-100)}#button:focus-visible::before{content:"";position:absolute;inset:0;bottom:-3px;border:2px solid var(--sinch-color-border-focus);border-top-left-radius:var(--sinch-shape-radius-l);border-top-right-radius:var(--sinch-shape-radius-l);pointer-events:none}:host([data-checked]) #button{color:var(--sinch-color-tropical-500);--sinch-color-icon:var(--sinch-color-tropical-500)}:host([data-checked]) #button::after{content:"";position:absolute;left:4px;right:4px;bottom:-1px;pointer-events:none;border-top:2px solid var(--sinch-color-tropical-500)}#button:disabled{cursor:unset;pointer-events:none;color:var(--sinch-color-border-default);--sinch-color-icon:var(--sinch-color-border-default)}#text{flex-shrink:1;flex-basis:auto;min-width:0}::slotted(*){display:block}</style><button id="button"><slot name="icon"></slot><sinch-text id="text" type="m" ellipsis></sinch-text></button>';
|
|
3
4
|
const template = document.createElement('template');
|
|
4
5
|
template.innerHTML = templateHTML;
|
|
5
6
|
defineCustomElement('sinch-tabs-option', class extends NectaryElement {
|
|
6
7
|
#$button;
|
|
7
|
-
#$
|
|
8
|
+
#$text;
|
|
8
9
|
constructor() {
|
|
9
10
|
super();
|
|
10
11
|
const shadowRoot = this.attachShadow();
|
|
11
12
|
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
12
13
|
this.#$button = shadowRoot.querySelector('#button');
|
|
13
|
-
this.#$
|
|
14
|
+
this.#$text = shadowRoot.querySelector('#text');
|
|
14
15
|
}
|
|
15
16
|
connectedCallback() {
|
|
16
17
|
this.setAttribute('role', 'tab');
|
|
@@ -20,13 +21,7 @@ defineCustomElement('sinch-tabs-option', class extends NectaryElement {
|
|
|
20
21
|
this.#$button.removeEventListener('click', this.#onClick);
|
|
21
22
|
}
|
|
22
23
|
static get observedAttributes() {
|
|
23
|
-
return ['checked', 'disabled', 'text'
|
|
24
|
-
}
|
|
25
|
-
set checked(isChecked) {
|
|
26
|
-
updateBooleanAttribute(this, 'checked', isChecked);
|
|
27
|
-
}
|
|
28
|
-
get checked() {
|
|
29
|
-
return getBooleanAttribute(this, 'checked');
|
|
24
|
+
return ['data-checked', 'disabled', 'text'];
|
|
30
25
|
}
|
|
31
26
|
set value(value) {
|
|
32
27
|
updateAttribute(this, 'value', value);
|
|
@@ -50,19 +45,17 @@ defineCustomElement('sinch-tabs-option', class extends NectaryElement {
|
|
|
50
45
|
switch (name) {
|
|
51
46
|
case 'text':
|
|
52
47
|
{
|
|
53
|
-
this.#$
|
|
48
|
+
this.#$text.textContent = newVal;
|
|
54
49
|
break;
|
|
55
50
|
}
|
|
56
|
-
case 'checked':
|
|
51
|
+
case 'data-checked':
|
|
57
52
|
{
|
|
58
53
|
updateExplicitBooleanAttribute(this, 'aria-selected', isAttrTrue(newVal));
|
|
59
54
|
break;
|
|
60
55
|
}
|
|
61
56
|
case 'disabled':
|
|
62
57
|
{
|
|
63
|
-
|
|
64
|
-
this.#$button.disabled = isDisabled;
|
|
65
|
-
updateBooleanAttribute(this, 'disabled', isDisabled);
|
|
58
|
+
this.#$button.disabled = isAttrTrue(newVal);
|
|
66
59
|
break;
|
|
67
60
|
}
|
|
68
61
|
}
|
package/tabs-option/types.d.ts
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import type { TSinchElementReact } from '../types';
|
|
2
2
|
export declare type TSinchTabsOptionElement = HTMLElement & {
|
|
3
|
+
/** Value */
|
|
3
4
|
value: string;
|
|
4
|
-
|
|
5
|
-
checked: boolean;
|
|
5
|
+
/** Text */
|
|
6
6
|
text: string;
|
|
7
|
+
/** Disabled */
|
|
8
|
+
disabled: boolean;
|
|
9
|
+
/** Value */
|
|
7
10
|
setAttribute(name: 'value', value: string): void;
|
|
8
|
-
|
|
9
|
-
setAttribute(name: 'checked', value: ''): void;
|
|
11
|
+
/** Text */
|
|
10
12
|
setAttribute(name: 'text', value: string): void;
|
|
13
|
+
/** Disabled */
|
|
14
|
+
setAttribute(name: 'disabled', value: ''): void;
|
|
11
15
|
};
|
|
12
16
|
export declare type TSinchTabsOptionReact = TSinchElementReact<TSinchTabsOptionElement> & {
|
|
17
|
+
/** Value */
|
|
13
18
|
value: string;
|
|
14
|
-
|
|
19
|
+
/** Text */
|
|
15
20
|
text: string;
|
|
21
|
+
/** Label that is used for a11y */
|
|
16
22
|
'aria-label': string;
|
|
23
|
+
/** Disabled */
|
|
24
|
+
disabled?: boolean;
|
|
17
25
|
};
|
package/theme/emoji.css
ADDED
package/theme/fonts.css
CHANGED
|
@@ -74,3 +74,12 @@
|
|
|
74
74
|
url("https://d2vu40klajma73.cloudfront.net/DM-Mono-400.woff2") format("woff2"),
|
|
75
75
|
url("https://d2vu40klajma73.cloudfront.net/DM-Mono-400.woff") format("woff");
|
|
76
76
|
}
|
|
77
|
+
|
|
78
|
+
@font-face {
|
|
79
|
+
font-family: "Material Icons Outlined";
|
|
80
|
+
font-style: normal;
|
|
81
|
+
font-weight: 400;
|
|
82
|
+
src:
|
|
83
|
+
url("https://fonts.gstatic.com/s/materialsymbolsoutlined/v63/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzazHD_dY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOejbd5zrDAt.woff2") format("woff2"),
|
|
84
|
+
url("https://fonts.gstatic.com/s/materialsymbolsoutlined/v63/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzazHD_dY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOelbd5zrDAt.woff") format("woff");
|
|
85
|
+
}
|
package/theme/fonts.json
CHANGED
|
@@ -75,5 +75,14 @@
|
|
|
75
75
|
"woff2": "https://d2vu40klajma73.cloudfront.net/DM-Mono-400.woff2",
|
|
76
76
|
"woff": "https://d2vu40klajma73.cloudfront.net/DM-Mono-400.woff"
|
|
77
77
|
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"family": "Material Icons Outlined",
|
|
81
|
+
"weight": 400,
|
|
82
|
+
"style": "normal",
|
|
83
|
+
"src": {
|
|
84
|
+
"woff2": "https://fonts.gstatic.com/s/materialsymbolsoutlined/v63/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzazHD_dY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOejbd5zrDAt.woff2",
|
|
85
|
+
"woff": "https://fonts.gstatic.com/s/materialsymbolsoutlined/v63/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzazHD_dY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOelbd5zrDAt.woff"
|
|
86
|
+
}
|
|
78
87
|
}
|
|
79
88
|
]
|
package/theme/icon.css
ADDED
package/theme.css
CHANGED
package/tile-control/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineCustomElement, getAttribute, getBooleanAttribute,
|
|
1
|
+
import { defineCustomElement, getAttribute, getBooleanAttribute, unpackCsv, getFirstCsvValue, getIntegerAttribute, getReactEventHandler, NectaryElement, updateAttribute, updateBooleanAttribute, updateCsv, updateIntegerAttribute } from '../utils';
|
|
2
2
|
const templateHTML = '<style>:host{display:block;outline:0;--sinch-grid-num-columns:1}#wrapper{display:grid;grid-template-columns:repeat(var(--sinch-grid-num-columns),auto);gap:16px;width:fit-content}:host([small]:not([small=false])) #wrapper{gap:8px}:host([cols="2"]){--sinch-grid-num-columns:2}:host([cols="3"]){--sinch-grid-num-columns:3}:host([cols="4"]){--sinch-grid-num-columns:4}:host([cols="5"]){--sinch-grid-num-columns:5}:host([cols="6"]){--sinch-grid-num-columns:6}:host([cols="7"]){--sinch-grid-num-columns:7}:host([cols="8"]){--sinch-grid-num-columns:8}</style><div id="wrapper"><slot></slot></div>';
|
|
3
3
|
const template = document.createElement('template');
|
|
4
4
|
template.innerHTML = templateHTML;
|
|
@@ -91,9 +91,9 @@ defineCustomElement('sinch-tile-control', class extends NectaryElement {
|
|
|
91
91
|
};
|
|
92
92
|
#onValueChange(csv) {
|
|
93
93
|
if (this.multiple) {
|
|
94
|
-
const values =
|
|
94
|
+
const values = unpackCsv(csv);
|
|
95
95
|
for (const $option of this.#$slot.assignedElements()) {
|
|
96
|
-
const isChecked = !getBooleanAttribute($option, 'disabled') && values.
|
|
96
|
+
const isChecked = !getBooleanAttribute($option, 'disabled') && values.includes(getAttribute($option, 'value', ''));
|
|
97
97
|
updateBooleanAttribute($option, 'data-checked', isChecked);
|
|
98
98
|
}
|
|
99
99
|
} else {
|