@brightspot/ui 1.2.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 (134) hide show
  1. package/dist/components/copy-to-clipboard/CopyToClipboard.d.ts +57 -0
  2. package/dist/components/copy-to-clipboard/CopyToClipboard.d.ts.map +1 -0
  3. package/dist/components/copy-to-clipboard/CopyToClipboard.js +84 -0
  4. package/dist/components/copy-to-clipboard/CopyToClipboard.js.map +1 -0
  5. package/dist/custom-elements.json +114 -0
  6. package/dist/global.d.ts +10 -0
  7. package/dist/storybook/assets/{Avatar.stories-BlxrclP0.js → Avatar.stories-DrhezTR1.js} +2 -2
  8. package/dist/storybook/assets/{AvatarGroup.stories-E3VUvBae.js → AvatarGroup.stories-DrlxT-mF.js} +1 -1
  9. package/dist/storybook/assets/{Badge.stories-f4YvPz0W.js → Badge.stories-DtJcBfOR.js} +1 -1
  10. package/dist/storybook/assets/{Button.stories-N66xrq4q.js → Button.stories-BKUfLgSY.js} +1 -1
  11. package/dist/storybook/assets/{CircularProgress.stories-zWyELtfc.js → CircularProgress.stories-dpmD-XJT.js} +1 -1
  12. package/dist/storybook/assets/ClipboardMixin.stories-C0pnQ7BY.js +228 -0
  13. package/dist/storybook/assets/Color-64QXVMR3-Dnd9S2a1.js +1 -0
  14. package/dist/storybook/assets/{Colors.stories-nEoNeHhf.js → Colors.stories-bKK25qgF.js} +1 -1
  15. package/dist/storybook/assets/ComponentStatesMixin-C2HZ9ZFb.js +1 -0
  16. package/dist/storybook/assets/ComponentStatesMixin.stories-9mRp2zuB.js +313 -0
  17. package/dist/storybook/assets/CopyToClipboard.stories-BW3oaT1i.js +277 -0
  18. package/dist/storybook/assets/Debounce.stories-BXx3CKvQ.js +199 -0
  19. package/dist/storybook/assets/{Events.stories-BP3ensxX.js → Events.stories-PBeiuWQn.js} +1 -1
  20. package/dist/storybook/assets/{Heading.stories-DGqWaBpi.js → Heading.stories-Djkl0MoC.js} +1 -1
  21. package/dist/storybook/assets/{Icon.stories-BWWjh4NZ.js → Icon.stories-Cam1fyud.js} +1 -1
  22. package/dist/storybook/assets/{LinearProgress.stories-DMVolkoE.js → LinearProgress.stories-BDNoYIJu.js} +1 -1
  23. package/dist/storybook/assets/Rtc.stories-BrTAIAi1.js +281 -0
  24. package/dist/storybook/assets/{ScrollShadow.stories-BmwSRNje.js → ScrollShadow.stories-DHcKhkag.js} +1 -1
  25. package/dist/storybook/assets/{Throttle.stories-DBj-9rhV.js → Throttle.stories-cSYT_BXu.js} +1 -1
  26. package/dist/storybook/assets/{WithTooltip-SK46ZJ2J-DW4NXFWt.js → WithTooltip-SK46ZJ2J-Df0E-KJO.js} +43 -43
  27. package/dist/storybook/assets/_commonjsHelpers-CqkleIqs.js +1 -0
  28. package/dist/storybook/assets/formatter-OMEEQ6HG-DFa_WTfb.js +1 -0
  29. package/dist/storybook/assets/{iframe-CxsKJSj-.css → iframe-BMxUFmpF.css} +1 -1
  30. package/dist/storybook/assets/{iframe-Z4F0Cgki.js → iframe-lTczLWsL.js} +76 -76
  31. package/dist/storybook/assets/index-yMswRDPh.js +1 -0
  32. package/dist/storybook/assets/onFind-C6olvKHR.js +1 -0
  33. package/dist/storybook/assets/onFind.stories-DfW54CDE.js +284 -0
  34. package/dist/storybook/assets/onRemove.stories-C7W9KyRr.js +234 -0
  35. package/dist/storybook/assets/onVisible.stories-CIl6R0q4.js +187 -0
  36. package/dist/storybook/assets/syntaxhighlighter-CAVLW7PM-DoI0ixeu.js +6 -0
  37. package/dist/storybook/iframe.html +2 -2
  38. package/dist/storybook/index.json +1 -1
  39. package/dist/storybook/project.json +1 -1
  40. package/dist/tailwind-plugin-button.js +3 -0
  41. package/dist/tailwind-plugin-button.js.map +1 -1
  42. package/dist/tailwind-plugin-button.ts +4 -0
  43. package/dist/util/ClipboardMixin.d.ts +39 -0
  44. package/dist/util/ClipboardMixin.d.ts.map +1 -0
  45. package/dist/util/ClipboardMixin.js +77 -0
  46. package/dist/util/ClipboardMixin.js.map +1 -0
  47. package/dist/util/ComponentStatesMixin.d.ts +54 -0
  48. package/dist/util/ComponentStatesMixin.d.ts.map +1 -0
  49. package/dist/util/ComponentStatesMixin.js +58 -0
  50. package/dist/util/ComponentStatesMixin.js.map +1 -0
  51. package/dist/util/EventEmitterMixin.d.ts +5 -3
  52. package/dist/util/EventEmitterMixin.d.ts.map +1 -1
  53. package/dist/util/EventEmitterMixin.js.map +1 -1
  54. package/dist/util/Socket.d.ts +29 -0
  55. package/dist/util/Socket.d.ts.map +1 -0
  56. package/dist/util/Socket.js +153 -0
  57. package/dist/util/Socket.js.map +1 -0
  58. package/dist/util/Tether.d.ts +18 -0
  59. package/dist/util/Tether.d.ts.map +1 -0
  60. package/dist/util/Tether.js +102 -0
  61. package/dist/util/Tether.js.map +1 -0
  62. package/dist/util/TetherLayout.d.ts +12 -0
  63. package/dist/util/TetherLayout.d.ts.map +1 -0
  64. package/dist/util/TetherLayout.js +121 -0
  65. package/dist/util/TetherLayout.js.map +1 -0
  66. package/dist/util/debounce.d.ts +3 -0
  67. package/dist/util/debounce.d.ts.map +1 -0
  68. package/dist/util/debounce.js +15 -0
  69. package/dist/util/debounce.js.map +1 -0
  70. package/dist/util/focusable.d.ts +9 -0
  71. package/dist/util/focusable.d.ts.map +1 -0
  72. package/dist/util/focusable.js +19 -0
  73. package/dist/util/focusable.js.map +1 -0
  74. package/dist/util/getComponentKey.d.ts +2 -0
  75. package/dist/util/getComponentKey.d.ts.map +1 -0
  76. package/dist/util/getComponentKey.js +21 -0
  77. package/dist/util/getComponentKey.js.map +1 -0
  78. package/dist/util/keyboard.d.ts +8 -0
  79. package/dist/util/keyboard.d.ts.map +1 -0
  80. package/dist/util/keyboard.js +138 -0
  81. package/dist/util/keyboard.js.map +1 -0
  82. package/dist/util/noise.d.ts +6 -0
  83. package/dist/util/noise.d.ts.map +1 -0
  84. package/dist/util/noise.js +43 -0
  85. package/dist/util/noise.js.map +1 -0
  86. package/dist/util/onFind.d.ts +11 -0
  87. package/dist/util/onFind.d.ts.map +1 -0
  88. package/dist/util/onFind.js +210 -0
  89. package/dist/util/onFind.js.map +1 -0
  90. package/dist/util/onFindOnce.d.ts +3 -0
  91. package/dist/util/onFindOnce.d.ts.map +1 -0
  92. package/dist/util/onFindOnce.js +25 -0
  93. package/dist/util/onFindOnce.js.map +1 -0
  94. package/dist/util/onRTEReady.d.ts +22 -0
  95. package/dist/util/onRTEReady.d.ts.map +1 -0
  96. package/dist/util/onRTEReady.js +69 -0
  97. package/dist/util/onRTEReady.js.map +1 -0
  98. package/dist/util/onRemove.d.ts +7 -0
  99. package/dist/util/onRemove.d.ts.map +1 -0
  100. package/dist/util/onRemove.js +24 -0
  101. package/dist/util/onRemove.js.map +1 -0
  102. package/dist/util/onVisible.d.ts +3 -0
  103. package/dist/util/onVisible.d.ts.map +1 -0
  104. package/dist/util/onVisible.js +22 -0
  105. package/dist/util/onVisible.js.map +1 -0
  106. package/dist/util/previousUntil.d.ts +2 -0
  107. package/dist/util/previousUntil.d.ts.map +1 -0
  108. package/dist/util/previousUntil.js +21 -0
  109. package/dist/util/previousUntil.js.map +1 -0
  110. package/dist/util/repaint.d.ts +3 -0
  111. package/dist/util/repaint.d.ts.map +1 -0
  112. package/dist/util/repaint.js +14 -0
  113. package/dist/util/repaint.js.map +1 -0
  114. package/dist/util/rtc.d.ts +10 -0
  115. package/dist/util/rtc.d.ts.map +1 -0
  116. package/dist/util/rtc.js +184 -0
  117. package/dist/util/rtc.js.map +1 -0
  118. package/dist/util/storage.d.ts +6 -0
  119. package/dist/util/storage.d.ts.map +1 -0
  120. package/dist/util/storage.js +18 -0
  121. package/dist/util/storage.js.map +1 -0
  122. package/dist/util/transition.d.ts +2 -0
  123. package/dist/util/transition.d.ts.map +1 -0
  124. package/dist/util/transition.js +4 -0
  125. package/dist/util/transition.js.map +1 -0
  126. package/dist/util/types.d.ts +10 -0
  127. package/dist/util/types.d.ts.map +1 -0
  128. package/dist/util/types.js +2 -0
  129. package/dist/util/types.js.map +1 -0
  130. package/package.json +7 -2
  131. package/dist/storybook/assets/Color-64QXVMR3-B3Y5c9dl.js +0 -1
  132. package/dist/storybook/assets/formatter-OMEEQ6HG-BBn014aZ.js +0 -1
  133. package/dist/storybook/assets/index-BUj5S-B7.js +0 -1
  134. package/dist/storybook/assets/syntaxhighlighter-CAVLW7PM-CsQveU1N.js +0 -6
@@ -0,0 +1,277 @@
1
+ import{g as s,x as i}from"./iframe-lTczLWsL.js";import"./preload-helper-PPVm8Dsz.js";var r=Object.freeze,c=Object.defineProperty,p=(e,l)=>r(c(e,"raw",{value:r(l||e.slice())})),d;const{events:b,args:u,argTypes:a}=s("btu-copy-to-clipboard"),f={title:"Components/CopyToClipboard",component:"btu-copy-to-clipboard",tags:["autodocs"],parameters:{docs:{subtitle:"btu-copy-to-clipboard",description:{component:`
2
+ A button component for copying text to the clipboard. The button becomes disabled and displays a success state for 3 seconds after copying.
3
+
4
+ <h3>When to use:</h3>
5
+ <ul>
6
+ <li>To allow users to quickly copy text, URLs, or codes</li>
7
+ <li>When providing API keys or tokens, which may be hidden</li>
8
+ <li>For giving users access to text content that does not need to be displayed</li>
9
+ </ul>
10
+
11
+ <h3>Use Cases in the CMS:</h3>
12
+ <ul>
13
+ <li>Saved Searches > more actions button > Copy Shareable Link</li>
14
+ <li>Mirror Preview (accessed via profile dropdown)</li>
15
+ <li>Admin > APIs >
16
+ <ul>
17
+ <li>Clients > \`.ApiKey-copy\`</li>
18
+ <li>GraphQL > \`.GraphQL-copy\`</li>
19
+ </ul>
20
+ </li>
21
+ </ul>
22
+
23
+ <h3>Behavior Notes:</h3>
24
+ <ul>
25
+ <li>The button is disabled when there is no text to copy (<code>copydata</code> is empty or not set)</li>
26
+ <li>Success styles are dependent on the <code>btu-clipboard-copied</code> state, which can be styled using the <code>:state()</code> pseudo-class</li>
27
+ </ul>
28
+ `}},actions:{handles:b},controls:{expanded:!0}},args:{...u,copydata:"https://example.com/cms/content/edit",buttonClasses:""},argTypes:{...a,copydata:{...a.copydata,control:{type:"text"},description:"The text to copy to clipboard"},buttonClasses:{...a.buttonClasses,control:{type:"text"},description:"Custom CSS classes for the button. If provided, replaces the default classes."}},render:e=>i`
29
+ <div style="display: flex; flex-direction: column; gap: 1rem;">
30
+ <div style="display: flex; align-items: center; gap: 1rem;">
31
+ <code style="padding: 0.5rem; background: #f5f5f5; border-radius: 4px; flex: 1;">${e.copydata}</code>
32
+ <btu-copy-to-clipboard copydata="${e.copydata}" .buttonClasses="${e.buttonClasses||void 0}"
33
+ >Copy to Clipboard</btu-copy-to-clipboard
34
+ >
35
+ </div>
36
+ <div style="display: flex; flex-direction: column; gap: 0.25rem;">
37
+ <textarea
38
+ aria-label="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
39
+ placeholder="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
40
+ style="padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 4px; font-family: monospace; font-size: 0.875rem;"
41
+ ></textarea>
42
+ </div>
43
+ </div>
44
+ `},t={args:{}},o={render:()=>i(d||(d=p([`
45
+ <div style="display: flex; flex-direction: column; gap: 1rem;">
46
+ <div style="display: flex; align-items: center; gap: 1rem;">
47
+ <code style="padding: 0.5rem; background: #f5f5f5; border-radius: 4px; flex: 1;">Hello, World!</code>
48
+ <btu-copy-to-clipboard copydata="Hello, World!" id="event-demo-button">Copy</btu-copy-to-clipboard>
49
+ </div>
50
+ <div
51
+ id="event-log"
52
+ style="padding: 0.5rem; background: #fffbeb; border: 1px solid #fbbf24; border-radius: 4px; font-family: monospace; font-size: 0.875rem; color: #92400e;"
53
+ >
54
+ Event Log: Waiting for copy event...
55
+ </div>
56
+ <div style="display: flex; flex-direction: column; gap: 0.25rem;">
57
+ <textarea
58
+ aria-label="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
59
+ placeholder="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
60
+ style="padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 4px; font-family: monospace; font-size: 0.875rem;"
61
+ ></textarea>
62
+ </div>
63
+ <script>
64
+ ;(() => {
65
+ const button = document.getElementById('event-demo-button')
66
+ const log = document.getElementById('event-log')
67
+ if (button && log) {
68
+ button.addEventListener('btu-clipboard-copied', e => {
69
+ const timestamp = new Date().toLocaleTimeString()
70
+ log.textContent = \`Event Log: btu-clipboard-copied fired at \${timestamp}\`
71
+ console.log('Event fired:', e)
72
+ })
73
+ }
74
+ })()
75
+ <\/script>
76
+ </div>
77
+ `],[`
78
+ <div style="display: flex; flex-direction: column; gap: 1rem;">
79
+ <div style="display: flex; align-items: center; gap: 1rem;">
80
+ <code style="padding: 0.5rem; background: #f5f5f5; border-radius: 4px; flex: 1;">Hello, World!</code>
81
+ <btu-copy-to-clipboard copydata="Hello, World!" id="event-demo-button">Copy</btu-copy-to-clipboard>
82
+ </div>
83
+ <div
84
+ id="event-log"
85
+ style="padding: 0.5rem; background: #fffbeb; border: 1px solid #fbbf24; border-radius: 4px; font-family: monospace; font-size: 0.875rem; color: #92400e;"
86
+ >
87
+ Event Log: Waiting for copy event...
88
+ </div>
89
+ <div style="display: flex; flex-direction: column; gap: 0.25rem;">
90
+ <textarea
91
+ aria-label="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
92
+ placeholder="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
93
+ style="padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 4px; font-family: monospace; font-size: 0.875rem;"
94
+ ></textarea>
95
+ </div>
96
+ <script>
97
+ ;(() => {
98
+ const button = document.getElementById('event-demo-button')
99
+ const log = document.getElementById('event-log')
100
+ if (button && log) {
101
+ button.addEventListener('btu-clipboard-copied', e => {
102
+ const timestamp = new Date().toLocaleTimeString()
103
+ log.textContent = \\\`Event Log: btu-clipboard-copied fired at \\\${timestamp}\\\`
104
+ console.log('Event fired:', e)
105
+ })
106
+ }
107
+ })()
108
+ <\/script>
109
+ </div>
110
+ `]))),parameters:{docs:{description:{story:"You can listen for the `btu-clipboard-copied` event to perform custom actions when text is copied. This example displays an event log that updates with a timestamp each time the button is clicked."}}}},n={render:()=>i`
111
+ <div class="flex flex-col gap-6">
112
+ <div class="flex flex-col gap-2">
113
+ <strong>Custom Button Styling:</strong>
114
+ <div style="display: flex; align-items: center; gap: 1rem;">
115
+ <code style="padding: 0.5rem; background: #f5f5f5; border-radius: 4px; flex: 1;">
116
+ https://example.com/cms/content/edit
117
+ </code>
118
+ <btu-copy-to-clipboard
119
+ copydata="https://example.com/cms/content/edit"
120
+ buttonClasses="btu-button btu-button-primary btu-button-fill-none after:btu-icon after:btu-icon-clipboard-copy"
121
+ >Copy Link</btu-copy-to-clipboard
122
+ >
123
+ </div>
124
+ <textarea
125
+ aria-label="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
126
+ placeholder="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
127
+ style="padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 4px; font-family: monospace; font-size: 0.875rem;"
128
+ ></textarea>
129
+ </div>
130
+
131
+ <div class="flex flex-col gap-2">
132
+ <strong>Icon-Only Button:</strong>
133
+ <div style="display: flex; align-items: center; gap: 1rem;">
134
+ <div
135
+ style="padding: 0.5rem; background: #f5f5f5; border-radius: 4px; flex: 1; display: flex; align-items: center; gap: 0.5rem; color: #6b7280;"
136
+ >
137
+ <span class="before:btu-icon before:btu-icon-key"></span>
138
+ <span style="font-family: monospace; font-style: italic;">API Key (hidden)</span>
139
+ </div>
140
+ <btu-copy-to-clipboard
141
+ id="icon-only-demo"
142
+ aria-label="Copy API key to clipboard"
143
+ copydata="sk_live_abc123xyz789secret"
144
+ buttonClasses="btu-button btu-button-primary before:btu-icon before:btu-icon-clipboard-copy btu-button-text-hidden"
145
+ >Copy API Key</btu-copy-to-clipboard
146
+ >
147
+ </div>
148
+ <textarea
149
+ aria-label="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
150
+ placeholder="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
151
+ style="padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 4px; font-family: monospace; font-size: 0.875rem;"
152
+ ></textarea>
153
+ <style>
154
+ #icon-only-demo:state(btu-clipboard-copied) button {
155
+ background-color: oklch(68.59% 0.167 157);
156
+ }
157
+ #icon-only-demo:state(btu-clipboard-copied) button::before {
158
+ content: '\\e168';
159
+ }
160
+ </style>
161
+ </div>
162
+ </div>
163
+ `,parameters:{docs:{description:{story:"\n**Custom Button Styling:** Use the `buttonClasses` attribute to override default button classes with your own styling.\n\n**Icon-Only Button:** An icon-only button for a minimal style. Uses `buttonClasses` for initial styles, notably `btu-button-text-hidden` to hide the text. The `aria-label` attribute is passed from the host element to the inner button for accessibility. CSS `:state(btu-clipboard-copied)` is used to change styles when copied.\n "}}}};t.parameters={...t.parameters,docs:{...t.parameters?.docs,source:{originalSource:`{
164
+ args: {}
165
+ }`,...t.parameters?.docs?.source}}};o.parameters={...o.parameters,docs:{...o.parameters?.docs,source:{originalSource:`{
166
+ render: () => {
167
+ return html\`
168
+ <div style="display: flex; flex-direction: column; gap: 1rem;">
169
+ <div style="display: flex; align-items: center; gap: 1rem;">
170
+ <code style="padding: 0.5rem; background: #f5f5f5; border-radius: 4px; flex: 1;">Hello, World!</code>
171
+ <btu-copy-to-clipboard copydata="Hello, World!" id="event-demo-button">Copy</btu-copy-to-clipboard>
172
+ </div>
173
+ <div
174
+ id="event-log"
175
+ style="padding: 0.5rem; background: #fffbeb; border: 1px solid #fbbf24; border-radius: 4px; font-family: monospace; font-size: 0.875rem; color: #92400e;"
176
+ >
177
+ Event Log: Waiting for copy event...
178
+ </div>
179
+ <div style="display: flex; flex-direction: column; gap: 0.25rem;">
180
+ <textarea
181
+ aria-label="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
182
+ placeholder="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
183
+ style="padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 4px; font-family: monospace; font-size: 0.875rem;"
184
+ ></textarea>
185
+ </div>
186
+ <script>
187
+ ;(() => {
188
+ const button = document.getElementById('event-demo-button')
189
+ const log = document.getElementById('event-log')
190
+ if (button && log) {
191
+ button.addEventListener('btu-clipboard-copied', e => {
192
+ const timestamp = new Date().toLocaleTimeString()
193
+ log.textContent = \\\`Event Log: btu-clipboard-copied fired at \\\${timestamp}\\\`
194
+ console.log('Event fired:', e)
195
+ })
196
+ }
197
+ })()
198
+ <\/script>
199
+ </div>
200
+ \`;
201
+ },
202
+ parameters: {
203
+ docs: {
204
+ description: {
205
+ story: \`You can listen for the \\\`btu-clipboard-copied\\\` event to perform custom actions when text is copied. This example displays an event log that updates with a timestamp each time the button is clicked.\`
206
+ }
207
+ }
208
+ }
209
+ }`,...o.parameters?.docs?.source}}};n.parameters={...n.parameters,docs:{...n.parameters?.docs,source:{originalSource:`{
210
+ render: () => {
211
+ return html\`
212
+ <div class="flex flex-col gap-6">
213
+ <div class="flex flex-col gap-2">
214
+ <strong>Custom Button Styling:</strong>
215
+ <div style="display: flex; align-items: center; gap: 1rem;">
216
+ <code style="padding: 0.5rem; background: #f5f5f5; border-radius: 4px; flex: 1;">
217
+ https://example.com/cms/content/edit
218
+ </code>
219
+ <btu-copy-to-clipboard
220
+ copydata="https://example.com/cms/content/edit"
221
+ buttonClasses="btu-button btu-button-primary btu-button-fill-none after:btu-icon after:btu-icon-clipboard-copy"
222
+ >Copy Link</btu-copy-to-clipboard
223
+ >
224
+ </div>
225
+ <textarea
226
+ aria-label="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
227
+ placeholder="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
228
+ style="padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 4px; font-family: monospace; font-size: 0.875rem;"
229
+ ></textarea>
230
+ </div>
231
+
232
+ <div class="flex flex-col gap-2">
233
+ <strong>Icon-Only Button:</strong>
234
+ <div style="display: flex; align-items: center; gap: 1rem;">
235
+ <div
236
+ style="padding: 0.5rem; background: #f5f5f5; border-radius: 4px; flex: 1; display: flex; align-items: center; gap: 0.5rem; color: #6b7280;"
237
+ >
238
+ <span class="before:btu-icon before:btu-icon-key"></span>
239
+ <span style="font-family: monospace; font-style: italic;">API Key (hidden)</span>
240
+ </div>
241
+ <btu-copy-to-clipboard
242
+ id="icon-only-demo"
243
+ aria-label="Copy API key to clipboard"
244
+ copydata="sk_live_abc123xyz789secret"
245
+ buttonClasses="btu-button btu-button-primary before:btu-icon before:btu-icon-clipboard-copy btu-button-text-hidden"
246
+ >Copy API Key</btu-copy-to-clipboard
247
+ >
248
+ </div>
249
+ <textarea
250
+ aria-label="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
251
+ placeholder="Click the copy button, then paste here (Cmd/Ctrl+V) to test"
252
+ style="padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 4px; font-family: monospace; font-size: 0.875rem;"
253
+ ></textarea>
254
+ <style>
255
+ #icon-only-demo:state(btu-clipboard-copied) button {
256
+ background-color: oklch(68.59% 0.167 157);
257
+ }
258
+ #icon-only-demo:state(btu-clipboard-copied) button::before {
259
+ content: '\\\\e168';
260
+ }
261
+ </style>
262
+ </div>
263
+ </div>
264
+ \`;
265
+ },
266
+ parameters: {
267
+ docs: {
268
+ description: {
269
+ story: \`
270
+ **Custom Button Styling:** Use the \\\`buttonClasses\\\` attribute to override default button classes with your own styling.
271
+
272
+ **Icon-Only Button:** An icon-only button for a minimal style. Uses \\\`buttonClasses\\\` for initial styles, notably \\\`btu-button-text-hidden\\\` to hide the text. The \\\`aria-label\\\` attribute is passed from the host element to the inner button for accessibility. CSS \\\`:state(btu-clipboard-copied)\\\` is used to change styles when copied.
273
+ \`
274
+ }
275
+ }
276
+ }
277
+ }`,...n.parameters?.docs?.source}}};const g=["Default","CopiedEvent","AdvancedUsage"];export{n as AdvancedUsage,o as CopiedEvent,t as Default,g as __namedExportsOrder,f as default};
@@ -0,0 +1,199 @@
1
+ import{x as c}from"./iframe-lTczLWsL.js";import"./preload-helper-PPVm8Dsz.js";function p(n,e){if(n<=0)return e;let t;return function(){clearTimeout(t),t=setTimeout(()=>{t=void 0,e.apply(this,[...arguments])},n)}}const g={title:"Utilities/Debounce",tags:["autodocs"],parameters:{docs:{subtitle:"The `debounce` utility delays function execution until a specified wait period has elapsed since the last invocation. Useful for search inputs, form validation, and window resize handlers."},controls:{expanded:!0}},argTypes:{wait:{control:{type:"number",min:0,max:2e3,step:50},description:"Debounce wait time in milliseconds"}},args:{wait:300}},o={render:n=>{const e=`debounce-${Math.random().toString(36).substring(2,9)}`;let t=0,i=0;const d=()=>{const a=document.getElementById(`${e}-normal-count`),r=document.getElementById(`${e}-debounced-count`);a&&(a.textContent=String(t)),r&&(r.textContent=String(i))},l=p(n.wait,()=>{i++,d()}),u=()=>{t++,d(),l()};return c`
2
+ <div class="space-y-4">
3
+ <div class="text-base">
4
+ <p class="mb-2">
5
+ Type in the input below. The normal counter increments on every keystroke, while the debounced counter only
6
+ fires after ${n.wait}ms of inactivity.
7
+ </p>
8
+ </div>
9
+
10
+ <input
11
+ @input=${u}
12
+ type="text"
13
+ placeholder="Start typing..."
14
+ class="w-full rounded border-2 border-gray-300 px-4 py-2 focus:border-blue-500 focus:outline-none"
15
+ />
16
+
17
+ <div class="flex justify-around">
18
+ <div>
19
+ <div class="text-xs text-gray-500">Keystrokes</div>
20
+ <div id="${e}-normal-count" class="text-2xl font-bold text-gray-900">0</div>
21
+ </div>
22
+ <div>
23
+ <div class="text-xs text-gray-500">Debounced calls (${n.wait}ms)</div>
24
+ <div id="${e}-debounced-count" class="text-primary-600 text-2xl font-bold">0</div>
25
+ </div>
26
+ </div>
27
+
28
+ <button
29
+ @click=${()=>{t=0,i=0,d()}}
30
+ class="rounded bg-gray-200 px-4 py-2 hover:bg-gray-300"
31
+ >
32
+ Reset Counters
33
+ </button>
34
+ </div>
35
+ `},parameters:{docs:{description:{story:"Interactive example showing debounce in action. Type rapidly in the input to see how the debounced handler waits for a pause before executing."}}}},s={render:()=>c`
36
+ <div class="space-y-4 text-sm">
37
+ <div>
38
+ <h3 class="mb-2 font-bold">Basic Usage</h3>
39
+ <pre
40
+ class="overflow-x-auto rounded bg-gray-900 p-4 text-gray-100"
41
+ ><code>import { debounce } from '@brightspot/ui/dist/util/debounce.js'
42
+
43
+ const handleSearch = debounce(300, () => {
44
+ console.log('Search triggered after 300ms of inactivity')
45
+ })
46
+
47
+ input.addEventListener('input', handleSearch)</code></pre>
48
+ </div>
49
+
50
+ <div>
51
+ <h3 class="mb-2 font-bold">Debounce vs Throttle</h3>
52
+ <ul class="list-inside list-disc space-y-1 text-gray-700">
53
+ <li><strong>Debounce</strong>: Waits until activity stops, then fires once</li>
54
+ <li><strong>Throttle</strong>: Fires at regular intervals during activity</li>
55
+ <li>Use debounce for search inputs, form validation, window resize end</li>
56
+ <li>Use throttle for scroll handlers, mouse tracking, progress updates</li>
57
+ </ul>
58
+ </div>
59
+
60
+ <div>
61
+ <h3 class="mb-2 font-bold">Parameters</h3>
62
+ <ul class="space-y-2">
63
+ <li>
64
+ <code class="rounded bg-gray-200 px-1">wait</code> (number): Delay in milliseconds. If 0, the function
65
+ passes through unchanged.
66
+ </li>
67
+ <li><code class="rounded bg-gray-200 px-1">fn</code> (function): The function to debounce</li>
68
+ </ul>
69
+ </div>
70
+
71
+ <div>
72
+ <h3 class="mb-2 font-bold">Returns</h3>
73
+ <p class="text-gray-700">
74
+ A debounced version of the input function that delays execution until
75
+ <code class="rounded bg-gray-200 px-1">wait</code> milliseconds have elapsed since the last call.
76
+ </p>
77
+ </div>
78
+ </div>
79
+ `,parameters:{docs:{description:{story:"Code examples and documentation for using the debounce utility."}}}};o.parameters={...o.parameters,docs:{...o.parameters?.docs,source:{originalSource:`{
80
+ render: args => {
81
+ const instanceId = \`debounce-\${Math.random().toString(36).substring(2, 9)}\`;
82
+ let normalCount = 0;
83
+ let debouncedCount = 0;
84
+ const updateCounts = () => {
85
+ const normalEl = document.getElementById(\`\${instanceId}-normal-count\`);
86
+ const debouncedEl = document.getElementById(\`\${instanceId}-debounced-count\`);
87
+ if (normalEl) normalEl.textContent = String(normalCount);
88
+ if (debouncedEl) debouncedEl.textContent = String(debouncedCount);
89
+ };
90
+ const handleDebounced = debounce(args.wait, () => {
91
+ debouncedCount++;
92
+ updateCounts();
93
+ });
94
+ const handleInput = () => {
95
+ normalCount++;
96
+ updateCounts();
97
+ handleDebounced();
98
+ };
99
+ return html\`
100
+ <div class="space-y-4">
101
+ <div class="text-base">
102
+ <p class="mb-2">
103
+ Type in the input below. The normal counter increments on every keystroke, while the debounced counter only
104
+ fires after \${args.wait}ms of inactivity.
105
+ </p>
106
+ </div>
107
+
108
+ <input
109
+ @input=\${handleInput}
110
+ type="text"
111
+ placeholder="Start typing..."
112
+ class="w-full rounded border-2 border-gray-300 px-4 py-2 focus:border-blue-500 focus:outline-none"
113
+ />
114
+
115
+ <div class="flex justify-around">
116
+ <div>
117
+ <div class="text-xs text-gray-500">Keystrokes</div>
118
+ <div id="\${instanceId}-normal-count" class="text-2xl font-bold text-gray-900">0</div>
119
+ </div>
120
+ <div>
121
+ <div class="text-xs text-gray-500">Debounced calls (\${args.wait}ms)</div>
122
+ <div id="\${instanceId}-debounced-count" class="text-primary-600 text-2xl font-bold">0</div>
123
+ </div>
124
+ </div>
125
+
126
+ <button
127
+ @click=\${() => {
128
+ normalCount = 0;
129
+ debouncedCount = 0;
130
+ updateCounts();
131
+ }}
132
+ class="rounded bg-gray-200 px-4 py-2 hover:bg-gray-300"
133
+ >
134
+ Reset Counters
135
+ </button>
136
+ </div>
137
+ \`;
138
+ },
139
+ parameters: {
140
+ docs: {
141
+ description: {
142
+ story: \`Interactive example showing debounce in action. Type rapidly in the input to see how the debounced handler waits for a pause before executing.\`
143
+ }
144
+ }
145
+ }
146
+ }`,...o.parameters?.docs?.source}}};s.parameters={...s.parameters,docs:{...s.parameters?.docs,source:{originalSource:`{
147
+ render: () => html\`
148
+ <div class="space-y-4 text-sm">
149
+ <div>
150
+ <h3 class="mb-2 font-bold">Basic Usage</h3>
151
+ <pre
152
+ class="overflow-x-auto rounded bg-gray-900 p-4 text-gray-100"
153
+ ><code>import { debounce } from '@brightspot/ui/dist/util/debounce.js'
154
+
155
+ const handleSearch = debounce(300, () => {
156
+ console.log('Search triggered after 300ms of inactivity')
157
+ })
158
+
159
+ input.addEventListener('input', handleSearch)</code></pre>
160
+ </div>
161
+
162
+ <div>
163
+ <h3 class="mb-2 font-bold">Debounce vs Throttle</h3>
164
+ <ul class="list-inside list-disc space-y-1 text-gray-700">
165
+ <li><strong>Debounce</strong>: Waits until activity stops, then fires once</li>
166
+ <li><strong>Throttle</strong>: Fires at regular intervals during activity</li>
167
+ <li>Use debounce for search inputs, form validation, window resize end</li>
168
+ <li>Use throttle for scroll handlers, mouse tracking, progress updates</li>
169
+ </ul>
170
+ </div>
171
+
172
+ <div>
173
+ <h3 class="mb-2 font-bold">Parameters</h3>
174
+ <ul class="space-y-2">
175
+ <li>
176
+ <code class="rounded bg-gray-200 px-1">wait</code> (number): Delay in milliseconds. If 0, the function
177
+ passes through unchanged.
178
+ </li>
179
+ <li><code class="rounded bg-gray-200 px-1">fn</code> (function): The function to debounce</li>
180
+ </ul>
181
+ </div>
182
+
183
+ <div>
184
+ <h3 class="mb-2 font-bold">Returns</h3>
185
+ <p class="text-gray-700">
186
+ A debounced version of the input function that delays execution until
187
+ <code class="rounded bg-gray-200 px-1">wait</code> milliseconds have elapsed since the last call.
188
+ </p>
189
+ </div>
190
+ </div>
191
+ \`,
192
+ parameters: {
193
+ docs: {
194
+ description: {
195
+ story: \`Code examples and documentation for using the debounce utility.\`
196
+ }
197
+ }
198
+ }
199
+ }`,...s.parameters?.docs?.source}}};const h=["Interactive","UsageExample"];export{o as Interactive,s as UsageExample,h as __namedExportsOrder,g as default};
@@ -1,4 +1,4 @@
1
- import{x as d}from"./iframe-Z4F0Cgki.js";import"./preload-helper-PPVm8Dsz.js";var n=Object.freeze,r=Object.defineProperty,s=(t,i)=>n(r(t,"raw",{value:n(t.slice())})),o;const l={title:"Mixins/Events",tags:["autodocs"],parameters:{docs:{subtitle:"Events inherited from EventEmitterMixin",description:{component:`
1
+ import{x as d}from"./iframe-lTczLWsL.js";import"./preload-helper-PPVm8Dsz.js";var n=Object.freeze,r=Object.defineProperty,s=(t,i)=>n(r(t,"raw",{value:n(t.slice())})),o;const l={title:"Mixins/Events",tags:["autodocs"],parameters:{docs:{subtitle:"Events inherited from EventEmitterMixin",description:{component:`
2
2
  <h3>EventEmitterMixin Events</h3>
3
3
 
4
4
  <p>All Brightspot UI components that extend EventEmitterMixin emit the following lifecycle events in addition to those inherited from LitElement. These events use CustomEvent and bubble through the DOM with <code>composed: true</code>, meaning they cross shadow DOM boundaries.</p>
@@ -1,3 +1,3 @@
1
- import{x as s}from"./iframe-Z4F0Cgki.js";import"./preload-helper-PPVm8Dsz.js";const r=({size:t})=>s` <div class=${[`btu-heading-${t}`].join(" ")}>Heading</div> `,o={title:"CSS Plugins/Heading",component:"btu-heading",tags:["autodocs"],parameters:{docs:{subtitle:"This Tailwind CSS plugin provides the `.btu-heading` utility class for styling headings. It supports five different sizes, from 1 (largest) to 5 (smallest). Apply the class to `<h1>` through `<h5>` elements to style them accordingly."},controls:{expanded:!0}},render:t=>r(t),argTypes:{size:{control:{type:"range",min:1,max:5,step:1},description:"Heading size from 1 to 5, where 1 is the largest and 5 is the smallest."}},args:{size:1}},e={args:{}};e.parameters={...e.parameters,docs:{...e.parameters?.docs,source:{originalSource:`{
1
+ import{x as s}from"./iframe-lTczLWsL.js";import"./preload-helper-PPVm8Dsz.js";const r=({size:t})=>s` <div class=${[`btu-heading-${t}`].join(" ")}>Heading</div> `,o={title:"CSS Plugins/Heading",component:"btu-heading",tags:["autodocs"],parameters:{docs:{subtitle:"This Tailwind CSS plugin provides the `.btu-heading` utility class for styling headings. It supports five different sizes, from 1 (largest) to 5 (smallest). Apply the class to `<h1>` through `<h5>` elements to style them accordingly."},controls:{expanded:!0}},render:t=>r(t),argTypes:{size:{control:{type:"range",min:1,max:5,step:1},description:"Heading size from 1 to 5, where 1 is the largest and 5 is the smallest."}},args:{size:1}},e={args:{}};e.parameters={...e.parameters,docs:{...e.parameters?.docs,source:{originalSource:`{
2
2
  args: {}
3
3
  }`,...e.parameters?.docs?.source}}};const n=["Default"];export{e as Default,n as __namedExportsOrder,o as default};
@@ -1,4 +1,4 @@
1
- import{g as d,x as r}from"./iframe-Z4F0Cgki.js";import"./preload-helper-PPVm8Dsz.js";const p="0.508.0",b={version:p},l=b.version,{events:u,args:m,argTypes:t}=d("btu-icon"),g=["xs","sm","md","lg","xl"],x=["ai","error","gray","primary","purple","rose","success","teal","warning"],v={title:"Components/Icon",component:"btu-icon",tags:["autodocs"],parameters:{docs:{subtitle:"An icon component using Lucide icons with built-in support for custom colors and sizes.",description:{component:`
1
+ import{g as d,x as r}from"./iframe-lTczLWsL.js";import"./preload-helper-PPVm8Dsz.js";const p="0.508.0",b={version:p},l=b.version,{events:u,args:m,argTypes:t}=d("btu-icon"),g=["xs","sm","md","lg","xl"],x=["ai","error","gray","primary","purple","rose","success","teal","warning"],v={title:"Components/Icon",component:"btu-icon",tags:["autodocs"],parameters:{docs:{subtitle:"An icon component using Lucide icons with built-in support for custom colors and sizes.",description:{component:`
2
2
  <strong>When to use:</strong>
3
3
  <ul>
4
4
  <li>To visually reinforce actions, states, or categories</li>
@@ -1,4 +1,4 @@
1
- import{g as I,E as h,x as T}from"./iframe-Z4F0Cgki.js";import"./preload-helper-PPVm8Dsz.js";const{events:D,args:V,argTypes:g}=I("btu-linear-progress"),k={title:"Components/Linear Progress",component:"btu-linear-progress",tags:["autodocs"],parameters:{docs:{subtitle:"A horizontal progress bar for showing task completion",description:{component:`
1
+ import{g as I,E as h,x as T}from"./iframe-lTczLWsL.js";import"./preload-helper-PPVm8Dsz.js";const{events:D,args:V,argTypes:g}=I("btu-linear-progress"),k={title:"Components/Linear Progress",component:"btu-linear-progress",tags:["autodocs"],parameters:{docs:{subtitle:"A horizontal progress bar for showing task completion",description:{component:`
2
2
  <h3>When to use:</h3>
3
3
  <ul>
4
4
  <li>To show progress of a specific task with known completion percentage</li>