@nectary/components 0.41.1 → 0.42.1

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 (139) hide show
  1. package/accordion/index.js +0 -16
  2. package/accordion/types.d.ts +9 -1
  3. package/accordion-item/index.js +0 -24
  4. package/accordion-item/types.d.ts +18 -3
  5. package/action-menu/index.js +1 -45
  6. package/action-menu-option/index.js +0 -18
  7. package/alert/index.js +0 -10
  8. package/alert/types.d.ts +6 -0
  9. package/avatar/index.js +57 -20
  10. package/avatar/types.d.ts +25 -7
  11. package/avatar/utils.d.ts +10 -2
  12. package/avatar/utils.js +23 -2
  13. package/badge/index.d.ts +11 -0
  14. package/badge/index.js +140 -0
  15. package/badge/types.d.ts +38 -0
  16. package/badge/utils.d.ts +11 -0
  17. package/badge/utils.js +23 -0
  18. package/button/index.js +0 -18
  19. package/card/index.js +0 -16
  20. package/card/types.d.ts +15 -3
  21. package/card-container/index.js +0 -1
  22. package/chat/index.js +0 -1
  23. package/chat-block/index.js +0 -19
  24. package/chat-block/types.d.ts +16 -4
  25. package/chat-bubble/index.js +0 -9
  26. package/chat-bubble/types.d.ts +6 -0
  27. package/checkbox/index.js +0 -23
  28. package/chip/index.js +16 -25
  29. package/chip/utils.d.ts +3 -0
  30. package/chip/utils.js +11 -0
  31. package/color-menu/index.js +8 -86
  32. package/color-menu/utils.js +0 -4
  33. package/color-swatch/index.js +17 -17
  34. package/color-swatch/types.d.ts +2 -2
  35. package/color-swatch/utils.d.ts +3 -0
  36. package/color-swatch/utils.js +11 -0
  37. package/date-picker/index.js +1 -50
  38. package/date-picker/utils.js +0 -7
  39. package/dialog/index.js +1 -17
  40. package/field/index.js +0 -19
  41. package/file-drop/index.js +0 -40
  42. package/file-drop/utils.js +0 -6
  43. package/file-picker/index.js +0 -17
  44. package/file-picker/utils.js +0 -1
  45. package/file-status/index.js +0 -12
  46. package/grid/index.js +0 -1
  47. package/grid-item/index.js +0 -9
  48. package/help-tooltip/index.js +0 -14
  49. package/horizontal-stepper/index.js +0 -12
  50. package/horizontal-stepper-item/index.js +0 -14
  51. package/icon-button/index.js +0 -15
  52. package/icons/create-icon-class.js +0 -2
  53. package/icons-branded/create-icon-class.js +0 -8
  54. package/icons-channel/create-icon-class.js +0 -6
  55. package/illustrations/create-illustration-class.js +0 -11
  56. package/inline-alert/index.js +0 -14
  57. package/input/index.js +0 -37
  58. package/link/index.js +0 -25
  59. package/list/index.js +0 -2
  60. package/list-item/index.js +0 -2
  61. package/logo/create-logo-class.js +0 -9
  62. package/package.json +3 -1
  63. package/pagination/index.js +0 -31
  64. package/pop/index.js +26 -68
  65. package/pop/utils.js +0 -1
  66. package/popover/index.js +0 -33
  67. package/popover/utils.js +0 -2
  68. package/progress/index.js +0 -10
  69. package/radio/index.js +0 -30
  70. package/radio-option/index.js +0 -20
  71. package/segment/index.js +0 -15
  72. package/segment-collapse/index.js +0 -13
  73. package/segmented-control/index.js +0 -12
  74. package/segmented-control-option/index.js +0 -18
  75. package/segmented-icon-control/index.js +0 -16
  76. package/segmented-icon-control-option/index.js +0 -14
  77. package/select-button/index.js +0 -23
  78. package/select-menu/index.js +1 -63
  79. package/select-menu-option/index.js +0 -14
  80. package/spinner/index.js +0 -4
  81. package/stop-events/index.js +0 -5
  82. package/table/index.js +0 -2
  83. package/table-body/index.js +0 -2
  84. package/table-cell/index.js +0 -4
  85. package/table-head/index.js +0 -2
  86. package/table-head-cell/index.js +0 -11
  87. package/table-row/index.js +0 -6
  88. package/tabs/index.js +0 -30
  89. package/tabs-option/index.js +0 -19
  90. package/tag/index.js +18 -21
  91. package/tag/utils.d.ts +3 -0
  92. package/tag/utils.js +11 -0
  93. package/text/index.js +1 -12
  94. package/textarea/index.js +0 -40
  95. package/theme/avatar.css +25 -0
  96. package/theme/badge.css +15 -0
  97. package/theme/chip.css +53 -0
  98. package/theme/color-swatch.css +65 -0
  99. package/{utils → theme}/colors.d.ts +0 -1
  100. package/{utils → theme}/colors.js +0 -1
  101. package/theme/elevation.css +7 -0
  102. package/theme/fonts.css +76 -0
  103. package/theme/fonts.json +79 -0
  104. package/theme/palette.css +90 -0
  105. package/theme/shapes.css +7 -0
  106. package/theme/tag.css +53 -0
  107. package/theme/typography.css +16 -0
  108. package/theme.css +13 -209
  109. package/tile-control/index.js +0 -24
  110. package/tile-control-option/index.js +0 -18
  111. package/time-picker/index.js +2 -51
  112. package/time-picker/utils.js +0 -18
  113. package/title/index.js +1 -12
  114. package/title/utils.js +0 -5
  115. package/toast/index.js +0 -19
  116. package/toast-manager/index.js +0 -27
  117. package/toggle/index.js +0 -23
  118. package/tooltip/index.js +0 -27
  119. package/tooltip/utils.js +0 -4
  120. package/utils/animation.js +0 -20
  121. package/utils/context.js +0 -6
  122. package/utils/index.d.ts +1 -0
  123. package/utils/index.js +11 -52
  124. package/vertical-stepper/index.js +0 -12
  125. package/vertical-stepper-item/index.js +0 -14
  126. package/avatar-badge/index.d.ts +0 -11
  127. package/avatar-badge/index.js +0 -38
  128. package/avatar-badge/types.d.ts +0 -8
  129. package/avatar-status/index.d.ts +0 -11
  130. package/avatar-status/index.js +0 -37
  131. package/avatar-status/types.d.ts +0 -9
  132. package/avatar-status/types.js +0 -1
  133. package/avatar-status/utils.d.ts +0 -5
  134. package/avatar-status/utils.js +0 -6
  135. package/chat-avatar/index.d.ts +0 -12
  136. package/chat-avatar/index.js +0 -52
  137. package/chat-avatar/types.d.ts +0 -12
  138. package/chat-avatar/types.js +0 -1
  139. /package/{avatar-badge → badge}/types.js +0 -0
@@ -33,7 +33,6 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
33
33
  #$submitButton;
34
34
  #hour = 0;
35
35
  #minute = 0;
36
-
37
36
  constructor() {
38
37
  super();
39
38
  const shadowRoot = this.attachShadow();
@@ -67,10 +66,9 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
67
66
  el.textContent = hourDisplayValue;
68
67
  hours12Frag.appendChild(el);
69
68
  }
70
-
71
69
  this.#$pickerHours.appendChild(hours12Frag);
72
- const hours24Frag = document.createDocumentFragment();
73
70
 
71
+ const hours24Frag = document.createDocumentFragment();
74
72
  for (let i = 12; i < 24; i++) {
75
73
  const rad = Math.PI / 6 * (i - 3);
76
74
  const el = document.createElement('div');
@@ -82,10 +80,9 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
82
80
  el.textContent = hourDisplayValue;
83
81
  hours24Frag.appendChild(el);
84
82
  }
85
-
86
83
  this.#$pickerHours.appendChild(hours24Frag);
87
- const minutesFrag = document.createDocumentFragment();
88
84
 
85
+ const minutesFrag = document.createDocumentFragment();
89
86
  for (let i = 0; i < 60; i += 5) {
90
87
  const rad = Math.PI / 30 * (i - 15);
91
88
  const el = document.createElement('div');
@@ -96,10 +93,8 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
96
93
  el.textContent = stringifyMinute(i);
97
94
  minutesFrag.appendChild(el);
98
95
  }
99
-
100
96
  this.#$pickerMinutes.appendChild(minutesFrag);
101
97
  }
102
-
103
98
  connectedCallback() {
104
99
  this.#$pickerTouch.addEventListener('click', this.#onPickerClick);
105
100
  this.#$ampm.addEventListener('change', this.#onAmPmChange);
@@ -108,7 +103,6 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
108
103
  this.#$headerMinutes.addEventListener('keydown', this.#onMinutesKeydown);
109
104
  this.addEventListener('-change', this.#onChangeReactHandler);
110
105
  }
111
-
112
106
  disconnectedCallback() {
113
107
  this.#$pickerTouch.removeEventListener('click', this.#onPickerClick);
114
108
  this.#$ampm.removeEventListener('change', this.#onAmPmChange);
@@ -117,23 +111,19 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
117
111
  this.#$headerMinutes.removeEventListener('keydown', this.#onMinutesKeydown);
118
112
  this.removeEventListener('-change', this.#onChangeReactHandler);
119
113
  }
120
-
121
114
  static get observedAttributes() {
122
115
  return ['value', 'ampm', 'submit-aria-label'];
123
116
  }
124
-
125
117
  attributeChangedCallback(name, prevValue, newVal) {
126
118
  if (newVal === prevValue) {
127
119
  return;
128
120
  }
129
-
130
121
  switch (name) {
131
122
  case 'value':
132
123
  {
133
124
  if (newVal === null) {
134
125
  throw new Error('Missing "value" attribute');
135
126
  }
136
-
137
127
  const {
138
128
  hours,
139
129
  minutes
@@ -143,7 +133,6 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
143
133
  this.#render();
144
134
  break;
145
135
  }
146
-
147
136
  case 'ampm':
148
137
  {
149
138
  const isAmpm = isAttrTrue(newVal);
@@ -151,7 +140,6 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
151
140
  this.#render();
152
141
  break;
153
142
  }
154
-
155
143
  case 'submit-aria-label':
156
144
  {
157
145
  updateAttribute(this.#$submitButton, 'aria-label', newVal);
@@ -159,67 +147,52 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
159
147
  }
160
148
  }
161
149
  }
162
-
163
150
  get nodeName() {
164
151
  return 'select';
165
152
  }
166
-
167
153
  set value(value) {
168
154
  updateAttribute(this, 'value', value);
169
155
  }
170
-
171
156
  get value() {
172
157
  return getAttribute(this, 'value', '');
173
158
  }
174
-
175
159
  set ampm(value) {
176
160
  updateBooleanAttribute(this, 'ampm', value);
177
161
  }
178
-
179
162
  get ampm() {
180
163
  return getBooleanAttribute(this, 'ampm');
181
164
  }
182
-
183
165
  set submitAriaLabel(value) {
184
166
  updateAttribute(this, 'submit-aria-label', value);
185
167
  }
186
-
187
168
  get submitAriaLabel() {
188
169
  return getAttribute(this, 'submit-aria-label', '');
189
170
  }
190
-
191
171
  get submitButtonRect() {
192
172
  return getRect(this.#$submitButton);
193
173
  }
194
-
195
174
  get amButtonRect() {
196
175
  if (!this.ampm) {
197
176
  return null;
198
177
  }
199
-
200
178
  const $am = this.#$ampm.querySelector('[value="am"]');
201
179
  return $am != null ? getRect($am) : null;
202
180
  }
203
-
204
181
  get pmButtonRect() {
205
182
  if (!this.ampm) {
206
183
  return null;
207
184
  }
208
-
209
185
  const $pm = this.#$ampm.querySelector('[value="pm"]');
210
186
  return $pm != null ? getRect($pm) : null;
211
187
  }
212
-
213
188
  hourDigitRect(hour) {
214
189
  const $digit = this.#$pickerHours.children[hourToIndex(hour, !this.ampm)];
215
190
  return $digit != null ? getRect($digit) : null;
216
191
  }
217
-
218
192
  minuteDigitRect(minute) {
219
193
  const $digit = this.#$pickerMinutes.children[Math.round(minute / 5)];
220
194
  return $digit != null ? getRect($digit) : null;
221
195
  }
222
-
223
196
  #getClickDegree(x, y) {
224
197
  const touchRect = this.#$pickerTouch.getBoundingClientRect();
225
198
  const cx = touchRect.width / 2;
@@ -233,7 +206,6 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
233
206
  const rad = Math.acos(cosRad * (dy < 0 ? -1 : 1));
234
207
  const deg = rad * (180 / Math.PI);
235
208
  let cssDeg = (deg - 90 - 360) % 360 * -1;
236
-
237
209
  if (dy < 0) {
238
210
  cssDeg += 180;
239
211
  }
@@ -241,16 +213,13 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
241
213
  const rowIndex = len > MINUTE_RADIUS ? 0 : len > HOUR_12_RADIUS ? 1 : 2;
242
214
  return [cssDeg, rowIndex];
243
215
  }
244
-
245
216
  #onPickerClick = e => {
246
217
  const [cssDeg, rowIndex] = this.#getClickDegree(e.x, e.y);
247
218
  const isHourRowClick = rowIndex > 0;
248
219
  const isHour24RowClick = rowIndex > 1;
249
-
250
220
  if (isHourRowClick) {
251
221
  const digitIndex = Math.round(cssDeg / 30) % 12;
252
222
  const is24 = getBooleanAttribute(this, 'ampm') === false;
253
-
254
223
  if (is24) {
255
224
  if (isHour24RowClick) {
256
225
  this.#hour = digitIndex === 0 ? 0 : digitIndex + 12;
@@ -260,16 +229,13 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
260
229
  } else {
261
230
  this.#hour = digitIndex + (this.#$ampm.value === 'pm' ? 12 : 0);
262
231
  }
263
-
264
232
  this.#$headerHours.focus();
265
233
  } else {
266
234
  this.#minute = Math.round(cssDeg / 6) % 60;
267
235
  this.#$headerMinutes.focus();
268
236
  }
269
-
270
237
  this.#render();
271
238
  };
272
-
273
239
  #render() {
274
240
  const is24 = getBooleanAttribute(this, 'ampm') === false;
275
241
  this.#selectHour(is24);
@@ -281,20 +247,16 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
281
247
  updateAttribute(this.#$headerMinutes, 'aria-valuenow', this.#minute);
282
248
  updateAttribute(this.#$headerMinutes, 'aria-valuetext', this.#minute);
283
249
  }
284
-
285
250
  #selectHour(is24) {
286
251
  const $hours = this.#$pickerHours.children;
287
252
  const hourDigitIndex = this.#hour % 12;
288
253
  const selectedIndex = hourToIndex(this.#hour, is24);
289
254
  const currentCssDeg = getNeedleRotationDeg(this.#$needleHour);
290
255
  const hourCssDeg = getShortestCssDeg(currentCssDeg, hourDigitIndex * 30);
291
-
292
256
  for (let i = 0; i < $hours.length; i++) {
293
257
  setClass($hours[i], 'selected', i === selectedIndex);
294
258
  }
295
-
296
259
  this.#$needleHour.style.transform = `rotate(${hourCssDeg}deg)`;
297
-
298
260
  if (is24) {
299
261
  if (this.#hour > 0 && this.#hour <= 12) {
300
262
  this.#$needleHour.style.height = `${NEEDLE_HOUR_12_LENGTH}px`;
@@ -304,29 +266,23 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
304
266
  } else {
305
267
  this.#$needleHour.style.height = `${NEEDLE_HOUR_12_LENGTH}px`;
306
268
  }
307
-
308
269
  this.#$ampm.setAttribute('value', this.#hour >= 0 && this.#hour < 12 ? 'am' : 'pm');
309
270
  }
310
-
311
271
  #selectMinute() {
312
272
  const $minutes = this.#$pickerMinutes.children;
313
273
  const isNeedleSelected = this.#minute % 5 === 0;
314
274
  const selectedIndex = this.#minute / 5;
315
275
  const currentCssDeg = getNeedleRotationDeg(this.#$needleMinute);
316
276
  const minuteCssDeg = getShortestCssDeg(currentCssDeg, this.#minute * 6);
317
-
318
277
  for (let i = 0; i < $minutes.length; i++) {
319
278
  setClass($minutes[i], 'selected', selectedIndex === i);
320
279
  }
321
-
322
280
  setClass(this.#$needleMinute, 'selected', isNeedleSelected);
323
281
  this.#$needleMinute.style.transform = `rotate(${minuteCssDeg}deg)`;
324
282
  }
325
-
326
283
  #onAmPmChange = e => {
327
284
  e.stopPropagation();
328
285
  const value = e.detail;
329
-
330
286
  switch (value) {
331
287
  case 'am':
332
288
  {
@@ -334,17 +290,14 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
334
290
  this.#hour -= 12;
335
291
  this.#render();
336
292
  }
337
-
338
293
  break;
339
294
  }
340
-
341
295
  case 'pm':
342
296
  {
343
297
  if (this.#hour < 12) {
344
298
  this.#hour += 12;
345
299
  this.#render();
346
300
  }
347
-
348
301
  break;
349
302
  }
350
303
  }
@@ -368,7 +321,6 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
368
321
  this.#render();
369
322
  break;
370
323
  }
371
-
372
324
  case 'ArrowDown':
373
325
  {
374
326
  e.preventDefault();
@@ -387,7 +339,6 @@ defineCustomElement('sinch-time-picker', class extends NectaryElement {
387
339
  this.#render();
388
340
  break;
389
341
  }
390
-
391
342
  case 'ArrowDown':
392
343
  {
393
344
  e.preventDefault();
@@ -5,39 +5,30 @@ export const parseTime = value => {
5
5
  minutes: 0
6
6
  };
7
7
  }
8
-
9
8
  const timeParts = value.split(':');
10
-
11
9
  if (timeParts.length < 3) {
12
10
  throw new Error(`Incorrect time format: ${value}. Should be "hh:mm:ss"`);
13
11
  }
14
-
15
12
  const hours = parseInt(timeParts[0]);
16
13
  const minutes = parseInt(timeParts[1]);
17
14
  const seconds = parseInt(timeParts[2]);
18
-
19
15
  if (isNaN(hours) || hours > 23 || hours < 0) {
20
16
  throw new Error(`Invalid hours value: ${value}`);
21
17
  }
22
-
23
18
  if (isNaN(minutes) || minutes > 59 || minutes < 0) {
24
19
  throw new Error(`Invalid minutes value: ${value}`);
25
20
  }
26
-
27
21
  if (isNaN(seconds) || seconds > 59 || seconds < 0) {
28
22
  throw new Error(`Invalid seconds value: ${value}`);
29
23
  }
30
-
31
24
  return {
32
25
  hours,
33
26
  minutes
34
27
  };
35
28
  };
36
-
37
29
  const pad = value => {
38
30
  return value.toString().padStart(2, '0');
39
31
  };
40
-
41
32
  export const stringifyTime = (hour, minute) => {
42
33
  return `${pad(hour)}:${pad(minute)}:00`;
43
34
  };
@@ -45,11 +36,9 @@ export const stringifyHour = (hour, is24) => {
45
36
  if (is24) {
46
37
  return pad(hour);
47
38
  }
48
-
49
39
  if (hour === 0 || hour === 12) {
50
40
  return '12';
51
41
  }
52
-
53
42
  return pad(hour % 12);
54
43
  };
55
44
  export const stringifyHourFace = hour => {
@@ -63,32 +52,25 @@ export const hourToIndex = (hour, is24) => {
63
52
  if (hour === 0) {
64
53
  return 12;
65
54
  }
66
-
67
55
  if (hour === 12) {
68
56
  return 0;
69
57
  }
70
-
71
58
  return hour;
72
59
  }
73
-
74
60
  return hour % 12;
75
61
  };
76
62
  export const getNeedleRotationDeg = elem => {
77
63
  const match = elem.style.transform.match(/^rotate\((-?\d+)deg\)$/);
78
-
79
64
  if (match === null) {
80
65
  return 0;
81
66
  }
82
-
83
67
  return Number(match[1]);
84
68
  };
85
69
  export const getShortestCssDeg = (currentDeg, nextDeg) => {
86
70
  const angle = currentDeg % 360;
87
71
  const diff = (360 - (angle - nextDeg)) % 360;
88
-
89
72
  if (diff > 180) {
90
73
  return currentDeg - 360 + diff;
91
74
  }
92
-
93
75
  return currentDeg + diff;
94
76
  };
package/title/index.js CHANGED
@@ -6,46 +6,38 @@ const template = document.createElement('template');
6
6
  template.innerHTML = templateHTML;
7
7
  defineCustomElement('sinch-title', class extends NectaryElement {
8
8
  #$text;
9
-
10
9
  constructor() {
11
10
  super();
12
11
  const shadowRoot = this.attachShadow();
13
12
  shadowRoot.appendChild(template.content.cloneNode(true));
14
13
  this.#$text = shadowRoot.querySelector('#text');
15
14
  }
16
-
17
15
  connectedCallback() {
18
16
  this.setAttribute('role', 'heading');
17
+
19
18
  }
20
19
 
21
20
  get text() {
22
21
  return getAttribute(this, 'text', '');
23
22
  }
24
-
25
23
  set text(value) {
26
24
  updateAttribute(this, 'text', value);
27
25
  }
28
-
29
26
  set type(value) {
30
27
  updateLiteralAttribute(this, typeValues, 'type', value);
31
28
  }
32
-
33
29
  get type() {
34
30
  return getLiteralAttribute(this, typeValues, 'type');
35
31
  }
36
-
37
32
  set ellipsis(isEllipsis) {
38
33
  updateBooleanAttribute(this, 'ellipsis', isEllipsis);
39
34
  }
40
-
41
35
  get ellipsis() {
42
36
  return getBooleanAttribute(this, 'ellipsis');
43
37
  }
44
-
45
38
  static get observedAttributes() {
46
39
  return ['text', 'type', 'level'];
47
40
  }
48
-
49
41
  attributeChangedCallback(name, _, newVal) {
50
42
  switch (name) {
51
43
  case 'text':
@@ -53,14 +45,12 @@ defineCustomElement('sinch-title', class extends NectaryElement {
53
45
  this.#$text.textContent = newVal;
54
46
  break;
55
47
  }
56
-
57
48
  case 'level':
58
49
  {
59
50
  assertLevel(newVal);
60
51
  updateAttribute(this, 'aria-level', newVal);
61
52
  break;
62
53
  }
63
-
64
54
  case 'type':
65
55
  {
66
56
  assertType(newVal);
@@ -68,5 +58,4 @@ defineCustomElement('sinch-title', class extends NectaryElement {
68
58
  }
69
59
  }
70
60
  }
71
-
72
61
  });
package/title/utils.js CHANGED
@@ -14,19 +14,14 @@ export const getTitleLevelFromType = type => {
14
14
  switch (type) {
15
15
  case 'xl':
16
16
  return '1';
17
-
18
17
  case 'l':
19
18
  return '2';
20
-
21
19
  case 'm':
22
20
  return '3';
23
-
24
21
  case 's':
25
22
  return '4';
26
-
27
23
  case 'xs':
28
24
  return '5';
29
-
30
25
  default:
31
26
  throw new Error(`sinch-title: invalid type value: ${type}`);
32
27
  }
package/toast/index.js CHANGED
@@ -13,72 +13,58 @@ template.innerHTML = templateHTML;
13
13
  defineCustomElement('sinch-toast', class extends NectaryElement {
14
14
  #$text;
15
15
  #tid = null;
16
-
17
16
  constructor() {
18
17
  super();
19
18
  const shadowRoot = this.attachShadow();
20
19
  shadowRoot.appendChild(template.content.cloneNode(true));
21
20
  this.#$text = shadowRoot.querySelector('#text');
22
21
  }
23
-
24
22
  connectedCallback() {
25
23
  this.setAttribute('aria-atomic', 'true');
26
24
  this.setAttribute('aria-live', 'polite');
27
25
  this.addEventListener('-timeout', this.#onTimeoutReactHandler);
28
26
  this.#updateTimeout();
29
27
  }
30
-
31
28
  disconnectedCallback() {
32
29
  this.removeEventListener('-timeout', this.#onTimeoutReactHandler);
33
30
  this.#clearTimeout();
34
31
  }
35
-
36
32
  get type() {
37
33
  return getLiteralAttribute(this, typeValues, 'type');
38
34
  }
39
-
40
35
  set type(value) {
41
36
  updateLiteralAttribute(this, typeValues, 'type', value);
42
37
  }
43
-
44
38
  get text() {
45
39
  return getAttribute(this, 'text', '');
46
40
  }
47
-
48
41
  set text(value) {
49
42
  updateAttribute(this, 'text', value);
50
43
  }
51
-
52
44
  get persistent() {
53
45
  return getBooleanAttribute(this, 'persistent');
54
46
  }
55
-
56
47
  set persistent(isPersistent) {
57
48
  updateBooleanAttribute(this, 'persistent', isPersistent);
58
49
  }
59
-
60
50
  static get observedAttributes() {
61
51
  return ['text', 'type', 'persistent'];
62
52
  }
63
-
64
53
  attributeChangedCallback(name, oldVal, newVal) {
65
54
  if (oldVal === newVal) {
66
55
  return;
67
56
  }
68
-
69
57
  switch (name) {
70
58
  case 'type':
71
59
  {
72
60
  assertType(newVal);
73
61
  break;
74
62
  }
75
-
76
63
  case 'text':
77
64
  {
78
65
  this.#$text.textContent = newVal;
79
66
  break;
80
67
  }
81
-
82
68
  case 'persistent':
83
69
  {
84
70
  this.#updateTimeout();
@@ -86,29 +72,24 @@ defineCustomElement('sinch-toast', class extends NectaryElement {
86
72
  }
87
73
  }
88
74
  }
89
-
90
75
  #updateTimeout() {
91
76
  if (this.persistent) {
92
77
  this.#clearTimeout();
93
78
  return;
94
79
  }
95
-
96
80
  if (this.#tid === null) {
97
81
  this.#tid = window.setTimeout(this.#onTimeout, TIMEOUT);
98
82
  }
99
83
  }
100
-
101
84
  #onTimeout = () => {
102
85
  this.dispatchEvent(new CustomEvent('-timeout'));
103
86
  };
104
-
105
87
  #clearTimeout() {
106
88
  if (this.#tid !== null) {
107
89
  window.clearTimeout(this.#tid);
108
90
  this.#tid = null;
109
91
  }
110
92
  }
111
-
112
93
  #onTimeoutReactHandler = e => {
113
94
  getReactEventHandler(this, 'on-timeout')?.(e);
114
95
  };
@@ -17,7 +17,6 @@ defineCustomElement('sinch-toast-manager', class extends NectaryElement {
17
17
  #map = new WeakMap();
18
18
  #shouldReduceMotion = false;
19
19
  #animations = new Set();
20
-
21
20
  constructor() {
22
21
  super();
23
22
  const shadowRoot = this.attachShadow();
@@ -25,31 +24,25 @@ defineCustomElement('sinch-toast-manager', class extends NectaryElement {
25
24
  this.#$slot = shadowRoot.querySelector('slot');
26
25
  this.#$list = shadowRoot.querySelector('#list');
27
26
  }
28
-
29
27
  connectedCallback() {
30
28
  this.#$slot.addEventListener('slotchange', this.#onSlotChange);
31
29
  this.#shouldReduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
32
30
  }
33
-
34
31
  disconnectedCallback() {
35
32
  this.#$slot.removeEventListener('slotchange', this.#onSlotChange);
36
33
  this.#clear();
37
34
  }
38
-
39
35
  get containerRect() {
40
36
  return getRect(this.#$list);
41
37
  }
42
-
43
38
  nthActionRect(nth) {
44
39
  const item = this.#$list.children[nth]?.querySelector('[slot=action]');
45
40
  return item != null ? getRect(item) : null;
46
41
  }
47
-
48
42
  nthCloseRect(nth) {
49
43
  const item = this.#$list.children[nth]?.querySelector('[slot=close]');
50
44
  return item != null ? getRect(item) : null;
51
45
  }
52
-
53
46
  #onAnimateAdd(item, index, height) {
54
47
  const duration = this.#shouldReduceMotion ? 0 : DURATION_ADD;
55
48
  const addAnim = item.animate({
@@ -63,7 +56,6 @@ defineCustomElement('sinch-toast-manager', class extends NectaryElement {
63
56
  });
64
57
  this.#storeAnimation(addAnim);
65
58
  }
66
-
67
59
  #onAnimateRemove(item, index) {
68
60
  const rect = item.getBoundingClientRect();
69
61
  const duration = this.#shouldReduceMotion ? 0 : DURATION_REMOVE;
@@ -88,42 +80,33 @@ defineCustomElement('sinch-toast-manager', class extends NectaryElement {
88
80
  this.#storeAnimation(heightAnim, () => item.remove());
89
81
  this.#storeAnimation(opacityAnim);
90
82
  }
91
-
92
83
  #onSlotChange = () => {
93
84
  const slotItems = this.#$slot.assignedElements();
94
85
  const listItems = Array.from(this.#$list.children);
95
86
  let removeIndex = 0;
96
-
97
87
  for (const item of listItems) {
98
88
  if (item.hasAttribute('data-deleting')) {
99
89
  ++removeIndex;
100
90
  continue;
101
91
  }
102
-
103
92
  const orig = this.#map.get(item);
104
-
105
93
  if (orig != null && slotItems.includes(orig)) {
106
94
  continue;
107
95
  }
108
-
109
96
  this.#map.delete(item);
110
-
111
97
  if (orig != null) {
112
98
  this.#map.delete(orig);
113
99
  }
114
-
115
100
  this.#unsubscribeChildren(item);
116
101
  this.#onAnimateRemove(item, removeIndex);
117
102
  ++removeIndex;
118
103
  }
119
104
 
120
105
  let addIndex = 0;
121
-
122
106
  for (const item of slotItems) {
123
107
  if (this.#map.has(item)) {
124
108
  continue;
125
109
  }
126
-
127
110
  const cloned = cloneNode(item, true);
128
111
  const rect = item.getBoundingClientRect();
129
112
  const wrapper = document.createElement('div');
@@ -137,7 +120,6 @@ defineCustomElement('sinch-toast-manager', class extends NectaryElement {
137
120
  addIndex++;
138
121
  }
139
122
  };
140
-
141
123
  #storeAnimation(anim, cb) {
142
124
  const onAnimEnd = () => {
143
125
  this.#animations.delete(anim);
@@ -146,40 +128,32 @@ defineCustomElement('sinch-toast-manager', class extends NectaryElement {
146
128
  anim.removeEventListener('remove', onAnimEnd);
147
129
  anim.removeEventListener('cancel', onAnimEnd);
148
130
  };
149
-
150
131
  anim.addEventListener('finish', onAnimEnd);
151
132
  anim.addEventListener('remove', onAnimEnd);
152
133
  anim.addEventListener('cancel', onAnimEnd);
153
134
  this.#animations.add(anim);
154
135
  }
155
-
156
136
  #clear() {
157
137
  const listItems = Array.from(this.#$list.children);
158
-
159
138
  for (const item of listItems) {
160
139
  this.#map.delete(item);
161
140
  this.#unsubscribeChildren(item);
162
141
  item.remove();
163
142
  }
164
-
165
143
  for (const anim of this.#animations) {
166
144
  anim.cancel();
167
145
  }
168
146
  }
169
-
170
147
  #subscribeChildren(item) {
171
148
  item.querySelector('[slot=close]')?.addEventListener('-click', this.#onCloneCloseClick);
172
149
  item.querySelector('[slot=action]')?.addEventListener('-click', this.#onCloneActionClick);
173
150
  }
174
-
175
151
  #unsubscribeChildren(item) {
176
152
  item.querySelector('[slot=close]')?.removeEventListener('-click', this.#onCloneCloseClick);
177
153
  item.querySelector('[slot=action]')?.removeEventListener('-click', this.#onCloneActionClick);
178
154
  }
179
-
180
155
  #onCloneCloseClick = e => {
181
156
  const item = e.target.parentElement?.parentElement;
182
-
183
157
  if (item != null) {
184
158
  item.setAttribute('data-delete-now', '');
185
159
  this.#map.get(item)?.querySelector('[slot=close]')?.dispatchEvent(new CustomEvent('-click'));
@@ -187,7 +161,6 @@ defineCustomElement('sinch-toast-manager', class extends NectaryElement {
187
161
  };
188
162
  #onCloneActionClick = e => {
189
163
  const item = e.target.parentElement?.parentElement;
190
-
191
164
  if (item != null) {
192
165
  this.#map.get(item)?.querySelector('[slot=action]')?.dispatchEvent(new CustomEvent('-click'));
193
166
  }