@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,84 +1,28 @@
1
- import _classPrivateFieldGet from '@babel/runtime/helpers/classPrivateFieldGet';
2
- import _classPrivateFieldSet from '@babel/runtime/helpers/classPrivateFieldSet';
3
-
4
- var _$slot, _onSlotChange, _onOptionChange, _onValueChange, _onChangeReactHandler;
5
-
6
- function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
7
-
8
- function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
9
-
10
- function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
11
-
12
- function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
13
-
14
1
  import { defineCustomElement, getAttribute, getBooleanAttribute, getCsvSet, getFirstCsvValue, getReactEventHandler, NectaryElement, updateAttribute, updateBooleanAttribute, updateCsv } from '../utils';
15
2
  const templateHTML = '<style>:host{display:block;outline:0}#wrapper{display:flex;flex-direction:row}</style><div id="wrapper"><slot></slot></div>';
16
3
  const template = document.createElement('template');
17
4
  template.innerHTML = templateHTML;
18
- defineCustomElement('sinch-segmented-icon-control', (_$slot = new WeakMap(), _onSlotChange = new WeakMap(), _onOptionChange = new WeakMap(), _onValueChange = new WeakSet(), _onChangeReactHandler = new WeakMap(), class extends NectaryElement {
5
+ defineCustomElement('sinch-segmented-icon-control', class extends NectaryElement {
6
+ #$slot;
7
+
19
8
  constructor() {
20
9
  super();
21
-
22
- _classPrivateMethodInitSpec(this, _onValueChange);
23
-
24
- _classPrivateFieldInitSpec(this, _$slot, {
25
- writable: true,
26
- value: void 0
27
- });
28
-
29
- _classPrivateFieldInitSpec(this, _onSlotChange, {
30
- writable: true,
31
- value: () => {
32
- _classPrivateMethodGet(this, _onValueChange, _onValueChange2).call(this, this.value);
33
- }
34
- });
35
-
36
- _classPrivateFieldInitSpec(this, _onOptionChange, {
37
- writable: true,
38
- value: e => {
39
- e.stopPropagation();
40
- const $elem = e.target;
41
- const value = e.detail;
42
- const detail = this.multiple ? updateCsv(this.value, value, !getBooleanAttribute($elem, 'data-checked')) : value;
43
- this.dispatchEvent(new CustomEvent('change', {
44
- detail,
45
- bubbles: true
46
- }));
47
- this.dispatchEvent(new CustomEvent('-change', {
48
- detail
49
- }));
50
- }
51
- });
52
-
53
- _classPrivateFieldInitSpec(this, _onChangeReactHandler, {
54
- writable: true,
55
- value: e => {
56
- getReactEventHandler(this, 'on-change')?.(e);
57
- }
58
- });
59
-
60
10
  const shadowRoot = this.attachShadow();
61
11
  shadowRoot.appendChild(template.content.cloneNode(true));
62
-
63
- _classPrivateFieldSet(this, _$slot, shadowRoot.querySelector('slot'));
12
+ this.#$slot = shadowRoot.querySelector('slot');
64
13
  }
65
14
 
66
15
  connectedCallback() {
67
16
  this.setAttribute('role', 'tablist');
68
-
69
- _classPrivateFieldGet(this, _$slot).addEventListener('slotchange', _classPrivateFieldGet(this, _onSlotChange));
70
-
71
- _classPrivateFieldGet(this, _$slot).addEventListener('option-change', _classPrivateFieldGet(this, _onOptionChange));
72
-
73
- this.addEventListener('-change', _classPrivateFieldGet(this, _onChangeReactHandler));
17
+ this.#$slot.addEventListener('slotchange', this.#onSlotChange);
18
+ this.#$slot.addEventListener('option-change', this.#onOptionChange);
19
+ this.addEventListener('-change', this.#onChangeReactHandler);
74
20
  }
75
21
 
76
22
  disconnectedCallback() {
77
- _classPrivateFieldGet(this, _$slot).removeEventListener('slotchange', _classPrivateFieldGet(this, _onSlotChange));
78
-
79
- _classPrivateFieldGet(this, _$slot).removeEventListener('option-change', _classPrivateFieldGet(this, _onOptionChange));
80
-
81
- this.removeEventListener('-change', _classPrivateFieldGet(this, _onChangeReactHandler));
23
+ this.#$slot.removeEventListener('slotchange', this.#onSlotChange);
24
+ this.#$slot.removeEventListener('option-change', this.#onOptionChange);
25
+ this.removeEventListener('-change', this.#onChangeReactHandler);
82
26
  }
83
27
 
84
28
  static get observedAttributes() {
@@ -113,29 +57,48 @@ defineCustomElement('sinch-segmented-icon-control', (_$slot = new WeakMap(), _on
113
57
  switch (name) {
114
58
  case 'value':
115
59
  {
116
- _classPrivateMethodGet(this, _onValueChange, _onValueChange2).call(this, newVal ?? '');
117
-
60
+ this.#onValueChange(newVal ?? '');
118
61
  break;
119
62
  }
120
63
  }
121
64
  }
122
65
 
123
- }));
124
-
125
- function _onValueChange2(csv) {
126
- if (this.multiple) {
127
- const values = getCsvSet(csv);
128
-
129
- for (const $option of _classPrivateFieldGet(this, _$slot).assignedElements()) {
130
- const isChecked = !getBooleanAttribute($option, 'disabled') && values.has(getAttribute($option, 'value', ''));
131
- updateBooleanAttribute($option, 'data-checked', isChecked);
132
- }
133
- } else {
134
- const value = getFirstCsvValue(csv);
66
+ #onSlotChange = () => {
67
+ this.#onValueChange(this.value);
68
+ };
69
+ #onOptionChange = e => {
70
+ e.stopPropagation();
71
+ const $elem = e.target;
72
+ const value = e.detail;
73
+ const detail = this.multiple ? updateCsv(this.value, value, !getBooleanAttribute($elem, 'data-checked')) : value;
74
+ this.dispatchEvent(new CustomEvent('change', {
75
+ detail,
76
+ bubbles: true
77
+ }));
78
+ this.dispatchEvent(new CustomEvent('-change', {
79
+ detail
80
+ }));
81
+ };
82
+
83
+ #onValueChange(csv) {
84
+ if (this.multiple) {
85
+ const values = getCsvSet(csv);
86
+
87
+ for (const $option of this.#$slot.assignedElements()) {
88
+ const isChecked = !getBooleanAttribute($option, 'disabled') && values.has(getAttribute($option, 'value', ''));
89
+ updateBooleanAttribute($option, 'data-checked', isChecked);
90
+ }
91
+ } else {
92
+ const value = getFirstCsvValue(csv);
135
93
 
136
- for (const $option of _classPrivateFieldGet(this, _$slot).assignedElements()) {
137
- const isChecked = !getBooleanAttribute($option, 'disabled') && value === getAttribute($option, 'value', '');
138
- updateBooleanAttribute($option, 'data-checked', isChecked);
94
+ for (const $option of this.#$slot.assignedElements()) {
95
+ const isChecked = !getBooleanAttribute($option, 'disabled') && value === getAttribute($option, 'value', '');
96
+ updateBooleanAttribute($option, 'data-checked', isChecked);
97
+ }
139
98
  }
140
99
  }
141
- }
100
+
101
+ #onChangeReactHandler = e => {
102
+ getReactEventHandler(this, 'on-change')?.(e);
103
+ };
104
+ });
@@ -1,92 +1,32 @@
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;
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 { defineCustomElement, getAttribute, getBooleanAttribute, getReactEventHandler, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute } from '../utils';
11
- const templateHTML = '<style>:host{display:block;outline:0}#wrapper{position:relative;width:56px;height:32px;padding:3px 16px;box-sizing:border-box;border:1px solid var(--sinch-color-snow-600);border-left-width:0;border-right-width:0;color:var(--sinch-color-stormy-500);background-color:var(--sinch-color-snow-100);--sinch-color-icon:var(--sinch-color-stormy-500);--sinch-size-icon:24px}#wrapper:hover{background-color:var(--sinch-color-snow-500)}:host(:first-child) #wrapper{border-left-width:1px;border-top-left-radius:4px;border-bottom-left-radius:4px}:host(:last-child) #wrapper{border-right-width:1px;border-top-right-radius:4px;border-bottom-right-radius:4px}:host([data-checked]) #wrapper{border-color:var(--sinch-color-stormy-500)}:host([data-checked]:not(:first-child)) #wrapper::before{content:"";width:1px;background-color:var(--sinch-color-stormy-500);position:absolute;left:-1px;top:-1px;bottom:-1px}:host([data-checked]:not(:last-child)) #wrapper::after{content:"";width:1px;background-color:var(--sinch-color-stormy-500);position:absolute;right:0;top:-1px;bottom:-1px}#button{all:initial;position:absolute;left:0;top:0;box-sizing:border-box;width:100%;height:100%;cursor:pointer;z-index:1}#button:disabled{cursor:unset}#button:focus::before{content:"";position:absolute;left:-4px;right:-3px;top:-4px;bottom:-4px;border-style:solid;border-color:var(--sinch-color-aqua-400);border-width:0}#button:focus-visible::before{border-width:2px}:host(:first-child) #button:focus::before{left:-4px;border-top-left-radius:6px;border-bottom-left-radius:6px}:host(:last-child) #button:focus::before{right:-4px;border-top-right-radius:6px;border-bottom-right-radius:6px}@supports not selector(:focus-visible){#button:focus::before{border-width:2px}}:host([disabled]:not([disabled=false])) #wrapper{background-color:var(--sinch-color-snow-100);color:var(--sinch-color-stormy-100);--sinch-color-icon:var(--sinch-color-stormy-100)}::slotted(*){display:block}</style><div id="wrapper"><slot name="icon"></slot><button id="button"></button></div>';
2
+ const templateHTML = '<style>:host{display:block;outline:0}#wrapper{position:relative;width:56px;height:32px;padding:3px 16px;box-sizing:border-box;border:1px solid var(--sinch-color-snow-600);border-left-width:0;border-right-width:0;color:var(--sinch-color-stormy-500);background-color:var(--sinch-color-snow-100);--sinch-color-icon:var(--sinch-color-stormy-500);--sinch-size-icon:24px}#wrapper:hover{background-color:var(--sinch-color-snow-400)}:host(:first-child) #wrapper{border-left-width:1px;border-top-left-radius:4px;border-bottom-left-radius:4px}:host(:last-child) #wrapper{border-right-width:1px;border-top-right-radius:4px;border-bottom-right-radius:4px}:host([data-checked]) #wrapper{border-color:var(--sinch-color-stormy-500)}:host([data-checked]:not(:first-child)) #wrapper::before{content:"";width:1px;background-color:var(--sinch-color-stormy-500);position:absolute;left:-1px;top:-1px;bottom:-1px}:host([data-checked]:not(:last-child)) #wrapper::after{content:"";width:1px;background-color:var(--sinch-color-stormy-500);position:absolute;right:0;top:-1px;bottom:-1px}#button{all:initial;position:absolute;left:0;top:0;box-sizing:border-box;width:100%;height:100%;cursor:pointer;z-index:1}#button:disabled{cursor:unset}#button:focus::before{content:"";position:absolute;left:-4px;right:-3px;top:-4px;bottom:-4px;border-style:solid;border-color:var(--sinch-color-border-focus);border-width:0}#button:focus-visible::before{border-width:2px}:host(:first-child) #button:focus::before{left:-4px;border-top-left-radius:6px;border-bottom-left-radius:6px}:host(:last-child) #button:focus::before{right:-4px;border-top-right-radius:6px;border-bottom-right-radius:6px}@supports not selector(:focus-visible){#button:focus::before{border-width:2px}}:host([disabled]:not([disabled=false])) #wrapper{background-color:var(--sinch-color-snow-100);color:var(--sinch-color-stormy-100);--sinch-color-icon:var(--sinch-color-stormy-100)}::slotted(*){display:block}</style><div id="wrapper"><slot name="icon"></slot><button id="button"></button></div>';
12
3
  const template = document.createElement('template');
13
4
  template.innerHTML = templateHTML;
14
- defineCustomElement('sinch-segmented-icon-control-option', (_$button = new WeakMap(), _onButtonClick = new WeakMap(), _onButtonFocus = new WeakMap(), _onButtonBlur = new WeakMap(), _onFocusReactHandler = new WeakMap(), _onBlurReactHandler = new WeakMap(), class extends NectaryElement {
5
+ defineCustomElement('sinch-segmented-icon-control-option', class extends NectaryElement {
6
+ #$button;
7
+
15
8
  constructor() {
16
9
  super();
17
-
18
- _classPrivateFieldInitSpec(this, _$button, {
19
- writable: true,
20
- value: void 0
21
- });
22
-
23
- _classPrivateFieldInitSpec(this, _onButtonClick, {
24
- writable: true,
25
- value: e => {
26
- e.stopPropagation();
27
- this.dispatchEvent(new CustomEvent('option-change', {
28
- detail: this.value,
29
- bubbles: true
30
- }));
31
- }
32
- });
33
-
34
- _classPrivateFieldInitSpec(this, _onButtonFocus, {
35
- writable: true,
36
- value: () => {
37
- this.dispatchEvent(new CustomEvent('-focus'));
38
- }
39
- });
40
-
41
- _classPrivateFieldInitSpec(this, _onButtonBlur, {
42
- writable: true,
43
- value: () => {
44
- this.dispatchEvent(new CustomEvent('-blur'));
45
- }
46
- });
47
-
48
- _classPrivateFieldInitSpec(this, _onFocusReactHandler, {
49
- writable: true,
50
- value: () => {
51
- getReactEventHandler(this, 'on-focus')?.();
52
- }
53
- });
54
-
55
- _classPrivateFieldInitSpec(this, _onBlurReactHandler, {
56
- writable: true,
57
- value: () => {
58
- getReactEventHandler(this, 'on-blur')?.();
59
- }
60
- });
61
-
62
10
  const shadowRoot = this.attachShadow();
63
11
  shadowRoot.appendChild(template.content.cloneNode(true));
64
-
65
- _classPrivateFieldSet(this, _$button, shadowRoot.querySelector('#button'));
12
+ this.#$button = shadowRoot.querySelector('#button');
66
13
  }
67
14
 
68
15
  connectedCallback() {
69
16
  this.setAttribute('role', 'tab');
70
-
71
- _classPrivateFieldGet(this, _$button).addEventListener('click', _classPrivateFieldGet(this, _onButtonClick));
72
-
73
- _classPrivateFieldGet(this, _$button).addEventListener('focus', _classPrivateFieldGet(this, _onButtonFocus));
74
-
75
- _classPrivateFieldGet(this, _$button).addEventListener('blur', _classPrivateFieldGet(this, _onButtonBlur));
76
-
77
- this.addEventListener('-focus', _classPrivateFieldGet(this, _onFocusReactHandler));
78
- this.addEventListener('-blur', _classPrivateFieldGet(this, _onBlurReactHandler));
17
+ this.#$button.addEventListener('click', this.#onButtonClick);
18
+ this.#$button.addEventListener('focus', this.#onButtonFocus);
19
+ this.#$button.addEventListener('blur', this.#onButtonBlur);
20
+ this.addEventListener('-focus', this.#onFocusReactHandler);
21
+ this.addEventListener('-blur', this.#onBlurReactHandler);
79
22
  }
80
23
 
81
24
  disconnectedCallback() {
82
- _classPrivateFieldGet(this, _$button).removeEventListener('click', _classPrivateFieldGet(this, _onButtonClick));
83
-
84
- _classPrivateFieldGet(this, _$button).removeEventListener('focus', _classPrivateFieldGet(this, _onButtonFocus));
85
-
86
- _classPrivateFieldGet(this, _$button).removeEventListener('blur', _classPrivateFieldGet(this, _onButtonBlur));
87
-
88
- this.removeEventListener('-focus', _classPrivateFieldGet(this, _onFocusReactHandler));
89
- this.removeEventListener('-blur', _classPrivateFieldGet(this, _onBlurReactHandler));
25
+ this.#$button.removeEventListener('click', this.#onButtonClick);
26
+ this.#$button.removeEventListener('focus', this.#onButtonFocus);
27
+ this.#$button.removeEventListener('blur', this.#onButtonBlur);
28
+ this.removeEventListener('-focus', this.#onFocusReactHandler);
29
+ this.removeEventListener('-blur', this.#onBlurReactHandler);
90
30
  }
91
31
 
92
32
  static get observedAttributes() {
@@ -119,18 +59,41 @@ defineCustomElement('sinch-segmented-icon-control-option', (_$button = new WeakM
119
59
 
120
60
  case 'disabled':
121
61
  {
122
- _classPrivateFieldGet(this, _$button).disabled = isAttrTrue(newVal);
62
+ this.#$button.disabled = isAttrTrue(newVal);
123
63
  break;
124
64
  }
125
65
  }
126
66
  }
127
67
 
68
+ get focusable() {
69
+ return true;
70
+ }
71
+
128
72
  focus() {
129
- _classPrivateFieldGet(this, _$button).focus();
73
+ this.#$button.focus();
130
74
  }
131
75
 
132
76
  blur() {
133
- _classPrivateFieldGet(this, _$button).blur();
77
+ this.#$button.blur();
134
78
  }
135
79
 
136
- }));
80
+ #onButtonClick = e => {
81
+ e.stopPropagation();
82
+ this.dispatchEvent(new CustomEvent('option-change', {
83
+ detail: this.value,
84
+ bubbles: true
85
+ }));
86
+ };
87
+ #onButtonFocus = () => {
88
+ this.dispatchEvent(new CustomEvent('-focus'));
89
+ };
90
+ #onButtonBlur = () => {
91
+ this.dispatchEvent(new CustomEvent('-blur'));
92
+ };
93
+ #onFocusReactHandler = () => {
94
+ getReactEventHandler(this, 'on-focus')?.();
95
+ };
96
+ #onBlurReactHandler = () => {
97
+ getReactEventHandler(this, 'on-blur')?.();
98
+ };
99
+ });
@@ -0,0 +1,13 @@
1
+ import '../text';
2
+ import '../icons/keyboard-arrow-down';
3
+ import type { TSinchSelectButtonElement, TSinchSelectButtonReact } from './types';
4
+ declare global {
5
+ namespace JSX {
6
+ interface IntrinsicElements {
7
+ 'sinch-select-button': TSinchSelectButtonReact;
8
+ }
9
+ }
10
+ interface HTMLElementTagNameMap {
11
+ 'sinch-select-button': TSinchSelectButtonElement;
12
+ }
13
+ }
@@ -0,0 +1,158 @@
1
+ import '../text';
2
+ import '../icons/keyboard-arrow-down';
3
+ import { defineCustomElement, getAttribute, getBooleanAttribute, getReactEventHandler, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute } from '../utils';
4
+ const templateHTML = '<style>:host{display:inline-block;vertical-align:middle}#wrapper{position:relative;display:flex;flex-direction:row;align-items:center;gap:8px;box-sizing:border-box;width:100%;height:48px;padding:0 12px;background-color:var(--sinch-color-snow-100);border-radius:var(--sinch-shape-radius-s);--sinch-size-icon:24px;--sinch-color-icon:var(--sinch-color-stormy-500)}#button{all:initial;cursor:pointer;position:absolute;left:0;top:0;width:100%;height:100%;z-index:1;border-radius:var(--sinch-shape-radius-s);border:1px solid var(--sinch-color-stormy-200);box-sizing:border-box}#text{flex:1;min-width:0;color:var(--sinch-color-text-muted)}:host([text]:not([text=""])) #text{color:var(--sinch-color-text-default)}#button:disabled{border-color:var(--sinch-color-snow-500);cursor:initial}#button:focus-visible{border-color:var(--sinch-color-stormy-600)}@supports not selector(:focus-visible){#button:focus{border-color:var(--sinch-color-stormy-600)}}:host([invalid]) #button:enabled{border-color:var(--sinch-color-text-invalid)}#button:disabled~#text{color:var(--sinch-color-stormy-100)}:host([disabled]) #wrapper{--sinch-color-icon:var(--sinch-color-stormy-100)}</style><div id="wrapper"><button id="button"></button><slot name="icon"></slot><sinch-text id="text" type="m" ellipsis></sinch-text><sinch-icon-keyboard-arrow-down></sinch-icon-keyboard-arrow-down></div>';
5
+ const template = document.createElement('template');
6
+ template.innerHTML = templateHTML;
7
+ defineCustomElement('sinch-select-button', class extends NectaryElement {
8
+ #$button;
9
+ #$text;
10
+ #controller = null;
11
+
12
+ constructor() {
13
+ super();
14
+ const shadowRoot = this.attachShadow();
15
+ shadowRoot.appendChild(template.content.cloneNode(true));
16
+ this.#$button = shadowRoot.querySelector('#button');
17
+ this.#$text = shadowRoot.querySelector('#text');
18
+ }
19
+
20
+ connectedCallback() {
21
+ this.#controller = new AbortController();
22
+ const {
23
+ signal
24
+ } = this.#controller;
25
+ this.setAttribute('role', 'button');
26
+ this.#$button.addEventListener('click', this.#onButtonClick, {
27
+ signal
28
+ });
29
+ this.#$button.addEventListener('focus', this.#onButtonFocus, {
30
+ signal
31
+ });
32
+ this.#$button.addEventListener('blur', this.#onButtonBlur, {
33
+ signal
34
+ });
35
+ this.addEventListener('-click', this.#onClickReactHandler, {
36
+ signal
37
+ });
38
+ this.addEventListener('-focus', this.#onFocusReactHandler, {
39
+ signal
40
+ });
41
+ this.addEventListener('-blur', this.#onBlurReactHandler, {
42
+ signal
43
+ });
44
+ }
45
+
46
+ disconnectedCallback() {
47
+ this.#controller.abort();
48
+ }
49
+
50
+ static get observedAttributes() {
51
+ return ['text', 'placeholder', 'invalid', 'disabled'];
52
+ }
53
+
54
+ set text(value) {
55
+ updateAttribute(this, 'text', value);
56
+ }
57
+
58
+ get text() {
59
+ return getAttribute(this, 'text', '');
60
+ }
61
+
62
+ set placeholder(value) {
63
+ updateAttribute(this, 'placeholder', value);
64
+ }
65
+
66
+ get placeholder() {
67
+ return getAttribute(this, 'placeholder');
68
+ }
69
+
70
+ set invalid(isInvalid) {
71
+ updateBooleanAttribute(this, 'invalid', isInvalid);
72
+ }
73
+
74
+ get invalid() {
75
+ return getBooleanAttribute(this, 'invalid');
76
+ }
77
+
78
+ set disabled(isDisabled) {
79
+ updateBooleanAttribute(this, 'disabled', isDisabled);
80
+ }
81
+
82
+ get disabled() {
83
+ return getBooleanAttribute(this, 'disabled');
84
+ }
85
+
86
+ attributeChangedCallback(name, oldVal, newVal) {
87
+ if (oldVal === newVal) {
88
+ return;
89
+ }
90
+
91
+ switch (name) {
92
+ case 'text':
93
+ {
94
+ const value = newVal ?? '';
95
+ this.#$text.textContent = value.length > 0 ? value : this.placeholder;
96
+ break;
97
+ }
98
+
99
+ case 'placeholder':
100
+ {
101
+ const value = this.text;
102
+
103
+ if (value.length === 0) {
104
+ this.#$text.textContent = newVal ?? '';
105
+ }
106
+
107
+ break;
108
+ }
109
+
110
+ case 'invalid':
111
+ {
112
+ const isInvalid = isAttrTrue(newVal);
113
+ updateBooleanAttribute(this, 'invalid', isInvalid);
114
+ updateExplicitBooleanAttribute(this, 'aria-invalid', isInvalid);
115
+ break;
116
+ }
117
+
118
+ case 'disabled':
119
+ {
120
+ const isDisabled = isAttrTrue(newVal);
121
+ this.#$button.disabled = isDisabled;
122
+ updateBooleanAttribute(this, 'disabled', isDisabled);
123
+ break;
124
+ }
125
+ }
126
+ }
127
+
128
+ get focusable() {
129
+ return true;
130
+ }
131
+
132
+ focus() {
133
+ this.#$button.focus();
134
+ }
135
+
136
+ blur() {
137
+ this.#$button.blur();
138
+ }
139
+
140
+ #onButtonFocus = () => {
141
+ this.dispatchEvent(new CustomEvent('-focus'));
142
+ };
143
+ #onButtonBlur = () => {
144
+ this.dispatchEvent(new CustomEvent('-blur'));
145
+ };
146
+ #onButtonClick = () => {
147
+ this.dispatchEvent(new CustomEvent('-click'));
148
+ };
149
+ #onClickReactHandler = e => {
150
+ getReactEventHandler(this, 'on-click')?.(e);
151
+ };
152
+ #onFocusReactHandler = () => {
153
+ getReactEventHandler(this, 'on-focus')?.();
154
+ };
155
+ #onBlurReactHandler = () => {
156
+ getReactEventHandler(this, 'on-blur')?.();
157
+ };
158
+ });
@@ -0,0 +1,43 @@
1
+ import type { TSinchElementReact } from '../types';
2
+ export declare type TSinchSelectButtonElement = HTMLElement & {
3
+ /** Text */
4
+ text: string;
5
+ /** Text that appears in the text field when it has no text set */
6
+ placeholder: string;
7
+ /** Invalid state */
8
+ invalid: boolean;
9
+ /** Disabled */
10
+ disabled: boolean;
11
+ /** Click event */
12
+ addEventListener(type: '-click', listener: (e: CustomEvent<void>) => void): void;
13
+ /** Focus event */
14
+ addEventListener(type: '-focus', listener: (e: CustomEvent<void>) => void): void;
15
+ /** Blur event */
16
+ addEventListener(type: '-blur', listener: (e: CustomEvent<void>) => void): void;
17
+ /** Text */
18
+ setAttribute(name: 'text', value: string): void;
19
+ /** Text that appears in the text field when it has no value set */
20
+ setAttribute(name: 'placeholder', value: string): void;
21
+ /** Invalid state */
22
+ setAttribute(name: 'invalid', value: ''): void;
23
+ /** Disabled */
24
+ setAttribute(name: 'disabled', value: ''): void;
25
+ };
26
+ export declare type TSinchSelectButtonReact = TSinchElementReact<TSinchSelectButtonElement> & {
27
+ /** Text */
28
+ text: string;
29
+ /** Label that is used for a11y` */
30
+ 'aria-label': string;
31
+ /** Text that appears in the text field when it has no text set */
32
+ placeholder: string;
33
+ /** Invalid state */
34
+ invalid?: boolean;
35
+ /** Disabled */
36
+ disabled?: boolean;
37
+ /** Click handler */
38
+ 'on-click'?: (e: CustomEvent<void>) => void;
39
+ /** Focus handler */
40
+ 'on-focus'?: (e: CustomEvent<void>) => void;
41
+ /** Blur handler */
42
+ 'on-blur'?: (e: CustomEvent<void>) => void;
43
+ };
@@ -0,0 +1,11 @@
1
+ import type { TSinchSelectMenuElement, TSinchSelectMenuReact } from './types';
2
+ declare global {
3
+ namespace JSX {
4
+ interface IntrinsicElements {
5
+ 'sinch-select-menu': TSinchSelectMenuReact;
6
+ }
7
+ }
8
+ interface HTMLElementTagNameMap {
9
+ 'sinch-select-menu': TSinchSelectMenuElement;
10
+ }
11
+ }