@nectary/components 0.39.0 → 0.41.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 (142) hide show
  1. package/accordion/index.js +47 -84
  2. package/accordion-item/index.js +30 -53
  3. package/action-menu/index.d.ts +0 -1
  4. package/action-menu/index.js +177 -223
  5. package/action-menu/types.d.ts +8 -18
  6. package/action-menu-option/index.d.ts +1 -0
  7. package/action-menu-option/index.js +52 -62
  8. package/action-menu-option/types.d.ts +9 -0
  9. package/action-menu-option/utils.d.ts +2 -0
  10. package/action-menu-option/utils.js +3 -0
  11. package/alert/index.js +6 -20
  12. package/avatar/index.js +12 -31
  13. package/avatar-badge/index.js +8 -22
  14. package/avatar-status/index.js +1 -1
  15. package/button/index.js +46 -92
  16. package/button/types.d.ts +1 -1
  17. package/card/index.js +21 -59
  18. package/chat-avatar/index.js +8 -22
  19. package/chat-block/index.js +29 -69
  20. package/chat-bubble/index.js +6 -20
  21. package/checkbox/index.js +59 -107
  22. package/chip/index.d.ts +13 -0
  23. package/chip/index.js +140 -0
  24. package/chip/types.d.ts +37 -0
  25. package/color-menu/index.d.ts +14 -0
  26. package/color-menu/index.js +450 -0
  27. package/color-menu/types.d.ts +36 -0
  28. package/color-menu/utils.d.ts +1 -0
  29. package/color-menu/utils.js +15 -0
  30. package/color-swatch/index.d.ts +13 -0
  31. package/color-swatch/index.js +60 -0
  32. package/color-swatch/types.d.ts +11 -0
  33. package/colors.json +61 -49
  34. package/date-picker/index.js +162 -293
  35. package/dialog/index.js +70 -142
  36. package/field/index.js +44 -65
  37. package/file-drop/index.js +123 -200
  38. package/file-picker/index.d.ts +0 -1
  39. package/file-picker/index.js +55 -108
  40. package/file-status/index.js +15 -39
  41. package/help-tooltip/index.js +11 -28
  42. package/horizontal-stepper/index.js +33 -59
  43. package/horizontal-stepper-item/index.js +13 -37
  44. package/icon-button/index.d.ts +1 -0
  45. package/icon-button/index.js +51 -85
  46. package/icon-button/types.d.ts +16 -2
  47. package/icons-channel/notify/index.d.ts +11 -0
  48. package/icons-channel/notify/index.js +4 -0
  49. package/illustrations/create-illustration-class.js +1 -1
  50. package/inline-alert/index.js +29 -81
  51. package/input/index.js +117 -222
  52. package/link/index.js +51 -97
  53. package/list-item/index.js +1 -1
  54. package/package.json +12 -14
  55. package/pagination/index.js +113 -163
  56. package/pop/index.d.ts +11 -0
  57. package/pop/index.js +391 -0
  58. package/pop/types.d.ts +35 -0
  59. package/pop/utils.d.ts +7 -0
  60. package/pop/utils.js +18 -0
  61. package/popover/index.d.ts +1 -0
  62. package/popover/index.js +105 -314
  63. package/popover/types.d.ts +8 -1
  64. package/popover/utils.d.ts +5 -0
  65. package/popover/utils.js +17 -1
  66. package/progress/index.js +9 -28
  67. package/radio/index.js +103 -169
  68. package/radio-option/index.js +28 -48
  69. package/segment/index.js +49 -130
  70. package/segment-collapse/index.js +28 -49
  71. package/segmented-control/index.js +36 -73
  72. package/segmented-control-option/index.js +45 -87
  73. package/segmented-icon-control/index.js +47 -84
  74. package/segmented-icon-control-option/index.js +42 -79
  75. package/select-button/index.d.ts +13 -0
  76. package/select-button/index.js +158 -0
  77. package/select-button/types.d.ts +43 -0
  78. package/select-menu/index.d.ts +11 -0
  79. package/select-menu/index.js +345 -0
  80. package/select-menu/types.d.ts +29 -0
  81. package/{dropdown-text-option → select-menu-option}/index.d.ts +5 -7
  82. package/select-menu-option/index.js +76 -0
  83. package/{select-option → select-menu-option}/types.d.ts +8 -9
  84. package/stop-events/index.js +7 -20
  85. package/table-head-cell/index.js +7 -21
  86. package/tabs/index.js +103 -165
  87. package/tabs-option/index.js +24 -44
  88. package/tag/index.d.ts +0 -1
  89. package/tag/index.js +35 -38
  90. package/tag/types.d.ts +12 -7
  91. package/textarea/index.js +96 -167
  92. package/theme.css +146 -49
  93. package/tile-control/index.js +55 -96
  94. package/tile-control-option/index.js +45 -87
  95. package/time-picker/index.js +216 -368
  96. package/title/index.js +6 -20
  97. package/toast/index.js +32 -70
  98. package/toast-manager/index.js +141 -217
  99. package/toggle/index.js +59 -107
  100. package/tooltip/index.d.ts +2 -0
  101. package/tooltip/index.js +160 -17
  102. package/tooltip/types.d.ts +13 -0
  103. package/tooltip/utils.d.ts +5 -0
  104. package/tooltip/utils.js +25 -1
  105. package/utils/animation.d.ts +17 -0
  106. package/utils/animation.js +142 -0
  107. package/utils/colors.d.ts +5 -0
  108. package/utils/colors.js +5 -0
  109. package/utils/context.d.ts +15 -0
  110. package/utils/context.js +57 -0
  111. package/{utils.d.ts → utils/index.d.ts} +15 -11
  112. package/{utils.js → utils/index.js} +104 -48
  113. package/vertical-stepper/index.js +29 -50
  114. package/vertical-stepper-item/index.js +13 -37
  115. package/dropdown/index.d.ts +0 -12
  116. package/dropdown/index.js +0 -415
  117. package/dropdown/types.d.ts +0 -32
  118. package/dropdown-checkbox-option/index.d.ts +0 -11
  119. package/dropdown-checkbox-option/index.js +0 -88
  120. package/dropdown-checkbox-option/types.d.ts +0 -15
  121. package/dropdown-radio-option/index.d.ts +0 -11
  122. package/dropdown-radio-option/index.js +0 -88
  123. package/dropdown-radio-option/types.d.ts +0 -15
  124. package/dropdown-text-option/index.js +0 -104
  125. package/dropdown-text-option/types.d.ts +0 -16
  126. package/select/index.d.ts +0 -13
  127. package/select/index.js +0 -316
  128. package/select/types.d.ts +0 -53
  129. package/select-option/index.d.ts +0 -11
  130. package/select-option/index.js +0 -8
  131. package/tag/utils.d.ts +0 -5
  132. package/tag/utils.js +0 -6
  133. package/tag-close/index.d.ts +0 -12
  134. package/tag-close/index.js +0 -42
  135. package/tag-close/types.d.ts +0 -5
  136. /package/{dropdown-checkbox-option → chip}/types.js +0 -0
  137. /package/{dropdown-radio-option → color-menu}/types.js +0 -0
  138. /package/{dropdown-text-option → color-swatch}/types.js +0 -0
  139. /package/{dropdown → pop}/types.js +0 -0
  140. /package/{select-option → select-button}/types.js +0 -0
  141. /package/{tag-close → select-menu}/types.js +0 -0
  142. /package/{select → select-menu-option}/types.js +0 -0
@@ -1,12 +1,3 @@
1
- import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
2
- import _classPrivateFieldSet from '@babel/runtime/helpers/classPrivateFieldSet';
3
-
4
- var _$filename, _$contentSlot, _onContentSlotChange;
5
-
6
- function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
7
-
8
- function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
9
-
10
1
  import '../spinner';
11
2
  import '../icons/check-circle';
12
3
  import '../icons/report';
@@ -14,47 +5,29 @@ import '../icons/pending-actions';
14
5
  import '../icons/text-snippet';
15
6
  import '../text';
16
7
  import { defineCustomElement, getAttribute, getLiteralAttribute, updateAttribute, updateLiteralAttribute, NectaryElement, updateBooleanAttribute } from '../utils';
17
- const templateHTML = '<style>:host{display:block}#wrapper{display:flex;flex-direction:row;align-items:flex-start;padding:12px 16px;box-sizing:border-box;min-height:48px;min-width:148px;background-color:var(--sinch-color-background-grey);border-radius:var(--sinch-shape-radius-m)}:host([type=error]) #wrapper{background-color:var(--sinch-color-error-200)}#content-wrapper{display:flex;flex-direction:column;gap:8px;flex:1;min-width:0;margin-left:16px;color:var(--sinch-color-stormy-500)}#icon-error,#icon-loading,#icon-pending,#icon-progress,#icon-success{display:none}#action{height:24px}#action ::slotted(*){position:relative;top:50%;transform:translateY(-50%)}:host([type=error]) #icon-error,:host([type=loading]) #icon-loading,:host([type=pending]) #icon-pending,:host([type=progress]) #icon-progress,:host([type=success]) #icon-success{display:block;--sinch-color-icon:var(--sinch-color-stormy-500)}:host([type=success]) #icon-success{--sinch-color-icon:var(--sinch-color-success-500)}:host([type=error]) #icon-error{--sinch-color-icon:var(--sinch-color-error-500)}</style><div id="wrapper"><sinch-spinner id="icon-loading" type="medium"></sinch-spinner><sinch-icon-check-circle id="icon-success"></sinch-icon-check-circle><sinch-icon-report id="icon-error"></sinch-icon-report><sinch-icon-pending-actions id="icon-pending"></sinch-icon-pending-actions><sinch-icon-text-snippet id="icon-progress"></sinch-icon-text-snippet><div id="content-wrapper"><sinch-text id="filename" type="m" ellipsis></sinch-text><slot name="content"></slot></div><div id="action"><slot name="action"></slot></div></div>';
8
+ const templateHTML = '<style>:host{display:block}#wrapper{display:flex;flex-direction:row;align-items:flex-start;padding:12px 16px;box-sizing:border-box;min-height:48px;min-width:148px;background-color:var(--sinch-color-bg-primary-contrast);border-radius:var(--sinch-shape-radius-m)}:host([type=error]) #wrapper{background-color:var(--sinch-color-error-200)}#content-wrapper{display:flex;flex-direction:column;gap:8px;flex:1;min-width:0;margin-left:16px;color:var(--sinch-color-stormy-500)}#icon-error,#icon-loading,#icon-pending,#icon-progress,#icon-success{display:none}#action{height:24px}#action ::slotted(*){position:relative;top:50%;transform:translateY(-50%)}:host([type=error]) #icon-error,:host([type=loading]) #icon-loading,:host([type=pending]) #icon-pending,:host([type=progress]) #icon-progress,:host([type=success]) #icon-success{display:block;--sinch-color-icon:var(--sinch-color-stormy-500)}:host([type=success]) #icon-success{--sinch-color-icon:var(--sinch-color-success-500)}:host([type=error]) #icon-error{--sinch-color-icon:var(--sinch-color-error-500)}</style><div id="wrapper"><sinch-spinner id="icon-loading" type="medium"></sinch-spinner><sinch-icon-check-circle id="icon-success"></sinch-icon-check-circle><sinch-icon-report id="icon-error"></sinch-icon-report><sinch-icon-pending-actions id="icon-pending"></sinch-icon-pending-actions><sinch-icon-text-snippet id="icon-progress"></sinch-icon-text-snippet><div id="content-wrapper"><sinch-text id="filename" type="m" ellipsis></sinch-text><slot name="content"></slot></div><div id="action"><slot name="action"></slot></div></div>';
18
9
  import { assertType, typeValues } from './utils';
19
10
  const template = document.createElement('template');
20
11
  template.innerHTML = templateHTML;
21
- defineCustomElement('sinch-file-status', (_$filename = new WeakMap(), _$contentSlot = new WeakMap(), _onContentSlotChange = new WeakMap(), class extends NectaryElement {
12
+ defineCustomElement('sinch-file-status', class extends NectaryElement {
13
+ #$filename;
14
+ #$contentSlot;
15
+
22
16
  constructor() {
23
17
  super();
24
-
25
- _classPrivateFieldInitSpec(this, _$filename, {
26
- writable: true,
27
- value: void 0
28
- });
29
-
30
- _classPrivateFieldInitSpec(this, _$contentSlot, {
31
- writable: true,
32
- value: void 0
33
- });
34
-
35
- _classPrivateFieldInitSpec(this, _onContentSlotChange, {
36
- writable: true,
37
- value: () => {
38
- updateBooleanAttribute(_classPrivateFieldGet(this, _$filename), 'emphasized', _classPrivateFieldGet(this, _$contentSlot).assignedElements().length > 0);
39
- }
40
- });
41
-
42
18
  const shadowRoot = this.attachShadow();
43
19
  shadowRoot.appendChild(template.content.cloneNode(true));
44
-
45
- _classPrivateFieldSet(this, _$filename, shadowRoot.querySelector('#filename'));
46
-
47
- _classPrivateFieldSet(this, _$contentSlot, shadowRoot.querySelector('slot[name="content"]'));
20
+ this.#$filename = shadowRoot.querySelector('#filename');
21
+ this.#$contentSlot = shadowRoot.querySelector('slot[name="content"]');
48
22
  }
49
23
 
50
24
  connectedCallback() {
51
- _classPrivateFieldGet(this, _$contentSlot).addEventListener('slotchange', _classPrivateFieldGet(this, _onContentSlotChange));
52
-
53
- _classPrivateFieldGet(this, _onContentSlotChange).call(this);
25
+ this.#$contentSlot.addEventListener('slotchange', this.#onContentSlotChange);
26
+ this.#onContentSlotChange();
54
27
  }
55
28
 
56
29
  disconnectedCallback() {
57
- _classPrivateFieldGet(this, _$contentSlot).removeEventListener('slotchange', _classPrivateFieldGet(this, _onContentSlotChange));
30
+ this.#$contentSlot.removeEventListener('slotchange', this.#onContentSlotChange);
58
31
  }
59
32
 
60
33
  get type() {
@@ -91,10 +64,13 @@ defineCustomElement('sinch-file-status', (_$filename = new WeakMap(), _$contentS
91
64
 
92
65
  case 'filename':
93
66
  {
94
- _classPrivateFieldGet(this, _$filename).textContent = newVal;
67
+ this.#$filename.textContent = newVal;
95
68
  break;
96
69
  }
97
70
  }
98
71
  }
99
72
 
100
- }));
73
+ #onContentSlotChange = () => {
74
+ updateBooleanAttribute(this.#$filename, 'emphasized', this.#$contentSlot.assignedElements().length > 0);
75
+ };
76
+ });
@@ -1,15 +1,17 @@
1
1
  import '../tooltip';
2
2
  import '../icons/help-outline';
3
3
  import { defineCustomElement, getAttribute, getBooleanAttribute, getIntegerAttribute, NectaryElement, updateAttribute, updateBooleanAttribute, updateIntegerAttribute } from '../utils';
4
- const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;--sinch-size-icon:18px}sinch-tooltip{display:block}</style><sinch-tooltip><sinch-icon-help-outline></sinch-icon-help-outline></sinch-tooltip>';
4
+ const templateHTML = '<style>:host{display:contents}#icon{--sinch-size-icon:18px}</style><sinch-tooltip><sinch-icon-help-outline id="icon"></sinch-icon-help-outline></sinch-tooltip>';
5
5
  const template = document.createElement('template');
6
6
  template.innerHTML = templateHTML;
7
7
  defineCustomElement('sinch-help-tooltip', class extends NectaryElement {
8
+ #$tooltip;
9
+
8
10
  constructor() {
9
11
  super();
10
12
  const shadowRoot = this.attachShadow();
11
13
  shadowRoot.appendChild(template.content.cloneNode(true));
12
- this.$tooltip = shadowRoot.querySelector('sinch-tooltip');
14
+ this.#$tooltip = shadowRoot.querySelector('sinch-tooltip');
13
15
  }
14
16
 
15
17
  static get observedAttributes() {
@@ -41,42 +43,23 @@ defineCustomElement('sinch-help-tooltip', class extends NectaryElement {
41
43
  }
42
44
 
43
45
  get orientation() {
44
- return getAttribute(this, 'orientation');
46
+ return getAttribute(this, 'orientation', 'top');
45
47
  }
46
48
 
47
49
  set orientation(value) {
48
50
  updateAttribute(this, 'orientation', value);
49
51
  }
50
52
 
53
+ get footprintRect() {
54
+ return this.#$tooltip.footprintRect;
55
+ }
56
+
51
57
  get tooltipRect() {
52
- return this.$tooltip.tooltipRect;
58
+ return this.#$tooltip.tooltipRect;
53
59
  }
54
60
 
55
61
  attributeChangedCallback(name, _, newVal) {
56
- switch (name) {
57
- case 'text':
58
- {
59
- updateAttribute(this.$tooltip, 'text', newVal);
60
- break;
61
- }
62
-
63
- case 'width':
64
- {
65
- updateAttribute(this.$tooltip, 'width', newVal);
66
- break;
67
- }
68
-
69
- case 'inverted':
70
- {
71
- updateAttribute(this.$tooltip, 'inverted', newVal);
72
- break;
73
- }
74
-
75
- case 'orientation':
76
- {
77
- updateAttribute(this.$tooltip, 'orientation', newVal);
78
- }
79
- }
62
+ updateAttribute(this.#$tooltip, name, newVal);
80
63
  }
81
64
 
82
65
  });
@@ -1,77 +1,29 @@
1
- import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
2
- import _classPrivateFieldSet from '@babel/runtime/helpers/classPrivateFieldSet';
3
-
4
- var _$itemsSlot, _$progressBar, _updateItems;
5
-
6
- function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
7
-
8
- function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
9
-
10
1
  import '../icons/check';
11
2
  import '../icons/error-outline';
12
3
  import { clampNumber, defineCustomElement, getAttribute, getIntegerAttribute, NectaryElement, updateAttribute } from '../utils';
13
4
  const templateHTML = '<style>:host{display:block;outline:0}#wrapper{position:relative;display:flex;flex-direction:row;gap:28px;width:fit-content}#progress{position:absolute;height:1px;background-color:var(--sinch-color-snow-700);left:72px;right:72px;top:16px;transform:translateY(-50%)}#bar{position:absolute;height:1px;background-color:var(--sinch-color-stormy-400);left:0;top:0}</style><div id="wrapper"><div id="progress"><div id="bar"></div></div><slot></slot></div>';
14
5
  const template = document.createElement('template');
15
6
  template.innerHTML = templateHTML;
16
- defineCustomElement('sinch-horizontal-stepper', (_$itemsSlot = new WeakMap(), _$progressBar = new WeakMap(), _updateItems = new WeakMap(), class extends NectaryElement {
7
+ defineCustomElement('sinch-horizontal-stepper', class extends NectaryElement {
8
+ #$itemsSlot;
9
+ #$progressBar;
10
+
17
11
  constructor() {
18
12
  super();
19
-
20
- _classPrivateFieldInitSpec(this, _$itemsSlot, {
21
- writable: true,
22
- value: void 0
23
- });
24
-
25
- _classPrivateFieldInitSpec(this, _$progressBar, {
26
- writable: true,
27
- value: void 0
28
- });
29
-
30
- _classPrivateFieldInitSpec(this, _updateItems, {
31
- writable: true,
32
- value: () => {
33
- const $items = _classPrivateFieldGet(this, _$itemsSlot).assignedElements();
34
-
35
- const activeIndex = clampNumber(getIntegerAttribute(this, 'index', 0), 0, $items.length + 1);
36
-
37
- for (let i = 0; i < $items.length; i++) {
38
- const $el = $items[i];
39
- const itemIndex = i + 1;
40
- $el.setAttribute('data-index', String(itemIndex));
41
-
42
- if (itemIndex === activeIndex) {
43
- $el.setAttribute('data-progress', 'active');
44
- } else if (itemIndex < activeIndex) {
45
- $el.setAttribute('data-progress', 'done');
46
- } else {
47
- $el.removeAttribute('data-progress');
48
- }
49
- }
50
-
51
- const valueIndex = clampNumber(activeIndex - 1, 0, $items.length - 1);
52
- _classPrivateFieldGet(this, _$progressBar).style.width = `${Math.floor(valueIndex / Math.max(1, $items.length - 1) * 100)}%`;
53
- this.setAttribute('aria-valuemax', String($items.length));
54
- this.setAttribute('aria-valuenow', String(valueIndex + 1));
55
- }
56
- });
57
-
58
13
  const shadowRoot = this.attachShadow();
59
14
  shadowRoot.appendChild(template.content.cloneNode(true));
60
-
61
- _classPrivateFieldSet(this, _$itemsSlot, shadowRoot.querySelector('slot'));
62
-
63
- _classPrivateFieldSet(this, _$progressBar, shadowRoot.querySelector('#bar'));
15
+ this.#$itemsSlot = shadowRoot.querySelector('slot');
16
+ this.#$progressBar = shadowRoot.querySelector('#bar');
64
17
  }
65
18
 
66
19
  connectedCallback() {
67
20
  this.setAttribute('role', 'progressbar');
68
21
  this.setAttribute('aria-valuemin', '0');
69
-
70
- _classPrivateFieldGet(this, _$itemsSlot).addEventListener('slotchange', _classPrivateFieldGet(this, _updateItems));
22
+ this.#$itemsSlot.addEventListener('slotchange', this.#updateItems);
71
23
  }
72
24
 
73
25
  disconnectedCallback() {
74
- _classPrivateFieldGet(this, _$itemsSlot).removeEventListener('slotchange', _classPrivateFieldGet(this, _updateItems));
26
+ this.#$itemsSlot.removeEventListener('slotchange', this.#updateItems);
75
27
  }
76
28
 
77
29
  static get observedAttributes() {
@@ -86,8 +38,7 @@ defineCustomElement('sinch-horizontal-stepper', (_$itemsSlot = new WeakMap(), _$
86
38
  switch (name) {
87
39
  case 'index':
88
40
  {
89
- _classPrivateFieldGet(this, _updateItems).call(this);
90
-
41
+ this.#updateItems();
91
42
  break;
92
43
  }
93
44
  }
@@ -101,4 +52,27 @@ defineCustomElement('sinch-horizontal-stepper', (_$itemsSlot = new WeakMap(), _$
101
52
  return getAttribute(this, 'index', '1');
102
53
  }
103
54
 
104
- }));
55
+ #updateItems = () => {
56
+ const $items = this.#$itemsSlot.assignedElements();
57
+ const activeIndex = clampNumber(getIntegerAttribute(this, 'index', 0), 0, $items.length + 1);
58
+
59
+ for (let i = 0; i < $items.length; i++) {
60
+ const $el = $items[i];
61
+ const itemIndex = i + 1;
62
+ $el.setAttribute('data-index', String(itemIndex));
63
+
64
+ if (itemIndex === activeIndex) {
65
+ $el.setAttribute('data-progress', 'active');
66
+ } else if (itemIndex < activeIndex) {
67
+ $el.setAttribute('data-progress', 'done');
68
+ } else {
69
+ $el.removeAttribute('data-progress');
70
+ }
71
+ }
72
+
73
+ const valueIndex = clampNumber(activeIndex - 1, 0, $items.length - 1);
74
+ this.#$progressBar.style.width = `${Math.floor(valueIndex / Math.max(1, $items.length - 1) * 100)}%`;
75
+ this.setAttribute('aria-valuemax', String($items.length));
76
+ this.setAttribute('aria-valuenow', String(valueIndex + 1));
77
+ };
78
+ });
@@ -1,46 +1,22 @@
1
- import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
2
- import _classPrivateFieldSet from '@babel/runtime/helpers/classPrivateFieldSet';
3
-
4
- var _$label, _$description, _$circleText;
5
-
6
- function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
7
-
8
- function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
9
-
10
1
  import '../icons/check';
11
2
  import '../icons/exclamation';
12
3
  import { defineCustomElement, getAttribute, getLiteralAttribute, NectaryElement, updateAttribute, updateLiteralAttribute } from '../utils';
13
- const templateHTML = '<style>:host{display:block;outline:0}#wrapper{width:144px;min-height:64px;display:flex;flex-direction:column}#circle{position:relative;display:flex;align-items:center;justify-content:center;align-self:center;width:32px;height:32px;background-color:var(--sinch-color-snow-700);font:var(--sinch-font-title-s);line-height:32px;text-align:center;color:var(--sinch-color-stormy-500);border:1px solid transparent;border-radius:50%;box-sizing:border-box;--sinch-icon-size:20px}#label{font:var(--sinch-font-title-s);color:var(--sinch-color-stormy-500);text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-top:8px}#description{font:var(--sinch-font-text-xs);color:var(--sinch-color-stormy-300);text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#icon-error,#icon-success{display:none}:host([data-progress=active]) #circle{color:var(--sinch-color-snow-100);background-color:var(--sinch-color-stormy-400)}:host([data-progress=done]) #circle{border-color:var(--sinch-color-stormy-400)}:host([data-progress=done]:not([status])) #icon-success{display:block}:host([data-progress=done][status=error]) #circle{background-color:var(--sinch-color-error-200);border-color:var(--sinch-color-stormy-400)}:host([data-progress=done][status=error]) #icon-error{display:block}:host([data-progress=done]:not([status=skip])) #circle-text{display:none}</style><div id="wrapper"><div id="circle" aria-hidden="true"><sinch-icon-check id="icon-success"></sinch-icon-check><sinch-icon-exclamation id="icon-error"></sinch-icon-exclamation><span id="circle-text"></span></div><span id="label"></span><span id="description"></span></div>';
4
+ const templateHTML = '<style>:host{display:block;outline:0}#wrapper{width:144px;min-height:64px;display:flex;flex-direction:column}#circle{position:relative;display:flex;align-items:center;justify-content:center;align-self:center;width:32px;height:32px;background-color:var(--sinch-color-snow-700);font:var(--sinch-font-title-s);line-height:32px;text-align:center;color:var(--sinch-color-stormy-500);border:1px solid transparent;border-radius:50%;box-sizing:border-box;--sinch-size-icon:20px}#label{font:var(--sinch-font-title-s);color:var(--sinch-color-stormy-500);text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-top:8px}#description{font:var(--sinch-font-text-xs);color:var(--sinch-color-stormy-300);text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#icon-error,#icon-success{display:none}:host([data-progress=active]) #circle{color:var(--sinch-color-snow-100);background-color:var(--sinch-color-stormy-400)}:host([data-progress=done]) #circle{border-color:var(--sinch-color-stormy-400)}:host([data-progress=done]:not([status])) #icon-success{display:block}:host([data-progress=done][status=error]) #circle{background-color:var(--sinch-color-error-200);border-color:var(--sinch-color-stormy-400)}:host([data-progress=done][status=error]) #icon-error{display:block}:host([data-progress=done]:not([status=skip])) #circle-text{display:none}</style><div id="wrapper"><div id="circle" aria-hidden="true"><sinch-icon-check id="icon-success"></sinch-icon-check><sinch-icon-exclamation id="icon-error"></sinch-icon-exclamation><span id="circle-text"></span></div><span id="label"></span><span id="description"></span></div>';
14
5
  import { statusValues } from './utils';
15
6
  const template = document.createElement('template');
16
7
  template.innerHTML = templateHTML;
17
- defineCustomElement('sinch-horizontal-stepper-item', (_$label = new WeakMap(), _$description = new WeakMap(), _$circleText = new WeakMap(), class extends NectaryElement {
8
+ defineCustomElement('sinch-horizontal-stepper-item', class extends NectaryElement {
9
+ #$label;
10
+ #$description;
11
+ #$circleText;
12
+
18
13
  constructor() {
19
14
  super();
20
-
21
- _classPrivateFieldInitSpec(this, _$label, {
22
- writable: true,
23
- value: void 0
24
- });
25
-
26
- _classPrivateFieldInitSpec(this, _$description, {
27
- writable: true,
28
- value: void 0
29
- });
30
-
31
- _classPrivateFieldInitSpec(this, _$circleText, {
32
- writable: true,
33
- value: void 0
34
- });
35
-
36
15
  const shadowRoot = this.attachShadow();
37
16
  shadowRoot.appendChild(template.content.cloneNode(true));
38
-
39
- _classPrivateFieldSet(this, _$label, shadowRoot.querySelector('#label'));
40
-
41
- _classPrivateFieldSet(this, _$description, shadowRoot.querySelector('#description'));
42
-
43
- _classPrivateFieldSet(this, _$circleText, shadowRoot.querySelector('#circle-text'));
17
+ this.#$label = shadowRoot.querySelector('#label');
18
+ this.#$description = shadowRoot.querySelector('#description');
19
+ this.#$circleText = shadowRoot.querySelector('#circle-text');
44
20
  }
45
21
 
46
22
  connectedCallback() {}
@@ -55,19 +31,19 @@ defineCustomElement('sinch-horizontal-stepper-item', (_$label = new WeakMap(), _
55
31
  switch (name) {
56
32
  case 'label':
57
33
  {
58
- _classPrivateFieldGet(this, _$label).textContent = newVal;
34
+ this.#$label.textContent = newVal;
59
35
  break;
60
36
  }
61
37
 
62
38
  case 'description':
63
39
  {
64
- _classPrivateFieldGet(this, _$description).textContent = newVal;
40
+ this.#$description.textContent = newVal;
65
41
  break;
66
42
  }
67
43
 
68
44
  case 'data-index':
69
45
  {
70
- _classPrivateFieldGet(this, _$circleText).textContent = newVal;
46
+ this.#$circleText.textContent = newVal;
71
47
  break;
72
48
  }
73
49
  }
@@ -97,4 +73,4 @@ defineCustomElement('sinch-horizontal-stepper-item', (_$label = new WeakMap(), _
97
73
  updateLiteralAttribute(this, statusValues, 'status', value);
98
74
  }
99
75
 
100
- }));
76
+ });
@@ -1,3 +1,4 @@
1
+ import '../tooltip';
1
2
  import type { TSinchIconButtonElement, TSinchIconButtonReact } from './types';
2
3
  declare global {
3
4
  namespace JSX {
@@ -1,97 +1,37 @@
1
- import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
2
- import _classPrivateFieldSet from '@babel/runtime/helpers/classPrivateFieldSet';
3
-
4
- var _$button, _onButtonClick, _onButtonFocus, _onButtonBlur, _onFocusReactHandler, _onBlurReactHandler, _onClickReactHandler;
5
-
6
- function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
7
-
8
- function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
9
-
1
+ import '../tooltip';
10
2
  import { defineCustomElement, getBooleanAttribute, getReactEventHandler, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute } from '../utils';
11
- const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}button{all:initial;position:relative;display:flex;align-items:center;justify-content:center;width:48px;height:48px;cursor:pointer;contain:size;--sinch-size-icon:24px;--sinch-color-icon:var(--sinch-icon-button-color, var(--sinch-color-stormy-500));--sinch-icon-button-shape-radius:var(--sinch-shape-radius-l)}button::before{content:"";position:absolute;left:0;top:0;width:100%;height:100%;border-radius:var(--sinch-icon-button-shape-radius);pointer-events:none;box-sizing:border-box;border:1px solid transparent;background-color:transparent;mix-blend-mode:multiply}button:focus-visible::after{position:absolute;content:"";left:50%;top:50%;transform:translate(-50%,-50%);width:100%;height:100%;padding:2px;border:2px solid var(--sinch-color-aqua-400);border-radius:calc(var(--sinch-icon-button-shape-radius) + 4px);pointer-events:none}@supports not selector(:focus-visible){button:focus::after{position:absolute;content:"";left:50%;top:50%;transform:translate(-50%,-50%);width:100%;height:100%;padding:2px;border:2px solid var(--sinch-color-aqua-400);border-radius:calc(var(--sinch-icon-button-shape-radius) + 4px);pointer-events:none}}button:enabled:hover::before{background-color:var(--sinch-color-snow-500)}button:enabled:active::before{background-color:var(--sinch-color-snow-600)}button:disabled{background-color:transparent;cursor:initial;--sinch-color-spinner-bg:var(--sinch-color-snow-200);--sinch-color-spinner-fg:var(--sinch-color-stormy-200);--sinch-color-icon:var(--sinch-color-stormy-100)}:host([small]:not([small=false]))>button{width:32px;height:32px;--sinch-icon-button-shape-radius:var(--sinch-shape-radius-m)}button>*{pointer-events:none}</style><button><slot name="icon"></slot></button>';
3
+ const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}button{all:initial;position:relative;display:flex;align-items:center;justify-content:center;width:48px;height:48px;cursor:pointer;contain:size;--sinch-size-icon:24px;--sinch-color-icon:var(--sinch-icon-button-color, var(--sinch-color-stormy-500));--sinch-icon-button-shape-radius:var(--sinch-shape-radius-l)}button::before{content:"";position:absolute;left:0;top:0;width:100%;height:100%;border-radius:var(--sinch-icon-button-shape-radius);pointer-events:none;box-sizing:border-box;border:1px solid transparent;background-color:transparent;mix-blend-mode:multiply}button:focus-visible::after{position:absolute;content:"";left:50%;top:50%;transform:translate(-50%,-50%);width:100%;height:100%;padding:2px;border:2px solid var(--sinch-color-border-focus);border-radius:calc(var(--sinch-icon-button-shape-radius) + 4px);pointer-events:none}@supports not selector(:focus-visible){button:focus::after{position:absolute;content:"";left:50%;top:50%;transform:translate(-50%,-50%);width:100%;height:100%;padding:2px;border:2px solid var(--sinch-color-border-focus);border-radius:calc(var(--sinch-icon-button-shape-radius) + 4px);pointer-events:none}}button:enabled:hover::before{background-color:#f1f2f4}button:enabled:active::before{background-color:#e3e6e8}button:disabled{background-color:transparent;cursor:initial;--sinch-color-spinner-bg:var(--sinch-color-snow-200);--sinch-color-spinner-fg:var(--sinch-color-stormy-200);--sinch-color-icon:var(--sinch-color-stormy-100)}:host([small]:not([small=false])) #button{width:32px;height:32px;--sinch-icon-button-shape-radius:var(--sinch-shape-radius-m)}button>*{pointer-events:none}</style><sinch-tooltip id="tooltip"><button id="button"><slot name="icon"></slot></button></sinch-tooltip>';
12
4
  const template = document.createElement('template');
13
5
  template.innerHTML = templateHTML;
14
- defineCustomElement('sinch-icon-button', (_$button = new WeakMap(), _onButtonClick = new WeakMap(), _onButtonFocus = new WeakMap(), _onButtonBlur = new WeakMap(), _onFocusReactHandler = new WeakMap(), _onBlurReactHandler = new WeakMap(), _onClickReactHandler = new WeakMap(), class extends NectaryElement {
6
+ defineCustomElement('sinch-icon-button', class extends NectaryElement {
7
+ #$button;
8
+ #$tooltip;
9
+ #controller = null;
10
+
15
11
  constructor() {
16
12
  super();
17
-
18
- _classPrivateFieldInitSpec(this, _$button, {
19
- writable: true,
20
- value: void 0
21
- });
22
-
23
- _classPrivateFieldInitSpec(this, _onButtonClick, {
24
- writable: true,
25
- value: () => {
26
- this.dispatchEvent(new CustomEvent('-click'));
27
- }
28
- });
29
-
30
- _classPrivateFieldInitSpec(this, _onButtonFocus, {
31
- writable: true,
32
- value: () => {
33
- this.dispatchEvent(new CustomEvent('-focus'));
34
- }
35
- });
36
-
37
- _classPrivateFieldInitSpec(this, _onButtonBlur, {
38
- writable: true,
39
- value: () => {
40
- this.dispatchEvent(new CustomEvent('-blur'));
41
- }
42
- });
43
-
44
- _classPrivateFieldInitSpec(this, _onFocusReactHandler, {
45
- writable: true,
46
- value: () => {
47
- getReactEventHandler(this, 'on-focus')?.();
48
- }
49
- });
50
-
51
- _classPrivateFieldInitSpec(this, _onBlurReactHandler, {
52
- writable: true,
53
- value: () => {
54
- getReactEventHandler(this, 'on-blur')?.();
55
- }
56
- });
57
-
58
- _classPrivateFieldInitSpec(this, _onClickReactHandler, {
59
- writable: true,
60
- value: e => {
61
- getReactEventHandler(this, 'on-click')?.(e);
62
- }
63
- });
64
-
65
13
  const shadowRoot = this.attachShadow();
66
14
  shadowRoot.appendChild(template.content.cloneNode(true));
67
-
68
- _classPrivateFieldSet(this, _$button, shadowRoot.querySelector('button'));
15
+ this.#$button = shadowRoot.querySelector('#button');
16
+ this.#$tooltip = shadowRoot.querySelector('#tooltip');
69
17
  }
70
18
 
71
19
  connectedCallback() {
20
+ this.#controller = new AbortController();
21
+ const options = {
22
+ signal: this.#controller.signal
23
+ };
72
24
  this.setAttribute('role', 'button');
73
-
74
- _classPrivateFieldGet(this, _$button).addEventListener('click', _classPrivateFieldGet(this, _onButtonClick));
75
-
76
- _classPrivateFieldGet(this, _$button).addEventListener('focus', _classPrivateFieldGet(this, _onButtonFocus));
77
-
78
- _classPrivateFieldGet(this, _$button).addEventListener('blur', _classPrivateFieldGet(this, _onButtonBlur));
79
-
80
- this.addEventListener('-click', _classPrivateFieldGet(this, _onClickReactHandler));
81
- this.addEventListener('-focus', _classPrivateFieldGet(this, _onFocusReactHandler));
82
- this.addEventListener('-blur', _classPrivateFieldGet(this, _onBlurReactHandler));
25
+ this.#$button.addEventListener('click', this.#onButtonClick, options);
26
+ this.#$button.addEventListener('focus', this.#onButtonFocus, options);
27
+ this.#$button.addEventListener('blur', this.#onButtonBlur, options);
28
+ this.addEventListener('-click', this.#onClickReactHandler, options);
29
+ this.addEventListener('-focus', this.#onFocusReactHandler, options);
30
+ this.addEventListener('-blur', this.#onBlurReactHandler, options);
83
31
  }
84
32
 
85
33
  disconnectedCallback() {
86
- _classPrivateFieldGet(this, _$button).removeEventListener('click', _classPrivateFieldGet(this, _onButtonClick));
87
-
88
- _classPrivateFieldGet(this, _$button).removeEventListener('focus', _classPrivateFieldGet(this, _onButtonFocus));
89
-
90
- _classPrivateFieldGet(this, _$button).removeEventListener('blur', _classPrivateFieldGet(this, _onButtonBlur));
91
-
92
- this.removeEventListener('-click', _classPrivateFieldGet(this, _onClickReactHandler));
93
- this.removeEventListener('-focus', _classPrivateFieldGet(this, _onFocusReactHandler));
94
- this.removeEventListener('-blur', _classPrivateFieldGet(this, _onBlurReactHandler));
34
+ this.#controller.abort();
95
35
  }
96
36
 
97
37
  static get observedAttributes() {
@@ -103,14 +43,14 @@ defineCustomElement('sinch-icon-button', (_$button = new WeakMap(), _onButtonCli
103
43
  case 'disabled':
104
44
  {
105
45
  const isDisabled = isAttrTrue(newVal);
106
- _classPrivateFieldGet(this, _$button).disabled = isDisabled;
46
+ this.#$button.disabled = isDisabled;
107
47
  updateBooleanAttribute(this, 'disabled', isDisabled);
108
48
  break;
109
49
  }
110
50
 
111
51
  case 'aria-label':
112
52
  {
113
- updateAttribute(this, 'title', newVal);
53
+ updateAttribute(this.#$tooltip, 'text', newVal);
114
54
  break;
115
55
  }
116
56
  }
@@ -132,12 +72,38 @@ defineCustomElement('sinch-icon-button', (_$button = new WeakMap(), _onButtonCli
132
72
  return getBooleanAttribute(this, 'small');
133
73
  }
134
74
 
75
+ get tooltipRect() {
76
+ return this.#$tooltip.tooltipRect;
77
+ }
78
+
79
+ get focusable() {
80
+ return true;
81
+ }
82
+
135
83
  focus() {
136
- _classPrivateFieldGet(this, _$button).focus();
84
+ this.#$button.focus();
137
85
  }
138
86
 
139
87
  blur() {
140
- _classPrivateFieldGet(this, _$button).blur();
88
+ this.#$button.blur();
141
89
  }
142
90
 
143
- }));
91
+ #onButtonClick = () => {
92
+ this.dispatchEvent(new CustomEvent('-click'));
93
+ };
94
+ #onButtonFocus = () => {
95
+ this.dispatchEvent(new CustomEvent('-focus'));
96
+ };
97
+ #onButtonBlur = () => {
98
+ this.dispatchEvent(new CustomEvent('-blur'));
99
+ };
100
+ #onFocusReactHandler = () => {
101
+ getReactEventHandler(this, 'on-focus')?.();
102
+ };
103
+ #onBlurReactHandler = () => {
104
+ getReactEventHandler(this, 'on-blur')?.();
105
+ };
106
+ #onClickReactHandler = e => {
107
+ getReactEventHandler(this, 'on-click')?.(e);
108
+ };
109
+ });
@@ -1,18 +1,32 @@
1
- import type { TSinchElementReact } from '../types';
1
+ import type { TRect, TSinchElementReact } from '../types';
2
2
  export declare type TSinchIconButtonElement = HTMLElement & {
3
+ /** Disabled */
3
4
  disabled: boolean;
5
+ /** Small */
4
6
  small: boolean;
7
+ readonly tooltipRect: TRect;
8
+ /** Click event */
5
9
  addEventListener(type: '-click', listener: (e: CustomEvent<void>) => void): void;
10
+ /** Focus event */
6
11
  addEventListener(type: '-focus', listener: (e: CustomEvent<void>) => void): void;
12
+ /** Blur event */
7
13
  addEventListener(type: '-blur', listener: (e: CustomEvent<void>) => void): void;
14
+ /** Disabled */
8
15
  setAttribute(name: 'disabled', value: ''): void;
16
+ /** Small */
9
17
  setAttribute(name: 'small', value: ''): void;
10
18
  };
11
19
  export declare type TSinchIconButtonReact = TSinchElementReact<TSinchIconButtonElement> & {
12
- 'aria-label': string;
20
+ /** Disabled */
13
21
  disabled?: boolean;
22
+ /** Small */
14
23
  small?: boolean;
24
+ /** Label that is used for a11y */
25
+ 'aria-label': string;
26
+ /** Click event handler */
15
27
  'on-click'?: (e: CustomEvent<void>) => void;
28
+ /** Focus event handler */
16
29
  'on-focus'?: (e: CustomEvent<void>) => void;
30
+ /** Blur event handler */
17
31
  'on-blur'?: (e: CustomEvent<void>) => void;
18
32
  };
@@ -0,0 +1,11 @@
1
+ import type { TSinchIconChannelElement, TSinchIconChannelReact } from '../types';
2
+ declare global {
3
+ namespace JSX {
4
+ interface IntrinsicElements {
5
+ 'sinch-icon-channel-notify': TSinchIconChannelReact;
6
+ }
7
+ }
8
+ interface HTMLElementTagNameMap {
9
+ 'sinch-icon-channel-notify': TSinchIconChannelElement;
10
+ }
11
+ }
@@ -0,0 +1,4 @@
1
+ import { defineCustomElement } from '../../utils';
2
+ import { createIconClass } from '../create-icon-class';
3
+ const templateHTML = '<svg viewBox="0 0 40 40" aria-hidden="true" focusable="false"><path fill="#0076BA" fill-rule="evenodd" d="M8.523 33.337C3.37 30.02 0 24.532 0 18.328 0 8.213 8.962 0 20 0s20 8.213 20 18.328c0 10.116-8.962 18.328-20 18.328-.64 0-1.273-.027-1.898-.081C16.235 38.665 13.395 40 10.22 40c-2.123 0-4.096-.597-5.729-1.617 1.911-1.195 3.357-2.97 4.033-5.047Z" clip-rule="evenodd"/><path fill="#fff" fill-rule="evenodd" d="M30.667 13.393c0-2.697-2.39-4.887-5.334-4.887H14.667c-2.944 0-5.334 2.19-5.334 4.887v9.775c0 2.698 2.39 4.888 5.334 4.888h10.666c2.944 0 5.334-2.19 5.334-4.888v-9.775Z" clip-rule="evenodd"/><path fill="#0076BA" fill-rule="evenodd" d="M17.866 23.46c0-.34.256-.635.617-.713.36-.078.733.081.899.385l2.751 5.043h-4.267V23.46Zm4.267-10.362c0 .34-.255.636-.616.714-.361.078-.733-.082-.9-.386l-2.75-5.042h4.266v4.714Z" clip-rule="evenodd"/><path fill="#0076BA" d="M29.705 13.703c2.805 0 5.078-2.084 5.078-4.654s-2.273-4.654-5.078-4.654c-2.804 0-5.078 2.084-5.078 4.654s2.274 4.654 5.078 4.654Z"/><path fill="#E44436" d="M29.705 12.226c1.915 0 3.467-1.422 3.467-3.177 0-1.754-1.552-3.177-3.467-3.177-1.914 0-3.466 1.423-3.466 3.177 0 1.755 1.552 3.177 3.466 3.177Z"/></svg>';
4
+ defineCustomElement('sinch-icon-channel-notify', createIconClass(templateHTML));
@@ -1,5 +1,5 @@
1
1
  import { getIntegerAttribute, getLiteralAttribute, NectaryElement, updateAttribute, updateIntegerAttribute, updateLiteralAttribute } from '../utils';
2
- const illustrationStylesHtml = '<style>:host{display:block}svg{display:block;pointer-events:none}#wrapper{display:flex;width:100%;height:100%;align-items:center;justify-content:center;overflow:hidden}#wrapper>*{flex-shrink:0}:host([valign=top]) #wrapper{align-items:flex-start}:host([valign=bottom]) #wrapper{align-items:flex-end}:host([background=yellow]) #wrapper{background-color:var(--sinch-color-background-yellow)}:host([background=green]) #wrapper{background-color:var(--sinch-color-background-green)}:host([background=blue]) #wrapper{background-color:var(--sinch-color-background-blue)}:host([background=grey]) #wrapper{background-color:var(--sinch-color-background-grey)}:host([background=white]) #wrapper{background-color:var(--sinch-color-background-white)}</style>';
2
+ const illustrationStylesHtml = '<style>:host{display:block}svg{display:block;pointer-events:none}#wrapper{display:flex;width:100%;height:100%;align-items:center;justify-content:center;overflow:hidden}#wrapper>*{flex-shrink:0}:host([valign=top]) #wrapper{align-items:flex-start}:host([valign=bottom]) #wrapper{align-items:flex-end}:host([background=yellow]) #wrapper{background-color:var(--sinch-color-bg-comp-yellow)}:host([background=green]) #wrapper{background-color:var(--sinch-color-bg-comp-green)}:host([background=blue]) #wrapper{background-color:var(--sinch-color-bg-comp-blue)}:host([background=grey]) #wrapper{background-color:var(--sinch-color-bg-primary-contrast)}:host([background=white]) #wrapper{background-color:var(--sinch-color-bg-primary-light)}</style>';
3
3
  import { backgroundValues, valignValues } from './utils';
4
4
  const DEFAULT_SIZE = 256;
5
5
  const MIN_SIZE = 16;