@nectary/components 0.41.0 → 0.42.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 +0 -16
- package/accordion/types.d.ts +9 -1
- package/accordion-item/index.js +0 -24
- package/accordion-item/types.d.ts +18 -3
- package/action-menu/index.js +1 -45
- package/action-menu-option/index.js +0 -18
- package/alert/index.js +0 -10
- package/alert/types.d.ts +6 -0
- package/avatar/index.js +57 -20
- package/avatar/types.d.ts +25 -7
- package/avatar/utils.d.ts +10 -2
- package/avatar/utils.js +23 -2
- package/badge/index.d.ts +11 -0
- package/badge/index.js +140 -0
- package/badge/types.d.ts +38 -0
- package/badge/utils.d.ts +11 -0
- package/badge/utils.js +23 -0
- package/button/index.js +0 -18
- package/card/index.js +0 -16
- package/card/types.d.ts +15 -3
- package/card-container/index.js +0 -1
- package/chat/index.js +0 -1
- package/chat-block/index.js +0 -19
- package/chat-block/types.d.ts +16 -4
- package/chat-bubble/index.js +0 -9
- package/chat-bubble/types.d.ts +6 -0
- package/checkbox/index.js +0 -23
- package/chip/index.js +16 -25
- package/chip/utils.d.ts +3 -0
- package/chip/utils.js +11 -0
- package/color-menu/index.js +8 -86
- package/color-menu/utils.js +0 -4
- package/color-swatch/index.js +17 -17
- package/color-swatch/types.d.ts +2 -2
- package/color-swatch/utils.d.ts +3 -0
- package/color-swatch/utils.js +11 -0
- package/date-picker/index.js +1 -50
- package/date-picker/utils.js +0 -7
- package/dialog/index.js +1 -17
- package/field/index.js +0 -19
- package/file-drop/index.js +0 -40
- package/file-drop/utils.js +0 -6
- package/file-picker/index.js +0 -17
- package/file-picker/utils.js +0 -1
- package/file-status/index.js +0 -12
- package/grid/index.js +0 -1
- package/grid-item/index.js +0 -9
- package/help-tooltip/index.js +0 -14
- package/horizontal-stepper/index.js +0 -12
- package/horizontal-stepper-item/index.js +0 -14
- package/icon-button/index.js +0 -15
- package/icons/create-icon-class.js +0 -2
- package/icons-branded/create-icon-class.js +0 -8
- package/icons-channel/create-icon-class.js +0 -6
- package/illustrations/create-illustration-class.js +0 -11
- package/inline-alert/index.js +0 -14
- package/input/index.js +0 -37
- package/link/index.js +0 -25
- package/list/index.js +0 -2
- package/list-item/index.js +0 -2
- package/logo/create-logo-class.js +0 -9
- package/package.json +1 -1
- package/pagination/index.js +0 -31
- package/pop/index.js +64 -68
- package/pop/utils.js +0 -1
- package/popover/index.js +0 -33
- package/popover/utils.js +0 -2
- package/progress/index.js +0 -10
- package/radio/index.js +0 -30
- package/radio-option/index.js +0 -20
- package/segment/index.js +0 -15
- package/segment-collapse/index.js +0 -13
- package/segmented-control/index.js +0 -12
- package/segmented-control-option/index.js +0 -18
- package/segmented-icon-control/index.js +0 -16
- package/segmented-icon-control-option/index.js +0 -14
- package/select-button/index.js +0 -23
- package/select-menu/index.js +1 -63
- package/select-menu-option/index.js +0 -14
- package/spinner/index.js +0 -4
- package/stop-events/index.js +0 -5
- package/table/index.js +0 -2
- package/table-body/index.js +0 -2
- package/table-cell/index.js +0 -4
- package/table-head/index.js +0 -2
- package/table-head-cell/index.js +0 -11
- package/table-row/index.js +0 -6
- package/tabs/index.js +0 -30
- package/tabs-option/index.js +0 -19
- package/tag/index.js +18 -21
- package/tag/utils.d.ts +3 -0
- package/tag/utils.js +11 -0
- package/text/index.js +1 -12
- package/textarea/index.js +0 -40
- package/{utils → theme}/colors.d.ts +0 -1
- package/{utils → theme}/colors.js +0 -1
- package/theme.css +13 -209
- package/tile-control/index.js +0 -24
- package/tile-control-option/index.js +0 -18
- package/time-picker/index.js +2 -51
- package/time-picker/utils.js +0 -18
- package/title/index.js +1 -12
- package/title/utils.js +0 -5
- package/toast/index.js +0 -19
- package/toast-manager/index.js +0 -27
- package/toggle/index.js +0 -23
- package/tooltip/index.js +0 -27
- package/tooltip/utils.js +0 -4
- package/utils/animation.js +0 -20
- package/utils/context.js +0 -6
- package/utils/index.d.ts +1 -0
- package/utils/index.js +11 -52
- package/vertical-stepper/index.js +0 -12
- package/vertical-stepper-item/index.js +0 -14
- package/avatar-badge/index.d.ts +0 -11
- package/avatar-badge/index.js +0 -38
- package/avatar-badge/types.d.ts +0 -8
- package/avatar-status/index.d.ts +0 -11
- package/avatar-status/index.js +0 -37
- package/avatar-status/types.d.ts +0 -9
- package/avatar-status/types.js +0 -1
- package/avatar-status/utils.d.ts +0 -5
- package/avatar-status/utils.js +0 -6
- package/chat-avatar/index.d.ts +0 -12
- package/chat-avatar/index.js +0 -52
- package/chat-avatar/types.d.ts +0 -12
- package/chat-avatar/types.js +0 -1
- /package/{avatar-badge → badge}/types.js +0 -0
package/avatar/index.js
CHANGED
|
@@ -1,56 +1,61 @@
|
|
|
1
1
|
import { defineCustomElement, getAttribute, getLiteralAttribute, NectaryElement, updateAttribute, updateLiteralAttribute } from '../utils';
|
|
2
|
-
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}#wrapper{position:relative;width:40px;height:40px;background-color:var(--sinch-color-snow-100);border-radius:50%;--sinch-avatar-badge-size:16px;--sinch-avatar-badge-font:700 12px/14px "Gilroy","Arial","sans-serif"}#circle{position:relative;width:calc(100% - 2px);height:calc(100% - 2px);left:1px;top:1px;border-radius:50%;-webkit-mask:linear-gradient(#fff,#000);mask:linear-gradient(#fff,#000)}#text{display:block;width:100%;height:100%;font:var(--sinch-font-title-s);line-height:38px;text-transform:uppercase;text-align:center
|
|
3
|
-
import {
|
|
2
|
+
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}#wrapper{position:relative;width:40px;height:40px;background-color:var(--sinch-color-snow-100);border-radius:50%;--sinch-avatar-badge-size:16px;--sinch-avatar-badge-font:700 12px/14px "Gilroy","Arial","sans-serif"}#circle{position:relative;width:calc(100% - 2px);height:calc(100% - 2px);left:1px;top:1px;border-radius:50%;-webkit-mask:linear-gradient(#fff,#000);mask:linear-gradient(#fff,#000);background-color:var(--sinch-avatar-color-default-bg);color:var(--sinch-avatar-color-default-fg)}#text{display:block;width:100%;height:100%;font:var(--sinch-font-title-s);line-height:38px;text-transform:uppercase;text-align:center}:host([size="l"]) #wrapper{width:56px;height:56px;--sinch-avatar-badge-size:20px;--sinch-avatar-badge-font:700 12px/18px "Gilroy","Arial","sans-serif"}:host([size="l"]) #text{font:var(--sinch-font-title-m);line-height:54px}:host([size="s"]) #wrapper{width:24px;height:24px;--sinch-avatar-badge-size:11px;--sinch-avatar-badge-font:500 8px/9px "Gilroy","Arial","sans-serif"}:host([size="s"]) #text{font:var(--sinch-font-extra-small-text);line-height:22px}#image{display:none;position:absolute;left:0;top:0;width:100%;height:100%;object-fit:contain}:host([src]:not([src=""])) #image{display:block}#status-wrapper{position:absolute;left:calc(85% - 5px);top:calc(85% - 5px);width:10px;height:10px;padding:1px;box-sizing:border-box;border-radius:50%;background-color:var(--sinch-color-snow-100);display:none;pointer-events:none}#status{width:8px;height:8px;border-radius:50%}:host([status=away]) #status-wrapper,:host([status=busy]) #status-wrapper,:host([status=offline]) #status-wrapper,:host([status=online]) #status-wrapper{display:block}:host([status=online]) #status{background-color:var(--sinch-avatar-status-color-online)}:host([status=away]) #status{background-color:var(--sinch-avatar-status-color-away)}:host([status=busy]) #status{background-color:var(--sinch-avatar-status-color-busy)}:host([status=offline]) #status{background-color:var(--sinch-avatar-status-color-offline)}</style><div id="wrapper"><div id="circle"><span id="text"></span><img id="image" alt=""/></div><div id="status-wrapper"><div id="status"></div></div></div>';
|
|
3
|
+
import { assertAvatarColor, assertSize, assertStatus, getAvatarColorBg, getAvatarColorFg, sizeValues, statusValues } from './utils';
|
|
4
4
|
const template = document.createElement('template');
|
|
5
5
|
template.innerHTML = templateHTML;
|
|
6
6
|
defineCustomElement('sinch-avatar', class extends NectaryElement {
|
|
7
|
+
#$circle;
|
|
7
8
|
#$text;
|
|
8
9
|
#$image;
|
|
9
|
-
|
|
10
|
+
#isConnected = false;
|
|
10
11
|
constructor() {
|
|
11
12
|
super();
|
|
12
13
|
const shadowRoot = this.attachShadow();
|
|
13
14
|
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
15
|
+
this.#$circle = shadowRoot.querySelector('#circle');
|
|
14
16
|
this.#$text = shadowRoot.querySelector('#text');
|
|
15
17
|
this.#$image = shadowRoot.querySelector('#image');
|
|
16
18
|
}
|
|
17
|
-
|
|
19
|
+
connectedCallback() {
|
|
20
|
+
this.#isConnected = true;
|
|
21
|
+
this.#updateColor();
|
|
22
|
+
}
|
|
23
|
+
disconnectedCallback() {
|
|
24
|
+
this.#isConnected = false;
|
|
25
|
+
}
|
|
18
26
|
get src() {
|
|
19
27
|
return getAttribute(this, 'src');
|
|
20
28
|
}
|
|
21
|
-
|
|
22
29
|
set src(value) {
|
|
23
30
|
updateAttribute(this, 'src', value);
|
|
24
31
|
}
|
|
25
|
-
|
|
26
32
|
get alt() {
|
|
27
33
|
return getAttribute(this, 'alt', '');
|
|
28
34
|
}
|
|
29
|
-
|
|
30
35
|
set alt(value) {
|
|
31
36
|
updateAttribute(this, 'alt', value);
|
|
32
37
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return getLiteralAttribute(this, backgroundValues, 'background', 'grey');
|
|
38
|
+
get color() {
|
|
39
|
+
return getAttribute(this, 'color');
|
|
36
40
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
updateLiteralAttribute(this, backgroundValues, 'background', value);
|
|
41
|
+
set color(value) {
|
|
42
|
+
updateAttribute(this, 'color', value);
|
|
40
43
|
}
|
|
41
|
-
|
|
42
44
|
get size() {
|
|
43
45
|
return getLiteralAttribute(this, sizeValues, 'size', 'm');
|
|
44
46
|
}
|
|
45
|
-
|
|
46
47
|
set size(value) {
|
|
47
48
|
updateLiteralAttribute(this, sizeValues, 'size', value);
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
+
get status() {
|
|
51
|
+
return getLiteralAttribute(this, statusValues, 'status', null);
|
|
52
|
+
}
|
|
53
|
+
set status(value) {
|
|
54
|
+
updateLiteralAttribute(this, statusValues, 'status', value);
|
|
55
|
+
}
|
|
50
56
|
static get observedAttributes() {
|
|
51
|
-
return ['alt', 'src'];
|
|
57
|
+
return ['alt', 'src', 'status', 'size', 'color'];
|
|
52
58
|
}
|
|
53
|
-
|
|
54
59
|
attributeChangedCallback(name, _, newVal) {
|
|
55
60
|
switch (name) {
|
|
56
61
|
case 'alt':
|
|
@@ -59,13 +64,45 @@ defineCustomElement('sinch-avatar', class extends NectaryElement {
|
|
|
59
64
|
this.#$image.alt = newVal ?? '';
|
|
60
65
|
break;
|
|
61
66
|
}
|
|
62
|
-
|
|
63
67
|
case 'src':
|
|
64
68
|
{
|
|
65
69
|
this.#$image.src = newVal ?? '';
|
|
66
70
|
break;
|
|
67
71
|
}
|
|
72
|
+
case 'size':
|
|
73
|
+
{
|
|
74
|
+
if (newVal !== null) {
|
|
75
|
+
assertSize(newVal);
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case 'status':
|
|
80
|
+
{
|
|
81
|
+
if (newVal !== null) {
|
|
82
|
+
assertStatus(newVal);
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case 'color':
|
|
87
|
+
{
|
|
88
|
+
this.#updateColor();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
#updateColor() {
|
|
93
|
+
if (!this.#isConnected) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const colorName = this.color;
|
|
97
|
+
if (colorName !== null && colorName.length > 0) {
|
|
98
|
+
assertAvatarColor(this, colorName);
|
|
99
|
+
const bg = getAvatarColorBg(colorName);
|
|
100
|
+
const fg = getAvatarColorFg(colorName);
|
|
101
|
+
this.#$circle.style.setProperty('background-color', bg);
|
|
102
|
+
this.#$circle.style.setProperty('color', fg);
|
|
103
|
+
} else {
|
|
104
|
+
this.#$circle.style.removeProperty('background-color');
|
|
105
|
+
this.#$circle.style.removeProperty('color');
|
|
68
106
|
}
|
|
69
107
|
}
|
|
70
|
-
|
|
71
108
|
});
|
package/avatar/types.d.ts
CHANGED
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
import type { TSinchElementReact } from '../types';
|
|
2
|
-
export declare type TSinchAvatarBackground = 'grey' | 'yellow' | 'blue';
|
|
3
2
|
export declare type TSinchAvatarSize = 'l' | 'm' | 's';
|
|
3
|
+
export declare type TSinchAvatarStatus = 'online' | 'busy' | 'away' | 'offline';
|
|
4
4
|
export declare type TSinchAvatarElement = HTMLElement & {
|
|
5
|
-
|
|
5
|
+
/** Image source */
|
|
6
6
|
src: string | null;
|
|
7
|
-
|
|
7
|
+
/** Alt text */
|
|
8
|
+
alt: string;
|
|
9
|
+
/** Background color */
|
|
10
|
+
color: string | null;
|
|
11
|
+
/** Status */
|
|
12
|
+
status: TSinchAvatarStatus | null;
|
|
13
|
+
/** Size, `m` by default */
|
|
8
14
|
size: TSinchAvatarSize;
|
|
9
|
-
|
|
15
|
+
/** Image source */
|
|
10
16
|
setAttribute(name: 'src', value: string): void;
|
|
11
|
-
|
|
17
|
+
/** Alt text */
|
|
18
|
+
setAttribute(name: 'alt', value: string): void;
|
|
19
|
+
/** Background color */
|
|
20
|
+
setAttribute(name: 'color', value: string): void;
|
|
21
|
+
/** Size, `m` by default */
|
|
12
22
|
setAttribute(name: 'size', value: TSinchAvatarSize): void;
|
|
23
|
+
/** Status */
|
|
24
|
+
setAttribute(name: 'status', value: TSinchAvatarStatus): void;
|
|
13
25
|
};
|
|
14
26
|
export declare type TSinchAvatarReact = TSinchElementReact<TSinchAvatarElement> & {
|
|
15
|
-
|
|
27
|
+
/** Image source */
|
|
16
28
|
src?: string;
|
|
17
|
-
|
|
29
|
+
/** Alt text */
|
|
30
|
+
alt: string;
|
|
31
|
+
/** Background color */
|
|
32
|
+
color?: string;
|
|
33
|
+
/** Size, `m` by default */
|
|
18
34
|
size?: TSinchAvatarSize;
|
|
35
|
+
/** Status */
|
|
36
|
+
status?: TSinchAvatarStatus;
|
|
19
37
|
};
|
package/avatar/utils.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const backgroundValues: readonly TSinchAvatarBackground[];
|
|
1
|
+
import type { TSinchAvatarSize, TSinchAvatarStatus } from './types';
|
|
3
2
|
export declare const sizeValues: readonly TSinchAvatarSize[];
|
|
3
|
+
export declare const statusValues: readonly TSinchAvatarStatus[];
|
|
4
|
+
declare type TAssertSize = (value: string | null) => asserts value is TSinchAvatarSize;
|
|
5
|
+
export declare const assertSize: TAssertSize;
|
|
6
|
+
declare type TAssertStatus = (value: string | null) => asserts value is TSinchAvatarStatus;
|
|
7
|
+
export declare const assertStatus: TAssertStatus;
|
|
8
|
+
export declare const getAvatarColorBg: (id: string) => string;
|
|
9
|
+
export declare const getAvatarColorFg: (id: string) => string;
|
|
10
|
+
export declare const assertAvatarColor: (root: Element, id: string | null) => void;
|
|
11
|
+
export {};
|
package/avatar/utils.js
CHANGED
|
@@ -1,2 +1,23 @@
|
|
|
1
|
-
export const
|
|
2
|
-
export const
|
|
1
|
+
export const sizeValues = ['l', 'm', 's'];
|
|
2
|
+
export const statusValues = ['online', 'busy', 'away', 'offline'];
|
|
3
|
+
export const assertSize = value => {
|
|
4
|
+
if (value === null || !sizeValues.includes(value)) {
|
|
5
|
+
throw new Error(`sinch-avatar: invalid size attribute: ${value}`);
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
export const assertStatus = value => {
|
|
9
|
+
if (value === null || !statusValues.includes(value)) {
|
|
10
|
+
throw new Error(`sinch-avatar: invalid status attribute: ${value}`);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
export const getAvatarColorBg = id => {
|
|
14
|
+
return `var(--sinch-avatar-color-${id}-bg)`;
|
|
15
|
+
};
|
|
16
|
+
export const getAvatarColorFg = id => {
|
|
17
|
+
return `var(--sinch-avatar-color-${id}-fg)`;
|
|
18
|
+
};
|
|
19
|
+
export const assertAvatarColor = (root, id) => {
|
|
20
|
+
if (id === null || window.getComputedStyle(root).getPropertyValue(`--sinch-avatar-color-${id}-bg`).length === 0) {
|
|
21
|
+
throw new Error(`Invalid sinch-avatar color name: ${id}`);
|
|
22
|
+
}
|
|
23
|
+
};
|
package/badge/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TSinchBadgeElement, TSinchBadgeReact } from './types';
|
|
2
|
+
declare global {
|
|
3
|
+
namespace JSX {
|
|
4
|
+
interface IntrinsicElements {
|
|
5
|
+
'sinch-badge': TSinchBadgeReact;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
interface HTMLElementTagNameMap {
|
|
9
|
+
'sinch-badge': TSinchBadgeElement;
|
|
10
|
+
}
|
|
11
|
+
}
|
package/badge/index.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { defineCustomElement, getAttribute, getBooleanAttribute, getLiteralAttribute, getRect, NectaryElement, setClass, updateAttribute, updateBooleanAttribute, updateLiteralAttribute } from '../utils';
|
|
2
|
+
const templateHTML = '<style>:host{display:inline-flex;flex-direction:column;position:relative}#badge-wrapper{position:absolute;left:0;top:0;width:fit-content;border-radius:11px;padding:1px;pointer-events:none;background-color:var(--sinch-color-snow-100)}#badge{box-sizing:border-box;color:var(--sinch-badge-color-default-fg);background-color:var(--sinch-badge-color-default-bg);width:20px;height:20px;border-radius:10px}#badge.long{width:fit-content;padding:0 5px}#text{display:block;width:100%;height:100%;text-align:center;font-family:var(--sinch-font-mono-family);font-weight:400;font-size:14px;line-height:20px;text-rendering:optimizelegibility}:host([size="m"]) #badge-wrapper{left:calc(100% - 8px);top:-8px}:host([size="m"]) #badge{width:14px;height:14px}:host([size="m"]) #badge.long{width:fit-content;padding:0 3px}:host([size="m"]) #text{font-size:12px;line-height:14px}:host([size="s"]) #badge{width:8px;height:8px;padding:0}:host([size="s"]) #text{display:none}:host([hidden]:not([hidden=false])) #badge-wrapper{display:none}</style><slot id="slot"></slot><div id="badge-wrapper"><div id="badge"><span id="text"></span></div></div>';
|
|
3
|
+
import { assertBadgeColor, assertMode, assertSize, getBadgeColorBg, getBadgeColorFg, modeValues, sizeValues } from './utils';
|
|
4
|
+
const template = document.createElement('template');
|
|
5
|
+
template.innerHTML = templateHTML;
|
|
6
|
+
defineCustomElement('sinch-badge', class extends NectaryElement {
|
|
7
|
+
#$badgeWrapper;
|
|
8
|
+
#$badge;
|
|
9
|
+
#$text;
|
|
10
|
+
#isConnected = false;
|
|
11
|
+
#observer;
|
|
12
|
+
constructor() {
|
|
13
|
+
super();
|
|
14
|
+
const shadowRoot = this.attachShadow();
|
|
15
|
+
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
16
|
+
this.#$badgeWrapper = shadowRoot.querySelector('#badge-wrapper');
|
|
17
|
+
this.#$badge = shadowRoot.querySelector('#badge');
|
|
18
|
+
this.#$text = shadowRoot.querySelector('#text');
|
|
19
|
+
this.#observer = new ResizeObserver(this.#onResize);
|
|
20
|
+
}
|
|
21
|
+
connectedCallback() {
|
|
22
|
+
this.#isConnected = true;
|
|
23
|
+
this.#updateColor();
|
|
24
|
+
this.#observer.observe(this);
|
|
25
|
+
}
|
|
26
|
+
disconnectedCallback() {
|
|
27
|
+
this.#observer.unobserve(this);
|
|
28
|
+
this.#isConnected = false;
|
|
29
|
+
}
|
|
30
|
+
get text() {
|
|
31
|
+
return getAttribute(this, 'text', '');
|
|
32
|
+
}
|
|
33
|
+
set text(value) {
|
|
34
|
+
updateAttribute(this, 'text', value);
|
|
35
|
+
}
|
|
36
|
+
get size() {
|
|
37
|
+
return getLiteralAttribute(this, sizeValues, 'size', 'm');
|
|
38
|
+
}
|
|
39
|
+
set size(value) {
|
|
40
|
+
updateLiteralAttribute(this, sizeValues, 'size', value);
|
|
41
|
+
}
|
|
42
|
+
get mode() {
|
|
43
|
+
return getLiteralAttribute(this, modeValues, 'mode', 'square');
|
|
44
|
+
}
|
|
45
|
+
set mode(value) {
|
|
46
|
+
updateLiteralAttribute(this, modeValues, 'mode', value);
|
|
47
|
+
}
|
|
48
|
+
get color() {
|
|
49
|
+
return getAttribute(this, 'color');
|
|
50
|
+
}
|
|
51
|
+
set color(value) {
|
|
52
|
+
updateAttribute(this, 'color', value);
|
|
53
|
+
}
|
|
54
|
+
get hidden() {
|
|
55
|
+
return getBooleanAttribute(this, 'hidden');
|
|
56
|
+
}
|
|
57
|
+
set hidden(isHidden) {
|
|
58
|
+
updateBooleanAttribute(this, 'hidden', isHidden);
|
|
59
|
+
}
|
|
60
|
+
get badgeRect() {
|
|
61
|
+
if (this.hidden) {
|
|
62
|
+
const selfRect = getRect(this);
|
|
63
|
+
return {
|
|
64
|
+
x: selfRect.x + selfRect.width,
|
|
65
|
+
y: selfRect.y,
|
|
66
|
+
width: 0,
|
|
67
|
+
height: 0
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return getRect(this.#$badgeWrapper);
|
|
71
|
+
}
|
|
72
|
+
static get observedAttributes() {
|
|
73
|
+
return ['text', 'size', 'mode', 'color', 'hidden'];
|
|
74
|
+
}
|
|
75
|
+
attributeChangedCallback(name, _, newVal) {
|
|
76
|
+
switch (name) {
|
|
77
|
+
case 'text':
|
|
78
|
+
{
|
|
79
|
+
this.#$text.textContent = newVal;
|
|
80
|
+
setClass(this.#$badge, 'long', newVal !== null && newVal.length > 1);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
case 'size':
|
|
84
|
+
{
|
|
85
|
+
assertSize(newVal);
|
|
86
|
+
this.#updatePosition();
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case 'mode':
|
|
90
|
+
{
|
|
91
|
+
assertMode(newVal);
|
|
92
|
+
this.#updatePosition();
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case 'color':
|
|
96
|
+
{
|
|
97
|
+
this.#updateColor();
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case 'hidden':
|
|
101
|
+
{
|
|
102
|
+
this.#updatePosition();
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
#updateColor() {
|
|
108
|
+
if (!this.#isConnected) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const colorName = this.color;
|
|
112
|
+
if (colorName !== null && colorName.length > 0) {
|
|
113
|
+
assertBadgeColor(this, colorName);
|
|
114
|
+
const bg = getBadgeColorBg(colorName);
|
|
115
|
+
const fg = getBadgeColorFg(colorName);
|
|
116
|
+
this.#$badge.style.setProperty('background-color', bg);
|
|
117
|
+
this.#$badge.style.setProperty('color', fg);
|
|
118
|
+
} else {
|
|
119
|
+
this.#$badge.style.removeProperty('background-color');
|
|
120
|
+
this.#$badge.style.removeProperty('color');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
#updatePosition() {
|
|
124
|
+
if (this.hidden) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const mode = this.mode;
|
|
128
|
+
const targetRect = this.getBoundingClientRect();
|
|
129
|
+
const badgeRect = this.#$badgeWrapper.getBoundingClientRect();
|
|
130
|
+
const offsetMultX = mode === 'circle' ? 0.85 : 1;
|
|
131
|
+
const offsetMultY = mode === 'circle' ? 0.15 : 0;
|
|
132
|
+
const posX = Math.round(targetRect.width * offsetMultX - badgeRect.height / 2);
|
|
133
|
+
const posY = Math.round(targetRect.height * offsetMultY - badgeRect.height / 2);
|
|
134
|
+
this.#$badgeWrapper.style.setProperty('left', `${posX}px`);
|
|
135
|
+
this.#$badgeWrapper.style.setProperty('top', `${posY}px`);
|
|
136
|
+
}
|
|
137
|
+
#onResize = () => {
|
|
138
|
+
this.#updatePosition();
|
|
139
|
+
};
|
|
140
|
+
});
|
package/badge/types.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { TRect, TSinchElementReact } from '../types';
|
|
2
|
+
export declare type TSinchBadgeSize = 'l' | 'm' | 's';
|
|
3
|
+
export declare type TSinchBadgeMode = 'square' | 'circle';
|
|
4
|
+
export declare type TSinchBadgeElement = HTMLElement & {
|
|
5
|
+
/** Text */
|
|
6
|
+
text: string;
|
|
7
|
+
/** Size */
|
|
8
|
+
size: TSinchBadgeSize;
|
|
9
|
+
/** Mode, `square` by default */
|
|
10
|
+
mode: TSinchBadgeMode;
|
|
11
|
+
/** Color */
|
|
12
|
+
color: string | null;
|
|
13
|
+
/** Hidden */
|
|
14
|
+
hidden: boolean;
|
|
15
|
+
readonly badgeRect: TRect;
|
|
16
|
+
/** Text */
|
|
17
|
+
setAttribute(name: 'text', value: string): void;
|
|
18
|
+
/** Size */
|
|
19
|
+
setAttribute(name: 'size', value: TSinchBadgeSize): void;
|
|
20
|
+
/** Mode, `square` by default */
|
|
21
|
+
setAttribute(name: 'mode', value: TSinchBadgeMode): void;
|
|
22
|
+
/** Color */
|
|
23
|
+
setAttribute(name: 'color', value: string): void;
|
|
24
|
+
/** Hidden */
|
|
25
|
+
setAttribute(name: 'hidden', value: ''): void;
|
|
26
|
+
};
|
|
27
|
+
export declare type TSinchBadgeReact = TSinchElementReact<TSinchBadgeElement> & {
|
|
28
|
+
/** Text */
|
|
29
|
+
text: string;
|
|
30
|
+
/** Size */
|
|
31
|
+
size: TSinchBadgeSize;
|
|
32
|
+
/** Mode, `square` by default */
|
|
33
|
+
mode?: TSinchBadgeMode;
|
|
34
|
+
/** Color */
|
|
35
|
+
color?: string;
|
|
36
|
+
/** Hidden */
|
|
37
|
+
hidden?: boolean;
|
|
38
|
+
};
|
package/badge/utils.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TSinchBadgeMode, TSinchBadgeSize } from './types';
|
|
2
|
+
export declare const sizeValues: readonly TSinchBadgeSize[];
|
|
3
|
+
declare type TAssertSize = (value: string | null) => asserts value is TSinchBadgeSize;
|
|
4
|
+
export declare const assertSize: TAssertSize;
|
|
5
|
+
export declare const modeValues: readonly TSinchBadgeMode[];
|
|
6
|
+
declare type TAssertMode = (value: string | null) => asserts value is TSinchBadgeMode;
|
|
7
|
+
export declare const assertMode: TAssertMode;
|
|
8
|
+
export declare const getBadgeColorBg: (id: string) => string;
|
|
9
|
+
export declare const getBadgeColorFg: (id: string) => string;
|
|
10
|
+
export declare const assertBadgeColor: (root: Element, id: string | null) => void;
|
|
11
|
+
export {};
|
package/badge/utils.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const sizeValues = ['l', 'm', 's'];
|
|
2
|
+
export const assertSize = value => {
|
|
3
|
+
if (value === null || !sizeValues.includes(value)) {
|
|
4
|
+
throw new Error(`sinch-badge: invalid size attribute: ${value}`);
|
|
5
|
+
}
|
|
6
|
+
};
|
|
7
|
+
export const modeValues = ['square', 'circle'];
|
|
8
|
+
export const assertMode = value => {
|
|
9
|
+
if (value === null || !modeValues.includes(value)) {
|
|
10
|
+
throw new Error(`sinch-badge: invalid mode attribute: ${value}`);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
export const getBadgeColorBg = id => {
|
|
14
|
+
return `var(--sinch-badge-color-${id}-bg)`;
|
|
15
|
+
};
|
|
16
|
+
export const getBadgeColorFg = id => {
|
|
17
|
+
return `var(--sinch-badge-color-${id}-fg)`;
|
|
18
|
+
};
|
|
19
|
+
export const assertBadgeColor = (root, id) => {
|
|
20
|
+
if (id === null || window.getComputedStyle(root).getPropertyValue(`--sinch-badge-color-${id}-bg`).length === 0) {
|
|
21
|
+
throw new Error(`Invalid sinch-badge color name: ${id}`);
|
|
22
|
+
}
|
|
23
|
+
};
|
package/button/index.js
CHANGED
|
@@ -6,7 +6,6 @@ template.innerHTML = templateHTML;
|
|
|
6
6
|
defineCustomElement('sinch-button', class extends NectaryElement {
|
|
7
7
|
#$button;
|
|
8
8
|
#$text;
|
|
9
|
-
|
|
10
9
|
constructor() {
|
|
11
10
|
super();
|
|
12
11
|
const shadowRoot = this.attachShadow();
|
|
@@ -14,7 +13,6 @@ defineCustomElement('sinch-button', class extends NectaryElement {
|
|
|
14
13
|
this.#$button = shadowRoot.querySelector('#button');
|
|
15
14
|
this.#$text = shadowRoot.querySelector('#text');
|
|
16
15
|
}
|
|
17
|
-
|
|
18
16
|
connectedCallback() {
|
|
19
17
|
this.setAttribute('role', 'button');
|
|
20
18
|
this.#$button.addEventListener('click', this.#onButtonClick);
|
|
@@ -24,7 +22,6 @@ defineCustomElement('sinch-button', class extends NectaryElement {
|
|
|
24
22
|
this.addEventListener('-focus', this.#onFocusReactHandler);
|
|
25
23
|
this.addEventListener('-blur', this.#onBlurReactHandler);
|
|
26
24
|
}
|
|
27
|
-
|
|
28
25
|
disconnectedCallback() {
|
|
29
26
|
this.#$button.removeEventListener('click', this.#onButtonClick);
|
|
30
27
|
this.#$button.removeEventListener('focus', this.#onButtonFocus);
|
|
@@ -33,11 +30,9 @@ defineCustomElement('sinch-button', class extends NectaryElement {
|
|
|
33
30
|
this.removeEventListener('-focus', this.#onFocusReactHandler);
|
|
34
31
|
this.removeEventListener('-blur', this.#onBlurReactHandler);
|
|
35
32
|
}
|
|
36
|
-
|
|
37
33
|
static get observedAttributes() {
|
|
38
34
|
return ['text', 'disabled'];
|
|
39
35
|
}
|
|
40
|
-
|
|
41
36
|
attributeChangedCallback(name, _, newVal) {
|
|
42
37
|
switch (name) {
|
|
43
38
|
case 'text':
|
|
@@ -45,7 +40,6 @@ defineCustomElement('sinch-button', class extends NectaryElement {
|
|
|
45
40
|
this.#$text.textContent = newVal;
|
|
46
41
|
break;
|
|
47
42
|
}
|
|
48
|
-
|
|
49
43
|
case 'disabled':
|
|
50
44
|
{
|
|
51
45
|
const isDisabled = isAttrTrue(newVal);
|
|
@@ -55,51 +49,39 @@ defineCustomElement('sinch-button', class extends NectaryElement {
|
|
|
55
49
|
}
|
|
56
50
|
}
|
|
57
51
|
}
|
|
58
|
-
|
|
59
52
|
set type(value) {
|
|
60
53
|
updateLiteralAttribute(this, buttonTypes, 'type', value);
|
|
61
54
|
}
|
|
62
|
-
|
|
63
55
|
get type() {
|
|
64
56
|
return getLiteralAttribute(this, buttonTypes, 'type', 'primary');
|
|
65
57
|
}
|
|
66
|
-
|
|
67
58
|
set text(value) {
|
|
68
59
|
updateAttribute(this, 'text', value);
|
|
69
60
|
}
|
|
70
|
-
|
|
71
61
|
get text() {
|
|
72
62
|
return getAttribute(this, 'text', '');
|
|
73
63
|
}
|
|
74
|
-
|
|
75
64
|
set disabled(isDisabled) {
|
|
76
65
|
updateBooleanAttribute(this, 'disabled', isDisabled);
|
|
77
66
|
}
|
|
78
|
-
|
|
79
67
|
get disabled() {
|
|
80
68
|
return getBooleanAttribute(this, 'disabled');
|
|
81
69
|
}
|
|
82
|
-
|
|
83
70
|
set small(isSmall) {
|
|
84
71
|
updateBooleanAttribute(this, 'small', isSmall);
|
|
85
72
|
}
|
|
86
|
-
|
|
87
73
|
get small() {
|
|
88
74
|
return getBooleanAttribute(this, 'small');
|
|
89
75
|
}
|
|
90
|
-
|
|
91
76
|
get focusable() {
|
|
92
77
|
return true;
|
|
93
78
|
}
|
|
94
|
-
|
|
95
79
|
focus() {
|
|
96
80
|
this.#$button.focus();
|
|
97
81
|
}
|
|
98
|
-
|
|
99
82
|
blur() {
|
|
100
83
|
this.#$button.blur();
|
|
101
84
|
}
|
|
102
|
-
|
|
103
85
|
#onButtonClick = () => {
|
|
104
86
|
this.dispatchEvent(new CustomEvent('-click'));
|
|
105
87
|
};
|
package/card/index.js
CHANGED
|
@@ -10,7 +10,6 @@ defineCustomElement('sinch-card', class extends NectaryElement {
|
|
|
10
10
|
#$caption;
|
|
11
11
|
#$illustrationSlot;
|
|
12
12
|
#$illustrationSlotWrapper;
|
|
13
|
-
|
|
14
13
|
constructor() {
|
|
15
14
|
super();
|
|
16
15
|
const shadowRoot = this.attachShadow();
|
|
@@ -21,19 +20,15 @@ defineCustomElement('sinch-card', class extends NectaryElement {
|
|
|
21
20
|
this.#$illustrationSlot = shadowRoot.querySelector('slot[name="illustration"]');
|
|
22
21
|
this.#$illustrationSlotWrapper = shadowRoot.querySelector('#illustration-wrapper');
|
|
23
22
|
}
|
|
24
|
-
|
|
25
23
|
connectedCallback() {
|
|
26
24
|
this.#$illustrationSlot.addEventListener('slotchange', this.#onIllustrationSlotChange);
|
|
27
25
|
}
|
|
28
|
-
|
|
29
26
|
disconnectedCallback() {
|
|
30
27
|
this.#$illustrationSlot.removeEventListener('slotchange', this.#onIllustrationSlotChange);
|
|
31
28
|
}
|
|
32
|
-
|
|
33
29
|
static get observedAttributes() {
|
|
34
30
|
return ['text', 'label', 'caption', 'disabled'];
|
|
35
31
|
}
|
|
36
|
-
|
|
37
32
|
attributeChangedCallback(name, _, newVal) {
|
|
38
33
|
switch (name) {
|
|
39
34
|
case 'text':
|
|
@@ -41,13 +36,11 @@ defineCustomElement('sinch-card', class extends NectaryElement {
|
|
|
41
36
|
this.#$text.textContent = newVal;
|
|
42
37
|
break;
|
|
43
38
|
}
|
|
44
|
-
|
|
45
39
|
case 'label':
|
|
46
40
|
{
|
|
47
41
|
this.#$label.textContent = newVal;
|
|
48
42
|
break;
|
|
49
43
|
}
|
|
50
|
-
|
|
51
44
|
case 'caption':
|
|
52
45
|
{
|
|
53
46
|
updateAttribute(this.#$caption, 'text', newVal);
|
|
@@ -55,39 +48,30 @@ defineCustomElement('sinch-card', class extends NectaryElement {
|
|
|
55
48
|
}
|
|
56
49
|
}
|
|
57
50
|
}
|
|
58
|
-
|
|
59
51
|
set text(value) {
|
|
60
52
|
updateAttribute(this, 'text', value);
|
|
61
53
|
}
|
|
62
|
-
|
|
63
54
|
get text() {
|
|
64
55
|
return getAttribute(this, 'text', '');
|
|
65
56
|
}
|
|
66
|
-
|
|
67
57
|
set caption(value) {
|
|
68
58
|
updateAttribute(this, 'caption', value);
|
|
69
59
|
}
|
|
70
|
-
|
|
71
60
|
get caption() {
|
|
72
61
|
return getAttribute(this, 'caption', '');
|
|
73
62
|
}
|
|
74
|
-
|
|
75
63
|
set label(value) {
|
|
76
64
|
updateAttribute(this, 'label', value);
|
|
77
65
|
}
|
|
78
|
-
|
|
79
66
|
get label() {
|
|
80
67
|
return getAttribute(this, 'label', '');
|
|
81
68
|
}
|
|
82
|
-
|
|
83
69
|
set disabled(isDisabled) {
|
|
84
70
|
updateBooleanAttribute(this, 'disabled', isDisabled);
|
|
85
71
|
}
|
|
86
|
-
|
|
87
72
|
get disabled() {
|
|
88
73
|
return getBooleanAttribute(this, 'disabled');
|
|
89
74
|
}
|
|
90
|
-
|
|
91
75
|
#onIllustrationSlotChange = () => {
|
|
92
76
|
setClass(this.#$illustrationSlotWrapper, 'active', this.#$illustrationSlot.assignedElements().length > 0);
|
|
93
77
|
};
|
package/card/types.d.ts
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
import type { TSinchElementReact } from '../types';
|
|
2
2
|
export declare type TSinchCardElement = HTMLElement & {
|
|
3
|
+
/** Text */
|
|
3
4
|
text: string;
|
|
4
|
-
|
|
5
|
+
/** Caption */
|
|
5
6
|
caption: string;
|
|
7
|
+
/** Label */
|
|
8
|
+
label: string | null;
|
|
9
|
+
/** Disabled */
|
|
6
10
|
disabled: boolean;
|
|
11
|
+
/** Text */
|
|
7
12
|
setAttribute(name: 'text', value: string): void;
|
|
8
|
-
|
|
13
|
+
/** Caption */
|
|
9
14
|
setAttribute(name: 'caption', value: string): void;
|
|
15
|
+
/** Label */
|
|
16
|
+
setAttribute(name: 'label', value: string): void;
|
|
17
|
+
/** Disabled */
|
|
10
18
|
setAttribute(name: 'disabled', value: ''): void;
|
|
11
19
|
};
|
|
12
20
|
export declare type TSinchCardReact = TSinchElementReact<TSinchCardElement> & {
|
|
21
|
+
/** Text */
|
|
13
22
|
text: string;
|
|
14
|
-
|
|
23
|
+
/** Caption */
|
|
15
24
|
caption: string;
|
|
25
|
+
/** Label */
|
|
26
|
+
label?: string;
|
|
27
|
+
/** Disabled */
|
|
16
28
|
disabled?: boolean;
|
|
17
29
|
};
|
package/card-container/index.js
CHANGED