@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
package/pop/index.js ADDED
@@ -0,0 +1,391 @@
1
+ import dialogPolyfill from 'dialog-polyfill';
2
+ import { defineCustomElement, getBooleanAttribute, getLiteralAttribute, getRect, isAttrTrue, updateLiteralAttribute, getReactEventHandler, updateBooleanAttribute, NectaryElement, throttleAnimationFrame, isElementFocused, updateIntegerAttribute, getIntegerAttribute, getFirstFocusableElement, getFirstSlotElement } from '../utils';
3
+ import { Context, dispatchContextConnectEvent, dispatchContextDisconnectEvent } from '../utils/context';
4
+ const templateHTML = '<style>:host{display:contents;position:relative}dialog{position:fixed;left:0;top:0;margin:0;outline:0;padding:0;border:none;box-sizing:border-box;max-width:unset;max-height:unset;z-index:1;background:0 0;overflow:visible}dialog:not([open]){display:none}dialog::backdrop{background-color:transparent}dialog+.backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background-color:transparent}dialog.fixed{position:fixed;top:50%;transform:translate(0,-50%)}._dialog_overlay{position:fixed;top:0;right:0;bottom:0;left:0}#content{position:relative;z-index:1}#target-open{display:flex;flex-direction:column;position:absolute;left:0;top:0}#focus{display:none;position:absolute;width:0;height:0}</style><slot id="target" aria-haspopup="dialog" aria-expanded="false" name="target"></slot><div id="focus" tabindex="-1"></div><dialog id="dialog"><div id="content"><slot name="content"></slot></div><div id="target-open"><slot name="target-open"></slot></div></dialog>';
5
+ import { assertOrientation, disableScroll, enableScroll, orientationValues } from './utils';
6
+ const template = document.createElement('template');
7
+ template.innerHTML = templateHTML;
8
+ defineCustomElement('sinch-pop', class extends NectaryElement {
9
+ #$target;
10
+ #$focus;
11
+ #$dialog;
12
+ #isConnected;
13
+ #resizeThrottle;
14
+ #$targetSlot;
15
+ #$targetOpenSlot;
16
+ #$contentSlot;
17
+ #$targetOpenWrapper;
18
+ #targetActiveElement = null;
19
+ #controller = null;
20
+ #keydownContext;
21
+ #visibilityContext;
22
+
23
+ constructor() {
24
+ super();
25
+ const shadowRoot = this.attachShadow();
26
+ shadowRoot.appendChild(template.content.cloneNode(true));
27
+ this.#$target = shadowRoot.querySelector('#target');
28
+ this.#$focus = shadowRoot.querySelector('#focus');
29
+ this.#$dialog = shadowRoot.querySelector('#dialog');
30
+ this.#$targetSlot = shadowRoot.querySelector('slot[name="target"]');
31
+ this.#$targetOpenSlot = shadowRoot.querySelector('slot[name="target-open"]');
32
+ this.#$contentSlot = shadowRoot.querySelector('slot[name="content"]');
33
+ this.#$targetOpenWrapper = shadowRoot.querySelector('#target-open');
34
+ this.#isConnected = false;
35
+ this.#resizeThrottle = throttleAnimationFrame(this.#updateOrientation);
36
+ this.#keydownContext = new Context(this.#$contentSlot, 'keydown');
37
+ this.#visibilityContext = new Context(this.#$contentSlot, 'visibility');
38
+ dialogPolyfill.registerDialog(this.#$dialog);
39
+
40
+ dialogPolyfill.dm.handleFocus_ = function () {};
41
+ }
42
+
43
+ connectedCallback() {
44
+ this.#controller = new AbortController();
45
+ const {
46
+ signal
47
+ } = this.#controller;
48
+ this.#keydownContext.subscribe();
49
+ this.#visibilityContext.subscribe();
50
+ this.setAttribute('role', 'dialog');
51
+ this.#$dialog.addEventListener('cancel', this.#onCancel, {
52
+ signal
53
+ });
54
+ this.#$dialog.addEventListener('mousedown', this.#onBackdropMouseDown, {
55
+ signal
56
+ });
57
+ this.addEventListener('-close', this.#onCloseReactHandler, {
58
+ signal
59
+ });
60
+ this.addEventListener('-visibility', this.#onContextVisibility, {
61
+ signal
62
+ });
63
+ dispatchContextConnectEvent(this, 'visibility');
64
+ this.#isConnected = true;
65
+
66
+ if (getBooleanAttribute(this, 'open')) {
67
+ this.#onExpand();
68
+ }
69
+ }
70
+
71
+ disconnectedCallback() {
72
+ this.#controller.abort();
73
+ this.#keydownContext.unsubscribe();
74
+ this.#visibilityContext.unsubscribe();
75
+ dispatchContextDisconnectEvent(this, 'visibility');
76
+ this.#onCollapse();
77
+ this.#isConnected = false;
78
+ }
79
+
80
+ static get observedAttributes() {
81
+ return ['orientation', 'open'];
82
+ }
83
+
84
+ set modal(isModal) {
85
+ updateBooleanAttribute(this, 'modal', isModal);
86
+ }
87
+
88
+ get modal() {
89
+ return getBooleanAttribute(this, 'modal');
90
+ }
91
+
92
+ set open(isOpen) {
93
+ updateBooleanAttribute(this, 'open', isOpen);
94
+ }
95
+
96
+ get open() {
97
+ return getBooleanAttribute(this, 'open');
98
+ }
99
+
100
+ get orientation() {
101
+ return getLiteralAttribute(this, orientationValues, 'orientation');
102
+ }
103
+
104
+ set orientation(value) {
105
+ updateLiteralAttribute(this, orientationValues, 'orientation', value);
106
+ }
107
+
108
+ set inset(inset) {
109
+ updateIntegerAttribute(this, 'inset', inset);
110
+ }
111
+
112
+ get inset() {
113
+ return getIntegerAttribute(this, 'inset', 0);
114
+ }
115
+
116
+ get footprintRect() {
117
+ return this.#getTargetRect();
118
+ }
119
+
120
+ get popoverRect() {
121
+ return getRect(this.#$dialog);
122
+ }
123
+
124
+ attributeChangedCallback(name, oldVal, newVal) {
125
+ if (oldVal === newVal) {
126
+ return;
127
+ }
128
+
129
+ switch (name) {
130
+ case 'open':
131
+ {
132
+ if (isAttrTrue(newVal)) {
133
+ requestAnimationFrame(() => {
134
+ this.#onExpand();
135
+ });
136
+ } else {
137
+ this.#onCollapse();
138
+ }
139
+
140
+ updateBooleanAttribute(this, 'open', isAttrTrue(newVal));
141
+ break;
142
+ }
143
+
144
+ case 'orientation':
145
+ {
146
+ assertOrientation(newVal);
147
+
148
+ if (this.#isOpen()) {
149
+ this.#updateOrientation();
150
+ }
151
+
152
+ break;
153
+ }
154
+ }
155
+ }
156
+
157
+ #getTargetRect() {
158
+ const item = getFirstSlotElement(this.#$targetSlot, true);
159
+
160
+ if (item === null) {
161
+ return getRect(this.#$target);
162
+ }
163
+
164
+ if (Reflect.has(item, 'footprintRect')) {
165
+ return item.footprintRect;
166
+ }
167
+
168
+ return getRect(item);
169
+ }
170
+
171
+ #onExpand() {
172
+ if (!this.#isConnected || this.#isOpen()) {
173
+ return;
174
+ }
175
+
176
+ this.#$targetSlot.addEventListener('blur', this.#stopEventPropagation, true);
177
+ this.#$focus.style.setProperty('display', 'block');
178
+ this.#$focus.addEventListener('focus', this.#captureRelatedActiveElement);
179
+ this.#$focus.focus();
180
+ this.#$focus.removeEventListener('focus', this.#captureRelatedActiveElement);
181
+ this.#$focus.style.removeProperty('display');
182
+ this.#$targetSlot.removeEventListener('blur', this.#stopEventPropagation, true);
183
+ this.#$dialog.showModal();
184
+ this.#$target.setAttribute('aria-expanded', 'true');
185
+ this.#updateOrientation();
186
+
187
+ if (this.modal) {
188
+ getFirstFocusableElement(this.#$contentSlot)?.focus();
189
+ } else {
190
+ const targetRect = this.#getTargetRect();
191
+ const widthPx = `${targetRect.width}px`;
192
+ const heightPx = `${targetRect.height}px`;
193
+ 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);
198
+ getFirstSlotElement(this.#$targetSlot)?.setAttribute('slot', 'target-open');
199
+ this.#$targetOpenSlot.addEventListener('keydown', this.#onTargetKeydown);
200
+
201
+ if (this.#targetActiveElement !== null) {
202
+ requestAnimationFrame(this.#focusTargetElementOnExpandNonModal);
203
+ this.#focusTargetElementOnExpandNonModal();
204
+ }
205
+ }
206
+
207
+ disableScroll();
208
+ window.addEventListener('resize', this.#onResize);
209
+ this.#dispatchContentVisibility(true);
210
+ }
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
+ #onCollapse() {
221
+ if (!this.#isOpen()) {
222
+ return;
223
+ }
224
+
225
+ const isNonModal = !this.modal;
226
+ this.#dispatchContentVisibility(false);
227
+ this.#$targetOpenSlot.removeEventListener('keydown', this.#onTargetKeydown);
228
+
229
+ if (isNonModal) {
230
+ this.#targetActiveElement = null;
231
+ this.#$targetOpenSlot.addEventListener('blur', this.#captureActiveElement, true);
232
+ }
233
+
234
+ this.#$dialog.close();
235
+ this.#$target.setAttribute('aria-expanded', 'false');
236
+
237
+ if (isNonModal) {
238
+ this.#$targetOpenSlot.removeEventListener('blur', this.#captureActiveElement, true);
239
+ }
240
+
241
+ getFirstSlotElement(this.#$targetOpenSlot)?.setAttribute('slot', 'target');
242
+ this.#$target.style.removeProperty('display');
243
+ this.#$target.style.removeProperty('width');
244
+ this.#$target.style.removeProperty('height');
245
+
246
+ if (this.#targetActiveElement !== null) {
247
+ if (!isElementFocused(this.#targetActiveElement)) {
248
+ this.#$targetSlot.addEventListener('focus', this.#stopEventPropagation, true);
249
+ this.#targetActiveElement.focus();
250
+ this.#$targetSlot.removeEventListener('focus', this.#stopEventPropagation, true);
251
+ }
252
+
253
+ this.#targetActiveElement = null;
254
+ }
255
+
256
+ enableScroll();
257
+ this.#resizeThrottle.cancel();
258
+ window.removeEventListener('resize', this.#onResize);
259
+ }
260
+
261
+ #isOpen() {
262
+ return getBooleanAttribute(this.#$dialog, 'open');
263
+ }
264
+
265
+ #onResize = () => {
266
+ this.#resizeThrottle.fn();
267
+ };
268
+ #updateOrientation = () => {
269
+ this.#$dialog.style.setProperty('width', 'max-content');
270
+ const targetRect = this.#getTargetRect();
271
+ const modalRect = this.#$dialog.getBoundingClientRect();
272
+ const orient = this.orientation;
273
+ const shouldSetWidthToTarget = orient === 'top-stretch' || orient === 'bottom-stretch';
274
+ const modalHeight = modalRect.height;
275
+ const modalWidth = shouldSetWidthToTarget ? targetRect.width : modalRect.width;
276
+ const inset = this.inset;
277
+ let xPos = 0;
278
+ let yPos = 0;
279
+
280
+ if (orient === 'bottom-right' || orient === 'top-right' || orient === 'top-stretch' || orient === 'bottom-stretch') {
281
+ xPos = targetRect.x;
282
+ }
283
+
284
+ if (orient === 'bottom-left' || orient === 'top-left') {
285
+ xPos = targetRect.x + targetRect.width - modalWidth;
286
+ }
287
+
288
+ if (orient === 'bottom-center' || orient === 'top-center') {
289
+ xPos = targetRect.x + targetRect.width / 2 - modalWidth / 2;
290
+ }
291
+
292
+ if (orient === 'center-right') {
293
+ xPos = targetRect.x + targetRect.width;
294
+ }
295
+
296
+ if (orient === 'center-left') {
297
+ xPos = targetRect.x - modalWidth;
298
+ }
299
+
300
+ if (orient === 'bottom-left' || orient === 'bottom-right' || orient === 'bottom-stretch' || orient === 'bottom-center') {
301
+ yPos = targetRect.y + targetRect.height;
302
+ }
303
+
304
+ if (orient === 'top-left' || orient === 'top-right' || orient === 'top-stretch' || orient === 'top-center') {
305
+ yPos = targetRect.y - modalHeight;
306
+ }
307
+
308
+ if (orient === 'center-left' || orient === 'center-right') {
309
+ yPos = targetRect.y + targetRect.height / 2 - modalHeight / 2;
310
+ }
311
+
312
+ xPos = Math.round(Math.max(inset, Math.min(xPos, window.innerWidth - modalWidth - inset)));
313
+ yPos = Math.round(Math.max(inset, Math.min(yPos, window.innerHeight - modalHeight - inset)));
314
+ this.#$dialog.style.setProperty('left', `${xPos}px`);
315
+ this.#$dialog.style.setProperty('top', `${yPos}px`);
316
+ this.#$dialog.style.setProperty('width', `${modalWidth}px`);
317
+
318
+ if (!this.modal) {
319
+ const targetLeftPos = targetRect.x - xPos;
320
+ const targetTopPos = targetRect.y - yPos;
321
+ this.#$targetOpenWrapper.style.setProperty('left', `${targetLeftPos}px`);
322
+ this.#$targetOpenWrapper.style.setProperty('top', `${targetTopPos}px`);
323
+ }
324
+ };
325
+ #onBackdropMouseDown = e => {
326
+ if (e.target !== this.#$dialog) {
327
+ return;
328
+ }
329
+
330
+ const rect = this.popoverRect;
331
+ const isInside = e.x >= rect.x && e.x < rect.x + rect.width && e.y >= rect.y && e.y < rect.y + rect.height;
332
+
333
+ if (!isInside) {
334
+ this.#dispatchCloseEvent();
335
+ }
336
+ };
337
+ #onCancel = e => {
338
+ e.preventDefault();
339
+ this.#dispatchCloseEvent();
340
+ };
341
+ #onCloseReactHandler = e => {
342
+ getReactEventHandler(this, 'on-close')?.(e);
343
+ };
344
+
345
+ #dispatchCloseEvent() {
346
+ this.dispatchEvent(new CustomEvent('-close'));
347
+ }
348
+
349
+ #captureRelatedActiveElement = e => {
350
+ e.stopPropagation();
351
+ this.#targetActiveElement = e.relatedTarget;
352
+ };
353
+ #captureActiveElement = e => {
354
+ e.stopPropagation();
355
+ this.#targetActiveElement = e.target;
356
+ };
357
+ #stopEventPropagation = e => {
358
+ e.stopPropagation();
359
+ };
360
+
361
+ #dispatchContentVisibility(isVisible) {
362
+ for (const $el of this.#visibilityContext.elements) {
363
+ $el.dispatchEvent(new CustomEvent('-visibility', {
364
+ detail: isVisible
365
+ }));
366
+ }
367
+ }
368
+
369
+ #onTargetKeydown = e => {
370
+ for (const $el of this.#keydownContext.elements) {
371
+ let isPrevented = false;
372
+ $el.dispatchEvent(new CustomEvent('-keydown', {
373
+ detail: {
374
+ code: e.code,
375
+ preventDefault: () => {
376
+ isPrevented = true;
377
+ }
378
+ }
379
+ }));
380
+
381
+ if (isPrevented) {
382
+ e.preventDefault();
383
+ }
384
+ }
385
+ };
386
+ #onContextVisibility = e => {
387
+ if (!e.detail) {
388
+ this.#dispatchCloseEvent();
389
+ }
390
+ };
391
+ });
package/pop/types.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ import type { TRect, TSinchElementReact } from '../types';
2
+ export declare type TSinchPopOrientation = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'bottom-center' | 'bottom-stretch' | 'top-center' | 'top-stretch' | 'center-right' | 'center-left';
3
+ export declare type TSinchPopElement = HTMLElement & {
4
+ /** Open/close state */
5
+ open: boolean;
6
+ /** Orientation, where it *points to* from origin */
7
+ orientation: TSinchPopOrientation;
8
+ /** Modal/non-modal mode */
9
+ modal: boolean;
10
+ inset: number;
11
+ readonly footprintRect: TRect;
12
+ readonly popoverRect: TRect;
13
+ /** Close event */
14
+ addEventListener(type: '-close', listener: (e: CustomEvent<void>) => void): void;
15
+ /** Open/close state */
16
+ setAttribute(name: 'open', value: ''): void;
17
+ /** Orientation, where it *points to* from origin */
18
+ setAttribute(name: 'orientation', value: TSinchPopOrientation): void;
19
+ /** Modal/non-modal mode */
20
+ setAttribute(name: 'modal', value: boolean): void;
21
+ setAttribute(name: 'inset', value: string): void;
22
+ };
23
+ export declare type TSinchPopReact = TSinchElementReact<TSinchPopElement> & {
24
+ /** Open/close state */
25
+ open: boolean;
26
+ /** Orientation, where it *points to* from origin */
27
+ orientation: TSinchPopOrientation;
28
+ /** Modal/non-modal mode */
29
+ modal?: boolean;
30
+ inset?: number;
31
+ /** Label that is used for a11y */
32
+ 'aria-label': string;
33
+ /** Close event handler */
34
+ 'on-close'?: (e: CustomEvent<void>) => void;
35
+ };
package/pop/utils.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { TSinchPopOrientation } from './types';
2
+ export declare const orientationValues: readonly TSinchPopOrientation[];
3
+ declare type TAssertOrientation = (value: string | null) => asserts value is TSinchPopOrientation;
4
+ export declare const assertOrientation: TAssertOrientation;
5
+ export declare const disableScroll: () => void;
6
+ export declare const enableScroll: () => void;
7
+ export {};
package/pop/utils.js ADDED
@@ -0,0 +1,18 @@
1
+ export const orientationValues = ['top-left', 'top-right', 'bottom-left', 'bottom-right', 'bottom-stretch', 'bottom-center', 'top-stretch', 'top-center', 'center-left', 'center-right'];
2
+ export const assertOrientation = value => {
3
+ if (value === null || !orientationValues.includes(value)) {
4
+ throw new Error(`sinch-pop: invalid orientation attribute: ${value}`);
5
+ }
6
+ };
7
+ const bodyEl = document.body;
8
+ export const disableScroll = () => {
9
+ bodyEl.style.overflow = 'hidden';
10
+ bodyEl.__pop_counter__ = (bodyEl.__pop_counter__ ?? 0) + 1;
11
+ };
12
+ export const enableScroll = () => {
13
+ bodyEl.__pop_counter__ = Math.max(0, (bodyEl.__pop_counter__ ?? 0) - 1);
14
+
15
+ if (bodyEl.__pop_counter__ === 0) {
16
+ document.body.style.overflow = '';
17
+ }
18
+ };
@@ -1,3 +1,4 @@
1
+ import '../pop';
1
2
  import type { TSinchPopoverElement, TSinchPopoverReact } from './types';
2
3
  declare global {
3
4
  namespace JSX {