@nectary/components 0.41.0 → 0.42.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 (128) 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 +1 -1
  63. package/pagination/index.js +0 -31
  64. package/pop/index.js +64 -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/{utils → theme}/colors.d.ts +0 -1
  96. package/{utils → theme}/colors.js +0 -1
  97. package/theme.css +13 -209
  98. package/tile-control/index.js +0 -24
  99. package/tile-control-option/index.js +0 -18
  100. package/time-picker/index.js +2 -51
  101. package/time-picker/utils.js +0 -18
  102. package/title/index.js +1 -12
  103. package/title/utils.js +0 -5
  104. package/toast/index.js +0 -19
  105. package/toast-manager/index.js +0 -27
  106. package/toggle/index.js +0 -23
  107. package/tooltip/index.js +0 -27
  108. package/tooltip/utils.js +0 -4
  109. package/utils/animation.js +0 -20
  110. package/utils/context.js +0 -6
  111. package/utils/index.d.ts +1 -0
  112. package/utils/index.js +11 -52
  113. package/vertical-stepper/index.js +0 -12
  114. package/vertical-stepper-item/index.js +0 -14
  115. package/avatar-badge/index.d.ts +0 -11
  116. package/avatar-badge/index.js +0 -38
  117. package/avatar-badge/types.d.ts +0 -8
  118. package/avatar-status/index.d.ts +0 -11
  119. package/avatar-status/index.js +0 -37
  120. package/avatar-status/types.d.ts +0 -9
  121. package/avatar-status/types.js +0 -1
  122. package/avatar-status/utils.d.ts +0 -5
  123. package/avatar-status/utils.js +0 -6
  124. package/chat-avatar/index.d.ts +0 -12
  125. package/chat-avatar/index.js +0 -52
  126. package/chat-avatar/types.d.ts +0 -12
  127. package/chat-avatar/types.js +0 -1
  128. /package/{avatar-badge → badge}/types.js +0 -0
@@ -15,7 +15,6 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
15
15
  #$right;
16
16
  #$buttons;
17
17
  #$wrapper;
18
-
19
18
  constructor() {
20
19
  super();
21
20
  const shadowRoot = this.attachShadow();
@@ -25,22 +24,18 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
25
24
  this.#$buttons = shadowRoot.querySelectorAll('.page');
26
25
  this.#$wrapper = shadowRoot.querySelector('#wrapper');
27
26
  }
28
-
29
27
  connectedCallback() {
30
28
  this.#onValueChange();
31
29
  this.#$wrapper.addEventListener('click', this.#onButtonClick);
32
30
  this.addEventListener('-change', this.#onChangeReactHandler);
33
31
  }
34
-
35
32
  disconnectedCallback() {
36
33
  this.#$wrapper.removeEventListener('click', this.#onButtonClick);
37
34
  this.removeEventListener('-change', this.#onChangeReactHandler);
38
35
  }
39
-
40
36
  static get observedAttributes() {
41
37
  return ['max', 'value'];
42
38
  }
43
-
44
39
  attributeChangedCallback(name, _) {
45
40
  switch (name) {
46
41
  case 'value':
@@ -48,7 +43,6 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
48
43
  this.#onValueChange();
49
44
  break;
50
45
  }
51
-
52
46
  case 'max':
53
47
  {
54
48
  this.#onValueChange();
@@ -56,35 +50,27 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
56
50
  }
57
51
  }
58
52
  }
59
-
60
53
  get nodeName() {
61
54
  return 'select';
62
55
  }
63
-
64
56
  set value(val) {
65
57
  updateAttribute(this, 'value', val);
66
58
  }
67
-
68
59
  get value() {
69
60
  return getIntegerAttribute(this, 'value', 0);
70
61
  }
71
-
72
62
  set max(val) {
73
63
  updateAttribute(this, 'max', val);
74
64
  }
75
-
76
65
  get max() {
77
66
  return getIntegerAttribute(this, 'value', 0);
78
67
  }
79
-
80
68
  #onValueChange() {
81
69
  const value = getIntegerAttribute(this, 'value', 0) - 1;
82
70
  const max = Math.max(0, getIntegerAttribute(this, 'max', 0));
83
71
  const valueOffset = Math.min(Math.max(0, value - MIDDLE_BTN_INDEX), Math.max(0, max - NUM_BUTTONS));
84
-
85
72
  for (let i = 0; i < this.#$buttons.length; i++) {
86
73
  const $b = this.#$buttons[i];
87
-
88
74
  if (value < 3) {
89
75
  setClass($b, 'active', value === i);
90
76
  } else if (value >= max - MIDDLE_BTN_INDEX) {
@@ -92,24 +78,19 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
92
78
  } else {
93
79
  setClass($b, 'active', i === MIDDLE_BTN_INDEX);
94
80
  }
95
-
96
81
  if (max > NUM_BUTTONS) {
97
82
  setClass($b, 'dots', i === DOTS_LEFT_INDEX && value > MIDDLE_BTN_INDEX || i === DOTS_RIGHT_INDEX && value <= max - DOTS_RIGHT_INDEX);
98
83
  }
99
-
100
84
  setClass($b, 'hidden', i >= max);
101
85
  const btnText = $b.firstElementChild;
102
-
103
86
  if (btnText != null) {
104
87
  btnText.textContent = i === FIRST_BTN_INDEX ? '1' : i === LAST_BTN_INDEX ? String(max) : String(i + 1 + valueOffset);
105
88
  }
106
89
  }
107
-
108
90
  const isValueBad = value < 0 || value >= max;
109
91
  this.#$left.disabled = isValueBad || value === 0;
110
92
  this.#$right.disabled = isValueBad || value === max - 1;
111
93
  }
112
-
113
94
  #onButtonClick = e => {
114
95
  e.stopPropagation();
115
96
  const value = getIntegerAttribute(this, 'value', 0) - 1;
@@ -122,9 +103,7 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
122
103
  if (e.target === this.#$right) {
123
104
  return this.#dispatchChangeEvent(value + 1);
124
105
  }
125
-
126
106
  const btnIndex = Array.prototype.indexOf.call(this.#$wrapper.children, e.target) - 1;
127
-
128
107
  if (btnIndex >= 0 && btnIndex < this.#$buttons.length) {
129
108
  if (btnIndex === FIRST_BTN_INDEX) {
130
109
  return this.#dispatchChangeEvent(0);
@@ -145,12 +124,10 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
145
124
  return this.#dispatchChangeEvent(btnIndex + Math.min(Math.max(0, value - MIDDLE_BTN_INDEX), Math.max(0, max - NUM_BUTTONS)));
146
125
  }
147
126
  };
148
-
149
127
  #clamp(value) {
150
128
  const max = getIntegerAttribute(this, 'max', 0);
151
129
  return Math.max(0, Math.min(max - 1, value)) + 1;
152
130
  }
153
-
154
131
  #dispatchChangeEvent(value) {
155
132
  const detail = this.#clamp(value);
156
133
  this.dispatchEvent(new CustomEvent('change', {
@@ -161,36 +138,28 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
161
138
  detail
162
139
  }));
163
140
  }
164
-
165
141
  #onChangeReactHandler = e => {
166
142
  getReactEventHandler(this, 'on-change')?.(e);
167
143
  };
168
-
169
144
  get focusable() {
170
145
  return true;
171
146
  }
172
-
173
147
  focus() {
174
148
  this.#$left.focus();
175
149
  }
176
-
177
150
  blur() {
178
151
  this.#$left.blur();
179
152
  this.#$right.blur();
180
153
  this.#$buttons.forEach($b => $b.blur());
181
154
  }
182
-
183
155
  get prevButtonRect() {
184
156
  return getRect(this.#$left);
185
157
  }
186
-
187
158
  get nextButtonRect() {
188
159
  return getRect(this.#$right);
189
160
  }
190
-
191
161
  nthButtonRect(index) {
192
162
  const btn = this.#$buttons[index];
193
163
  return btn == null ? null : getRect(btn);
194
164
  }
195
-
196
165
  });
package/pop/index.js CHANGED
@@ -19,7 +19,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
19
19
  #controller = null;
20
20
  #keydownContext;
21
21
  #visibilityContext;
22
-
22
+ #targetStyleValue = null;
23
23
  constructor() {
24
24
  super();
25
25
  const shadowRoot = this.attachShadow();
@@ -39,7 +39,6 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
39
39
 
40
40
  dialogPolyfill.dm.handleFocus_ = function () {};
41
41
  }
42
-
43
42
  connectedCallback() {
44
43
  this.#controller = new AbortController();
45
44
  const {
@@ -62,12 +61,10 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
62
61
  });
63
62
  dispatchContextConnectEvent(this, 'visibility');
64
63
  this.#isConnected = true;
65
-
66
64
  if (getBooleanAttribute(this, 'open')) {
67
65
  this.#onExpand();
68
66
  }
69
67
  }
70
-
71
68
  disconnectedCallback() {
72
69
  this.#controller.abort();
73
70
  this.#keydownContext.unsubscribe();
@@ -76,56 +73,43 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
76
73
  this.#onCollapse();
77
74
  this.#isConnected = false;
78
75
  }
79
-
80
76
  static get observedAttributes() {
81
77
  return ['orientation', 'open'];
82
78
  }
83
-
84
79
  set modal(isModal) {
85
80
  updateBooleanAttribute(this, 'modal', isModal);
86
81
  }
87
-
88
82
  get modal() {
89
83
  return getBooleanAttribute(this, 'modal');
90
84
  }
91
-
92
85
  set open(isOpen) {
93
86
  updateBooleanAttribute(this, 'open', isOpen);
94
87
  }
95
-
96
88
  get open() {
97
89
  return getBooleanAttribute(this, 'open');
98
90
  }
99
-
100
91
  get orientation() {
101
92
  return getLiteralAttribute(this, orientationValues, 'orientation');
102
93
  }
103
-
104
94
  set orientation(value) {
105
95
  updateLiteralAttribute(this, orientationValues, 'orientation', value);
106
96
  }
107
-
108
97
  set inset(inset) {
109
98
  updateIntegerAttribute(this, 'inset', inset);
110
99
  }
111
-
112
100
  get inset() {
113
101
  return getIntegerAttribute(this, 'inset', 0);
114
102
  }
115
-
116
103
  get footprintRect() {
117
104
  return this.#getTargetRect();
118
105
  }
119
-
120
106
  get popoverRect() {
121
107
  return getRect(this.#$dialog);
122
108
  }
123
-
124
109
  attributeChangedCallback(name, oldVal, newVal) {
125
110
  if (oldVal === newVal) {
126
111
  return;
127
112
  }
128
-
129
113
  switch (name) {
130
114
  case 'open':
131
115
  {
@@ -136,38 +120,39 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
136
120
  } else {
137
121
  this.#onCollapse();
138
122
  }
139
-
140
123
  updateBooleanAttribute(this, 'open', isAttrTrue(newVal));
141
124
  break;
142
125
  }
143
-
144
126
  case 'orientation':
145
127
  {
146
128
  assertOrientation(newVal);
147
-
148
129
  if (this.#isOpen()) {
149
130
  this.#updateOrientation();
150
131
  }
151
-
152
132
  break;
153
133
  }
154
134
  }
155
135
  }
156
-
157
136
  #getTargetRect() {
158
- const item = getFirstSlotElement(this.#$targetSlot, true);
159
-
137
+ let item = getFirstSlotElement(this.#$targetSlot, true);
138
+ if (item === null && this.#isOpen()) {
139
+ item = getFirstSlotElement(this.#$targetOpenSlot, true);
140
+ }
160
141
  if (item === null) {
161
142
  return getRect(this.#$target);
162
143
  }
163
-
164
144
  if (Reflect.has(item, 'footprintRect')) {
165
145
  return item.footprintRect;
166
146
  }
167
-
168
147
  return getRect(item);
169
148
  }
170
-
149
+ #getFirstTargetElement(slot) {
150
+ const item = getFirstSlotElement(slot, true);
151
+ if (item === null) {
152
+ return this.#$target;
153
+ }
154
+ return item;
155
+ }
171
156
  #onExpand() {
172
157
  if (!this.#isConnected || this.#isOpen()) {
173
158
  return;
@@ -180,50 +165,64 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
180
165
  this.#$focus.removeEventListener('focus', this.#captureRelatedActiveElement);
181
166
  this.#$focus.style.removeProperty('display');
182
167
  this.#$targetSlot.removeEventListener('blur', this.#stopEventPropagation, true);
168
+
183
169
  this.#$dialog.showModal();
184
170
  this.#$target.setAttribute('aria-expanded', 'true');
185
171
  this.#updateOrientation();
186
-
187
172
  if (this.modal) {
188
173
  getFirstFocusableElement(this.#$contentSlot)?.focus();
189
174
  } else {
175
+ const $targetEl = this.#getFirstTargetElement(this.#$targetSlot);
176
+ const targetElComputedStyle = getComputedStyle($targetEl);
177
+ const marginLeft = parseInt(targetElComputedStyle.marginLeft);
178
+ const marginRight = parseInt(targetElComputedStyle.marginRight);
179
+ const marginTop = parseInt(targetElComputedStyle.marginTop);
180
+ const marginBottom = parseInt(targetElComputedStyle.marginBottom);
190
181
  const targetRect = this.#getTargetRect();
191
- const widthPx = `${targetRect.width}px`;
192
- const heightPx = `${targetRect.height}px`;
193
182
  this.#$target.style.setProperty('display', 'block');
194
- this.#$target.style.setProperty('width', widthPx);
195
- this.#$target.style.setProperty('height', heightPx);
196
- this.#$targetOpenWrapper.style.setProperty('width', widthPx);
197
- this.#$targetOpenWrapper.style.setProperty('height', heightPx);
183
+ this.#$target.style.setProperty('width', `${targetRect.width + marginLeft + marginRight}px`);
184
+ this.#$target.style.setProperty('height', `${targetRect.height + marginTop + marginBottom}px`);
185
+ this.#$targetOpenWrapper.style.setProperty('width', `${targetRect.width}px`);
186
+ this.#$targetOpenWrapper.style.setProperty('height', `${targetRect.height}px`);
187
+ this.#targetStyleValue = $targetEl.getAttribute('style');
188
+ $targetEl.style.setProperty('margin', '0');
189
+ $targetEl.style.setProperty('position', 'static');
190
+ if (targetElComputedStyle.transform !== 'none') {
191
+ const matrix = new DOMMatrixReadOnly(targetElComputedStyle.transform);
192
+ $targetEl.style.setProperty('transform', matrix.translate(-matrix.e, -matrix.f).toString());
193
+ }
194
+
198
195
  getFirstSlotElement(this.#$targetSlot)?.setAttribute('slot', 'target-open');
199
- this.#$targetOpenSlot.addEventListener('keydown', this.#onTargetKeydown);
200
196
 
197
+ this.#$targetOpenSlot.addEventListener('keydown', this.#onTargetKeydown);
201
198
  if (this.#targetActiveElement !== null) {
202
- requestAnimationFrame(this.#focusTargetElementOnExpandNonModal);
203
- this.#focusTargetElementOnExpandNonModal();
199
+ this.#$targetOpenSlot.addEventListener('focus', this.#stopEventPropagation, true);
200
+ this.#targetActiveElement.focus();
201
+ this.#$targetOpenSlot.removeEventListener('focus', this.#stopEventPropagation, true);
202
+
203
+ if (!isElementFocused(this.#targetActiveElement)) {
204
+ requestAnimationFrame(() => {
205
+ this.#$targetOpenSlot.addEventListener('focus', this.#stopEventPropagation, true);
206
+ this.#targetActiveElement.focus();
207
+ this.#$targetOpenSlot.removeEventListener('focus', this.#stopEventPropagation, true);
208
+ });
209
+ }
204
210
  }
205
211
  }
206
212
 
207
213
  disableScroll();
208
214
  window.addEventListener('resize', this.#onResize);
215
+
209
216
  this.#dispatchContentVisibility(true);
210
217
  }
211
-
212
- #focusTargetElementOnExpandNonModal = () => {
213
- if (this.#targetActiveElement !== null) {
214
- this.#$targetOpenSlot.addEventListener('focus', this.#stopEventPropagation, true);
215
- this.#targetActiveElement.focus();
216
- this.#$targetOpenSlot.removeEventListener('focus', this.#stopEventPropagation, true);
217
- }
218
- };
219
-
220
218
  #onCollapse() {
221
219
  if (!this.#isOpen()) {
222
220
  return;
223
221
  }
224
-
225
222
  const isNonModal = !this.modal;
223
+
226
224
  this.#dispatchContentVisibility(false);
225
+
227
226
  this.#$targetOpenSlot.removeEventListener('keydown', this.#onTargetKeydown);
228
227
 
229
228
  if (isNonModal) {
@@ -238,6 +237,14 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
238
237
  this.#$targetOpenSlot.removeEventListener('blur', this.#captureActiveElement, true);
239
238
  }
240
239
 
240
+ const targetEl = this.#getFirstTargetElement(this.#$targetOpenSlot);
241
+ targetEl.style.removeProperty('margin');
242
+ targetEl.style.removeProperty('position');
243
+ targetEl.style.removeProperty('transform');
244
+ if (this.#targetStyleValue !== null) {
245
+ targetEl.setAttribute('style', this.#targetStyleValue);
246
+ this.#targetStyleValue = null;
247
+ }
241
248
  getFirstSlotElement(this.#$targetOpenSlot)?.setAttribute('slot', 'target');
242
249
  this.#$target.style.removeProperty('display');
243
250
  this.#$target.style.removeProperty('width');
@@ -248,20 +255,26 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
248
255
  this.#$targetSlot.addEventListener('focus', this.#stopEventPropagation, true);
249
256
  this.#targetActiveElement.focus();
250
257
  this.#$targetSlot.removeEventListener('focus', this.#stopEventPropagation, true);
251
- }
252
258
 
253
- this.#targetActiveElement = null;
259
+ if (!isElementFocused(this.#targetActiveElement)) {
260
+ const $targetEl = this.#targetActiveElement;
261
+ requestAnimationFrame(() => {
262
+ this.#$targetSlot.addEventListener('focus', this.#stopEventPropagation, true);
263
+ $targetEl.focus();
264
+ this.#$targetSlot.removeEventListener('focus', this.#stopEventPropagation, true);
265
+ });
266
+ }
267
+ this.#targetActiveElement = null;
268
+ }
254
269
  }
255
270
 
256
271
  enableScroll();
257
272
  this.#resizeThrottle.cancel();
258
273
  window.removeEventListener('resize', this.#onResize);
259
274
  }
260
-
261
275
  #isOpen() {
262
276
  return getBooleanAttribute(this.#$dialog, 'open');
263
277
  }
264
-
265
278
  #onResize = () => {
266
279
  this.#resizeThrottle.fn();
267
280
  };
@@ -276,45 +289,35 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
276
289
  const inset = this.inset;
277
290
  let xPos = 0;
278
291
  let yPos = 0;
279
-
280
292
  if (orient === 'bottom-right' || orient === 'top-right' || orient === 'top-stretch' || orient === 'bottom-stretch') {
281
293
  xPos = targetRect.x;
282
294
  }
283
-
284
295
  if (orient === 'bottom-left' || orient === 'top-left') {
285
296
  xPos = targetRect.x + targetRect.width - modalWidth;
286
297
  }
287
-
288
298
  if (orient === 'bottom-center' || orient === 'top-center') {
289
299
  xPos = targetRect.x + targetRect.width / 2 - modalWidth / 2;
290
300
  }
291
-
292
301
  if (orient === 'center-right') {
293
302
  xPos = targetRect.x + targetRect.width;
294
303
  }
295
-
296
304
  if (orient === 'center-left') {
297
305
  xPos = targetRect.x - modalWidth;
298
306
  }
299
-
300
307
  if (orient === 'bottom-left' || orient === 'bottom-right' || orient === 'bottom-stretch' || orient === 'bottom-center') {
301
308
  yPos = targetRect.y + targetRect.height;
302
309
  }
303
-
304
310
  if (orient === 'top-left' || orient === 'top-right' || orient === 'top-stretch' || orient === 'top-center') {
305
311
  yPos = targetRect.y - modalHeight;
306
312
  }
307
-
308
313
  if (orient === 'center-left' || orient === 'center-right') {
309
314
  yPos = targetRect.y + targetRect.height / 2 - modalHeight / 2;
310
315
  }
311
-
312
316
  xPos = Math.round(Math.max(inset, Math.min(xPos, window.innerWidth - modalWidth - inset)));
313
317
  yPos = Math.round(Math.max(inset, Math.min(yPos, window.innerHeight - modalHeight - inset)));
314
318
  this.#$dialog.style.setProperty('left', `${xPos}px`);
315
319
  this.#$dialog.style.setProperty('top', `${yPos}px`);
316
320
  this.#$dialog.style.setProperty('width', `${modalWidth}px`);
317
-
318
321
  if (!this.modal) {
319
322
  const targetLeftPos = targetRect.x - xPos;
320
323
  const targetTopPos = targetRect.y - yPos;
@@ -326,10 +329,8 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
326
329
  if (e.target !== this.#$dialog) {
327
330
  return;
328
331
  }
329
-
330
332
  const rect = this.popoverRect;
331
333
  const isInside = e.x >= rect.x && e.x < rect.x + rect.width && e.y >= rect.y && e.y < rect.y + rect.height;
332
-
333
334
  if (!isInside) {
334
335
  this.#dispatchCloseEvent();
335
336
  }
@@ -341,11 +342,9 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
341
342
  #onCloseReactHandler = e => {
342
343
  getReactEventHandler(this, 'on-close')?.(e);
343
344
  };
344
-
345
345
  #dispatchCloseEvent() {
346
346
  this.dispatchEvent(new CustomEvent('-close'));
347
347
  }
348
-
349
348
  #captureRelatedActiveElement = e => {
350
349
  e.stopPropagation();
351
350
  this.#targetActiveElement = e.relatedTarget;
@@ -357,7 +356,6 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
357
356
  #stopEventPropagation = e => {
358
357
  e.stopPropagation();
359
358
  };
360
-
361
359
  #dispatchContentVisibility(isVisible) {
362
360
  for (const $el of this.#visibilityContext.elements) {
363
361
  $el.dispatchEvent(new CustomEvent('-visibility', {
@@ -365,7 +363,6 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
365
363
  }));
366
364
  }
367
365
  }
368
-
369
366
  #onTargetKeydown = e => {
370
367
  for (const $el of this.#keydownContext.elements) {
371
368
  let isPrevented = false;
@@ -377,7 +374,6 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
377
374
  }
378
375
  }
379
376
  }));
380
-
381
377
  if (isPrevented) {
382
378
  e.preventDefault();
383
379
  }
package/pop/utils.js CHANGED
@@ -11,7 +11,6 @@ export const disableScroll = () => {
11
11
  };
12
12
  export const enableScroll = () => {
13
13
  bodyEl.__pop_counter__ = Math.max(0, (bodyEl.__pop_counter__ ?? 0) - 1);
14
-
15
14
  if (bodyEl.__pop_counter__ === 0) {
16
15
  document.body.style.overflow = '';
17
16
  }
package/popover/index.js CHANGED
@@ -11,7 +11,6 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
11
11
  #$content;
12
12
  #$tip;
13
13
  #controller = null;
14
-
15
14
  constructor() {
16
15
  super();
17
16
  const shadowRoot = this.attachShadow();
@@ -20,7 +19,6 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
20
19
  this.#$content = shadowRoot.querySelector('#content');
21
20
  this.#$tip = shadowRoot.querySelector('#tip');
22
21
  }
23
-
24
22
  connectedCallback() {
25
23
  this.#controller = new AbortController();
26
24
  const {
@@ -38,12 +36,10 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
38
36
  dispatchContextConnectEvent(this.#$content, 'visibility');
39
37
  updateAttribute(this.#$pop, 'orientation', getPopOrientation(this.orientation));
40
38
  }
41
-
42
39
  disconnectedCallback() {
43
40
  dispatchContextDisconnectEvent(this.#$content, 'visibility');
44
41
  this.#controller.abort();
45
42
  }
46
-
47
43
  #onPopClose = () => {
48
44
  this.#dispatchCloseEvent();
49
45
  };
@@ -51,84 +47,64 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
51
47
  getReactEventHandler(this, 'onClose')?.();
52
48
  getReactEventHandler(this, 'on-close')?.(e);
53
49
  };
54
-
55
50
  #dispatchCloseEvent() {
56
51
  this.dispatchEvent(new CustomEvent('-close'));
57
52
  }
58
-
59
53
  static get observedAttributes() {
60
54
  return ['orientation', 'open', 'modal', 'tip'];
61
55
  }
62
-
63
56
  set modal(isModal) {
64
57
  updateBooleanAttribute(this, 'modal', isModal);
65
58
  }
66
-
67
59
  get modal() {
68
60
  return getBooleanAttribute(this, 'modal');
69
61
  }
70
-
71
62
  set open(isOpen) {
72
63
  updateBooleanAttribute(this, 'open', isOpen);
73
64
  }
74
-
75
65
  get open() {
76
66
  return getBooleanAttribute(this, 'open');
77
67
  }
78
-
79
68
  set tip(hasTip) {
80
69
  updateBooleanAttribute(this, 'tip', hasTip);
81
70
  }
82
-
83
71
  get tip() {
84
72
  return getBooleanAttribute(this, 'tip');
85
73
  }
86
-
87
74
  get orientation() {
88
75
  return getLiteralAttribute(this, orientationValues, 'orientation', 'bottom-left');
89
76
  }
90
-
91
77
  set orientation(value) {
92
78
  updateLiteralAttribute(this, orientationValues, 'orientation', value);
93
79
  }
94
-
95
80
  get footprintRect() {
96
81
  return this.#$pop.footprintRect;
97
82
  }
98
-
99
83
  get popoverRect() {
100
84
  return this.#$pop.popoverRect;
101
85
  }
102
-
103
86
  attributeChangedCallback(name, oldVal, newVal) {
104
87
  if (oldVal === newVal) {
105
88
  return;
106
89
  }
107
-
108
90
  switch (name) {
109
91
  case 'orientation':
110
92
  {
111
93
  assertOrientation(newVal);
112
94
  updateAttribute(this.#$pop, 'orientation', getPopOrientation(newVal));
113
-
114
95
  if (this.#isOpen()) {
115
96
  this.#updateTipOrientation();
116
97
  }
117
-
118
98
  break;
119
99
  }
120
-
121
100
  case 'tip':
122
101
  {
123
102
  updateBooleanAttribute(this, 'tip', isAttrTrue(newVal));
124
-
125
103
  if (newVal === '' && this.#isOpen()) {
126
104
  this.#updateTipOrientation();
127
105
  }
128
-
129
106
  break;
130
107
  }
131
-
132
108
  case 'open':
133
109
  {
134
110
  const isOpen = isAttrTrue(newVal);
@@ -136,14 +112,12 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
136
112
  updateBooleanAttribute(this, name, isOpen);
137
113
  break;
138
114
  }
139
-
140
115
  default:
141
116
  {
142
117
  updateAttribute(this.#$pop, name, newVal);
143
118
  }
144
119
  }
145
120
  }
146
-
147
121
  #onContextVisibility = e => {
148
122
  if (e.detail) {
149
123
  this.#updateTipOrientation();
@@ -151,34 +125,27 @@ defineCustomElement('sinch-popover', class extends NectaryElement {
151
125
  this.#resetTipOrientation();
152
126
  }
153
127
  };
154
-
155
128
  #resetTipOrientation() {
156
129
  this.#$tip.style.top = '';
157
130
  this.#$tip.style.left = '';
158
131
  }
159
-
160
132
  #updateTipOrientation = () => {
161
133
  const orientation = this.orientation;
162
134
  const targetRect = this.#$pop.footprintRect;
163
135
  const contentRect = this.#$content.getBoundingClientRect();
164
136
  const diffX = targetRect.x - contentRect.x;
165
137
  let desiredX = diffX + targetRect.width / 2;
166
-
167
138
  if (orientation === 'bottom-left' || orientation === 'top-left') {
168
139
  desiredX = Math.max(desiredX, contentRect.width * 0.75);
169
140
  }
170
-
171
141
  if (orientation === 'bottom-right' || orientation === 'top-right') {
172
142
  desiredX = Math.min(desiredX, contentRect.width * 0.25);
173
143
  }
174
-
175
144
  const xPos = Math.max(TIP_SIZE, Math.min(desiredX, contentRect.width - TIP_SIZE));
176
145
  this.#$tip.style.left = `${xPos}px`;
177
146
  setClass(this.#$tip, 'hidden', rectOverlap(targetRect, contentRect));
178
147
  };
179
-
180
148
  #isOpen() {
181
149
  return this.#$pop.open;
182
150
  }
183
-
184
151
  });
package/popover/utils.js CHANGED
@@ -3,11 +3,9 @@ export const getPopOrientation = orientation => {
3
3
  if (orientation === 'top') {
4
4
  return 'top-stretch';
5
5
  }
6
-
7
6
  if (orientation === 'bottom') {
8
7
  return 'bottom-stretch';
9
8
  }
10
-
11
9
  return orientation;
12
10
  };
13
11
  export const assertOrientation = value => {