@nectary/components 2.1.4 → 2.2.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/action-menu/index.js +2 -3
- package/action-menu-option/index.js +1 -0
- package/avatar/index.js +1 -1
- package/button/index.js +4 -5
- package/card/index.js +3 -2
- package/checkbox/index.js +28 -32
- package/chip/index.js +3 -4
- package/color-menu/index.js +3 -5
- package/color-swatch/index.js +1 -1
- package/date-picker/index.js +11 -9
- package/date-picker/utils.d.ts +1 -0
- package/date-picker/utils.js +8 -0
- package/dialog/index.js +3 -2
- package/emoji/index.js +1 -1
- package/emoji-picker/index.js +2 -1
- package/field/index.js +2 -1
- package/flag/index.js +1 -1
- package/help-tooltip/index.js +1 -0
- package/icon-button/index.js +4 -5
- package/input/index.js +374 -41
- package/input/types.d.ts +14 -0
- package/input/utils.d.ts +24 -0
- package/input/utils.js +302 -1
- package/package.json +1 -1
- package/pop/index.js +5 -5
- package/popover/index.js +1 -0
- package/progress-stepper/index.d.ts +11 -0
- package/progress-stepper/index.js +209 -0
- package/progress-stepper/types.d.ts +22 -0
- package/progress-stepper/types.js +1 -0
- package/progress-stepper-item/index.d.ts +12 -0
- package/progress-stepper-item/index.js +82 -0
- package/progress-stepper-item/types.d.ts +23 -0
- package/progress-stepper-item/types.js +1 -0
- package/progress-stepper-item/utils.d.ts +11 -0
- package/progress-stepper-item/utils.js +13 -0
- package/select-button/index.js +3 -4
- package/select-menu/index.js +3 -4
- package/spinner/index.js +1 -0
- package/stop-events/index.js +1 -0
- package/tabs/index.js +1 -0
- package/tabs-icon-option/index.js +5 -3
- package/tabs-option/index.js +5 -3
- package/tag/index.js +1 -1
- package/textarea/index.js +5 -2
- package/time-picker/index.js +1 -0
- package/time-picker/utils.js +2 -15
- package/toggle/index.js +28 -31
- package/tooltip/index.js +4 -3
- package/utils/countries.d.ts +1 -0
- package/utils/countries.json +487 -268
- package/utils/element.d.ts +1 -1
- package/utils/element.js +6 -6
- package/utils/event-target.d.ts +1 -0
- package/utils/event-target.js +9 -0
- package/utils/get-react-event-handler.js +1 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import '../text';
|
|
2
|
+
import { defineCustomElement, getAttribute, getBooleanAttribute, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute } from '../utils';
|
|
3
|
+
const templateHTML = '<style>:host{display:block;outline:0}#button{position:relative;display:flex;flex-direction:column;gap:4px;width:100%;height:100%;padding:8px 4px 4px;box-sizing:border-box;cursor:pointer;border-radius:var(--sinch-comp-progress-stepper-step-shape-radius)}:host([data-status=inactive])>#button{cursor:not-allowed}:host([data-status=incomplete]:hover)>#button{background-color:var(--sinch-comp-progress-stepper-step-color-incomplete-background-hover)}:host([data-status=complete]:hover)>#button{background-color:var(--sinch-comp-progress-stepper-step-color-complete-background-hover)}:host([data-status=invalid]:hover)>#button{background-color:var(--sinch-comp-progress-stepper-step-color-invalid-background-hover)}#outline{position:absolute;inset:-2px;border:2px solid var(--sinch-comp-progress-stepper-step-color-outline-focus);border-radius:calc(var(--sinch-comp-progress-stepper-step-shape-radius) + 2px);pointer-events:none;opacity:0}:host(:focus-visible) #outline{opacity:1}#text{flex-shrink:1;flex-basis:auto;min-width:0;transform:translate(0,0);will-change:transform;transition:transform .25s ease-out;padding-right:24px}:host([data-status=incomplete]) #text{--sinch-global-color-text:var(--sinch-comp-progress-stepper-step-color-incomplete-label-default);--sinch-comp-text-font:var(--sinch-comp-progress-stepper-step-font-incomplete-label)}:host([data-status=complete]) #text{--sinch-global-color-text:var(--sinch-comp-progress-stepper-step-color-complete-label-default);--sinch-comp-text-font:var(--sinch-comp-progress-stepper-step-font-complete-label)}:host([data-status=inactive]) #text{--sinch-global-color-text:var(--sinch-comp-progress-stepper-step-color-inactive-label-default);--sinch-comp-text-font:var(--sinch-comp-progress-stepper-step-font-inactive-label)}:host([invalid]) #text{--sinch-global-color-text:var(--sinch-comp-progress-stepper-step-color-invalid-label-default);--sinch-comp-text-font:var(--sinch-comp-progress-stepper-step-font-invalid-label);transform:translate(24px,0)}:host([data-status=incomplete][data-checked]) #text{--sinch-global-color-text:var(--sinch-comp-progress-stepper-step-color-incomplete-current-label-default);--sinch-comp-text-font:var(--sinch-comp-progress-stepper-step-font-incomplete-current-label)}:host([data-status=complete][data-checked]) #text{--sinch-global-color-text:var(--sinch-comp-progress-stepper-step-color-complete-current-label-default);--sinch-comp-text-font:var(--sinch-comp-progress-stepper-step-font-complete-current-label)}:host([invalid][data-checked]) #text{--sinch-global-color-text:var(--sinch-comp-progress-stepper-step-color-invalid-label-default);--sinch-comp-text-font:var(--sinch-comp-progress-stepper-step-font-invalid-current-label)}#icon-error{position:absolute;left:0;top:4px;pointer-events:none;opacity:0;transition:opacity .25s ease-in-out;--sinch-global-color-icon:var(--sinch-comp-progress-stepper-step-color-invalid-icon-default);--sinch-global-size-icon:16px}:host([invalid]) #icon-error{opacity:1}#progress{height:8px;border-radius:4px;transition:background-color .25s ease-in-out}:host([data-status=incomplete]) #progress{background-color:var(--sinch-comp-progress-stepper-step-color-incomplete-progress-background)}:host([data-status=complete]) #progress{background-color:var(--sinch-comp-progress-stepper-step-color-complete-progress-background)}:host([data-status=inactive]) #progress{background-color:var(--sinch-comp-progress-stepper-step-color-inactive-progress-background)}:host([invalid]) #progress{background-color:var(--sinch-comp-progress-stepper-step-color-invalid-progress-background)}#bar{width:8px;height:8px;border-radius:4px;opacity:0;transition:width .25s ease-in-out,opacity .25s ease-in-out}:host([data-status=incomplete]) #bar{background-color:var(--sinch-comp-progress-stepper-step-color-incomplete-progress-bar)}:host([data-status=complete]) #bar{background-color:var(--sinch-comp-progress-stepper-step-color-complete-progress-bar);width:100%}:host([data-status=complete]:not([invalid])) #bar,:host([data-status=incomplete]:not([invalid])) #bar{opacity:1}#label-bar{position:relative}</style><div id="button"><div id="progress"><div id="bar"></div></div><div id="label-bar"><sinch-icon id="icon-error" name="report_problem" aria-hidden="true"></sinch-icon><sinch-text id="text" type="m"></sinch-text></div><div id="outline"></div></div>';
|
|
4
|
+
import { ATTR_PROGRESS_STEPPER_ITEM_ACTIVE_DESCENDANT, ATTR_PROGRESS_STEPPER_ITEM_CHECKED, ATTR_PROGRESS_STEPPER_ITEM_STATUS, isProgressStepperItemActive, isProgressStepperItemActiveDescendant } from './utils';
|
|
5
|
+
const template = document.createElement('template');
|
|
6
|
+
template.innerHTML = templateHTML;
|
|
7
|
+
defineCustomElement('sinch-progress-stepper-item', class extends NectaryElement {
|
|
8
|
+
#$text;
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
const shadowRoot = this.attachShadow({
|
|
12
|
+
delegatesFocus: false
|
|
13
|
+
});
|
|
14
|
+
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
15
|
+
this.#$text = shadowRoot.querySelector('#text');
|
|
16
|
+
}
|
|
17
|
+
connectedCallback() {
|
|
18
|
+
this.role = 'tab';
|
|
19
|
+
}
|
|
20
|
+
disconnectedCallback() {}
|
|
21
|
+
static get observedAttributes() {
|
|
22
|
+
return ['text', 'invalid', ATTR_PROGRESS_STEPPER_ITEM_STATUS, ATTR_PROGRESS_STEPPER_ITEM_CHECKED, ATTR_PROGRESS_STEPPER_ITEM_ACTIVE_DESCENDANT];
|
|
23
|
+
}
|
|
24
|
+
attributeChangedCallback(name, oldVal, newVal) {
|
|
25
|
+
if (oldVal === newVal) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
switch (name) {
|
|
29
|
+
case 'text':
|
|
30
|
+
{
|
|
31
|
+
this.#$text.textContent = newVal;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case ATTR_PROGRESS_STEPPER_ITEM_CHECKED:
|
|
35
|
+
{
|
|
36
|
+
updateExplicitBooleanAttribute(this, 'aria-selected', isAttrTrue(newVal));
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case ATTR_PROGRESS_STEPPER_ITEM_STATUS:
|
|
40
|
+
{
|
|
41
|
+
this.#updateTabIndex();
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
case ATTR_PROGRESS_STEPPER_ITEM_ACTIVE_DESCENDANT:
|
|
45
|
+
{
|
|
46
|
+
this.#updateTabIndex();
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case 'invalid':
|
|
50
|
+
{
|
|
51
|
+
const isInvalid = isAttrTrue(newVal);
|
|
52
|
+
updateBooleanAttribute(this, 'invalid', isInvalid);
|
|
53
|
+
updateExplicitBooleanAttribute(this, 'aria-invalid', isInvalid);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
set value(value) {
|
|
59
|
+
updateAttribute(this, 'value', value);
|
|
60
|
+
}
|
|
61
|
+
get value() {
|
|
62
|
+
return getAttribute(this, 'value', '');
|
|
63
|
+
}
|
|
64
|
+
set text(value) {
|
|
65
|
+
updateAttribute(this, 'text', value);
|
|
66
|
+
}
|
|
67
|
+
get text() {
|
|
68
|
+
return getAttribute(this, 'text', '');
|
|
69
|
+
}
|
|
70
|
+
set invalid(isInvalid) {
|
|
71
|
+
updateBooleanAttribute(this, 'invalid', isInvalid);
|
|
72
|
+
}
|
|
73
|
+
get invalid() {
|
|
74
|
+
return getBooleanAttribute(this, 'invalid');
|
|
75
|
+
}
|
|
76
|
+
get focusable() {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
#updateTabIndex() {
|
|
80
|
+
this.tabIndex = isProgressStepperItemActiveDescendant(this) && isProgressStepperItemActive(this) ? 0 : -1;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TSinchElementReact } from '../types';
|
|
2
|
+
export type TSinchProgressStepperItemElement = HTMLElement & {
|
|
3
|
+
/** Value */
|
|
4
|
+
value: string;
|
|
5
|
+
/** Text */
|
|
6
|
+
text: string;
|
|
7
|
+
/** Invalid */
|
|
8
|
+
invalid: boolean;
|
|
9
|
+
/** Value */
|
|
10
|
+
setAttribute(name: 'value', value: string): void;
|
|
11
|
+
/** Text */
|
|
12
|
+
setAttribute(name: 'text', value: string): void;
|
|
13
|
+
/** Invalid */
|
|
14
|
+
setAttribute(name: 'invalid', value: ''): void;
|
|
15
|
+
};
|
|
16
|
+
export type TSinchProgressStepperItemReact = TSinchElementReact<TSinchProgressStepperItemElement> & {
|
|
17
|
+
/** Value */
|
|
18
|
+
value: string;
|
|
19
|
+
/** Text */
|
|
20
|
+
text: string;
|
|
21
|
+
/** Invalid */
|
|
22
|
+
invalid?: boolean;
|
|
23
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type TSinchProgressStepperItemStatus = 'inactive' | 'incomplete' | 'invalid' | 'complete';
|
|
2
|
+
export declare const ATTR_PROGRESS_STEPPER_ITEM_CHECKED = "data-checked";
|
|
3
|
+
export declare const ATTR_PROGRESS_STEPPER_ITEM_STATUS = "data-status";
|
|
4
|
+
export declare const ATTR_PROGRESS_STEPPER_ITEM_ACTIVE_DESCENDANT = "data-active-descendant";
|
|
5
|
+
export declare const isProgressStepperItemChecked: ($el: Element) => boolean;
|
|
6
|
+
export declare const setProgressStepperItemChecked: ($el: Element, isChecked: boolean) => void;
|
|
7
|
+
export declare const isProgressStepperItemActive: ($el: Element) => boolean;
|
|
8
|
+
export declare const setProgressStepperItemStatus: ($el: Element, status: TSinchProgressStepperItemStatus) => void;
|
|
9
|
+
export declare const isProgressStepperItemActiveDescendant: ($el: Element) => boolean;
|
|
10
|
+
export declare const setProgressStepperItemActiveDescendant: ($el: Element, isActiveDescendant: boolean) => void;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getAttribute, getBooleanAttribute, updateAttribute, updateBooleanAttribute } from '../utils';
|
|
2
|
+
export const ATTR_PROGRESS_STEPPER_ITEM_CHECKED = 'data-checked';
|
|
3
|
+
export const ATTR_PROGRESS_STEPPER_ITEM_STATUS = 'data-status';
|
|
4
|
+
export const ATTR_PROGRESS_STEPPER_ITEM_ACTIVE_DESCENDANT = 'data-active-descendant';
|
|
5
|
+
export const isProgressStepperItemChecked = $el => getBooleanAttribute($el, ATTR_PROGRESS_STEPPER_ITEM_CHECKED);
|
|
6
|
+
export const setProgressStepperItemChecked = ($el, isChecked) => updateBooleanAttribute($el, ATTR_PROGRESS_STEPPER_ITEM_CHECKED, isChecked);
|
|
7
|
+
export const isProgressStepperItemActive = $el => {
|
|
8
|
+
const attrValue = getAttribute($el, ATTR_PROGRESS_STEPPER_ITEM_STATUS);
|
|
9
|
+
return attrValue !== null && attrValue !== 'inactive';
|
|
10
|
+
};
|
|
11
|
+
export const setProgressStepperItemStatus = ($el, status) => updateAttribute($el, ATTR_PROGRESS_STEPPER_ITEM_STATUS, status);
|
|
12
|
+
export const isProgressStepperItemActiveDescendant = $el => getBooleanAttribute($el, ATTR_PROGRESS_STEPPER_ITEM_ACTIVE_DESCENDANT);
|
|
13
|
+
export const setProgressStepperItemActiveDescendant = ($el, isActiveDescendant) => updateBooleanAttribute($el, ATTR_PROGRESS_STEPPER_ITEM_ACTIVE_DESCENDANT, isActiveDescendant);
|
package/select-button/index.js
CHANGED
|
@@ -15,9 +15,7 @@ defineCustomElement('sinch-select-button', class extends NectaryElement {
|
|
|
15
15
|
#sizeContext;
|
|
16
16
|
constructor() {
|
|
17
17
|
super();
|
|
18
|
-
const shadowRoot = this.attachShadow(
|
|
19
|
-
delegatesFocus: false
|
|
20
|
-
});
|
|
18
|
+
const shadowRoot = this.attachShadow();
|
|
21
19
|
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
22
20
|
this.#$text = shadowRoot.querySelector('#text');
|
|
23
21
|
this.#$placeholder = shadowRoot.querySelector('#placeholder');
|
|
@@ -66,6 +64,7 @@ defineCustomElement('sinch-select-button', class extends NectaryElement {
|
|
|
66
64
|
disconnectedCallback() {
|
|
67
65
|
super.disconnectedCallback();
|
|
68
66
|
this.#controller.abort();
|
|
67
|
+
this.#controller = null;
|
|
69
68
|
}
|
|
70
69
|
static get observedAttributes() {
|
|
71
70
|
return ['text', 'placeholder', 'invalid', 'disabled', 'size', 'data-size'];
|
|
@@ -160,7 +159,7 @@ defineCustomElement('sinch-select-button', class extends NectaryElement {
|
|
|
160
159
|
}
|
|
161
160
|
};
|
|
162
161
|
#onSizeUpdate() {
|
|
163
|
-
if (!this.
|
|
162
|
+
if (!this.isDomConnected) {
|
|
164
163
|
return;
|
|
165
164
|
}
|
|
166
165
|
const size = this.getAttribute('data-size') ?? DEFAULT_SIZE;
|
package/select-menu/index.js
CHANGED
|
@@ -18,9 +18,7 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
18
18
|
#searchDebounce;
|
|
19
19
|
constructor() {
|
|
20
20
|
super();
|
|
21
|
-
const shadowRoot = this.attachShadow(
|
|
22
|
-
delegatesFocus: false
|
|
23
|
-
});
|
|
21
|
+
const shadowRoot = this.attachShadow();
|
|
24
22
|
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
25
23
|
this.#$optionSlot = shadowRoot.querySelector('slot');
|
|
26
24
|
this.#$listbox = shadowRoot.querySelector('#listbox');
|
|
@@ -49,8 +47,9 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
49
47
|
this.#onOptionSlotChange();
|
|
50
48
|
}
|
|
51
49
|
disconnectedCallback() {
|
|
52
|
-
this.#controller.abort();
|
|
53
50
|
this.#searchDebounce.cancel();
|
|
51
|
+
this.#controller.abort();
|
|
52
|
+
this.#controller = null;
|
|
54
53
|
}
|
|
55
54
|
static get observedAttributes() {
|
|
56
55
|
return ['value', 'rows', 'multiple'];
|
package/spinner/index.js
CHANGED
package/stop-events/index.js
CHANGED
package/tabs/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
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;background-color:var(--sinch-comp-tab-color-default-background-initial);border-top-left-radius:var(--sinch-comp-tab-shape-radius);border-top-right-radius:var(--sinch-comp-tab-shape-radius);height:39px;--sinch-global-color-icon:var(--sinch-comp-tab-color-default-icon-initial);--sinch-global-size-icon:var(--sinch-comp-tab-size-icon)}#button:hover{background-color:var(--sinch-comp-tab-color-default-background-hover)}#button:focus-visible::
|
|
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;background-color:var(--sinch-comp-tab-color-default-background-initial);border-top-left-radius:var(--sinch-comp-tab-shape-radius);border-top-right-radius:var(--sinch-comp-tab-shape-radius);height:39px;--sinch-global-color-icon:var(--sinch-comp-tab-color-default-icon-initial);--sinch-global-size-icon:var(--sinch-comp-tab-size-icon)}#button:hover{background-color:var(--sinch-comp-tab-color-default-background-hover)}#button:focus-visible::after{content:"";position:absolute;inset:0;bottom:-3px;border:2px solid var(--sinch-comp-tab-color-default-outline-focus);border-top-left-radius:var(--sinch-comp-tab-shape-radius);border-top-right-radius:var(--sinch-comp-tab-shape-radius);pointer-events:none}#button:disabled{cursor:unset;pointer-events:none;--sinch-global-color-icon:var(--sinch-comp-tab-color-disabled-icon-initial)}:host([data-checked]) #button{--sinch-global-color-icon:var(--sinch-comp-tab-color-checked-icon-initial)}:host([data-checked]) #button::before{content:"";position:absolute;left:0;right:0;bottom:-1px;pointer-events:none;border-top:2px solid var(--sinch-comp-tab-color-checked-border-initial)}::slotted(*){display:block}</style><sinch-tooltip id="tooltip"><button id="button" tabindex="0"><slot name="icon"></slot></button></sinch-tooltip>';
|
|
3
3
|
const template = document.createElement('template');
|
|
4
4
|
template.innerHTML = templateHTML;
|
|
5
5
|
defineCustomElement('sinch-tabs-icon-option', class extends NectaryElement {
|
|
@@ -7,13 +7,15 @@ defineCustomElement('sinch-tabs-icon-option', class extends NectaryElement {
|
|
|
7
7
|
#$tooltip;
|
|
8
8
|
constructor() {
|
|
9
9
|
super();
|
|
10
|
-
const shadowRoot = this.attachShadow(
|
|
10
|
+
const shadowRoot = this.attachShadow({
|
|
11
|
+
delegatesFocus: true
|
|
12
|
+
});
|
|
11
13
|
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
12
14
|
this.#$button = shadowRoot.querySelector('#button');
|
|
13
15
|
this.#$tooltip = shadowRoot.querySelector('#tooltip');
|
|
14
16
|
}
|
|
15
17
|
connectedCallback() {
|
|
16
|
-
this.
|
|
18
|
+
this.role = 'tab';
|
|
17
19
|
this.#$button.addEventListener('click', this.#onClick);
|
|
18
20
|
}
|
|
19
21
|
disconnectedCallback() {
|
package/tabs-option/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '../text';
|
|
2
2
|
import { defineCustomElement, getAttribute, getBooleanAttribute, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute } from '../utils';
|
|
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;background-color:var(--sinch-comp-tab-color-default-background-initial);border-top-left-radius:var(--sinch-comp-tab-shape-radius);border-top-right-radius:var(--sinch-comp-tab-shape-radius);height:39px;--sinch-global-color-text:var(--sinch-comp-tab-color-default-text-initial);--sinch-global-color-icon:var(--sinch-comp-tab-color-default-icon-initial);--sinch-global-size-icon:var(--sinch-comp-tab-size-icon)}#button:hover{background-color:var(--sinch-comp-tab-color-default-background-hover)}#button:focus-visible::
|
|
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;background-color:var(--sinch-comp-tab-color-default-background-initial);border-top-left-radius:var(--sinch-comp-tab-shape-radius);border-top-right-radius:var(--sinch-comp-tab-shape-radius);height:39px;--sinch-global-color-text:var(--sinch-comp-tab-color-default-text-initial);--sinch-global-color-icon:var(--sinch-comp-tab-color-default-icon-initial);--sinch-global-size-icon:var(--sinch-comp-tab-size-icon)}#button:hover{background-color:var(--sinch-comp-tab-color-default-background-hover)}#button:focus-visible::after{content:"";position:absolute;inset:0;bottom:-3px;border:2px solid var(--sinch-comp-tab-color-default-outline-focus);border-top-left-radius:var(--sinch-comp-tab-shape-radius);border-top-right-radius:var(--sinch-comp-tab-shape-radius);pointer-events:none}#button:disabled{cursor:unset;pointer-events:none;--sinch-global-color-text:var(--sinch-comp-tab-color-disabled-text-initial);--sinch-global-color-icon:var(--sinch-comp-tab-color-disabled-icon-initial)}:host([data-checked]) #button{--sinch-global-color-text:var(--sinch-comp-tab-color-checked-text-initial);--sinch-global-color-icon:var(--sinch-comp-tab-color-checked-icon-initial)}:host([data-checked]) #button::before{content:"";position:absolute;left:0;right:0;bottom:-1px;pointer-events:none;border-top:2px solid var(--sinch-comp-tab-color-checked-border-initial)}#text{flex-shrink:1;flex-basis:auto;min-width:0;--sinch-comp-text-font:var(--sinch-comp-tab-font-label)}::slotted(*){display:block}</style><button id="button" tabindex="0"><slot name="icon"></slot><sinch-text id="text" type="m" ellipsis></sinch-text></button>';
|
|
4
4
|
const template = document.createElement('template');
|
|
5
5
|
template.innerHTML = templateHTML;
|
|
6
6
|
defineCustomElement('sinch-tabs-option', class extends NectaryElement {
|
|
@@ -8,13 +8,15 @@ defineCustomElement('sinch-tabs-option', class extends NectaryElement {
|
|
|
8
8
|
#$text;
|
|
9
9
|
constructor() {
|
|
10
10
|
super();
|
|
11
|
-
const shadowRoot = this.attachShadow(
|
|
11
|
+
const shadowRoot = this.attachShadow({
|
|
12
|
+
delegatesFocus: true
|
|
13
|
+
});
|
|
12
14
|
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
13
15
|
this.#$button = shadowRoot.querySelector('#button');
|
|
14
16
|
this.#$text = shadowRoot.querySelector('#text');
|
|
15
17
|
}
|
|
16
18
|
connectedCallback() {
|
|
17
|
-
this.
|
|
19
|
+
this.role = 'tab';
|
|
18
20
|
this.#$button.addEventListener('click', this.#onClick);
|
|
19
21
|
}
|
|
20
22
|
disconnectedCallback() {
|
package/tag/index.js
CHANGED
package/textarea/index.js
CHANGED
|
@@ -13,7 +13,9 @@ defineCustomElement('sinch-textarea', class extends NectaryElement {
|
|
|
13
13
|
#sizeContext;
|
|
14
14
|
constructor() {
|
|
15
15
|
super();
|
|
16
|
-
const shadowRoot = this.attachShadow(
|
|
16
|
+
const shadowRoot = this.attachShadow({
|
|
17
|
+
delegatesFocus: true
|
|
18
|
+
});
|
|
17
19
|
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
18
20
|
this.#$input = shadowRoot.querySelector('#input');
|
|
19
21
|
this.#$bottomSlot = shadowRoot.querySelector('slot[name="bottom"]');
|
|
@@ -45,6 +47,7 @@ defineCustomElement('sinch-textarea', class extends NectaryElement {
|
|
|
45
47
|
disconnectedCallback() {
|
|
46
48
|
super.disconnectedCallback();
|
|
47
49
|
this.#controller.abort();
|
|
50
|
+
this.#controller = null;
|
|
48
51
|
}
|
|
49
52
|
static get observedAttributes() {
|
|
50
53
|
return ['value', 'placeholder', 'invalid', 'disabled', 'rows', 'resizable'];
|
|
@@ -201,7 +204,7 @@ defineCustomElement('sinch-textarea', class extends NectaryElement {
|
|
|
201
204
|
setClass(this.#$bottomWrapper, 'empty', isEmpty);
|
|
202
205
|
};
|
|
203
206
|
#onSizeUpdate() {
|
|
204
|
-
if (!this.
|
|
207
|
+
if (!this.isDomConnected) {
|
|
205
208
|
return;
|
|
206
209
|
}
|
|
207
210
|
const size = this.getAttribute('data-size') ?? DEFAULT_SIZE;
|
package/time-picker/index.js
CHANGED
|
@@ -105,6 +105,7 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
|
|
|
105
105
|
}
|
|
106
106
|
disconnectedCallback() {
|
|
107
107
|
this.#controller.abort();
|
|
108
|
+
this.#controller = null;
|
|
108
109
|
}
|
|
109
110
|
static get observedAttributes() {
|
|
110
111
|
return ['value', 'ampm', 'submit-aria-label'];
|
package/time-picker/utils.js
CHANGED
|
@@ -6,15 +6,8 @@ export const parseTime = value => {
|
|
|
6
6
|
};
|
|
7
7
|
}
|
|
8
8
|
const timeParts = value.split(':');
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
hours: 0,
|
|
12
|
-
minutes: 0
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
const hours = parseInt(timeParts[0]);
|
|
16
|
-
const minutes = parseInt(timeParts[1]);
|
|
17
|
-
const seconds = parseInt(timeParts[2]);
|
|
9
|
+
const hours = parseInt(timeParts[0] ?? '00');
|
|
10
|
+
const minutes = parseInt(timeParts[1] ?? '00');
|
|
18
11
|
if (isNaN(hours) || hours > 23 || hours < 0) {
|
|
19
12
|
return {
|
|
20
13
|
hours: 0,
|
|
@@ -27,12 +20,6 @@ export const parseTime = value => {
|
|
|
27
20
|
minutes: 0
|
|
28
21
|
};
|
|
29
22
|
}
|
|
30
|
-
if (isNaN(seconds) || seconds > 59 || seconds < 0) {
|
|
31
|
-
return {
|
|
32
|
-
hours: 0,
|
|
33
|
-
minutes: 0
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
23
|
return {
|
|
37
24
|
hours,
|
|
38
25
|
minutes
|
package/toggle/index.js
CHANGED
|
@@ -1,33 +1,36 @@
|
|
|
1
1
|
import { defineCustomElement, getAttribute, getBooleanAttribute, getReactEventHandler, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute } from '../utils';
|
|
2
|
-
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle}#wrapper{position:relative;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;width:100%;height:var(--sinch-local-size);--sinch-local-size:24px}:host([small]) #wrapper{--sinch-local-size:22px}#input{all:initial;display:block;position:absolute;left:0;top:2px;width:40px;height:20px;cursor:pointer;pointer-events:initial}#input
|
|
2
|
+
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}#wrapper{position:relative;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;width:100%;height:var(--sinch-local-size);--sinch-local-size:24px}:host([small]) #wrapper{--sinch-local-size:22px}#input{all:initial;display:block;position:absolute;left:0;top:2px;width:40px;height:20px;cursor:pointer;pointer-events:initial}:host([disabled]) #input{cursor:initial}:host(:focus-visible) #input::after{position:absolute;content:"";left:-4px;top:-4px;right:-4px;bottom:-4px;border:2px solid var(--sinch-comp-toggle-color-default-outline-focus);border-radius:18px;pointer-events:none}:host([small]) #input{width:32px;height:16px;top:3px}#knob-container{position:relative;box-sizing:border-box;width:40px;height:20px;border-radius:10px;pointer-events:none;padding:2px;background-color:var(--sinch-comp-toggle-color-default-background-initial);overflow:hidden}:host([small]) #knob-container{width:32px;height:16px;border-radius:8px}:host([checked]) #knob-container{background-color:var(--sinch-comp-toggle-color-checked-background-initial)}:host([disabled]) #knob-container{background-color:var(--sinch-comp-toggle-color-disabled-background-initial)}:host([checked][disabled]) #knob-container{background-color:var(--sinch-comp-toggle-color-checked-disabled-background-initial)}#knob{position:relative;box-sizing:border-box;width:16px;height:16px;border-radius:50%;background-color:var(--sinch-comp-toggle-color-default-knob-background-initial);box-shadow:var(--sinch-comp-toggle-shadow-knob-default);transform:translateX(0);transition:transform .1s ease-in-out;will-change:transform}:host([small]) #knob{width:12px;height:12px}:host([disabled]) #knob-container>#knob{box-shadow:var(--sinch-comp-toggle-shadow-knob-disabled)}:host([checked]) #knob-container>#knob{transform:translateX(20px)}:host([small][checked]) #knob-container>#knob{transform:translateX(16px)}#knob::after,#knob::before{font:var(--sinch-comp-toggle-font-size-m-inside-text);color:var(--sinch-comp-toggle-color-default-text-inside-initial);text-transform:uppercase;font-size:8px;line-height:16px;display:none;position:absolute;top:0;padding:0 3px}#knob::before{content:"on";right:100%}#knob::after{content:"off";left:100%}:host([labeled]:not([small])) #knob::after,:host([labeled]:not([small])) #knob::before{display:block}@media (prefers-reduced-motion){#knob{transition:none}}#label{flex:1;align-self:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:8px;font:var(--sinch-comp-toggle-font-size-m-label);color:var(--sinch-comp-toggle-color-default-label-initial);cursor:pointer}#label:empty{display:none}:host([small]) #label{font:var(--sinch-comp-toggle-font-size-s-label)}:host([disabled]) #label{color:var(--sinch-comp-toggle-color-disabled-label-initial);cursor:initial}</style><div id="wrapper"><div id="input"></div><div id="knob-container"><div id="knob"></div></div><span id="label"></span></div>';
|
|
3
3
|
const template = document.createElement('template');
|
|
4
4
|
template.innerHTML = templateHTML;
|
|
5
5
|
defineCustomElement('sinch-toggle', class extends NectaryElement {
|
|
6
|
-
#$input;
|
|
7
6
|
#$label;
|
|
7
|
+
#controller = null;
|
|
8
8
|
constructor() {
|
|
9
9
|
super();
|
|
10
10
|
const shadowRoot = this.attachShadow();
|
|
11
11
|
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
12
|
-
this.#$input = shadowRoot.querySelector('#input');
|
|
13
12
|
this.#$label = shadowRoot.querySelector('#label');
|
|
14
13
|
}
|
|
15
14
|
connectedCallback() {
|
|
16
|
-
this
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
this.#controller = new AbortController();
|
|
16
|
+
const {
|
|
17
|
+
signal
|
|
18
|
+
} = this.#controller;
|
|
19
|
+
const options = {
|
|
20
|
+
signal
|
|
21
|
+
};
|
|
22
|
+
this.role = 'checkbox';
|
|
23
|
+
this.tabIndex = 0;
|
|
24
|
+
this.addEventListener('click', this.#onClick, options);
|
|
25
|
+
this.addEventListener('focus', this.#onFocus, options);
|
|
26
|
+
this.addEventListener('blur', this.#onBlur, options);
|
|
27
|
+
this.addEventListener('-change', this.#onChangeReactHandler, options);
|
|
28
|
+
this.addEventListener('-focus', this.#onFocusReactHandler, options);
|
|
29
|
+
this.addEventListener('-blur', this.#onBlurReactHandler, options);
|
|
23
30
|
}
|
|
24
31
|
disconnectedCallback() {
|
|
25
|
-
this
|
|
26
|
-
this
|
|
27
|
-
this.#$input.removeEventListener('blur', this.#onCheckboxBlur);
|
|
28
|
-
this.removeEventListener('-change', this.#onChangeReactHandler);
|
|
29
|
-
this.removeEventListener('-focus', this.#onFocusReactHandler);
|
|
30
|
-
this.removeEventListener('-blur', this.#onBlurReactHandler);
|
|
32
|
+
this.#controller.abort();
|
|
33
|
+
this.#controller = null;
|
|
31
34
|
}
|
|
32
35
|
static get observedAttributes() {
|
|
33
36
|
return ['checked', 'disabled', 'text', 'labeled', 'small'];
|
|
@@ -45,14 +48,14 @@ defineCustomElement('sinch-toggle', class extends NectaryElement {
|
|
|
45
48
|
case 'checked':
|
|
46
49
|
{
|
|
47
50
|
const isChecked = isAttrTrue(newVal);
|
|
48
|
-
this.#$input.checked = isChecked;
|
|
49
51
|
updateExplicitBooleanAttribute(this, 'aria-checked', isChecked);
|
|
52
|
+
updateBooleanAttribute(this, name, isChecked);
|
|
50
53
|
break;
|
|
51
54
|
}
|
|
52
55
|
case 'disabled':
|
|
53
56
|
{
|
|
54
57
|
const isDisabled = isAttrTrue(newVal);
|
|
55
|
-
this
|
|
58
|
+
updateExplicitBooleanAttribute(this, 'aria-disabled', isDisabled);
|
|
56
59
|
updateBooleanAttribute(this, name, isDisabled);
|
|
57
60
|
break;
|
|
58
61
|
}
|
|
@@ -97,24 +100,18 @@ defineCustomElement('sinch-toggle', class extends NectaryElement {
|
|
|
97
100
|
get focusable() {
|
|
98
101
|
return true;
|
|
99
102
|
}
|
|
100
|
-
|
|
101
|
-
this
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
this.#$input.blur();
|
|
105
|
-
}
|
|
106
|
-
#onInput = e => {
|
|
107
|
-
e.stopPropagation();
|
|
108
|
-
const isChecked = this.#$input.checked;
|
|
109
|
-
this.#$input.checked = this.checked;
|
|
103
|
+
#onClick = () => {
|
|
104
|
+
if (this.disabled) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
110
107
|
this.dispatchEvent(new CustomEvent('-change', {
|
|
111
|
-
detail:
|
|
108
|
+
detail: !this.checked
|
|
112
109
|
}));
|
|
113
110
|
};
|
|
114
|
-
#
|
|
111
|
+
#onFocus = () => {
|
|
115
112
|
this.dispatchEvent(new CustomEvent('-focus'));
|
|
116
113
|
};
|
|
117
|
-
#
|
|
114
|
+
#onBlur = () => {
|
|
118
115
|
this.dispatchEvent(new CustomEvent('-blur'));
|
|
119
116
|
};
|
|
120
117
|
#onChangeReactHandler = e => {
|
package/tooltip/index.js
CHANGED
|
@@ -57,9 +57,10 @@ defineCustomElement('sinch-tooltip', class extends NectaryElement {
|
|
|
57
57
|
this.#updateText();
|
|
58
58
|
}
|
|
59
59
|
disconnectedCallback() {
|
|
60
|
+
this.#tooltipState.destroy();
|
|
60
61
|
super.disconnectedCallback();
|
|
61
62
|
this.#controller.abort();
|
|
62
|
-
this.#
|
|
63
|
+
this.#controller = null;
|
|
63
64
|
}
|
|
64
65
|
static get observedAttributes() {
|
|
65
66
|
return ['text', 'orientation', 'type'];
|
|
@@ -191,7 +192,7 @@ defineCustomElement('sinch-tooltip', class extends NectaryElement {
|
|
|
191
192
|
setClass(this.#$tip, 'hidden', rectOverlap(targetRect, contentRect));
|
|
192
193
|
};
|
|
193
194
|
#updateText() {
|
|
194
|
-
if (!this.
|
|
195
|
+
if (!this.isDomConnected) {
|
|
195
196
|
return;
|
|
196
197
|
}
|
|
197
198
|
const text = this.text;
|
|
@@ -206,7 +207,7 @@ defineCustomElement('sinch-tooltip', class extends NectaryElement {
|
|
|
206
207
|
}
|
|
207
208
|
}
|
|
208
209
|
#subscribeMouseEnterEvent() {
|
|
209
|
-
if (!this.
|
|
210
|
+
if (!this.isDomConnected || this.#isSubscribed) {
|
|
210
211
|
return;
|
|
211
212
|
}
|
|
212
213
|
this.#$target.addEventListener('mouseenter', this.#onMouseEnter, {
|