@brightspot/ui 1.3.0 → 1.4.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 (109) hide show
  1. package/dist/global.d.ts +10 -0
  2. package/dist/storybook/assets/{Avatar.stories-CpXI9mXR.js → Avatar.stories-DrhezTR1.js} +1 -1
  3. package/dist/storybook/assets/{AvatarGroup.stories-D4NymG47.js → AvatarGroup.stories-DrlxT-mF.js} +1 -1
  4. package/dist/storybook/assets/{Badge.stories-BP4Yixze.js → Badge.stories-DtJcBfOR.js} +1 -1
  5. package/dist/storybook/assets/{Button.stories-DDpQzCOq.js → Button.stories-BKUfLgSY.js} +1 -1
  6. package/dist/storybook/assets/{CircularProgress.stories-B82LXwfS.js → CircularProgress.stories-dpmD-XJT.js} +1 -1
  7. package/dist/storybook/assets/{ClipboardMixin.stories-Cr3efF-v.js → ClipboardMixin.stories-C0pnQ7BY.js} +1 -1
  8. package/dist/storybook/assets/{Color-64QXVMR3-BucypS4O.js → Color-64QXVMR3-Dnd9S2a1.js} +1 -1
  9. package/dist/storybook/assets/{Colors.stories-CeKs5FaB.js → Colors.stories-bKK25qgF.js} +1 -1
  10. package/dist/storybook/assets/{ComponentStatesMixin-BkLj42wt.js → ComponentStatesMixin-C2HZ9ZFb.js} +1 -1
  11. package/dist/storybook/assets/{ComponentStatesMixin.stories--YPoyrpQ.js → ComponentStatesMixin.stories-9mRp2zuB.js} +1 -1
  12. package/dist/storybook/assets/{CopyToClipboard.stories-6vqDwd-F.js → CopyToClipboard.stories-BW3oaT1i.js} +1 -1
  13. package/dist/storybook/assets/Debounce.stories-BXx3CKvQ.js +199 -0
  14. package/dist/storybook/assets/{Events.stories-DD9wfoHi.js → Events.stories-PBeiuWQn.js} +1 -1
  15. package/dist/storybook/assets/{Heading.stories-D-Pvm7NG.js → Heading.stories-Djkl0MoC.js} +1 -1
  16. package/dist/storybook/assets/{Icon.stories-BbR3S56H.js → Icon.stories-Cam1fyud.js} +1 -1
  17. package/dist/storybook/assets/{LinearProgress.stories-B9XHLvVn.js → LinearProgress.stories-BDNoYIJu.js} +1 -1
  18. package/dist/storybook/assets/Rtc.stories-BrTAIAi1.js +281 -0
  19. package/dist/storybook/assets/{ScrollShadow.stories-CHFpB4Zf.js → ScrollShadow.stories-DHcKhkag.js} +1 -1
  20. package/dist/storybook/assets/{Throttle.stories-BGNJSyDp.js → Throttle.stories-cSYT_BXu.js} +1 -1
  21. package/dist/storybook/assets/{WithTooltip-SK46ZJ2J-QQZnlVfm.js → WithTooltip-SK46ZJ2J-Df0E-KJO.js} +5 -5
  22. package/dist/storybook/assets/{formatter-OMEEQ6HG-D3LRXsK-.js → formatter-OMEEQ6HG-DFa_WTfb.js} +1 -1
  23. package/dist/storybook/assets/{iframe-CpEKhsmw.css → iframe-BMxUFmpF.css} +1 -1
  24. package/dist/storybook/assets/{iframe-D-tG1MVV.js → iframe-lTczLWsL.js} +73 -73
  25. package/dist/storybook/assets/{index-mcT8sPvs.js → index-yMswRDPh.js} +1 -1
  26. package/dist/storybook/assets/onFind-C6olvKHR.js +1 -0
  27. package/dist/storybook/assets/{onFind.stories-Dagoyfc5.js → onFind.stories-DfW54CDE.js} +10 -10
  28. package/dist/storybook/assets/onRemove.stories-C7W9KyRr.js +234 -0
  29. package/dist/storybook/assets/onVisible.stories-CIl6R0q4.js +187 -0
  30. package/dist/storybook/assets/{syntaxhighlighter-CAVLW7PM-BoS99i_u.js → syntaxhighlighter-CAVLW7PM-DoI0ixeu.js} +1 -1
  31. package/dist/storybook/iframe.html +2 -2
  32. package/dist/storybook/index.json +1 -1
  33. package/dist/storybook/project.json +1 -1
  34. package/dist/tailwind-plugin-button.js +3 -0
  35. package/dist/tailwind-plugin-button.js.map +1 -1
  36. package/dist/tailwind-plugin-button.ts +4 -0
  37. package/dist/util/Socket.d.ts +29 -0
  38. package/dist/util/Socket.d.ts.map +1 -0
  39. package/dist/util/Socket.js +153 -0
  40. package/dist/util/Socket.js.map +1 -0
  41. package/dist/util/Tether.d.ts +18 -0
  42. package/dist/util/Tether.d.ts.map +1 -0
  43. package/dist/util/Tether.js +102 -0
  44. package/dist/util/Tether.js.map +1 -0
  45. package/dist/util/TetherLayout.d.ts +12 -0
  46. package/dist/util/TetherLayout.d.ts.map +1 -0
  47. package/dist/util/TetherLayout.js +121 -0
  48. package/dist/util/TetherLayout.js.map +1 -0
  49. package/dist/util/debounce.d.ts +3 -0
  50. package/dist/util/debounce.d.ts.map +1 -0
  51. package/dist/util/debounce.js +15 -0
  52. package/dist/util/debounce.js.map +1 -0
  53. package/dist/util/focusable.d.ts +9 -0
  54. package/dist/util/focusable.d.ts.map +1 -0
  55. package/dist/util/focusable.js +19 -0
  56. package/dist/util/focusable.js.map +1 -0
  57. package/dist/util/getComponentKey.d.ts +2 -0
  58. package/dist/util/getComponentKey.d.ts.map +1 -0
  59. package/dist/util/getComponentKey.js +21 -0
  60. package/dist/util/getComponentKey.js.map +1 -0
  61. package/dist/util/keyboard.d.ts +8 -0
  62. package/dist/util/keyboard.d.ts.map +1 -0
  63. package/dist/util/keyboard.js +138 -0
  64. package/dist/util/keyboard.js.map +1 -0
  65. package/dist/util/noise.d.ts +6 -0
  66. package/dist/util/noise.d.ts.map +1 -0
  67. package/dist/util/noise.js +43 -0
  68. package/dist/util/noise.js.map +1 -0
  69. package/dist/util/onFindOnce.d.ts +3 -0
  70. package/dist/util/onFindOnce.d.ts.map +1 -0
  71. package/dist/util/onFindOnce.js +25 -0
  72. package/dist/util/onFindOnce.js.map +1 -0
  73. package/dist/util/onRTEReady.d.ts +22 -0
  74. package/dist/util/onRTEReady.d.ts.map +1 -0
  75. package/dist/util/onRTEReady.js +69 -0
  76. package/dist/util/onRTEReady.js.map +1 -0
  77. package/dist/util/onRemove.d.ts +7 -0
  78. package/dist/util/onRemove.d.ts.map +1 -0
  79. package/dist/util/onRemove.js +24 -0
  80. package/dist/util/onRemove.js.map +1 -0
  81. package/dist/util/onVisible.d.ts +3 -0
  82. package/dist/util/onVisible.d.ts.map +1 -0
  83. package/dist/util/onVisible.js +22 -0
  84. package/dist/util/onVisible.js.map +1 -0
  85. package/dist/util/previousUntil.d.ts +2 -0
  86. package/dist/util/previousUntil.d.ts.map +1 -0
  87. package/dist/util/previousUntil.js +21 -0
  88. package/dist/util/previousUntil.js.map +1 -0
  89. package/dist/util/repaint.d.ts +3 -0
  90. package/dist/util/repaint.d.ts.map +1 -0
  91. package/dist/util/repaint.js +14 -0
  92. package/dist/util/repaint.js.map +1 -0
  93. package/dist/util/rtc.d.ts +10 -0
  94. package/dist/util/rtc.d.ts.map +1 -0
  95. package/dist/util/rtc.js +184 -0
  96. package/dist/util/rtc.js.map +1 -0
  97. package/dist/util/storage.d.ts +6 -0
  98. package/dist/util/storage.d.ts.map +1 -0
  99. package/dist/util/storage.js +18 -0
  100. package/dist/util/storage.js.map +1 -0
  101. package/dist/util/transition.d.ts +2 -0
  102. package/dist/util/transition.d.ts.map +1 -0
  103. package/dist/util/transition.js +4 -0
  104. package/dist/util/transition.js.map +1 -0
  105. package/dist/util/types.d.ts +10 -0
  106. package/dist/util/types.d.ts.map +1 -0
  107. package/dist/util/types.js +2 -0
  108. package/dist/util/types.js.map +1 -0
  109. package/package.json +6 -2
@@ -0,0 +1,121 @@
1
+ import { repaint } from './repaint.js';
2
+ export class TetherLayout {
3
+ #oldUpdates;
4
+ #tethers;
5
+ #update;
6
+ #updateInterval;
7
+ constructor() {
8
+ this.#oldUpdates = new WeakMap();
9
+ this.#tethers = [];
10
+ this.#updateInterval = null;
11
+ this.#update = repaint(this.updateImmediately.bind(this));
12
+ }
13
+ get tethers() {
14
+ return this.#tethers;
15
+ }
16
+ add(tether) {
17
+ this.#tethers.push(tether);
18
+ this.start();
19
+ }
20
+ remove(tether) {
21
+ const tethers = this.#tethers;
22
+ const index = tethers.indexOf(tether);
23
+ if (index > -1) {
24
+ tethers.splice(index, 1);
25
+ }
26
+ if (tethers.length < 0) {
27
+ this.stop();
28
+ }
29
+ }
30
+ start() {
31
+ this.updateImmediately();
32
+ if (this.#updateInterval === null) {
33
+ window.addEventListener('resize', this.#update, true);
34
+ window.addEventListener('scroll', this.#update, true);
35
+ this.#updateInterval = setInterval(this.#update, 50);
36
+ }
37
+ }
38
+ stop() {
39
+ if (this.#updateInterval !== null) {
40
+ window.removeEventListener('resize', this.#update);
41
+ window.removeEventListener('scroll', this.#update);
42
+ clearInterval(this.#updateInterval);
43
+ this.#updateInterval = null;
44
+ }
45
+ }
46
+ updateImmediately() {
47
+ const tethers = this.#tethers;
48
+ if (tethers.length === 0) {
49
+ return;
50
+ }
51
+ const updates = [];
52
+ const root = document.documentElement;
53
+ let rw2 = root.clientWidth / 2;
54
+ let rh2 = root.clientHeight / 2;
55
+ const isRTL = root.dir === 'rtl';
56
+ for (const tether of tethers) {
57
+ const e = tether.element;
58
+ const rr = tether.reference.getBoundingClientRect();
59
+ const w = rr.width;
60
+ const h = rr.height;
61
+ if (w === 0 && h === 0) {
62
+ continue;
63
+ }
64
+ let top = rr.top;
65
+ let left = rr.left;
66
+ let viewportWidth = root.clientWidth;
67
+ // Adjust top and left values if inside fixed-position popover.
68
+ if (e.parentElement?.hasAttribute('popover')) {
69
+ top = tether.reference.offsetTop;
70
+ left = tether.reference.offsetLeft;
71
+ const popover = e.parentElement;
72
+ viewportWidth = popover.clientWidth;
73
+ rw2 = viewportWidth / 2;
74
+ rh2 = popover.clientHeight / 2;
75
+ }
76
+ // Calculate horizontal position, accounting for RTL direction
77
+ let horizontalPosition;
78
+ let calculatedLeft = left;
79
+ if (isRTL) {
80
+ // In RTL, we need to mirror the positioning
81
+ // Convert left position to right position, then back to left for calculation
82
+ const rightPosition = viewportWidth - left - w;
83
+ calculatedLeft = rightPosition;
84
+ // Determine which side based on mirrored position
85
+ horizontalPosition = rightPosition < rw2 ? 'l' : 'r';
86
+ }
87
+ else {
88
+ // In LTR, use normal logic: left side uses 'l', right side uses 'r'
89
+ horizontalPosition = left < rw2 ? 'l' : 'r';
90
+ }
91
+ updates.push({
92
+ element: e,
93
+ x: horizontalPosition,
94
+ y: top + h / 2 < rh2 ? 't' : 'b',
95
+ l: `${calculatedLeft}px`,
96
+ w: `${w}px`,
97
+ t: `${top}px`,
98
+ h: `${h}px`,
99
+ });
100
+ }
101
+ for (const update of updates) {
102
+ const e = update.element;
103
+ const oldUpdate = this.#oldUpdates.get(e) || {};
104
+ const es = e.style;
105
+ if (update.x !== oldUpdate.x)
106
+ e.setAttribute('data-tether-rx', update.x);
107
+ if (update.y !== oldUpdate.y)
108
+ e.setAttribute('data-tether-ry', update.y);
109
+ if (update.l !== oldUpdate.l)
110
+ es.setProperty('--Tether-rl', update.l);
111
+ if (update.w !== oldUpdate.w)
112
+ es.setProperty('--Tether-rw', update.w);
113
+ if (update.t !== oldUpdate.t)
114
+ es.setProperty('--Tether-rt', update.t);
115
+ if (update.h !== oldUpdate.h)
116
+ es.setProperty('--Tether-rh', update.h);
117
+ this.#oldUpdates.set(e, update);
118
+ }
119
+ }
120
+ }
121
+ //# sourceMappingURL=TetherLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TetherLayout.js","sourceRoot":"","sources":["../../src/util/TetherLayout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { UnknownFunction } from './types.js';
2
+ export declare function debounce(wait: number, fn: UnknownFunction): UnknownFunction;
3
+ //# sourceMappingURL=debounce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../src/util/debounce.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAGjD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,eAAe,GAAG,eAAe,CAe3E"}
@@ -0,0 +1,15 @@
1
+ /* eslint-disable prefer-rest-params */
2
+ export function debounce(wait, fn) {
3
+ if (wait <= 0) {
4
+ return fn;
5
+ }
6
+ let timeoutId;
7
+ return function () {
8
+ clearTimeout(timeoutId);
9
+ timeoutId = setTimeout(() => {
10
+ timeoutId = undefined;
11
+ fn.apply(this, [...arguments]);
12
+ }, wait);
13
+ };
14
+ }
15
+ //# sourceMappingURL=debounce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debounce.js","sourceRoot":"","sources":["../../src/util/debounce.ts"],"names":[],"mappings":"AAEA,uCAAuC;AACvC,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,EAAmB;IACxD,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACd,OAAO,EAAE,CAAA;IACX,CAAC;IAED,IAAI,SAAoD,CAAA;IAExD,OAAO;QACL,YAAY,CAAC,SAAS,CAAC,CAAA;QAEvB,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,SAAS,GAAG,SAAS,CAAA;YACrB,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAA;QAChC,CAAC,EAAE,IAAI,CAAC,CAAA;IACV,CAAC,CAAA;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare function getFocusableDescendants(selector: string, domElement: Element | null, startIndex?: number): {
2
+ first: import("tabbable").FocusableElement;
3
+ last: import("tabbable").FocusableElement;
4
+ } | null;
5
+ export declare function getFirstAndLastFocusableDescendants(el: Element, startIndex?: number): {
6
+ first: import("tabbable").FocusableElement;
7
+ last: import("tabbable").FocusableElement;
8
+ } | null;
9
+ //# sourceMappingURL=focusable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusable.d.ts","sourceRoot":"","sources":["../../src/util/focusable.ts"],"names":[],"mappings":"AAEA,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,EAAE,UAAU,SAAI;;;SAInG;AAGD,wBAAgB,mCAAmC,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,SAAI;;;SAU9E"}
@@ -0,0 +1,19 @@
1
+ import { tabbable } from 'tabbable';
2
+ export function getFocusableDescendants(selector, domElement, startIndex = 0) {
3
+ const element = domElement ? domElement.querySelector(selector) : document.querySelector(selector);
4
+ if (!element)
5
+ return null;
6
+ return getFirstAndLastFocusableDescendants(element, startIndex);
7
+ }
8
+ // A function to get the first and last tabbable elements of a container
9
+ export function getFirstAndLastFocusableDescendants(el, startIndex = 0) {
10
+ const tabbableArray = tabbable(el, { includeContainer: true });
11
+ if (tabbableArray.length === 0)
12
+ return null;
13
+ const safeStartIndex = Math.min(startIndex, tabbableArray.length - 1);
14
+ return {
15
+ first: tabbableArray[safeStartIndex],
16
+ last: tabbableArray[tabbableArray.length - 1],
17
+ };
18
+ }
19
+ //# sourceMappingURL=focusable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusable.js","sourceRoot":"","sources":["../../src/util/focusable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAEnC,MAAM,UAAU,uBAAuB,CAAC,QAAgB,EAAE,UAA0B,EAAE,UAAU,GAAG,CAAC;IAClG,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;IAClG,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IACzB,OAAO,mCAAmC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;AACjE,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,mCAAmC,CAAC,EAAW,EAAE,UAAU,GAAG,CAAC;IAC7E,MAAM,aAAa,GAAG,QAAQ,CAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAA;IAE9D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3C,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAErE,OAAO;QACL,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC;QACpC,IAAI,EAAE,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;KAC9C,CAAA;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function getComponentKey(component: HTMLElement, nameAttribute: string): string | null;
2
+ //# sourceMappingURL=getComponentKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getComponentKey.d.ts","sourceRoot":"","sources":["../../src/util/getComponentKey.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkB5F"}
@@ -0,0 +1,21 @@
1
+ export function getComponentKey(component, nameAttribute) {
2
+ const edit = component.closest('.ContentEdit') || component.closest('btu-widget');
3
+ if (!edit)
4
+ return null;
5
+ let typeId;
6
+ let componentName;
7
+ if (edit.classList.contains('ContentEdit')) {
8
+ typeId = edit.getAttribute('data-type-id');
9
+ componentName = component.getAttribute(nameAttribute);
10
+ if (!typeId || !componentName)
11
+ return null;
12
+ }
13
+ else if (edit instanceof HTMLElement) {
14
+ typeId = edit.getAttribute('widgetid');
15
+ componentName = edit.getAttribute('internalname');
16
+ if (!typeId || !componentName)
17
+ return null;
18
+ }
19
+ return typeId && componentName ? `BSP.ContentEdit.widgetCollapsed.${typeId}.${componentName}` : null;
20
+ }
21
+ //# sourceMappingURL=getComponentKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getComponentKey.js","sourceRoot":"","sources":["../../src/util/getComponentKey.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAAC,SAAsB,EAAE,aAAqB;IAC3E,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IACjF,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IAEtB,IAAI,MAAM,CAAA;IACV,IAAI,aAAa,CAAA;IAEjB,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QAC3C,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,CAAA;QAC1C,aAAa,GAAG,SAAS,CAAC,YAAY,CAAC,aAAa,CAAC,CAAA;QACrD,IAAI,CAAC,MAAM,IAAI,CAAC,aAAa;YAAE,OAAO,IAAI,CAAA;IAC5C,CAAC;SAAM,IAAI,IAAI,YAAY,WAAW,EAAE,CAAC;QACvC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA;QACtC,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,CAAA;QACjD,IAAI,CAAC,MAAM,IAAI,CAAC,aAAa;YAAE,OAAO,IAAI,CAAA;IAC5C,CAAC;IAED,OAAO,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,mCAAmC,MAAM,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACtG,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { FocusableElement } from 'tabbable';
2
+ interface FocusableGroup {
3
+ first: FocusableElement;
4
+ last: FocusableElement;
5
+ }
6
+ export declare function trapFocusWithin(e: KeyboardEvent, elementGroups: FocusableGroup[], cycle?: boolean): void;
7
+ export {};
8
+ //# sourceMappingURL=keyboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../src/util/keyboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAGhD,UAAU,cAAc;IACtB,KAAK,EAAE,gBAAgB,CAAA;IACvB,IAAI,EAAE,gBAAgB,CAAA;CACvB;AAQD,wBAAgB,eAAe,CAAC,CAAC,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,EAAE,KAAK,UAAO,QAsC9F"}
@@ -0,0 +1,138 @@
1
+ import { announce } from './aria.js';
2
+ /*
3
+ NOTE: This function will not perform as expected with the Safari Browser. Safari by default
4
+ does not tab to anchor and button elements. Therefore, if the item being checked is a button or anchor tag,
5
+ it will not be triggered since Safari will not tab to that element. For this functionality to work with Safari, the following
6
+ must be set in the Safari settings: 'Press Tab to highlight each item on a webpage' in the 'advanced' section.
7
+ */
8
+ export function trapFocusWithin(e, elementGroups, cycle = true) {
9
+ let keyType;
10
+ if (e.key === 'Tab' && e.shiftKey) {
11
+ keyType = 'back';
12
+ }
13
+ else if (e.key === 'Tab') {
14
+ keyType = 'forward';
15
+ }
16
+ else {
17
+ return;
18
+ }
19
+ /*
20
+ * NOTE: The following guard is a temporary workaround for users who get stuck in a focus trap due to poor DOM
21
+ * ordering not playing nicely with our focus trap logic. This code will become unnecessary once we reorder
22
+ * key elements in the DOM to match visual/tabbing order.
23
+ */
24
+ if (!cycle) {
25
+ guardAgainstFocusLoop(e, elementGroups, keyType);
26
+ }
27
+ for (let i = 0; i < elementGroups.length; i++) {
28
+ const group = elementGroups[i];
29
+ if (keyType === 'forward' && e.target === group.last) {
30
+ const nextGroup = elementGroups[i + 1] || (cycle ? elementGroups[0] : undefined);
31
+ if (nextGroup) {
32
+ e.preventDefault();
33
+ nextGroup.first?.focus();
34
+ return;
35
+ }
36
+ }
37
+ else if (keyType === 'back' && e.target === group.first) {
38
+ const prevGroup = elementGroups[i - 1] || (cycle ? elementGroups[elementGroups.length - 1] : undefined);
39
+ if (prevGroup) {
40
+ e.preventDefault();
41
+ prevGroup.last?.focus();
42
+ return;
43
+ }
44
+ }
45
+ }
46
+ }
47
+ /*
48
+ * Checks if one of the following conditions are met, and shows an escape hint if so:
49
+ * 1. User is tabbing forward from the last element of the last group, and there are elements
50
+ * from earlier groups positioned after the last element in DOM order.
51
+ * 2. User is tabbing backward from the first element of the first group, and there are elements
52
+ * from later groups positioned before the first element in DOM order.
53
+ */
54
+ function guardAgainstFocusLoop(e, elementGroups, keyType) {
55
+ const lastGroup = elementGroups[elementGroups.length - 1];
56
+ const firstGroup = elementGroups[0];
57
+ if (keyType === 'forward' && e.target === lastGroup?.last) {
58
+ // Check if any element from an earlier group comes after the last element in DOM order
59
+ const lastElement = lastGroup.last;
60
+ for (let i = 0; i < elementGroups.length - 1; i++) {
61
+ const group = elementGroups[i];
62
+ if (comesAfter(group.first, lastElement) || comesAfter(group.last, lastElement)) {
63
+ showEscapeHint();
64
+ return;
65
+ }
66
+ }
67
+ }
68
+ if (keyType === 'back' && e.target === firstGroup?.first) {
69
+ // Check if any element from a later group comes before the first element in DOM order
70
+ const firstElement = firstGroup.first;
71
+ for (let i = 1; i < elementGroups.length; i++) {
72
+ const group = elementGroups[i];
73
+ if (comesBefore(group.first, firstElement) || comesBefore(group.last, firstElement)) {
74
+ showEscapeHint();
75
+ return;
76
+ }
77
+ }
78
+ }
79
+ }
80
+ /*
81
+ * Checks if an element comes after a reference element in DOM order.
82
+ */
83
+ function comesAfter(element, reference) {
84
+ const position = reference.compareDocumentPosition(element);
85
+ return Boolean(position & Node.DOCUMENT_POSITION_FOLLOWING);
86
+ }
87
+ /*
88
+ * Checks if an element comes before a reference element in DOM order.
89
+ */
90
+ function comesBefore(element, reference) {
91
+ const position = reference.compareDocumentPosition(element);
92
+ return Boolean(position & Node.DOCUMENT_POSITION_PRECEDING);
93
+ }
94
+ /*
95
+ * Shows a hint to the user about how to escape the focus trap.
96
+ * This hint is shown at most once every HINT_COOLDOWN milliseconds.
97
+ */
98
+ let lastHintTime = 0;
99
+ const HINT_COOLDOWN = 5000;
100
+ function showEscapeHint() {
101
+ const now = Date.now();
102
+ if (now - lastHintTime < HINT_COOLDOWN)
103
+ return;
104
+ lastHintTime = now;
105
+ const message = window.BRIGHTSPOT?.ui?.tooltips?.focusTrapHint;
106
+ if (!message)
107
+ return;
108
+ // ARIA announcement for screen readers
109
+ announce(message);
110
+ // Visual popover for sighted users
111
+ showVisualPopover(message);
112
+ }
113
+ // A rudimentary visual popover that should be replaced later on with a list of landmark skip links.
114
+ function showVisualPopover(message) {
115
+ const existingPopover = document.getElementById('focus-escape-hint');
116
+ if (existingPopover)
117
+ existingPopover.remove();
118
+ const popover = document.createElement('div');
119
+ popover.id = 'focus-escape-hint';
120
+ popover.textContent = message;
121
+ popover.setAttribute('role', 'status');
122
+ popover.style.position = 'fixed';
123
+ popover.style.bottom = '20px';
124
+ popover.style.right = '20px';
125
+ popover.style.padding = '12px 16px';
126
+ popover.style.backgroundColor = '#333';
127
+ popover.style.color = '#fff';
128
+ popover.style.borderRadius = '4px';
129
+ popover.style.fontSize = '14px';
130
+ popover.style.zIndex = '10000';
131
+ popover.style.boxShadow = '0 2px 8px rgba(0,0,0,0.3)';
132
+ popover.style.pointerEvents = 'none';
133
+ document.body.appendChild(popover);
134
+ setTimeout(() => {
135
+ popover.remove();
136
+ }, 4000);
137
+ }
138
+ //# sourceMappingURL=keyboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard.js","sourceRoot":"","sources":["../../src/util/keyboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function noise(): {
2
+ getVal: (x: number) => number;
3
+ setAmplitude: (newAmplitude: number) => void;
4
+ setScale: (newScale: number) => void;
5
+ };
6
+ //# sourceMappingURL=noise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noise.d.ts","sourceRoot":"","sources":["../../src/util/noise.ts"],"names":[],"mappings":"AAEA,wBAAgB,KAAK;gBAYS,MAAM;iCA6BM,MAAM;yBAGd,MAAM;EAIvC"}
@@ -0,0 +1,43 @@
1
+ // via: https://www.michaelbromley.co.uk/blog/simple-1d-noise-in-javascript/
2
+ export function noise() {
3
+ const MAX_VERTICES = 256;
4
+ const MAX_VERTICES_MASK = MAX_VERTICES - 1;
5
+ let amplitude = 1;
6
+ let scale = 1;
7
+ const r = [];
8
+ for (let i = 0; i < MAX_VERTICES; ++i) {
9
+ r.push(Math.random());
10
+ }
11
+ const getVal = function (x) {
12
+ const scaledX = x * scale;
13
+ const xFloor = Math.floor(scaledX);
14
+ const t = scaledX - xFloor;
15
+ const tRemapSmoothstep = t * t * (3 - 2 * t);
16
+ /// Modulo using &
17
+ const xMin = xFloor & MAX_VERTICES_MASK;
18
+ const xMax = (xMin + 1) & MAX_VERTICES_MASK;
19
+ const y = lerp(r[xMin], r[xMax], tRemapSmoothstep);
20
+ return y * amplitude;
21
+ };
22
+ /**
23
+ * Linear interpolation function.
24
+ * @param a The lower integer value
25
+ * @param b The upper integer value
26
+ * @param t The value between the two
27
+ * @returns {number}
28
+ */
29
+ const lerp = function (a, b, t) {
30
+ return a * (1 - t) + b * t;
31
+ };
32
+ // return the API
33
+ return {
34
+ getVal: getVal,
35
+ setAmplitude: function (newAmplitude) {
36
+ amplitude = newAmplitude;
37
+ },
38
+ setScale: function (newScale) {
39
+ scale = newScale;
40
+ },
41
+ };
42
+ }
43
+ //# sourceMappingURL=noise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noise.js","sourceRoot":"","sources":["../../src/util/noise.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,MAAM,UAAU,KAAK;IACnB,MAAM,YAAY,GAAG,GAAG,CAAA;IACxB,MAAM,iBAAiB,GAAG,YAAY,GAAG,CAAC,CAAA;IAC1C,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,IAAI,KAAK,GAAG,CAAC,CAAA;IAEb,MAAM,CAAC,GAAa,EAAE,CAAA;IAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC;QACtC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IACvB,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAS;QAChC,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAA;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAClC,MAAM,CAAC,GAAG,OAAO,GAAG,MAAM,CAAA;QAC1B,MAAM,gBAAgB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAE5C,kBAAkB;QAClB,MAAM,IAAI,GAAG,MAAM,GAAG,iBAAiB,CAAA;QACvC,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,iBAAiB,CAAA;QAE3C,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,CAAA;QAElD,OAAO,CAAC,GAAG,SAAS,CAAA;IACtB,CAAC,CAAA;IAED;;;;;;OAMG;IACH,MAAM,IAAI,GAAG,UAAU,CAAS,EAAE,CAAS,EAAE,CAAS;QACpD,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC,CAAA;IAED,iBAAiB;IACjB,OAAO;QACL,MAAM,EAAE,MAAM;QACd,YAAY,EAAE,UAAU,YAAoB;YAC1C,SAAS,GAAG,YAAY,CAAA;QAC1B,CAAC;QACD,QAAQ,EAAE,UAAU,QAAgB;YAClC,KAAK,GAAG,QAAQ,CAAA;QAClB,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Selectors } from './onFind.js';
2
+ export declare function onFindOnce(selectors: Selectors, callback: () => void): void;
3
+ //# sourceMappingURL=onFindOnce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onFindOnce.d.ts","sourceRoot":"","sources":["../../src/util/onFindOnce.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI,QA4BpE"}
@@ -0,0 +1,25 @@
1
+ export function onFindOnce(selectors, callback) {
2
+ if (Array.isArray(selectors)) {
3
+ selectors = selectors.join(',');
4
+ }
5
+ if (document.querySelector(selectors)) {
6
+ callback();
7
+ return;
8
+ }
9
+ let called = false;
10
+ const observer = new MutationObserver(() => {
11
+ if (document.querySelector(selectors)) {
12
+ observer.disconnect();
13
+ if (!called) {
14
+ called = true;
15
+ callback();
16
+ }
17
+ }
18
+ });
19
+ observer.observe(document, {
20
+ attributes: true,
21
+ childList: true,
22
+ subtree: true,
23
+ });
24
+ }
25
+ //# sourceMappingURL=onFindOnce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onFindOnce.js","sourceRoot":"","sources":["../../src/util/onFindOnce.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,SAAoB,EAAE,QAAoB;IACnE,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACjC,CAAC;IAED,IAAI,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;QACtC,QAAQ,EAAE,CAAA;QACV,OAAM;IACR,CAAC;IAED,IAAI,MAAM,GAAG,KAAK,CAAA;IAElB,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE;QACzC,IAAI,QAAQ,CAAC,aAAa,CAAC,SAAmB,CAAC,EAAE,CAAC;YAChD,QAAQ,CAAC,UAAU,EAAE,CAAA;YAErB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,GAAG,IAAI,CAAA;gBACb,QAAQ,EAAE,CAAA;YACZ,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE;QACzB,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,IAAI;KACd,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ interface RTEInstance {
2
+ ctx: HTMLTextAreaElement;
3
+ loaded: boolean;
4
+ view: {
5
+ dom: HTMLElement;
6
+ };
7
+ }
8
+ export interface OnRTEReadyOptions {
9
+ /** If true, auto-unsubscribe after first callback execution. Defaults to true. */
10
+ once?: boolean;
11
+ }
12
+ /**
13
+ * Execute callback when a specific RTE is fully loaded
14
+ * @param callback - Function called with RTE instance when ready
15
+ * @param target - Textarea element or selector for the specific RTE
16
+ * @param options - Optional configuration
17
+ * @param options.once - Auto-cleanup after first fire (default: true)
18
+ * @returns Cleanup function to unsubscribe
19
+ */
20
+ export default function onRTEReady(callback: (rte: RTEInstance) => void, target: HTMLTextAreaElement | string, options?: OnRTEReadyOptions): () => void;
21
+ export {};
22
+ //# sourceMappingURL=onRTEReady.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onRTEReady.d.ts","sourceRoot":"","sources":["../../src/util/onRTEReady.ts"],"names":[],"mappings":"AAAA,UAAU,WAAW;IACnB,GAAG,EAAE,mBAAmB,CAAA;IACxB,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE;QACJ,GAAG,EAAE,WAAW,CAAA;KACjB,CAAA;CACF;AAMD,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAsCD;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,QAAQ,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,EACpC,MAAM,EAAE,mBAAmB,GAAG,MAAM,EACpC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM,IAAI,CAwCZ"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Check if a textarea has an RTE instance
3
+ */
4
+ function hasRTE(textarea) {
5
+ return textarea !== null && 'rte' in textarea && typeof textarea.rte === 'object';
6
+ }
7
+ /**
8
+ * Execute the RTE ready callback with context
9
+ * @param rte - The RTE instance that has loaded
10
+ * @param context - Execution context containing callback, once flag, and state
11
+ */
12
+ function executeCallback(rte, context) {
13
+ if (context.once && context.hasExecuted) {
14
+ return;
15
+ }
16
+ try {
17
+ context.callback(rte);
18
+ context.hasExecuted = true;
19
+ if (context.once && context.subscription) {
20
+ context.subscription.remove();
21
+ context.subscription = null;
22
+ }
23
+ }
24
+ catch (error) {
25
+ console.error('onRTEReady callback failed', error);
26
+ }
27
+ }
28
+ /**
29
+ * Execute callback when a specific RTE is fully loaded
30
+ * @param callback - Function called with RTE instance when ready
31
+ * @param target - Textarea element or selector for the specific RTE
32
+ * @param options - Optional configuration
33
+ * @param options.once - Auto-cleanup after first fire (default: true)
34
+ * @returns Cleanup function to unsubscribe
35
+ */
36
+ export default function onRTEReady(callback, target, options) {
37
+ const { once = true } = options || {};
38
+ // Resolve target to textarea element
39
+ const targetTextarea = typeof target === 'string' ? document.querySelector(target) : target;
40
+ if (!(targetTextarea instanceof HTMLTextAreaElement)) {
41
+ return () => { }; // No-op
42
+ }
43
+ // Context shared by all executeCallback invocations
44
+ const context = {
45
+ callback,
46
+ once,
47
+ hasExecuted: false,
48
+ subscription: null,
49
+ };
50
+ // Already loaded?
51
+ if (hasRTE(targetTextarea) && targetTextarea.rte.loaded) {
52
+ executeCallback(targetTextarea.rte, context);
53
+ if (once) {
54
+ return () => { }; // Already executed, no cleanup needed
55
+ }
56
+ }
57
+ const pubSub = window.PubSub;
58
+ if (!pubSub || typeof pubSub.subscribe !== 'function') {
59
+ // PubSub not available: fail gracefully
60
+ return () => { };
61
+ }
62
+ context.subscription = pubSub.subscribe('rteLoaded', (rte) => {
63
+ if (rte.ctx === targetTextarea) {
64
+ executeCallback(rte, context);
65
+ }
66
+ });
67
+ return () => context.subscription?.remove();
68
+ }
69
+ //# sourceMappingURL=onRTEReady.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onRTEReady.js","sourceRoot":"","sources":["../../src/util/onRTEReady.ts"],"names":[],"mappings":"AAwBA;;GAEG;AACH,SAAS,MAAM,CAAC,QAAoC;IAClD,OAAO,QAAQ,KAAK,IAAI,IAAI,KAAK,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,GAAG,KAAK,QAAQ,CAAA;AACnF,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,GAAgB,EAAE,OAAuB;IAChE,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxC,OAAM;IACR,CAAC;IAED,IAAI,CAAC;QACH,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;QACrB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAA;QAC1B,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzC,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,CAAA;YAC7B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAA;QAC7B,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAA;IACpD,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,QAAoC,EACpC,MAAoC,EACpC,OAA2B;IAE3B,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IAErC,qCAAqC;IACrC,MAAM,cAAc,GAClB,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IAEtE,IAAI,CAAC,CAAC,cAAc,YAAY,mBAAmB,CAAC,EAAE,CAAC;QACrD,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA,CAAC,QAAQ;IAC1B,CAAC;IAED,oDAAoD;IACpD,MAAM,OAAO,GAAmB;QAC9B,QAAQ;QACR,IAAI;QACJ,WAAW,EAAE,KAAK;QAClB,YAAY,EAAE,IAAI;KACnB,CAAA;IAED,kBAAkB;IAClB,IAAI,MAAM,CAAC,cAAc,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QACxD,eAAe,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAC5C,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA,CAAC,sCAAsC;QACxD,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAI,MAAc,CAAC,MAAM,CAAA;IACrC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;QACtD,wCAAwC;QACxC,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;IACjB,CAAC;IAED,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,GAAgB,EAAE,EAAE;QACxE,IAAI,GAAG,CAAC,GAAG,KAAK,cAAc,EAAE,CAAC;YAC/B,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,CAAA;AAC7C,CAAC"}
@@ -0,0 +1,7 @@
1
+ declare function onRemove(element: Element, callback: () => void): void;
2
+ declare namespace onRemove {
3
+ var pause: () => void;
4
+ var resume: () => void;
5
+ }
6
+ export default onRemove;
7
+ //# sourceMappingURL=onRemove.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onRemove.d.ts","sourceRoot":"","sources":["../../src/util/onRemove.ts"],"names":[],"mappings":"AAGA,iBAAwB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,QAatE;kBAbuB,QAAQ;qBAgBX,IAAI;sBAKH,IAAI;;eArBF,QAAQ"}
@@ -0,0 +1,24 @@
1
+ let triggerPaused = false;
2
+ /* Triggers a callback when a DOM element is removed from the document. */
3
+ export default function onRemove(element, callback) {
4
+ const observer = new MutationObserver(mutations => {
5
+ for (const mutation of mutations) {
6
+ for (const removedNode of mutation.removedNodes) {
7
+ if (removedNode.contains(element) && !triggerPaused) {
8
+ observer.disconnect();
9
+ callback();
10
+ }
11
+ }
12
+ }
13
+ });
14
+ observer.observe(document, { childList: true, subtree: true });
15
+ }
16
+ /* Globally pauses all callback invocations. */
17
+ onRemove.pause = () => {
18
+ triggerPaused = true;
19
+ };
20
+ /* Globally resumes all callback invocations. */
21
+ onRemove.resume = () => {
22
+ triggerPaused = false;
23
+ };
24
+ //# sourceMappingURL=onRemove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onRemove.js","sourceRoot":"","sources":["../../src/util/onRemove.ts"],"names":[],"mappings":"AAAA,IAAI,aAAa,GAAG,KAAK,CAAA;AAEzB,0EAA0E;AAC1E,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,OAAgB,EAAE,QAAoB;IACrE,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,SAAS,CAAC,EAAE;QAChD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;gBAChD,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;oBACpD,QAAQ,CAAC,UAAU,EAAE,CAAA;oBACrB,QAAQ,EAAE,CAAA;gBACZ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;AAChE,CAAC;AAED,+CAA+C;AAC/C,QAAQ,CAAC,KAAK,GAAG,GAAS,EAAE;IAC1B,aAAa,GAAG,IAAI,CAAA;AACtB,CAAC,CAAA;AAED,gDAAgD;AAChD,QAAQ,CAAC,MAAM,GAAG,GAAS,EAAE;IAC3B,aAAa,GAAG,KAAK,CAAA;AACvB,CAAC,CAAA"}