@brightspot/ui 1.3.0 → 1.4.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 (131) hide show
  1. package/dist/custom-elements.json +144 -144
  2. package/dist/global.d.ts +10 -0
  3. package/dist/storybook/assets/{Avatar.stories-CpXI9mXR.js → Avatar.stories-QxWs-YfX.js} +1 -1
  4. package/dist/storybook/assets/{AvatarGroup.stories-D4NymG47.js → AvatarGroup.stories-Cy_Bvn7E.js} +1 -1
  5. package/dist/storybook/assets/{Badge.stories-BP4Yixze.js → Badge.stories-BpaApWbR.js} +1 -1
  6. package/dist/storybook/assets/{Button.stories-DDpQzCOq.js → Button.stories-C5h2usmd.js} +1 -1
  7. package/dist/storybook/assets/{CircularProgress.stories-B82LXwfS.js → CircularProgress.stories-DlPOiGja.js} +1 -1
  8. package/dist/storybook/assets/{ClipboardMixin.stories-Cr3efF-v.js → ClipboardMixin.stories-Bb45-UOM.js} +1 -1
  9. package/dist/storybook/assets/Color-6BZIO3FS-CcgGYVAo.js +1 -0
  10. package/dist/storybook/assets/{Colors.stories-CeKs5FaB.js → Colors.stories-DP2JKWUJ.js} +1 -1
  11. package/dist/storybook/assets/{ComponentStatesMixin-BkLj42wt.js → ComponentStatesMixin-B7ci0thi.js} +1 -1
  12. package/dist/storybook/assets/{ComponentStatesMixin.stories--YPoyrpQ.js → ComponentStatesMixin.stories-CyQ2aSTu.js} +1 -1
  13. package/dist/storybook/assets/{CopyToClipboard.stories-6vqDwd-F.js → CopyToClipboard.stories-DR7pckeV.js} +1 -1
  14. package/dist/storybook/assets/Debounce.stories-hkqyvqmg.js +199 -0
  15. package/dist/storybook/assets/DocsRenderer-LL677BLK-Dtw9GMer.js +758 -0
  16. package/dist/storybook/assets/{Events.stories-DD9wfoHi.js → Events.stories-BAgDzdyl.js} +1 -1
  17. package/dist/storybook/assets/{Heading.stories-D-Pvm7NG.js → Heading.stories-CN_fPsRf.js} +1 -1
  18. package/dist/storybook/assets/{Icon.stories-BbR3S56H.js → Icon.stories-CSx_2K8V.js} +1 -1
  19. package/dist/storybook/assets/{LinearProgress.stories-B9XHLvVn.js → LinearProgress.stories-In48DY2g.js} +1 -1
  20. package/dist/storybook/assets/Rtc.stories-19d7WXe4.js +281 -0
  21. package/dist/storybook/assets/{ScrollShadow.stories-CHFpB4Zf.js → ScrollShadow.stories-BFjracVd.js} +1 -1
  22. package/dist/storybook/assets/{Throttle.stories-BGNJSyDp.js → Throttle.stories-DD6ydiVq.js} +8 -8
  23. package/dist/storybook/assets/WithTooltip-65CFNBJE-Be1dKqOF.js +9 -0
  24. package/dist/storybook/assets/formatter-EIJCOSYU-anC2P5HS.js +1 -0
  25. package/dist/storybook/assets/{iframe-CpEKhsmw.css → iframe-B4njXYq6.css} +1 -1
  26. package/dist/storybook/assets/iframe-Bl9oHz5c.js +1061 -0
  27. package/dist/storybook/assets/index-Cn5E5A3G.js +1 -0
  28. package/dist/storybook/assets/onFind-DqriYjEB.js +1 -0
  29. package/dist/storybook/assets/onFind.stories-BMDLUk0l.js +1069 -0
  30. package/dist/storybook/assets/onRemove.stories-C3FcxtYh.js +234 -0
  31. package/dist/storybook/assets/onVisible.stories-B8Zyu0Th.js +187 -0
  32. package/dist/storybook/assets/syntaxhighlighter-ED5Y7EFY-BfTKsIVL.js +6 -0
  33. package/dist/storybook/iframe.html +57 -39
  34. package/dist/storybook/index.html +11 -4
  35. package/dist/storybook/index.json +1 -1
  36. package/dist/storybook/project.json +1 -1
  37. package/dist/storybook/sb-addons/docs-1/manager-bundle.js +1 -1
  38. package/dist/storybook/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +112 -290
  39. package/dist/storybook/sb-addons/vitest-2/manager-bundle.js +3 -0
  40. package/dist/storybook/sb-manager/globals-runtime.js +60754 -66346
  41. package/dist/storybook/sb-manager/globals.js +2 -3
  42. package/dist/storybook/sb-manager/manager-stores.js +23 -0
  43. package/dist/storybook/sb-manager/runtime.js +12983 -11699
  44. package/dist/storybook/vite-inject-mocker-entry.js +2 -2
  45. package/dist/tailwind-plugin-button.js +3 -0
  46. package/dist/tailwind-plugin-button.js.map +1 -1
  47. package/dist/tailwind-plugin-button.ts +4 -0
  48. package/dist/util/Socket.d.ts +29 -0
  49. package/dist/util/Socket.d.ts.map +1 -0
  50. package/dist/util/Socket.js +153 -0
  51. package/dist/util/Socket.js.map +1 -0
  52. package/dist/util/Tether.d.ts +18 -0
  53. package/dist/util/Tether.d.ts.map +1 -0
  54. package/dist/util/Tether.js +102 -0
  55. package/dist/util/Tether.js.map +1 -0
  56. package/dist/util/TetherLayout.d.ts +12 -0
  57. package/dist/util/TetherLayout.d.ts.map +1 -0
  58. package/dist/util/TetherLayout.js +121 -0
  59. package/dist/util/TetherLayout.js.map +1 -0
  60. package/dist/util/debounce.d.ts +3 -0
  61. package/dist/util/debounce.d.ts.map +1 -0
  62. package/dist/util/debounce.js +15 -0
  63. package/dist/util/debounce.js.map +1 -0
  64. package/dist/util/focusable.d.ts +9 -0
  65. package/dist/util/focusable.d.ts.map +1 -0
  66. package/dist/util/focusable.js +19 -0
  67. package/dist/util/focusable.js.map +1 -0
  68. package/dist/util/getComponentKey.d.ts +2 -0
  69. package/dist/util/getComponentKey.d.ts.map +1 -0
  70. package/dist/util/getComponentKey.js +21 -0
  71. package/dist/util/getComponentKey.js.map +1 -0
  72. package/dist/util/keyboard.d.ts +8 -0
  73. package/dist/util/keyboard.d.ts.map +1 -0
  74. package/dist/util/keyboard.js +138 -0
  75. package/dist/util/keyboard.js.map +1 -0
  76. package/dist/util/noise.d.ts +6 -0
  77. package/dist/util/noise.d.ts.map +1 -0
  78. package/dist/util/noise.js +43 -0
  79. package/dist/util/noise.js.map +1 -0
  80. package/dist/util/onFind.d.ts +1 -0
  81. package/dist/util/onFind.d.ts.map +1 -1
  82. package/dist/util/onFind.js +73 -48
  83. package/dist/util/onFind.js.map +1 -1
  84. package/dist/util/onFindOnce.d.ts +3 -0
  85. package/dist/util/onFindOnce.d.ts.map +1 -0
  86. package/dist/util/onFindOnce.js +25 -0
  87. package/dist/util/onFindOnce.js.map +1 -0
  88. package/dist/util/onRTEReady.d.ts +22 -0
  89. package/dist/util/onRTEReady.d.ts.map +1 -0
  90. package/dist/util/onRTEReady.js +69 -0
  91. package/dist/util/onRTEReady.js.map +1 -0
  92. package/dist/util/onRemove.d.ts +7 -0
  93. package/dist/util/onRemove.d.ts.map +1 -0
  94. package/dist/util/onRemove.js +24 -0
  95. package/dist/util/onRemove.js.map +1 -0
  96. package/dist/util/onVisible.d.ts +3 -0
  97. package/dist/util/onVisible.d.ts.map +1 -0
  98. package/dist/util/onVisible.js +33 -0
  99. package/dist/util/onVisible.js.map +1 -0
  100. package/dist/util/previousUntil.d.ts +2 -0
  101. package/dist/util/previousUntil.d.ts.map +1 -0
  102. package/dist/util/previousUntil.js +21 -0
  103. package/dist/util/previousUntil.js.map +1 -0
  104. package/dist/util/repaint.d.ts +3 -0
  105. package/dist/util/repaint.d.ts.map +1 -0
  106. package/dist/util/repaint.js +14 -0
  107. package/dist/util/repaint.js.map +1 -0
  108. package/dist/util/rtc.d.ts +10 -0
  109. package/dist/util/rtc.d.ts.map +1 -0
  110. package/dist/util/rtc.js +184 -0
  111. package/dist/util/rtc.js.map +1 -0
  112. package/dist/util/storage.d.ts +6 -0
  113. package/dist/util/storage.d.ts.map +1 -0
  114. package/dist/util/storage.js +18 -0
  115. package/dist/util/storage.js.map +1 -0
  116. package/dist/util/transition.d.ts +2 -0
  117. package/dist/util/transition.d.ts.map +1 -0
  118. package/dist/util/transition.js +4 -0
  119. package/dist/util/transition.js.map +1 -0
  120. package/dist/util/types.d.ts +10 -0
  121. package/dist/util/types.d.ts.map +1 -0
  122. package/dist/util/types.js +2 -0
  123. package/dist/util/types.js.map +1 -0
  124. package/package.json +17 -6
  125. package/dist/storybook/assets/Color-64QXVMR3-BucypS4O.js +0 -1
  126. package/dist/storybook/assets/WithTooltip-SK46ZJ2J-QQZnlVfm.js +0 -825
  127. package/dist/storybook/assets/formatter-OMEEQ6HG-D3LRXsK-.js +0 -1
  128. package/dist/storybook/assets/iframe-D-tG1MVV.js +0 -1064
  129. package/dist/storybook/assets/index-mcT8sPvs.js +0 -1
  130. package/dist/storybook/assets/onFind.stories-Dagoyfc5.js +0 -284
  131. package/dist/storybook/assets/syntaxhighlighter-CAVLW7PM-BoS99i_u.js +0 -6
@@ -0,0 +1,234 @@
1
+ import{x as p}from"./iframe-Bl9oHz5c.js";import"./preload-helper-PPVm8Dsz.js";let l=!1;function m(e,o){const s=new MutationObserver(r=>{for(const v of r)for(const n of v.removedNodes)n.contains(e)&&!l&&(s.disconnect(),o())});s.observe(document,{childList:!0,subtree:!0})}m.pause=()=>{l=!0};m.resume=()=>{l=!1};const b={title:"Utilities/onRemove",tags:["autodocs"],parameters:{docs:{subtitle:"The `onRemove` utility triggers a callback when a DOM element is removed from the document. Uses MutationObserver to watch for removals, with global pause/resume support."},controls:{expanded:!0}},argTypes:{selector:{control:{type:"text"},description:"CSS selector of element to watch"}},args:{selector:".watched-item"}},i={render:()=>{const e=`onremove-${Math.random().toString(36).substring(2,9)}`;let o=0,s=0;const r=()=>{const n=document.getElementById(`${e}-items-count`),t=document.getElementById(`${e}-removed-count`);n&&(n.textContent=String(o)),t&&(t.textContent=String(s))};return p`
2
+ <div class="space-y-4">
3
+ <div class="text-base">
4
+ <p class="mb-2">
5
+ Click "Add Item" to create elements, then click "Remove" on each item. The onRemove callback detects
6
+ removals and logs them.
7
+ </p>
8
+ </div>
9
+
10
+ <div class="flex gap-2">
11
+ <button @click=${()=>{o++;const n=document.getElementById(`${e}-container`);if(!n)return;const t=document.createElement("div"),u=o;t.className="flex items-center justify-between rounded border bg-white p-4",t.innerHTML=`<span>Item ${u}</span>`;const d=document.createElement("button");d.className="rounded bg-red-100 px-2 py-1 text-xs text-red-700 hover:bg-red-200",d.textContent="Remove",d.addEventListener("click",()=>t.remove()),t.appendChild(d),n.appendChild(t),m(t,()=>{s++,o--,r();const g=document.getElementById(`${e}-log`);if(g){const c=document.createElement("div");c.className="text-sm text-gray-600",c.textContent=`Item ${u} removed at ${new Date().toLocaleTimeString()}`,g.prepend(c)}}),r()}} class="bg-primary-500 hover:bg-primary-600 rounded px-4 py-2 text-white">
12
+ Add Item
13
+ </button>
14
+ </div>
15
+
16
+ <div id="${e}-container" class="min-h-32 space-y-2 rounded border-2 border-gray-300 bg-gray-50 p-4">
17
+ <div class="text-sm text-gray-500">Items will appear here...</div>
18
+ </div>
19
+
20
+ <div class="flex justify-around">
21
+ <div>
22
+ <div class="text-xs text-gray-500">Active items</div>
23
+ <div id="${e}-items-count" class="text-2xl font-bold text-gray-900">0</div>
24
+ </div>
25
+ <div>
26
+ <div class="text-xs text-gray-500">Removals detected</div>
27
+ <div id="${e}-removed-count" class="text-primary-600 text-2xl font-bold">0</div>
28
+ </div>
29
+ </div>
30
+
31
+ <div>
32
+ <h4 class="mb-1 text-xs font-bold text-gray-500">Removal Log</h4>
33
+ <div id="${e}-log" class="max-h-32 overflow-y-auto rounded border border-gray-200 bg-gray-50 p-2">
34
+ <div class="text-sm text-gray-400">No removals yet.</div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ `},parameters:{docs:{description:{story:"Interactive example showing onRemove detecting when elements are removed from the DOM. Add items, then remove them to see the callback fire."}}}},a={render:()=>p`
39
+ <div class="space-y-4 text-sm">
40
+ <div>
41
+ <h3 class="mb-2 font-bold">Basic Usage</h3>
42
+ <pre
43
+ class="overflow-x-auto rounded bg-gray-900 p-4 text-gray-100"
44
+ ><code>import onRemove from '@brightspot/ui/util/onRemove.js'
45
+
46
+ // Clean up when element is removed
47
+ const widget = document.querySelector('.my-widget')
48
+ onRemove(widget, () => {
49
+ console.log('Widget was removed')
50
+ // Tear down event listeners, intervals, etc.
51
+ })</code></pre>
52
+ </div>
53
+
54
+ <div>
55
+ <h3 class="mb-2 font-bold">Pause and Resume</h3>
56
+ <pre class="overflow-x-auto rounded bg-gray-900 p-4 text-gray-100"><code>// Pause during bulk DOM operations
57
+ onRemove.pause()
58
+
59
+ // Move elements around without triggering callbacks
60
+ container.innerHTML = ''
61
+ container.append(...reorderedElements)
62
+
63
+ // Resume watching
64
+ onRemove.resume()</code></pre>
65
+ </div>
66
+
67
+ <div>
68
+ <h3 class="mb-2 font-bold">Common Use Cases</h3>
69
+ <ul class="list-inside list-disc space-y-1 text-gray-700">
70
+ <li>Cleaning up event listeners when elements are removed</li>
71
+ <li>Cancelling intervals or timeouts tied to DOM elements</li>
72
+ <li>Disconnecting observers or WebSocket connections</li>
73
+ <li>Releasing resources when components are destroyed</li>
74
+ </ul>
75
+ </div>
76
+
77
+ <div>
78
+ <h3 class="mb-2 font-bold">Parameters</h3>
79
+ <ul class="space-y-2">
80
+ <li><code class="rounded bg-gray-200 px-1">element</code> (Element): The DOM element to watch for removal</li>
81
+ <li>
82
+ <code class="rounded bg-gray-200 px-1">callback</code> (function): Called once when the element is removed
83
+ from the document
84
+ </li>
85
+ </ul>
86
+ </div>
87
+ </div>
88
+ `,parameters:{docs:{description:{story:"Code examples and documentation for using the onRemove utility."}}}};i.parameters={...i.parameters,docs:{...i.parameters?.docs,source:{originalSource:`{
89
+ render: () => {
90
+ const instanceId = \`onremove-\${Math.random().toString(36).substring(2, 9)}\`;
91
+ let itemCount = 0;
92
+ let removeCount = 0;
93
+ const updateCounts = () => {
94
+ const itemsEl = document.getElementById(\`\${instanceId}-items-count\`);
95
+ const removedEl = document.getElementById(\`\${instanceId}-removed-count\`);
96
+ if (itemsEl) itemsEl.textContent = String(itemCount);
97
+ if (removedEl) removedEl.textContent = String(removeCount);
98
+ };
99
+ const addItem = () => {
100
+ itemCount++;
101
+ const container = document.getElementById(\`\${instanceId}-container\`);
102
+ if (!container) return;
103
+ const item = document.createElement('div');
104
+ const itemNum = itemCount;
105
+ item.className = 'flex items-center justify-between rounded border bg-white p-4';
106
+ item.innerHTML = \`<span>Item \${itemNum}</span>\`;
107
+ const removeBtn = document.createElement('button');
108
+ removeBtn.className = 'rounded bg-red-100 px-2 py-1 text-xs text-red-700 hover:bg-red-200';
109
+ removeBtn.textContent = 'Remove';
110
+ removeBtn.addEventListener('click', () => item.remove());
111
+ item.appendChild(removeBtn);
112
+ container.appendChild(item);
113
+
114
+ // Watch for this element's removal
115
+ onRemove(item, () => {
116
+ removeCount++;
117
+ itemCount--;
118
+ updateCounts();
119
+ const log = document.getElementById(\`\${instanceId}-log\`);
120
+ if (log) {
121
+ const entry = document.createElement('div');
122
+ entry.className = 'text-sm text-gray-600';
123
+ entry.textContent = \`Item \${itemNum} removed at \${new Date().toLocaleTimeString()}\`;
124
+ log.prepend(entry);
125
+ }
126
+ });
127
+ updateCounts();
128
+ };
129
+ return html\`
130
+ <div class="space-y-4">
131
+ <div class="text-base">
132
+ <p class="mb-2">
133
+ Click "Add Item" to create elements, then click "Remove" on each item. The onRemove callback detects
134
+ removals and logs them.
135
+ </p>
136
+ </div>
137
+
138
+ <div class="flex gap-2">
139
+ <button @click=\${addItem} class="bg-primary-500 hover:bg-primary-600 rounded px-4 py-2 text-white">
140
+ Add Item
141
+ </button>
142
+ </div>
143
+
144
+ <div id="\${instanceId}-container" class="min-h-32 space-y-2 rounded border-2 border-gray-300 bg-gray-50 p-4">
145
+ <div class="text-sm text-gray-500">Items will appear here...</div>
146
+ </div>
147
+
148
+ <div class="flex justify-around">
149
+ <div>
150
+ <div class="text-xs text-gray-500">Active items</div>
151
+ <div id="\${instanceId}-items-count" class="text-2xl font-bold text-gray-900">0</div>
152
+ </div>
153
+ <div>
154
+ <div class="text-xs text-gray-500">Removals detected</div>
155
+ <div id="\${instanceId}-removed-count" class="text-primary-600 text-2xl font-bold">0</div>
156
+ </div>
157
+ </div>
158
+
159
+ <div>
160
+ <h4 class="mb-1 text-xs font-bold text-gray-500">Removal Log</h4>
161
+ <div id="\${instanceId}-log" class="max-h-32 overflow-y-auto rounded border border-gray-200 bg-gray-50 p-2">
162
+ <div class="text-sm text-gray-400">No removals yet.</div>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ \`;
167
+ },
168
+ parameters: {
169
+ docs: {
170
+ description: {
171
+ story: \`Interactive example showing onRemove detecting when elements are removed from the DOM. Add items, then remove them to see the callback fire.\`
172
+ }
173
+ }
174
+ }
175
+ }`,...i.parameters?.docs?.source}}};a.parameters={...a.parameters,docs:{...a.parameters?.docs,source:{originalSource:`{
176
+ render: () => html\`
177
+ <div class="space-y-4 text-sm">
178
+ <div>
179
+ <h3 class="mb-2 font-bold">Basic Usage</h3>
180
+ <pre
181
+ class="overflow-x-auto rounded bg-gray-900 p-4 text-gray-100"
182
+ ><code>import onRemove from '@brightspot/ui/util/onRemove.js'
183
+
184
+ // Clean up when element is removed
185
+ const widget = document.querySelector('.my-widget')
186
+ onRemove(widget, () => {
187
+ console.log('Widget was removed')
188
+ // Tear down event listeners, intervals, etc.
189
+ })</code></pre>
190
+ </div>
191
+
192
+ <div>
193
+ <h3 class="mb-2 font-bold">Pause and Resume</h3>
194
+ <pre class="overflow-x-auto rounded bg-gray-900 p-4 text-gray-100"><code>// Pause during bulk DOM operations
195
+ onRemove.pause()
196
+
197
+ // Move elements around without triggering callbacks
198
+ container.innerHTML = ''
199
+ container.append(...reorderedElements)
200
+
201
+ // Resume watching
202
+ onRemove.resume()</code></pre>
203
+ </div>
204
+
205
+ <div>
206
+ <h3 class="mb-2 font-bold">Common Use Cases</h3>
207
+ <ul class="list-inside list-disc space-y-1 text-gray-700">
208
+ <li>Cleaning up event listeners when elements are removed</li>
209
+ <li>Cancelling intervals or timeouts tied to DOM elements</li>
210
+ <li>Disconnecting observers or WebSocket connections</li>
211
+ <li>Releasing resources when components are destroyed</li>
212
+ </ul>
213
+ </div>
214
+
215
+ <div>
216
+ <h3 class="mb-2 font-bold">Parameters</h3>
217
+ <ul class="space-y-2">
218
+ <li><code class="rounded bg-gray-200 px-1">element</code> (Element): The DOM element to watch for removal</li>
219
+ <li>
220
+ <code class="rounded bg-gray-200 px-1">callback</code> (function): Called once when the element is removed
221
+ from the document
222
+ </li>
223
+ </ul>
224
+ </div>
225
+ </div>
226
+ \`,
227
+ parameters: {
228
+ docs: {
229
+ description: {
230
+ story: \`Code examples and documentation for using the onRemove utility.\`
231
+ }
232
+ }
233
+ }
234
+ }`,...a.parameters?.docs?.source}}};const y=["Interactive","UsageExample"];export{i as Interactive,a as UsageExample,y as __namedExportsOrder,b as default};
@@ -0,0 +1,187 @@
1
+ import{x as d}from"./iframe-Bl9oHz5c.js";import{o as g}from"./onFind-DqriYjEB.js";import"./preload-helper-PPVm8Dsz.js";import"./_commonjsHelpers-CqkleIqs.js";const b=Symbol.for("brightspot.onVisible");let t;function v(){return t||(t=globalThis[b],t||(t={calledIndex:0},globalThis[b]=t),t)}function h(i,r){const s=`_ovc${v().calledIndex++}`,n=new IntersectionObserver(e=>{for(const o of e)if(o.isIntersecting){const c=o.target,m=c.classList;m.contains(s)||(m.add(s),n.unobserve(c),r(c))}});g(i,e=>{n.observe(e)})}const x={title:"Utilities/onVisible",tags:["autodocs"],parameters:{docs:{subtitle:"The `onVisible` utility triggers a callback once when elements matching a selector become visible in the viewport. Combines `onFind` with `IntersectionObserver` for lazy initialization of dynamically added elements."},controls:{expanded:!0}},argTypes:{selector:{control:{type:"text"},description:"CSS selector to watch for visibility"}},args:{selector:".lazy-item"}},l={render:()=>{const i=`onvisible-${Math.random().toString(36).substring(2,9)}`,r=`.lazy-item-${i}`;let s=0;const n=()=>{const e=document.getElementById(`${i}-visible-count`);e&&(e.textContent=String(s))};return h(r,e=>{s++,n(),e.classList.remove("opacity-30"),e.classList.add("ring-2","ring-success-500","opacity-100"),e.textContent+=" — visible!"}),d`
2
+ <div class="space-y-4">
3
+ <div class="text-base">
4
+ <p class="mb-2">
5
+ Scroll down inside the box below. Items start faded and are highlighted when they enter the viewport. Each
6
+ callback fires only once per element.
7
+ </p>
8
+ </div>
9
+
10
+ <div class="flex justify-around">
11
+ <div>
12
+ <div class="text-xs text-gray-500">Items detected as visible</div>
13
+ <div id="${i}-visible-count" class="text-primary-600 text-2xl font-bold">0</div>
14
+ </div>
15
+ </div>
16
+
17
+ <div class="h-64 overflow-y-scroll rounded border-2 border-gray-300 bg-gray-50 p-4">
18
+ <div class="space-y-4">
19
+ ${Array.from({length:30},(e,o)=>d`<div class="${`lazy-item-${i}`} rounded border bg-white p-4 opacity-30 transition-all">
20
+ Item ${o+1}
21
+ </div>`)}
22
+ </div>
23
+ </div>
24
+ </div>
25
+ `},parameters:{docs:{description:{story:"Interactive example showing onVisible detecting elements as they scroll into view. Elements are highlighted once when they become visible."}}}},a={render:()=>d`
26
+ <div class="space-y-4 text-sm">
27
+ <div>
28
+ <h3 class="mb-2 font-bold">Basic Usage</h3>
29
+ <pre
30
+ class="overflow-x-auto rounded bg-gray-900 p-4 text-gray-100"
31
+ ><code>import { onVisible } from '@brightspot/ui/util/onVisible.js'
32
+
33
+ // Lazy-load images when they scroll into view
34
+ onVisible('.lazy-image', (element) => {
35
+ element.src = element.dataset.src
36
+ })
37
+
38
+ // Initialize heavy components only when visible
39
+ onVisible('.chart-container', (element) => {
40
+ initChart(element)
41
+ })</code></pre>
42
+ </div>
43
+
44
+ <div>
45
+ <h3 class="mb-2 font-bold">How It Works</h3>
46
+ <p class="text-gray-700">
47
+ onVisible combines two utilities: <code class="rounded bg-gray-200 px-1">onFind</code> detects when matching
48
+ elements are added to the DOM, then <code class="rounded bg-gray-200 px-1">IntersectionObserver</code> watches
49
+ for when those elements enter the viewport. The callback fires at most once per element.
50
+ </p>
51
+ </div>
52
+
53
+ <div>
54
+ <h3 class="mb-2 font-bold">Common Use Cases</h3>
55
+ <ul class="list-inside list-disc space-y-1 text-gray-700">
56
+ <li>Lazy-loading images or iframes</li>
57
+ <li>Deferring expensive component initialization</li>
58
+ <li>Triggering animations on scroll</li>
59
+ <li>Analytics tracking for element impressions</li>
60
+ </ul>
61
+ </div>
62
+
63
+ <div>
64
+ <h3 class="mb-2 font-bold">Parameters</h3>
65
+ <ul class="space-y-2">
66
+ <li>
67
+ <code class="rounded bg-gray-200 px-1">selectors</code> (string | string[]): CSS selector(s) to watch for
68
+ </li>
69
+ <li>
70
+ <code class="rounded bg-gray-200 px-1">callback</code> (function): Called once per element when it becomes
71
+ visible
72
+ </li>
73
+ </ul>
74
+ </div>
75
+ </div>
76
+ `,parameters:{docs:{description:{story:"Code examples and documentation for using the onVisible utility."}}}};l.parameters={...l.parameters,docs:{...l.parameters?.docs,source:{originalSource:`{
77
+ render: () => {
78
+ const instanceId = \`onvisible-\${Math.random().toString(36).substring(2, 9)}\`;
79
+ const uniqueSelector = \`.lazy-item-\${instanceId}\`;
80
+ let visibleCount = 0;
81
+ const updateCount = () => {
82
+ const el = document.getElementById(\`\${instanceId}-visible-count\`);
83
+ if (el) el.textContent = String(visibleCount);
84
+ };
85
+ onVisible(uniqueSelector, (element: HTMLElement) => {
86
+ visibleCount++;
87
+ updateCount();
88
+ element.classList.remove('opacity-30');
89
+ element.classList.add('ring-2', 'ring-success-500', 'opacity-100');
90
+ element.textContent += ' — visible!';
91
+ });
92
+ return html\`
93
+ <div class="space-y-4">
94
+ <div class="text-base">
95
+ <p class="mb-2">
96
+ Scroll down inside the box below. Items start faded and are highlighted when they enter the viewport. Each
97
+ callback fires only once per element.
98
+ </p>
99
+ </div>
100
+
101
+ <div class="flex justify-around">
102
+ <div>
103
+ <div class="text-xs text-gray-500">Items detected as visible</div>
104
+ <div id="\${instanceId}-visible-count" class="text-primary-600 text-2xl font-bold">0</div>
105
+ </div>
106
+ </div>
107
+
108
+ <div class="h-64 overflow-y-scroll rounded border-2 border-gray-300 bg-gray-50 p-4">
109
+ <div class="space-y-4">
110
+ \${Array.from({
111
+ length: 30
112
+ }, (_, i) => html\`<div class="\${\`lazy-item-\${instanceId}\`} rounded border bg-white p-4 opacity-30 transition-all">
113
+ Item \${i + 1}
114
+ </div>\`)}
115
+ </div>
116
+ </div>
117
+ </div>
118
+ \`;
119
+ },
120
+ parameters: {
121
+ docs: {
122
+ description: {
123
+ story: \`Interactive example showing onVisible detecting elements as they scroll into view. Elements are highlighted once when they become visible.\`
124
+ }
125
+ }
126
+ }
127
+ }`,...l.parameters?.docs?.source}}};a.parameters={...a.parameters,docs:{...a.parameters?.docs,source:{originalSource:`{
128
+ render: () => html\`
129
+ <div class="space-y-4 text-sm">
130
+ <div>
131
+ <h3 class="mb-2 font-bold">Basic Usage</h3>
132
+ <pre
133
+ class="overflow-x-auto rounded bg-gray-900 p-4 text-gray-100"
134
+ ><code>import { onVisible } from '@brightspot/ui/util/onVisible.js'
135
+
136
+ // Lazy-load images when they scroll into view
137
+ onVisible('.lazy-image', (element) => {
138
+ element.src = element.dataset.src
139
+ })
140
+
141
+ // Initialize heavy components only when visible
142
+ onVisible('.chart-container', (element) => {
143
+ initChart(element)
144
+ })</code></pre>
145
+ </div>
146
+
147
+ <div>
148
+ <h3 class="mb-2 font-bold">How It Works</h3>
149
+ <p class="text-gray-700">
150
+ onVisible combines two utilities: <code class="rounded bg-gray-200 px-1">onFind</code> detects when matching
151
+ elements are added to the DOM, then <code class="rounded bg-gray-200 px-1">IntersectionObserver</code> watches
152
+ for when those elements enter the viewport. The callback fires at most once per element.
153
+ </p>
154
+ </div>
155
+
156
+ <div>
157
+ <h3 class="mb-2 font-bold">Common Use Cases</h3>
158
+ <ul class="list-inside list-disc space-y-1 text-gray-700">
159
+ <li>Lazy-loading images or iframes</li>
160
+ <li>Deferring expensive component initialization</li>
161
+ <li>Triggering animations on scroll</li>
162
+ <li>Analytics tracking for element impressions</li>
163
+ </ul>
164
+ </div>
165
+
166
+ <div>
167
+ <h3 class="mb-2 font-bold">Parameters</h3>
168
+ <ul class="space-y-2">
169
+ <li>
170
+ <code class="rounded bg-gray-200 px-1">selectors</code> (string | string[]): CSS selector(s) to watch for
171
+ </li>
172
+ <li>
173
+ <code class="rounded bg-gray-200 px-1">callback</code> (function): Called once per element when it becomes
174
+ visible
175
+ </li>
176
+ </ul>
177
+ </div>
178
+ </div>
179
+ \`,
180
+ parameters: {
181
+ docs: {
182
+ description: {
183
+ story: \`Code examples and documentation for using the onVisible utility.\`
184
+ }
185
+ }
186
+ }
187
+ }`,...a.parameters?.docs?.source}}};const w=["Interactive","UsageExample"];export{l as Interactive,a as UsageExample,w as __namedExportsOrder,x as default};