@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.
Files changed (69) hide show
  1. package/accordion/index.js +3 -3
  2. package/action-menu/index.js +1 -2
  3. package/card-container/index.js +1 -1
  4. package/color-menu/index.d.ts +3 -3
  5. package/color-menu/index.js +2 -3
  6. package/color-menu/types.d.ts +2 -2
  7. package/date-picker/index.js +173 -64
  8. package/date-picker/types.d.ts +6 -0
  9. package/date-picker/utils.d.ts +6 -3
  10. package/date-picker/utils.js +19 -4
  11. package/dialog/index.js +2 -2
  12. package/emoji/index.d.ts +11 -0
  13. package/emoji/index.js +47 -0
  14. package/emoji/types.d.ts +11 -0
  15. package/emoji/types.js +1 -0
  16. package/emoji/utils.d.ts +1 -0
  17. package/emoji/utils.js +46 -0
  18. package/emoji-picker/index.d.ts +28 -0
  19. package/emoji-picker/index.js +319 -0
  20. package/emoji-picker/types.d.ts +25 -0
  21. package/emoji-picker/types.js +1 -0
  22. package/file-drop/types.d.ts +2 -2
  23. package/file-picker/types.d.ts +1 -1
  24. package/icon/index.d.ts +11 -0
  25. package/icon/index.js +32 -0
  26. package/icon/types.d.ts +11 -0
  27. package/icon/types.js +1 -0
  28. package/icon-button/index.js +1 -1
  29. package/package.json +2 -2
  30. package/pop/index.js +1 -2
  31. package/popover/index.js +1 -2
  32. package/segment/index.js +1 -1
  33. package/segmented-icon-control/index.js +3 -3
  34. package/select-menu/index.js +3 -4
  35. package/stop-events/index.js +3 -3
  36. package/tabs/index.js +24 -76
  37. package/tabs/types.d.ts +9 -2
  38. package/tabs-icon-option/index.d.ts +11 -0
  39. package/tabs-icon-option/index.js +75 -0
  40. package/tabs-icon-option/types.d.ts +19 -0
  41. package/tabs-icon-option/types.js +1 -0
  42. package/tabs-option/index.d.ts +1 -0
  43. package/tabs-option/index.js +8 -15
  44. package/tabs-option/types.d.ts +13 -5
  45. package/theme/emoji.css +6 -0
  46. package/theme/fonts.css +9 -0
  47. package/theme/fonts.json +9 -0
  48. package/theme/icon.css +7 -0
  49. package/theme.css +2 -0
  50. package/tile-control/index.js +3 -3
  51. package/tooltip/index.js +78 -31
  52. package/utils/csv.d.ts +5 -0
  53. package/utils/csv.js +22 -0
  54. package/utils/dom.d.ts +30 -0
  55. package/utils/dom.js +143 -0
  56. package/utils/element.d.ts +12 -0
  57. package/utils/element.js +38 -0
  58. package/utils/get-react-event-handler.d.ts +1 -0
  59. package/utils/get-react-event-handler.js +8 -0
  60. package/utils/index.d.ts +8 -57
  61. package/utils/index.js +8 -301
  62. package/utils/rect.d.ts +4 -0
  63. package/utils/rect.js +29 -0
  64. package/utils/slot.d.ts +4 -0
  65. package/utils/slot.js +38 -0
  66. package/utils/throttle.d.ts +4 -0
  67. package/utils/throttle.js +25 -0
  68. /package/{utils/animation.d.ts → tooltip/tooltip-state.d.ts} +0 -0
  69. /package/{utils/animation.js → tooltip/tooltip-state.js} +0 -0
@@ -1,5 +1,4 @@
1
- import { attrValueToPixels, defineCustomElement, getAttribute, getBooleanAttribute, getCsvSet, getFirstCsvValue, getIntegerAttribute, getReactEventHandler, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateCsv, updateExplicitBooleanAttribute, updateIntegerAttribute } from '../utils';
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 = getCsvSet(csv);
162
+ const values = unpackCsv(csv);
164
163
  for (const $option of this.#getOptionElements()) {
165
- const isChecked = !getBooleanAttribute($option, 'disabled') && values.has(getAttribute($option, 'value', ''));
164
+ const isChecked = !getBooleanAttribute($option, 'disabled') && values.includes(getAttribute($option, 'value', ''));
166
165
  updateBooleanAttribute($option, 'data-checked', isChecked);
167
166
  }
168
167
  } else {
@@ -1,17 +1,17 @@
1
- import { defineCustomElement, getCsvSet } from '../utils';
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 = getCsvSet(this.getAttribute('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 = getCsvSet(this.getAttribute('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;outline:0}#wrapper{display:flex;flex-direction:row;height:44px;width:100%;box-sizing:border-box}</style><div id="wrapper"><slot></slot></div>';
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('keydown', this.#onOptionKeyDown);
19
- this.#$slot.addEventListener('option-change', this.#onOptionChange);
20
- this.#$slot.addEventListener('slotchange', this.#onSlotChange);
21
- this.addEventListener('-change', this.#onChangeReactHandler);
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.#$slot.removeEventListener('keydown', this.#onOptionKeyDown);
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
- #onOptionKeyDown = e => {
51
- switch (e.code) {
52
- case 'ArrowUp':
53
- case 'ArrowLeft':
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 {};
@@ -1,3 +1,4 @@
1
+ import '../text';
1
2
  import type { TSinchTabsOptionElement, TSinchTabsOptionReact } from './types';
2
3
  declare global {
3
4
  namespace JSX {
@@ -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;outline:0}:host()>*{pointer-events:none}#wrapper{display:flex;flex-direction:row;align-items:center;gap:12px;position:relative;width:100%;height:42px;padding:8px 20px;box-sizing:border-box;box-shadow:0 1px 0 0 var(--sinch-color-stormy-100);color:var(--sinch-color-stormy-500);background-color:var(--sinch-color-snow-100);--sinch-color-icon:var(--sinch-color-stormy-500);--sinch-size-icon:16px}#content{font:var(--sinch-font-title-s);flex-shrink:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host([checked]:not([checked=false])) #wrapper{box-shadow:0 2px 0 0 var(--sinch-color-stormy-500)}#button{all:initial;position:absolute;left:0;top:0;box-sizing:border-box;width:100%;height:100%;cursor:pointer}#button:disabled{cursor:unset}:host([disabled]:not([disabled=false])) #wrapper{color:var(--sinch-color-stormy-100);--sinch-color-icon:var(--sinch-color-stormy-100)}</style><div id="wrapper"><slot name="icon"></slot><label for="input" id="content"></label><button id="button" type="radio"/></div>';
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
- #$label;
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.#$label = shadowRoot.querySelector('#content');
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', 'value'];
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.#$label.textContent = newVal;
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
- const isDisabled = isAttrTrue(newVal);
64
- this.#$button.disabled = isDisabled;
65
- updateBooleanAttribute(this, 'disabled', isDisabled);
58
+ this.#$button.disabled = isAttrTrue(newVal);
66
59
  break;
67
60
  }
68
61
  }
@@ -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
- disabled: boolean;
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
- setAttribute(name: 'disabled', value: ''): void;
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
- disabled?: boolean;
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
  };
@@ -0,0 +1,6 @@
1
+ :root,
2
+ :host {
3
+ --sinch-emoji-src-url: "https://twemoji.maxcdn.com/v/latest/svg/%s.svg";
4
+
5
+ /* --sinch-emoji-src-url: "https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/svg/%s.svg"; */
6
+ }
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
@@ -0,0 +1,7 @@
1
+ :root,
2
+ :host {
3
+ --sinch-icon-font-family: "Material Icons Outlined";
4
+ --sinch-icon-font-variation-settings: "FILL" 1;
5
+ --sinch-icon-font-feature-settings: "liga";
6
+ --sinch-icon-font-weight: 400;
7
+ }
package/theme.css CHANGED
@@ -10,6 +10,8 @@
10
10
  @import "theme/chip.css";
11
11
  @import "theme/color-swatch.css";
12
12
  @import "theme/tag.css";
13
+ @import "theme/emoji.css";
14
+ @import "theme/icon.css";
13
15
 
14
16
  :root,
15
17
  :host {
@@ -1,4 +1,4 @@
1
- import { defineCustomElement, getAttribute, getBooleanAttribute, getCsvSet, getFirstCsvValue, getIntegerAttribute, getReactEventHandler, NectaryElement, updateAttribute, updateBooleanAttribute, updateCsv, updateIntegerAttribute } from '../utils';
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 = getCsvSet(csv);
94
+ const values = unpackCsv(csv);
95
95
  for (const $option of this.#$slot.assignedElements()) {
96
- const isChecked = !getBooleanAttribute($option, 'disabled') && values.has(getAttribute($option, 'value', ''));
96
+ const isChecked = !getBooleanAttribute($option, 'disabled') && values.includes(getAttribute($option, 'value', ''));
97
97
  updateBooleanAttribute($option, 'data-checked', isChecked);
98
98
  }
99
99
  } else {