@smartnet360/svelte-components 0.0.43 → 0.0.44

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.
@@ -341,16 +341,21 @@
341
341
  {/snippet}
342
342
 
343
343
  <div class="chart-component" bind:this={componentElement}>
344
- <!-- Global Controls Section (appears above tabs/scrollspy) -->
345
- {#if showGlobalControls && showControlsPanel}
346
- <GlobalControls controls={globalControls} onUpdate={handleControlsUpdate} />
344
+ <!-- Floating Global Controls (renders as fixed position overlay) -->
345
+ {#if showGlobalControls}
346
+ <GlobalControls
347
+ controls={globalControls}
348
+ onUpdate={handleControlsUpdate}
349
+ isExpanded={showControlsPanel}
350
+ onToggle={() => showControlsPanel = !showControlsPanel}
351
+ />
347
352
  {/if}
348
353
 
349
354
  <!-- Always render the main content (tabs or scrollspy) -->
350
355
  {#if mode === 'tabs'}
351
356
  <!-- Tab Mode with Navigation -->
352
357
  <div class="tabs-container">
353
- <!-- Tab Navigation with Controls Toggle -->
358
+ <!-- Tab Navigation -->
354
359
  <div class="nav-tabs-wrapper">
355
360
  <ul class="nav nav-tabs" role="tablist">
356
361
  {#each layout.sections as section, index}
@@ -369,21 +374,6 @@
369
374
  </li>
370
375
  {/each}
371
376
  </ul>
372
-
373
- <!-- Controls Toggle Button -->
374
- {#if showGlobalControls}
375
- <button
376
- class="btn btn-sm btn-outline-secondary controls-toggle"
377
- onclick={() => showControlsPanel = !showControlsPanel}
378
- title={showControlsPanel ? "Hide Controls" : "Show Controls"}
379
- type="button"
380
- >
381
- <svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
382
- <path d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"/>
383
- </svg>
384
- <span class="ms-1">{showControlsPanel ? 'Hide' : 'Show'} Controls</span>
385
- </button>
386
- {/if}
387
377
  </div>
388
378
 
389
379
  <!-- Tab Content -->
@@ -402,7 +392,7 @@
402
392
  {:else if mode === 'scrollspy'}
403
393
  <!-- ScrollSpy Mode with Navigation -->
404
394
  <div class="scrollspy-container">
405
- <!-- ScrollSpy Navigation with Controls Toggle -->
395
+ <!-- ScrollSpy Navigation -->
406
396
  <nav class="scrollspy-nav">
407
397
  <div class="nav-wrapper">
408
398
  <ul class="nav nav-pills">
@@ -418,21 +408,6 @@
418
408
  </li>
419
409
  {/each}
420
410
  </ul>
421
-
422
- <!-- Controls Toggle Button -->
423
- {#if showGlobalControls}
424
- <button
425
- class="btn btn-sm btn-outline-secondary controls-toggle"
426
- onclick={() => showControlsPanel = !showControlsPanel}
427
- title={showControlsPanel ? "Hide Controls" : "Show Controls"}
428
- type="button"
429
- >
430
- <svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
431
- <path d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"/>
432
- </svg>
433
- <!-- <span class="ms-1">{showControlsPanel ? 'Hide' : 'Show'} Controls</span> -->
434
- </button>
435
- {/if}
436
411
  </div>
437
412
  </nav>
438
413
 
@@ -722,11 +697,10 @@
722
697
  max-height: 100%; /* Constrain to slot */
723
698
  }
724
699
 
725
- /* Tab navigation wrapper with toggle button */
700
+ /* Tab navigation wrapper */
726
701
  .nav-tabs-wrapper {
727
702
  display: flex;
728
703
  align-items: center;
729
- gap: 1rem;
730
704
  border-bottom: 1px solid #dee2e6;
731
705
  }
732
706
 
@@ -736,25 +710,7 @@
736
710
  margin-bottom: 0;
737
711
  }
738
712
 
739
- .controls-toggle {
740
- display: flex;
741
- align-items: center;
742
- gap: 0.25rem;
743
- white-space: nowrap;
744
- border-radius: 0.25rem;
745
- transition: all 0.2s ease;
746
- }
747
-
748
- .controls-toggle:hover {
749
- background-color: #f8f9fa;
750
- border-color: #6c757d;
751
- }
752
-
753
- .controls-toggle svg {
754
- flex-shrink: 0;
755
- }
756
-
757
- /* ScrollSpy navigation wrapper with toggle button */
713
+ /* ScrollSpy navigation wrapper */
758
714
  .scrollspy-nav .nav-wrapper {
759
715
  display: flex;
760
716
  align-items: center;
@@ -6,9 +6,11 @@
6
6
  interface Props {
7
7
  controls: GlobalChartControls;
8
8
  onUpdate: (controls: GlobalChartControls) => void;
9
+ isExpanded?: boolean;
10
+ onToggle?: () => void;
9
11
  }
10
12
 
11
- let { controls, onUpdate }: Props = $props();
13
+ let { controls, onUpdate, isExpanded = false, onToggle }: Props = $props();
12
14
 
13
15
  function updateControls(updates: Partial<GlobalChartControls>) {
14
16
  onUpdate({
@@ -48,178 +50,377 @@
48
50
  }
49
51
  </script>
50
52
 
51
- <div class="global-controls">
52
- <div class="controls-section">
53
- <!-- <span class="controls-label">Display Controls:</span> -->
54
-
55
- <!-- Moving Average Controls -->
56
- {#if controls.movingAverage}
57
- <div class="control-group">
58
- <!-- MA Enable Toggle Button -->
59
- <input
60
- type="checkbox"
61
- class="btn-check"
62
- id="maToggle"
63
- checked={controls.movingAverage.enabled}
64
- onchange={() => updateMovingAverage({ enabled: !controls.movingAverage!.enabled })}
65
- />
66
- <label class="btn btn-outline-primary btn-sm" for="maToggle">
67
- Moving Average
68
- </label>
69
-
70
- {#if controls.movingAverage.enabled}
71
- <div class="control-subgroup">
72
- <!-- MA Window Size -->
73
- <div class="btn-group btn-group-sm" role="group" aria-label="MA Window">
74
- <input
75
- type="radio"
76
- class="btn-check"
77
- name="maWindow"
78
- id="maWindowAuto"
79
- checked={controls.movingAverage.windowOverride === undefined}
80
- onchange={() => updateMovingAverage({ windowOverride: undefined })}
81
- />
82
- <label class="btn btn-outline-primary" for="maWindowAuto">Auto</label>
83
-
84
- <input
85
- type="radio"
86
- class="btn-check"
87
- name="maWindow"
88
- id="maWindow7"
89
- checked={controls.movingAverage.windowOverride === 7}
90
- onchange={() => updateMovingAverage({ windowOverride: 7 })}
91
- />
92
- <label class="btn btn-outline-primary" for="maWindow7">7</label>
93
-
94
- <input
95
- type="radio"
96
- class="btn-check"
97
- name="maWindow"
98
- id="maWindow14"
99
- checked={controls.movingAverage.windowOverride === 14}
100
- onchange={() => updateMovingAverage({ windowOverride: 14 })}
101
- />
102
- <label class="btn btn-outline-primary" for="maWindow14">14</label>
53
+ <!-- Floating Controls Container -->
54
+ <div class="floating-controls-wrapper">
55
+ <!-- Toggle Button (always visible) -->
56
+ <button
57
+ class="floating-toggle-btn"
58
+ onclick={onToggle}
59
+ title={isExpanded ? "Hide Controls" : "Show Controls"}
60
+ type="button"
61
+ aria-expanded={isExpanded}
62
+ aria-label="Toggle chart controls"
63
+ >
64
+ <svg width="18" height="18" fill="currentColor" viewBox="0 0 16 16">
65
+ <path d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"/>
66
+ </svg>
67
+ <svg
68
+ class="chevron"
69
+ class:expanded={isExpanded}
70
+ width="12"
71
+ height="12"
72
+ fill="currentColor"
73
+ viewBox="0 0 16 16"
74
+ >
75
+ <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
76
+ </svg>
77
+ </button>
103
78
 
79
+ <!-- Controls Panel (expandable) -->
80
+ {#if isExpanded}
81
+ <div class="floating-controls-panel">
82
+ <div class="controls-section">
83
+ <!-- Top Row: Markers and Legend side by side -->
84
+ <div class="controls-row">
85
+ <!-- Markers Toggle -->
86
+ {#if controls.markers}
87
+ <div class="control-group-inline">
104
88
  <input
105
- type="radio"
89
+ type="checkbox"
106
90
  class="btn-check"
107
- name="maWindow"
108
- id="maWindow24"
109
- checked={controls.movingAverage.windowOverride === 24}
110
- onchange={() => updateMovingAverage({ windowOverride: 24 })}
91
+ id="markersToggle"
92
+ checked={controls.markers.enabled}
93
+ onchange={() => updateMarkers({ enabled: !controls.markers!.enabled })}
111
94
  />
112
- <label class="btn btn-outline-primary" for="maWindow24">24</label>
95
+ <label class="btn btn-outline-secondary btn-sm" for="markersToggle">
96
+ Markers
97
+ </label>
98
+ </div>
99
+ {/if}
113
100
 
101
+ <!-- Legend Toggle -->
102
+ {#if controls.legend}
103
+ <div class="control-group-inline">
114
104
  <input
115
- type="radio"
105
+ type="checkbox"
116
106
  class="btn-check"
117
- name="maWindow"
118
- id="maWindow30"
119
- checked={controls.movingAverage.windowOverride === 30}
120
- onchange={() => updateMovingAverage({ windowOverride: 30 })}
107
+ id="legendToggle"
108
+ checked={controls.legend.enabled}
109
+ onchange={() => updateLegend({ enabled: !controls.legend!.enabled })}
121
110
  />
122
- <label class="btn btn-outline-primary" for="maWindow30">30</label>
111
+ <label class="btn btn-outline-secondary btn-sm" for="legendToggle">
112
+ Legend
113
+ </label>
123
114
  </div>
115
+ {/if}
116
+ </div>
124
117
 
125
- <!-- Show Original Toggle Button -->
118
+ <!-- Bottom: Moving Average Controls -->
119
+ {#if controls.movingAverage}
120
+ <div class="control-group">
121
+ <!-- MA Enable Toggle Button -->
126
122
  <input
127
123
  type="checkbox"
128
124
  class="btn-check"
129
- id="showOriginal"
130
- checked={controls.movingAverage.showOriginal}
131
- onchange={() => updateMovingAverage({ showOriginal: !controls.movingAverage!.showOriginal })}
125
+ id="maToggle"
126
+ checked={controls.movingAverage.enabled}
127
+ onchange={() => updateMovingAverage({ enabled: !controls.movingAverage!.enabled })}
132
128
  />
133
- <label class="btn btn-outline-primary btn-sm ms-2" for="showOriginal">
134
- Show Original
129
+ <label class="btn btn-outline-primary btn-sm" for="maToggle">
130
+ Moving Average
135
131
  </label>
132
+
133
+ {#if controls.movingAverage.enabled}
134
+ <div class="control-subgroup">
135
+ <!-- MA Window Size -->
136
+ <div class="btn-group btn-group-sm" role="group" aria-label="MA Window">
137
+ <input
138
+ type="radio"
139
+ class="btn-check"
140
+ name="maWindow"
141
+ id="maWindowAuto"
142
+ checked={controls.movingAverage.windowOverride === undefined}
143
+ onchange={() => updateMovingAverage({ windowOverride: undefined })}
144
+ />
145
+ <label class="btn btn-outline-primary" for="maWindowAuto">Auto</label>
146
+
147
+ <input
148
+ type="radio"
149
+ class="btn-check"
150
+ name="maWindow"
151
+ id="maWindow7"
152
+ checked={controls.movingAverage.windowOverride === 7}
153
+ onchange={() => updateMovingAverage({ windowOverride: 7 })}
154
+ />
155
+ <label class="btn btn-outline-primary" for="maWindow7">7</label>
156
+
157
+ <input
158
+ type="radio"
159
+ class="btn-check"
160
+ name="maWindow"
161
+ id="maWindow14"
162
+ checked={controls.movingAverage.windowOverride === 14}
163
+ onchange={() => updateMovingAverage({ windowOverride: 14 })}
164
+ />
165
+ <label class="btn btn-outline-primary" for="maWindow14">14</label>
166
+
167
+ <input
168
+ type="radio"
169
+ class="btn-check"
170
+ name="maWindow"
171
+ id="maWindow24"
172
+ checked={controls.movingAverage.windowOverride === 24}
173
+ onchange={() => updateMovingAverage({ windowOverride: 24 })}
174
+ />
175
+ <label class="btn btn-outline-primary" for="maWindow24">24</label>
176
+
177
+ <input
178
+ type="radio"
179
+ class="btn-check"
180
+ name="maWindow"
181
+ id="maWindow30"
182
+ checked={controls.movingAverage.windowOverride === 30}
183
+ onchange={() => updateMovingAverage({ windowOverride: 30 })}
184
+ />
185
+ <label class="btn btn-outline-primary" for="maWindow30">30</label>
186
+ </div>
187
+
188
+ <!-- Show Original Toggle Button -->
189
+ <input
190
+ type="checkbox"
191
+ class="btn-check"
192
+ id="showOriginal"
193
+ checked={controls.movingAverage.showOriginal}
194
+ onchange={() => updateMovingAverage({ showOriginal: !controls.movingAverage!.showOriginal })}
195
+ />
196
+ <label class="btn btn-outline-primary btn-sm ms-2" for="showOriginal">
197
+ Show Original
198
+ </label>
199
+ </div>
200
+ {/if}
136
201
  </div>
137
202
  {/if}
138
203
  </div>
139
- {/if}
140
-
141
- <!-- Markers Toggle -->
142
- {#if controls.markers}
143
- <div class="control-group">
144
- <input
145
- type="checkbox"
146
- class="btn-check"
147
- id="markersToggle"
148
- checked={controls.markers.enabled}
149
- onchange={() => updateMarkers({ enabled: !controls.markers!.enabled })}
150
- />
151
- <label class="btn btn-outline-secondary btn-sm" for="markersToggle">
152
- Markers
153
- </label>
154
- </div>
155
- {/if}
156
-
157
- <!-- Legend Toggle -->
158
- {#if controls.legend}
159
- <div class="control-group">
160
- <input
161
- type="checkbox"
162
- class="btn-check"
163
- id="legendToggle"
164
- checked={controls.legend.enabled}
165
- onchange={() => updateLegend({ enabled: !controls.legend!.enabled })}
166
- />
167
- <label class="btn btn-outline-secondary btn-sm" for="legendToggle">
168
- Legend
169
- </label>
170
- </div>
171
- {/if}
172
-
173
- </div>
204
+ </div>
205
+ {/if}
174
206
  </div>
175
207
 
176
208
  <style>
177
- /* Global Controls Section */
178
- .global-controls {
179
- flex-shrink: 0;
180
- background-color: #f8f9fa;
181
- border-bottom: 1px solid #dee2e6;
182
- padding: 0.5rem 1rem;
209
+ /* Floating Controls Wrapper - positioned in top-right */
210
+ .floating-controls-wrapper {
211
+ position: fixed;
212
+ top: 0.5rem;
213
+ right: 0.5rem;
214
+ z-index: 1000;
215
+ display: flex;
216
+ flex-direction: column;
217
+ align-items: flex-end;
218
+ gap: 0.5rem;
219
+ }
220
+
221
+ /* Toggle Button - Always visible */
222
+ .floating-toggle-btn {
223
+ display: flex;
224
+ align-items: center;
225
+ gap: 0.375rem;
226
+ padding: 0.5rem 0.75rem;
227
+ background: rgba(255, 255, 255, 0.95);
228
+ backdrop-filter: blur(10px);
229
+ -webkit-backdrop-filter: blur(10px);
230
+ border: 1px solid rgba(0, 0, 0, 0.08);
231
+ border-radius: 8px;
232
+ box-shadow:
233
+ 0 2px 8px rgba(0, 0, 0, 0.08),
234
+ 0 4px 16px rgba(0, 0, 0, 0.04);
235
+ cursor: pointer;
236
+ transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
183
237
  font-size: 0.875rem;
238
+ font-weight: 500;
239
+ color: #495057;
240
+ opacity: 0.5;
241
+ }
242
+
243
+ .floating-toggle-btn:hover {
244
+ background: rgba(255, 255, 255, 1);
245
+ border-color: rgba(0, 0, 0, 0.12);
246
+ box-shadow:
247
+ 0 4px 12px rgba(0, 0, 0, 0.12),
248
+ 0 8px 24px rgba(0, 0, 0, 0.08);
249
+ transform: translateY(-1px);
250
+ opacity: 1;
251
+ }
252
+
253
+ .floating-toggle-btn:active {
254
+ transform: translateY(0);
255
+ box-shadow:
256
+ 0 1px 4px rgba(0, 0, 0, 0.08),
257
+ 0 2px 8px rgba(0, 0, 0, 0.04);
258
+ }
259
+
260
+ .floating-toggle-btn .chevron {
261
+ transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
262
+ opacity: 0.6;
263
+ }
264
+
265
+ .floating-toggle-btn .chevron.expanded {
266
+ transform: rotate(180deg);
267
+ }
268
+
269
+ /* Floating Controls Panel - Glass-morphism style */
270
+ .floating-controls-panel {
271
+ background: rgba(255, 255, 255, 0.95);
272
+ backdrop-filter: blur(12px);
273
+ -webkit-backdrop-filter: blur(12px);
274
+ border: 1px solid rgba(0, 0, 0, 0.08);
275
+ border-radius: 12px;
276
+ box-shadow:
277
+ 0 4px 16px rgba(0, 0, 0, 0.1),
278
+ 0 8px 32px rgba(0, 0, 0, 0.08);
279
+ padding: 1rem;
280
+ min-width: 320px;
281
+ max-width: 480px;
282
+ opacity: 1;
283
+ animation: slideIn 200ms cubic-bezier(0.4, 0, 0.2, 1);
284
+ }
285
+
286
+ .floating-controls-panel:hover {
287
+ opacity: 1;
288
+ }
289
+
290
+ @keyframes slideIn {
291
+ from {
292
+ opacity: 0;
293
+ transform: translateY(-8px);
294
+ }
295
+ to {
296
+ opacity: 1;
297
+ transform: translateY(0);
298
+ }
184
299
  }
185
300
 
186
301
  .controls-section {
302
+ display: flex;
303
+ flex-direction: column;
304
+ gap: 1rem;
305
+ }
306
+
307
+ /* Horizontal row for Markers and Legend at top */
308
+ .controls-row {
187
309
  display: flex;
188
310
  align-items: center;
189
- gap: 1.5rem;
190
- flex-wrap: wrap;
311
+ gap: 0.75rem;
312
+ padding-bottom: 0.75rem;
313
+ border-bottom: 1px solid rgba(0, 0, 0, 0.08);
191
314
  }
192
315
 
193
- .control-group {
316
+ /* Inline control group for horizontal layout */
317
+ .control-group-inline {
194
318
  display: flex;
195
319
  align-items: center;
320
+ }
321
+
322
+ /* Vertical control group for Moving Average */
323
+ .control-group {
324
+ display: flex;
325
+ flex-direction: column;
196
326
  gap: 0.75rem;
197
327
  }
198
328
 
329
+ .control-group > label:first-of-type {
330
+ font-weight: 500;
331
+ }
332
+
199
333
  .control-subgroup {
200
334
  display: flex;
335
+ flex-wrap: wrap;
201
336
  align-items: center;
202
337
  gap: 0.5rem;
203
- padding-left: 0.5rem;
204
- border-left: 2px solid #dee2e6;
338
+ padding-left: 0.75rem;
339
+ padding-top: 0.5rem;
340
+ border-left: 2px solid rgba(0, 0, 0, 0.08);
205
341
  }
206
342
 
207
- .global-controls :global(.btn-group-sm .btn) {
208
- padding: 0.25rem 0.75rem;
209
- font-size: 0.75rem;
343
+ /* Bootstrap button overrides for better integration */
344
+ .floating-controls-panel :global(.btn-sm) {
345
+ padding: 0.375rem 0.75rem;
346
+ font-size: 0.8125rem;
210
347
  font-weight: 500;
348
+ border-radius: 6px;
349
+ transition: all 150ms ease;
350
+ }
351
+
352
+ .floating-controls-panel :global(.btn-outline-primary) {
353
+ border-color: rgba(13, 110, 253, 0.3);
354
+ }
355
+
356
+ .floating-controls-panel :global(.btn-outline-primary:hover) {
357
+ background-color: rgba(13, 110, 253, 0.1);
358
+ border-color: rgba(13, 110, 253, 0.5);
359
+ }
360
+
361
+ .floating-controls-panel :global(.btn-check:checked + .btn-outline-primary) {
362
+ background-color: #0d6efd;
363
+ border-color: #0d6efd;
364
+ }
365
+
366
+ .floating-controls-panel :global(.btn-outline-secondary) {
367
+ border-color: rgba(108, 117, 125, 0.3);
368
+ }
369
+
370
+ .floating-controls-panel :global(.btn-outline-secondary:hover) {
371
+ background-color: rgba(108, 117, 125, 0.1);
372
+ border-color: rgba(108, 117, 125, 0.5);
373
+ }
374
+
375
+ .floating-controls-panel :global(.btn-check:checked + .btn-outline-secondary) {
376
+ background-color: #6c757d;
377
+ border-color: #6c757d;
378
+ }
379
+
380
+ .floating-controls-panel :global(.btn-group) {
381
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
382
+ border-radius: 6px;
383
+ overflow: hidden;
211
384
  }
212
385
 
213
386
  /* Responsive adjustments */
214
387
  @media (max-width: 768px) {
215
- .controls-section {
216
- flex-direction: column;
217
- align-items: flex-start;
218
- gap: 0.75rem;
388
+ .floating-controls-wrapper {
389
+ top: 0.5rem;
390
+ right: 0.5rem;
391
+ }
392
+
393
+ .floating-controls-panel {
394
+ min-width: 280px;
395
+ max-width: calc(100vw - 2rem);
396
+ padding: 0.875rem;
397
+ }
398
+
399
+ .control-subgroup {
400
+ padding-left: 0.5rem;
401
+ }
402
+ }
403
+
404
+ /* Dark mode support (optional - activate if needed) */
405
+ @media (prefers-color-scheme: dark) {
406
+ .floating-toggle-btn {
407
+ background: rgba(33, 37, 41, 0.95);
408
+ border-color: rgba(255, 255, 255, 0.1);
409
+ color: #f8f9fa;
219
410
  }
220
-
411
+
412
+ .floating-toggle-btn:hover {
413
+ background: rgba(33, 37, 41, 1);
414
+ border-color: rgba(255, 255, 255, 0.15);
415
+ }
416
+
417
+ .floating-controls-panel {
418
+ background: rgba(33, 37, 41, 0.95);
419
+ border-color: rgba(255, 255, 255, 0.1);
420
+ }
421
+
221
422
  .control-subgroup {
222
- flex-wrap: wrap;
423
+ border-left-color: rgba(255, 255, 255, 0.1);
223
424
  }
224
425
  }
225
426
  </style>
@@ -2,6 +2,8 @@ import type { GlobalChartControls } from './charts.model.js';
2
2
  interface Props {
3
3
  controls: GlobalChartControls;
4
4
  onUpdate: (controls: GlobalChartControls) => void;
5
+ isExpanded?: boolean;
6
+ onToggle?: () => void;
5
7
  }
6
8
  declare const GlobalControls: import("svelte").Component<Props, {}, "">;
7
9
  type GlobalControls = ReturnType<typeof GlobalControls>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartnet360/svelte-components",
3
- "version": "0.0.43",
3
+ "version": "0.0.44",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",