@eduboxpro/studio 0.1.2 → 0.1.3

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.
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output } from '@angular/core';
2
+ import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, model } from '@angular/core';
3
3
  import { DOCUMENT } from '@angular/common';
4
4
  import * as i1 from 'lucide-angular';
5
- import { icons, LucideAngularModule, LucideIconProvider, LUCIDE_ICONS, ShoppingCart, Loader2, Loader, RotateCw, RefreshCw, Printer, Save, Image, Folder, FileText, File, HelpCircle, XCircle, CheckCircle, Info, AlertTriangle, AlertCircle, LogOut, LogIn, Unlock, Lock, EyeOff, Eye, Clock, Calendar, Bell, MoreHorizontal, MoreVertical, Menu, Home, Share2, Copy, Link, ExternalLink, Filter, Search, X, Check, Minus, Plus, Edit, Trash2, User, Settings, Star, Heart, Phone, Mail, Upload, Download, ChevronRight, ChevronLeft, ChevronUp, ChevronDown, ArrowLeft, ArrowRight } from 'lucide-angular';
5
+ import { icons, LucideAngularModule, LucideIconProvider, LUCIDE_ICONS, Moon, Sun, ShoppingCart, Loader2, Loader, RotateCw, RefreshCw, Printer, Save, Image, Folder, FileText, File, HelpCircle, XCircle, CheckCircle, Info, AlertTriangle, AlertCircle, LogOut, LogIn, Unlock, Lock, EyeOff, Eye, Clock, Calendar, Bell, MoreHorizontal, MoreVertical, Menu, Home, Share2, Copy, Link, ExternalLink, Filter, Search, X, Check, Minus, Plus, Edit, Trash2, User, Settings, Star, Heart, Phone, Mail, Upload, Download, ChevronRight, ChevronLeft, ChevronUp, ChevronDown, ArrowLeft, ArrowRight } from 'lucide-angular';
6
6
 
7
7
  /**
8
8
  * Injection token for Studio configuration
@@ -19,7 +19,7 @@ class StudioConfigService {
19
19
  constructor() {
20
20
  effect(() => {
21
21
  this.applyTheme(this.config().theme);
22
- }, { allowSignalWrites: false });
22
+ });
23
23
  }
24
24
  configure(config) {
25
25
  this.config.set(config);
@@ -35,29 +35,23 @@ class StudioConfigService {
35
35
  const newMode = this.themeMode() === 'light' ? 'dark' : 'light';
36
36
  this.setThemeMode(newMode);
37
37
  }
38
- async loadFromBackend(organizationSlug) {
39
- try {
40
- const response = await fetch(`/api/organizations/${organizationSlug}/design-config`);
41
- if (!response.ok) {
42
- throw new Error(`HTTP error! status: ${response.status}`);
43
- }
44
- const config = await response.json();
45
- this.configure(config);
46
- }
47
- catch (error) {
48
- console.error('[Studio] Failed to load config from backend:', error);
49
- throw error;
50
- }
38
+ updateTheme(theme) {
39
+ this.config.update(cfg => ({
40
+ ...cfg,
41
+ theme: { ...cfg.theme, ...theme }
42
+ }));
43
+ }
44
+ reset() {
45
+ this.config.set({});
46
+ this.setThemeMode('light');
51
47
  }
52
48
  applyTheme(theme) {
53
49
  if (!theme)
54
50
  return;
55
51
  const root = this.document.documentElement;
56
- // Apply colors
57
52
  if (theme.colors) {
58
53
  this.applyColorTokens(root, theme.colors);
59
54
  }
60
- // Apply typography
61
55
  if (theme.typography) {
62
56
  if (theme.typography.fontFamily) {
63
57
  root.style.setProperty('--studio-font-family', theme.typography.fontFamily);
@@ -75,29 +69,23 @@ class StudioConfigService {
75
69
  this.applyTokens(root, 'studio-line-height', theme.typography.lineHeight);
76
70
  }
77
71
  }
78
- // Apply spacing
79
72
  if (theme.spacing) {
80
73
  this.applyTokens(root, 'studio-spacing', theme.spacing);
81
74
  }
82
- // Apply border radius
83
75
  if (theme.borderRadius) {
84
76
  this.applyTokens(root, 'studio-radius', theme.borderRadius);
85
77
  }
86
- // Apply shadows
87
78
  if (theme.shadows) {
88
79
  this.applyTokens(root, 'studio-shadow', theme.shadows);
89
80
  }
90
- // Apply transitions
91
81
  if (theme.transitions) {
92
82
  this.applyTokens(root, 'studio-transition', theme.transitions);
93
83
  }
94
- // Apply z-index
95
84
  if (theme.zIndex) {
96
85
  this.applyZIndexTokens(root, theme.zIndex);
97
86
  }
98
87
  }
99
88
  applyColorTokens(root, colors) {
100
- // Brand colors with hover/active states
101
89
  const brandColors = ['primary', 'secondary', 'success', 'error', 'warning', 'info'];
102
90
  brandColors.forEach(colorName => {
103
91
  const colorValue = colors[colorName];
@@ -122,15 +110,12 @@ class StudioConfigService {
122
110
  }
123
111
  }
124
112
  });
125
- // Background colors
126
113
  if (colors.bg) {
127
114
  this.applyTokens(root, 'studio-bg', colors.bg);
128
115
  }
129
- // Text colors
130
116
  if (colors.text) {
131
117
  this.applyTokens(root, 'studio-text', colors.text);
132
118
  }
133
- // Border colors
134
119
  if (colors.border) {
135
120
  this.applyTokens(root, 'studio-border', colors.border);
136
121
  }
@@ -212,17 +197,48 @@ function provideStudioConfig(config = {}) {
212
197
  * @module config
213
198
  */
214
199
 
200
+ /**
201
+ * Icon component with Lucide icons support
202
+ *
203
+ * @example
204
+ * <studio-icon name="check" size="24" color="primary" />
205
+ */
215
206
  class IconComponent {
216
207
  name = input.required(...(ngDevMode ? [{ debugName: "name" }] : []));
217
208
  size = input(24, ...(ngDevMode ? [{ debugName: "size" }] : []));
218
209
  color = input('inherit', ...(ngDevMode ? [{ debugName: "color" }] : []));
219
210
  strokeWidth = input(2, ...(ngDevMode ? [{ debugName: "strokeWidth" }] : []));
220
211
  absoluteStrokeWidth = input(false, ...(ngDevMode ? [{ debugName: "absoluteStrokeWidth" }] : []));
212
+ showFallback = input(true, ...(ngDevMode ? [{ debugName: "showFallback" }] : []));
213
+ fallbackIcon = input('help-circle', ...(ngDevMode ? [{ debugName: "fallbackIcon" }] : []));
221
214
  icons = icons;
222
215
  lucideIcon = computed(() => {
223
216
  const iconName = this.name();
224
- return iconName;
217
+ if (iconName && icons[iconName]) {
218
+ return iconName;
219
+ }
220
+ const pascalCaseName = this.kebabToPascalCase(iconName);
221
+ if (pascalCaseName && icons[pascalCaseName]) {
222
+ return pascalCaseName;
223
+ }
224
+ if (this.showFallback()) {
225
+ const fallback = this.fallbackIcon();
226
+ if (icons[fallback]) {
227
+ return fallback;
228
+ }
229
+ const pascalCaseFallback = this.kebabToPascalCase(fallback);
230
+ if (pascalCaseFallback && icons[pascalCaseFallback]) {
231
+ return pascalCaseFallback;
232
+ }
233
+ }
234
+ return null;
225
235
  }, ...(ngDevMode ? [{ debugName: "lucideIcon" }] : []));
236
+ kebabToPascalCase(str) {
237
+ return str
238
+ .split('-')
239
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
240
+ .join('');
241
+ }
226
242
  computedColor = computed(() => {
227
243
  const colorValue = this.color();
228
244
  const colorMap = {
@@ -239,7 +255,7 @@ class IconComponent {
239
255
  return ['studio-icon'];
240
256
  }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
241
257
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
242
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: IconComponent, isStandalone: true, selector: "studio-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, absoluteStrokeWidth: { classPropertyName: "absoluteStrokeWidth", publicName: "absoluteStrokeWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "style.width.px": "size()", "style.height.px": "size()" } }, ngImport: i0, template: `
258
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: IconComponent, isStandalone: true, selector: "studio-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, absoluteStrokeWidth: { classPropertyName: "absoluteStrokeWidth", publicName: "absoluteStrokeWidth", isSignal: true, isRequired: false, transformFunction: null }, showFallback: { classPropertyName: "showFallback", publicName: "showFallback", isSignal: true, isRequired: false, transformFunction: null }, fallbackIcon: { classPropertyName: "fallbackIcon", publicName: "fallbackIcon", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "style.width.px": "size()", "style.height.px": "size()" } }, ngImport: i0, template: `
243
259
  @if (lucideIcon(); as iconName) {
244
260
  <lucide-icon
245
261
  [name]="iconName"
@@ -268,11 +284,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
268
284
  />
269
285
  }
270
286
  `, styles: [":host{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}\n"] }]
271
- }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], strokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "strokeWidth", required: false }] }], absoluteStrokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "absoluteStrokeWidth", required: false }] }] } });
287
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], strokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "strokeWidth", required: false }] }], absoluteStrokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "absoluteStrokeWidth", required: false }] }], showFallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFallback", required: false }] }], fallbackIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallbackIcon", required: false }] }] } });
272
288
 
273
289
  /**
274
- * Провайдер иконок для Studio
275
- * Регистрирует базовый набор часто используемых иконок
290
+ * Studio icon provider
291
+ * Registers commonly used Lucide icons
276
292
  *
277
293
  * @example
278
294
  * ```typescript
@@ -286,7 +302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
286
302
  * };
287
303
  * ```
288
304
  *
289
- * Для добавления дополнительных иконок:
305
+ * To add additional icons:
290
306
  * @example
291
307
  * ```typescript
292
308
  * import { LUCIDE_ICONS, LucideIconProvider } from 'lucide-angular';
@@ -363,17 +379,19 @@ function provideStudioIcons() {
363
379
  RotateCw,
364
380
  Loader,
365
381
  Loader2,
366
- ShoppingCart
382
+ ShoppingCart,
383
+ Sun,
384
+ Moon
367
385
  })
368
386
  }
369
387
  ]);
370
388
  }
371
389
 
372
390
  /**
373
- * Проверяет безопасность URL для навигации
391
+ * Checks if URL is safe for navigation
374
392
  *
375
- * @param url - URL для проверки
376
- * @returns true если URL безопасен (http/https или относительный)
393
+ * @param url - URL to check
394
+ * @returns true if URL is safe (http/https or relative)
377
395
  *
378
396
  * @example
379
397
  * ```typescript
@@ -388,24 +406,22 @@ function isSafeUrl(url) {
388
406
  }
389
407
  try {
390
408
  const parsed = new URL(url, window.location.origin);
391
- // Разрешаем только http(s) и относительные URL (пустой protocol)
392
409
  return ['http:', 'https:', ''].includes(parsed.protocol);
393
410
  }
394
411
  catch {
395
- // Невалидный URL
396
412
  return false;
397
413
  }
398
414
  }
399
415
  /**
400
- * Sanitize URL перед использованием в навигации
416
+ * Sanitize URL before using in navigation
401
417
  *
402
- * @param url - URL для sanitization
403
- * @returns Безопасный URL или '#' если URL небезопасен
418
+ * @param url - URL to sanitize
419
+ * @returns Safe URL or '#' if URL is unsafe
404
420
  *
405
421
  * @example
406
422
  * ```typescript
407
423
  * sanitizeUrl('https://example.com') // 'https://example.com'
408
- * sanitizeUrl('javascript:alert(1)') // '#' (с предупреждением в консоли)
424
+ * sanitizeUrl('javascript:alert(1)') // '#' (with console warning)
409
425
  * ```
410
426
  */
411
427
  function sanitizeUrl(url) {
@@ -417,15 +433,15 @@ function sanitizeUrl(url) {
417
433
  }
418
434
 
419
435
  /**
420
- * Объединяет CSS классы, игнорируя falsy значения
436
+ * Combines CSS classes, ignoring falsy values
421
437
  *
422
- * @param classes - Массив классов (строки, undefined, null, false)
423
- * @returns Строка с объединенными классами
438
+ * @param classes - Array of classes (strings, undefined, null, false)
439
+ * @returns String with combined classes
424
440
  *
425
441
  * @example
426
442
  * ```typescript
427
443
  * classNames('btn', 'btn-primary') // 'btn btn-primary'
428
- * classNames('btn', isActive && 'active') // 'btn active' если isActive=true, иначе 'btn'
444
+ * classNames('btn', isActive && 'active') // 'btn active' if isActive=true, else 'btn'
429
445
  * classNames('btn', undefined, null, false, 'large') // 'btn large'
430
446
  * ```
431
447
  */
@@ -434,24 +450,20 @@ function classNames(...classes) {
434
450
  }
435
451
 
436
452
  /**
437
- * Создает computed signal с fallback chain: input → config → default
453
+ * Creates computed signal with fallback chain: input → config → default
438
454
  *
439
- * Упрощает паттерн configurable inputs, убирая boilerplate код.
440
- *
441
- * @param inputSignal - Input signal от пользователя
442
- * @param configSignal - Config значение (может быть undefined)
443
- * @param defaultValue - Fallback значение
444
- * @returns Computed signal с resolved значением
455
+ * @param inputSignal - User input signal
456
+ * @param configSignal - Config value (can be undefined)
457
+ * @param defaultValue - Fallback value
458
+ * @returns Computed signal with resolved value
445
459
  *
446
460
  * @example
447
461
  * ```typescript
448
462
  * export class ButtonComponent {
449
463
  * private defaults = computed(() => this.configService.config().components?.button);
450
464
  *
451
- * // Input
452
465
  * variantInput = input<Variant | undefined>(undefined, { alias: 'variant' });
453
466
  *
454
- * // Resolved value с config fallback
455
467
  * variant = withConfigDefault(
456
468
  * this.variantInput,
457
469
  * computed(() => this.defaults()?.variant),
@@ -481,40 +493,30 @@ function withConfigDefault(inputSignal, configSignal, defaultValue) {
481
493
  class BadgeComponent {
482
494
  configService = inject(StudioConfigService);
483
495
  badgeDefaults = computed(() => this.configService.config().components?.badge, ...(ngDevMode ? [{ debugName: "badgeDefaults" }] : []));
484
- // Appearance - inputs
485
496
  variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
486
497
  sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
487
498
  colorInput = input(undefined, ...(ngDevMode ? [{ debugName: "colorInput", alias: 'color' }] : [{ alias: 'color' }]));
488
499
  radiusInput = input(undefined, ...(ngDevMode ? [{ debugName: "radiusInput", alias: 'radius' }] : [{ alias: 'radius' }]));
489
- // Values with config defaults
490
500
  variant = withConfigDefault(this.variantInput, computed(() => this.badgeDefaults()?.variant), 'solid');
491
501
  size = withConfigDefault(this.sizeInput, computed(() => this.badgeDefaults()?.size), 'md');
492
502
  color = withConfigDefault(this.colorInput, computed(() => this.badgeDefaults()?.color), 'primary');
493
503
  radius = withConfigDefault(this.radiusInput, computed(() => this.badgeDefaults()?.radius), 'full');
494
- // Icon
495
504
  icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : []));
496
505
  iconPosition = input('left', ...(ngDevMode ? [{ debugName: "iconPosition" }] : []));
497
- // Dot indicator
498
506
  dot = input(false, ...(ngDevMode ? [{ debugName: "dot" }] : []));
499
507
  dotColor = input(...(ngDevMode ? [undefined, { debugName: "dotColor" }] : []));
500
- // Removable
501
508
  removable = input(false, ...(ngDevMode ? [{ debugName: "removable" }] : []));
502
509
  removed = output();
503
- // Clickable & Navigation
504
510
  href = input(...(ngDevMode ? [undefined, { debugName: "href" }] : []));
505
511
  target = input('_self', ...(ngDevMode ? [{ debugName: "target" }] : []));
506
512
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
507
513
  clicked = output();
508
- // Number badge
509
514
  value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
510
515
  max = input(...(ngDevMode ? [undefined, { debugName: "max" }] : []));
511
516
  showZero = input(true, ...(ngDevMode ? [{ debugName: "showZero" }] : []));
512
- // Typography
513
517
  uppercase = input(false, ...(ngDevMode ? [{ debugName: "uppercase" }] : []));
514
518
  bold = input(false, ...(ngDevMode ? [{ debugName: "bold" }] : []));
515
- // Animation
516
519
  pulse = input(false, ...(ngDevMode ? [{ debugName: "pulse" }] : []));
517
- // Auto color (будет реализовано позже если нужно)
518
520
  autoColor = input(false, ...(ngDevMode ? [{ debugName: "autoColor" }] : []));
519
521
  iconSize = computed(() => {
520
522
  const sizeMap = { sm: 12, md: 14, lg: 16 };
@@ -525,12 +527,9 @@ class BadgeComponent {
525
527
  if (val === undefined || val === null)
526
528
  return '';
527
529
  const numVal = typeof val === 'number' ? val : parseInt(val, 10);
528
- // Если это число
529
530
  if (!isNaN(numVal)) {
530
- // Не показывать 0 если showZero = false
531
531
  if (numVal === 0 && !this.showZero())
532
532
  return '';
533
- // Показать max+ если превышает максимум
534
533
  const maxVal = this.max();
535
534
  if (maxVal !== undefined && numVal > maxVal) {
536
535
  return `${maxVal}+`;
@@ -540,7 +539,6 @@ class BadgeComponent {
540
539
  return val.toString();
541
540
  }, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
542
541
  isVisible = computed(() => {
543
- // Скрыть если значение 0 и showZero = false
544
542
  const val = this.value();
545
543
  if (val !== undefined && val !== null) {
546
544
  const numVal = typeof val === 'number' ? val : parseInt(val, 10);
@@ -557,12 +555,10 @@ class BadgeComponent {
557
555
  event.stopPropagation();
558
556
  return;
559
557
  }
560
- // Handle link navigation
561
558
  const url = this.href();
562
559
  if (url) {
563
560
  const safeUrl = sanitizeUrl(url);
564
561
  if (safeUrl === '#') {
565
- // URL was blocked - don't navigate
566
562
  return;
567
563
  }
568
564
  const target = this.target();
@@ -615,7 +611,7 @@ class BadgeComponent {
615
611
  </button>
616
612
  }
617
613
  </span>
618
- `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;font-family:var(--studio-font-family);font-weight:var(--studio-badge-font-weight, 500);line-height:1;white-space:nowrap;transition:all .2s ease;cursor:default;-webkit-user-select:none;user-select:none}.studio-badge__content{display:inline-flex;align-items:center;gap:var(--studio-badge-gap);padding:var(--studio-badge-padding-y) var(--studio-badge-padding-x);border-radius:var(--studio-badge-radius);background:var(--studio-badge-bg);color:var(--studio-badge-color);border:var(--studio-badge-border-width, 1px) solid var(--studio-badge-border-color, transparent);font-size:var(--studio-badge-font-size)}.studio-badge__text{display:inline-block}.studio-badge__dot{width:var(--studio-badge-dot-size, 6px);height:var(--studio-badge-dot-size, 6px);border-radius:50%;background:var(--studio-badge-dot-bg);flex-shrink:0}.studio-badge__remove{all:unset;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;opacity:.7;transition:opacity .2s ease}.studio-badge__remove:hover{opacity:1}.studio-badge__remove:focus-visible{outline:2px solid currentColor;outline-offset:2px;border-radius:2px}:host(.studio-badge--solid){--studio-badge-bg: var(--studio-primary);--studio-badge-color: white}:host(.studio-badge--solid).studio-badge--primary{--studio-badge-bg: var(--studio-primary)}:host(.studio-badge--solid).studio-badge--secondary{--studio-badge-bg: var(--studio-secondary)}:host(.studio-badge--solid).studio-badge--success{--studio-badge-bg: var(--studio-success)}:host(.studio-badge--solid).studio-badge--error{--studio-badge-bg: var(--studio-error)}:host(.studio-badge--solid).studio-badge--warning{--studio-badge-bg: var(--studio-warning)}:host(.studio-badge--solid).studio-badge--info{--studio-badge-bg: var(--studio-info)}:host(.studio-badge--solid).studio-badge--neutral{--studio-badge-bg: var(--studio-border-secondary);--studio-badge-color: var(--studio-text-primary)}:host(.studio-badge--outline){--studio-badge-bg: transparent;--studio-badge-color: var(--studio-primary);--studio-badge-border-color: var(--studio-primary)}:host(.studio-badge--outline).studio-badge--primary{--studio-badge-color: var(--studio-primary);--studio-badge-border-color: var(--studio-primary)}:host(.studio-badge--outline).studio-badge--secondary{--studio-badge-color: var(--studio-secondary);--studio-badge-border-color: var(--studio-secondary)}:host(.studio-badge--outline).studio-badge--success{--studio-badge-color: var(--studio-success);--studio-badge-border-color: var(--studio-success)}:host(.studio-badge--outline).studio-badge--error{--studio-badge-color: var(--studio-error);--studio-badge-border-color: var(--studio-error)}:host(.studio-badge--outline).studio-badge--warning{--studio-badge-color: var(--studio-warning);--studio-badge-border-color: var(--studio-warning)}:host(.studio-badge--outline).studio-badge--info{--studio-badge-color: var(--studio-info);--studio-badge-border-color: var(--studio-info)}:host(.studio-badge--outline).studio-badge--neutral{--studio-badge-color: var(--studio-text-secondary);--studio-badge-border-color: var(--studio-border-secondary)}:host(.studio-badge--soft){--studio-badge-bg: rgba(124, 58, 237, .1);--studio-badge-color: var(--studio-primary)}:host(.studio-badge--soft).studio-badge--primary{--studio-badge-bg: rgba(124, 58, 237, .1);--studio-badge-color: var(--studio-primary)}:host(.studio-badge--soft).studio-badge--secondary{--studio-badge-bg: rgba(99, 102, 241, .1);--studio-badge-color: var(--studio-secondary)}:host(.studio-badge--soft).studio-badge--success{--studio-badge-bg: var(--studio-success-bg);--studio-badge-color: var(--studio-success)}:host(.studio-badge--soft).studio-badge--error{--studio-badge-bg: var(--studio-error-bg);--studio-badge-color: var(--studio-error)}:host(.studio-badge--soft).studio-badge--warning{--studio-badge-bg: var(--studio-warning-bg);--studio-badge-color: var(--studio-warning)}:host(.studio-badge--soft).studio-badge--info{--studio-badge-bg: var(--studio-info-bg);--studio-badge-color: var(--studio-info)}:host(.studio-badge--soft).studio-badge--neutral{--studio-badge-bg: var(--studio-bg-secondary);--studio-badge-color: var(--studio-text-secondary)}:host(.studio-badge--dot){--studio-badge-bg: transparent;--studio-badge-color: var(--studio-text-primary);--studio-badge-border-width: 0}:host(.studio-badge--sm){--studio-badge-padding-y: .125rem;--studio-badge-padding-x: .5rem;--studio-badge-font-size: .6875rem;--studio-badge-gap: .25rem}:host(.studio-badge--md){--studio-badge-padding-y: .25rem;--studio-badge-padding-x: .625rem;--studio-badge-font-size: .75rem;--studio-badge-gap: .375rem}:host(.studio-badge--lg){--studio-badge-padding-y: .375rem;--studio-badge-padding-x: .75rem;--studio-badge-font-size: .875rem;--studio-badge-gap: .5rem}:host(.studio-badge--radius-sm){--studio-badge-radius: 2px}:host(.studio-badge--radius-md){--studio-badge-radius: 4px}:host(.studio-badge--radius-lg){--studio-badge-radius: 8px}:host(.studio-badge--radius-full){--studio-badge-radius: 9999px}.studio-badge__dot--primary{--studio-badge-dot-bg: var(--studio-primary)}.studio-badge__dot--secondary{--studio-badge-dot-bg: var(--studio-secondary)}.studio-badge__dot--success{--studio-badge-dot-bg: var(--studio-success)}.studio-badge__dot--error{--studio-badge-dot-bg: var(--studio-error)}.studio-badge__dot--warning{--studio-badge-dot-bg: var(--studio-warning)}.studio-badge__dot--info{--studio-badge-dot-bg: var(--studio-info)}.studio-badge__dot--neutral{--studio-badge-dot-bg: var(--studio-text-secondary)}:host(.studio-badge--clickable){cursor:pointer}:host(.studio-badge--clickable):hover{opacity:.9;transform:translateY(-1px)}:host(.studio-badge--clickable):active{transform:translateY(0)}:host(.studio-badge--disabled){opacity:.5;cursor:not-allowed;pointer-events:none}:host(.studio-badge--uppercase){text-transform:uppercase;letter-spacing:.5px}:host(.studio-badge--bold){--studio-badge-font-weight: 600}@keyframes badge-pulse{0%,to{opacity:1}50%{opacity:.5}}:host(.studio-badge--pulse) .studio-badge__dot{animation:badge-pulse 2s cubic-bezier(.4,0,.6,1) infinite}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
614
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;font-family:var(--studio-font-family);font-weight:var(--studio-badge-font-weight, 500);line-height:1;white-space:nowrap;transition:all .2s ease;cursor:default;-webkit-user-select:none;user-select:none}.studio-badge__content{display:inline-flex;align-items:center;gap:var(--studio-badge-gap);padding:var(--studio-badge-padding-y) var(--studio-badge-padding-x);border-radius:var(--studio-badge-radius);background:var(--studio-badge-bg);color:var(--studio-badge-color);border:var(--studio-badge-border-width, 1px) solid var(--studio-badge-border-color, transparent);font-size:var(--studio-badge-font-size)}.studio-badge__text{display:inline-block}.studio-badge__dot{width:var(--studio-badge-dot-size, 6px);height:var(--studio-badge-dot-size, 6px);border-radius:50%;background:var(--studio-badge-dot-bg);flex-shrink:0}.studio-badge__remove{all:unset;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;opacity:.7;transition:opacity .2s ease}.studio-badge__remove:hover{opacity:1}.studio-badge__remove:focus-visible{outline:2px solid currentColor;outline-offset:2px;border-radius:2px}:host(.studio-badge--solid){--studio-badge-bg: var(--studio-primary);--studio-badge-color: white}:host(.studio-badge--solid).studio-badge--primary{--studio-badge-bg: var(--studio-primary)}:host(.studio-badge--solid).studio-badge--secondary{--studio-badge-bg: var(--studio-secondary)}:host(.studio-badge--solid).studio-badge--success{--studio-badge-bg: var(--studio-success)}:host(.studio-badge--solid).studio-badge--error{--studio-badge-bg: var(--studio-error)}:host(.studio-badge--solid).studio-badge--warning{--studio-badge-bg: var(--studio-warning)}:host(.studio-badge--solid).studio-badge--info{--studio-badge-bg: var(--studio-info)}:host(.studio-badge--solid).studio-badge--neutral{--studio-badge-bg: var(--studio-border-secondary);--studio-badge-color: var(--studio-text-primary)}:host(.studio-badge--outline){--studio-badge-bg: transparent;--studio-badge-color: var(--studio-primary);--studio-badge-border-color: var(--studio-primary)}:host(.studio-badge--outline).studio-badge--primary{--studio-badge-color: var(--studio-primary);--studio-badge-border-color: var(--studio-primary)}:host(.studio-badge--outline).studio-badge--secondary{--studio-badge-color: var(--studio-secondary);--studio-badge-border-color: var(--studio-secondary)}:host(.studio-badge--outline).studio-badge--success{--studio-badge-color: var(--studio-success);--studio-badge-border-color: var(--studio-success)}:host(.studio-badge--outline).studio-badge--error{--studio-badge-color: var(--studio-error);--studio-badge-border-color: var(--studio-error)}:host(.studio-badge--outline).studio-badge--warning{--studio-badge-color: var(--studio-warning);--studio-badge-border-color: var(--studio-warning)}:host(.studio-badge--outline).studio-badge--info{--studio-badge-color: var(--studio-info);--studio-badge-border-color: var(--studio-info)}:host(.studio-badge--outline).studio-badge--neutral{--studio-badge-color: var(--studio-text-secondary);--studio-badge-border-color: var(--studio-border-secondary)}:host(.studio-badge--soft){--studio-badge-bg: rgba(124, 58, 237, .1);--studio-badge-color: var(--studio-primary)}:host(.studio-badge--soft).studio-badge--primary{--studio-badge-bg: rgba(124, 58, 237, .1);--studio-badge-color: var(--studio-primary)}:host(.studio-badge--soft).studio-badge--secondary{--studio-badge-bg: rgba(99, 102, 241, .1);--studio-badge-color: var(--studio-secondary)}:host(.studio-badge--soft).studio-badge--success{--studio-badge-bg: var(--studio-success-bg);--studio-badge-color: var(--studio-success)}:host(.studio-badge--soft).studio-badge--error{--studio-badge-bg: var(--studio-error-bg);--studio-badge-color: var(--studio-error)}:host(.studio-badge--soft).studio-badge--warning{--studio-badge-bg: var(--studio-warning-bg);--studio-badge-color: var(--studio-warning)}:host(.studio-badge--soft).studio-badge--info{--studio-badge-bg: var(--studio-info-bg);--studio-badge-color: var(--studio-info)}:host(.studio-badge--soft).studio-badge--neutral{--studio-badge-bg: var(--studio-bg-secondary);--studio-badge-color: var(--studio-text-secondary)}:host(.studio-badge--dot){--studio-badge-bg: transparent;--studio-badge-color: var(--studio-text-primary);--studio-badge-border-width: 0}:host(.studio-badge--sm){--studio-badge-padding-y: .125rem;--studio-badge-padding-x: .5rem;--studio-badge-font-size: .6875rem;--studio-badge-gap: .25rem}:host(.studio-badge--md){--studio-badge-padding-y: .25rem;--studio-badge-padding-x: .625rem;--studio-badge-font-size: .75rem;--studio-badge-gap: .375rem}:host(.studio-badge--lg){--studio-badge-padding-y: .375rem;--studio-badge-padding-x: .75rem;--studio-badge-font-size: .875rem;--studio-badge-gap: .5rem}:host(.studio-badge--radius-sm){--studio-badge-radius: 2px}:host(.studio-badge--radius-md){--studio-badge-radius: 4px}:host(.studio-badge--radius-lg){--studio-badge-radius: 8px}:host(.studio-badge--radius-full){--studio-badge-radius: 9999px}.studio-badge__dot--primary{--studio-badge-dot-bg: var(--studio-primary)}.studio-badge__dot--secondary{--studio-badge-dot-bg: var(--studio-secondary)}.studio-badge__dot--success{--studio-badge-dot-bg: var(--studio-success)}.studio-badge__dot--error{--studio-badge-dot-bg: var(--studio-error)}.studio-badge__dot--warning{--studio-badge-dot-bg: var(--studio-warning)}.studio-badge__dot--info{--studio-badge-dot-bg: var(--studio-info)}.studio-badge__dot--neutral{--studio-badge-dot-bg: var(--studio-text-secondary)}:host(.studio-badge--clickable){cursor:pointer}:host(.studio-badge--clickable):hover{opacity:.9;transform:translateY(-1px)}:host(.studio-badge--clickable):active{transform:translateY(0)}:host(.studio-badge--disabled){opacity:.5;cursor:not-allowed;pointer-events:none}:host(.studio-badge--uppercase){text-transform:uppercase;letter-spacing:.5px}:host(.studio-badge--bold){--studio-badge-font-weight: 600}@keyframes badge-pulse{0%,to{opacity:1}50%{opacity:.5}}:host(.studio-badge--pulse) .studio-badge__dot{animation:badge-pulse 2s cubic-bezier(.4,0,.6,1) infinite}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
619
615
  }
620
616
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BadgeComponent, decorators: [{
621
617
  type: Component,
@@ -666,41 +662,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
666
662
  * Badge component
667
663
  */
668
664
 
665
+ /**
666
+ * Button component with multiple variants, sizes, colors and states
667
+ *
668
+ * @example
669
+ * <studio-button variant="solid" color="primary" (clicked)="onClick()">
670
+ * Click me
671
+ * </studio-button>
672
+ */
669
673
  class ButtonComponent {
670
674
  configService = inject(StudioConfigService);
671
675
  buttonDefaults = computed(() => this.configService.config().components?.button, ...(ngDevMode ? [{ debugName: "buttonDefaults" }] : []));
672
- // Appearance - inputs
673
676
  variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
674
677
  sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
675
678
  colorInput = input(undefined, ...(ngDevMode ? [{ debugName: "colorInput", alias: 'color' }] : [{ alias: 'color' }]));
676
679
  radiusInput = input(undefined, ...(ngDevMode ? [{ debugName: "radiusInput", alias: 'radius' }] : [{ alias: 'radius' }]));
677
680
  shadowInput = input(undefined, ...(ngDevMode ? [{ debugName: "shadowInput", alias: 'shadow' }] : [{ alias: 'shadow' }]));
678
681
  compactInput = input(undefined, ...(ngDevMode ? [{ debugName: "compactInput", alias: 'compact' }] : [{ alias: 'compact' }]));
679
- // Values with config defaults
680
682
  variant = withConfigDefault(this.variantInput, computed(() => this.buttonDefaults()?.variant), 'solid');
681
683
  size = withConfigDefault(this.sizeInput, computed(() => this.buttonDefaults()?.size), 'md');
682
684
  color = withConfigDefault(this.colorInput, computed(() => this.buttonDefaults()?.color), 'primary');
683
685
  radius = withConfigDefault(this.radiusInput, computed(() => this.buttonDefaults()?.radius), 'sm');
684
686
  shadow = withConfigDefault(this.shadowInput, computed(() => this.buttonDefaults()?.shadow), 'none');
685
687
  compact = withConfigDefault(this.compactInput, computed(() => this.buttonDefaults()?.compact), false);
686
- // State
687
688
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
688
689
  loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
689
690
  loadingText = input('Loading...', ...(ngDevMode ? [{ debugName: "loadingText" }] : []));
690
- // Layout
691
691
  fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
692
- // Button props
693
692
  type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : []));
694
- // Icon
695
693
  icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : []));
696
694
  iconPosition = input('left', ...(ngDevMode ? [{ debugName: "iconPosition" }] : []));
697
- // Link mode
698
695
  href = input(...(ngDevMode ? [undefined, { debugName: "href" }] : []));
699
696
  target = input('_self', ...(ngDevMode ? [{ debugName: "target" }] : []));
700
- // Badge
701
697
  badge = input(...(ngDevMode ? [undefined, { debugName: "badge" }] : []));
702
698
  badgeColor = input('error', ...(ngDevMode ? [{ debugName: "badgeColor" }] : []));
703
- // Accessibility
704
699
  ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : []));
705
700
  clicked = output();
706
701
  iconSize = computed(() => {
@@ -714,14 +709,11 @@ class ButtonComponent {
714
709
  event.stopPropagation();
715
710
  return;
716
711
  }
717
- // Handle link navigation
718
712
  const url = this.href();
719
713
  if (url) {
720
714
  const safeUrl = sanitizeUrl(url);
721
- if (safeUrl === '#') {
722
- // URL was blocked - don't navigate
715
+ if (safeUrl === '#')
723
716
  return;
724
- }
725
717
  const target = this.target();
726
718
  if (target === '_blank') {
727
719
  window.open(safeUrl, '_blank', 'noopener,noreferrer');
@@ -755,7 +747,6 @@ class ButtonComponent {
755
747
  <studio-icon [name]="icon()!" [size]="iconSize()" />
756
748
  }
757
749
  @if (loading() && iconPosition() === 'only') {
758
- <!-- Empty, spinner already shown -->
759
750
  } @else if (loading()) {
760
751
  <span>{{ loadingText() }}</span>
761
752
  }
@@ -765,7 +756,7 @@ class ButtonComponent {
765
756
  </span>
766
757
  }
767
758
  </span>
768
- `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;gap:var(--studio-spacing-sm);font-family:var(--studio-font-family);font-weight:var(--studio-font-weight-medium);border:none;cursor:pointer;-webkit-user-select:none;user-select:none;position:relative;white-space:nowrap;vertical-align:middle;transition:background-color var(--studio-transition-fast),color var(--studio-transition-fast),border-color var(--studio-transition-fast),box-shadow var(--studio-transition-fast),transform var(--studio-transition-fast)}:host:focus-visible{outline:2px solid var(--studio-primary);outline-offset:2px}:host(.studio-button--sm){padding:var(--studio-spacing-xs) var(--studio-spacing-sm);font-size:var(--studio-font-size-sm);height:2rem;min-width:2rem}:host(.studio-button--md){padding:var(--studio-spacing-sm) var(--studio-spacing-md);font-size:var(--studio-font-size-base);height:2.5rem;min-width:2.5rem}:host(.studio-button--lg){padding:var(--studio-spacing-md) var(--studio-spacing-lg);font-size:var(--studio-font-size-lg);height:3rem;min-width:3rem}:host(.studio-button--radius-none){border-radius:var(--studio-radius-none)}:host(.studio-button--radius-sm){border-radius:var(--studio-radius-sm)}:host(.studio-button--radius-md){border-radius:var(--studio-radius-md)}:host(.studio-button--radius-lg){border-radius:var(--studio-radius-lg)}:host(.studio-button--radius-xl){border-radius:var(--studio-radius-xl)}:host(.studio-button--radius-full){border-radius:var(--studio-radius-full)}:host(.studio-button--shadow-none){box-shadow:none}:host(.studio-button--shadow-sm){box-shadow:var(--studio-shadow-sm)}:host(.studio-button--shadow-md){box-shadow:var(--studio-shadow-md)}:host(.studio-button--shadow-lg){box-shadow:var(--studio-shadow-lg)}:host(.studio-button--compact.studio-button--sm){padding:var(--studio-spacing-xs) var(--studio-spacing-sm);height:1.75rem;min-width:1.75rem;font-size:.813rem}:host(.studio-button--compact.studio-button--md){padding:var(--studio-spacing-sm) var(--studio-spacing-md);height:2rem;min-width:2rem;font-size:.875rem}:host(.studio-button--compact.studio-button--lg){padding:var(--studio-spacing-sm) var(--studio-spacing-lg);height:2.5rem;min-width:2.5rem;font-size:1rem}:host(.studio-button--solid.studio-button--primary){background:var(--studio-primary);color:#fff}:host(.studio-button--solid.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-primary-hover)}:host(.studio-button--outline.studio-button--primary){background:transparent;border:1px solid var(--studio-primary);color:var(--studio-primary)}:host(.studio-button--outline.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-primary);color:#fff}:host(.studio-button--ghost.studio-button--primary){background:transparent;color:var(--studio-primary)}:host(.studio-button--ghost.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:#3b82f61a}:host(.studio-button--solid.studio-button--secondary){background:var(--studio-secondary);color:#fff}:host(.studio-button--solid.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-secondary-hover)}:host(.studio-button--outline.studio-button--secondary){background:transparent;border:1px solid var(--studio-secondary);color:var(--studio-secondary)}:host(.studio-button--outline.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-secondary);color:#fff}:host(.studio-button--ghost.studio-button--secondary){background:transparent;color:var(--studio-secondary)}:host(.studio-button--ghost.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:#8b5cf61a}:host(.studio-button--solid.studio-button--success){background:var(--studio-success);color:#fff}:host(.studio-button--solid.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success-hover)}:host(.studio-button--outline.studio-button--success){background:transparent;border:1px solid var(--studio-success);color:var(--studio-success)}:host(.studio-button--outline.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success);color:#fff}:host(.studio-button--ghost.studio-button--success){background:transparent;color:var(--studio-success)}:host(.studio-button--ghost.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success-bg)}:host(.studio-button--solid.studio-button--error){background:var(--studio-error);color:#fff}:host(.studio-button--solid.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error-hover)}:host(.studio-button--outline.studio-button--error){background:transparent;border:1px solid var(--studio-error);color:var(--studio-error)}:host(.studio-button--outline.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error);color:#fff}:host(.studio-button--ghost.studio-button--error){background:transparent;color:var(--studio-error)}:host(.studio-button--ghost.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error-bg)}:host(.studio-button--solid.studio-button--warning){background:var(--studio-warning);color:#fff}:host(.studio-button--solid.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning-hover)}:host(.studio-button--outline.studio-button--warning){background:transparent;border:1px solid var(--studio-warning);color:var(--studio-warning)}:host(.studio-button--outline.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning);color:#fff}:host(.studio-button--ghost.studio-button--warning){background:transparent;color:var(--studio-warning)}:host(.studio-button--ghost.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning-bg)}:host(.studio-button--full){width:100%}:host(.studio-button--icon-only){padding:0;aspect-ratio:1}:host(.studio-button--icon-only.studio-button--sm){width:2rem;padding:0}:host(.studio-button--icon-only.studio-button--md){width:2.5rem;padding:0}:host(.studio-button--icon-only.studio-button--lg){width:3rem;padding:0}:host(.studio-button--loading){cursor:wait;pointer-events:none}:host([disabled]){opacity:.6;cursor:not-allowed!important;background:var(--studio-bg-secondary)!important;color:var(--studio-text-tertiary)!important;border-color:var(--studio-border-primary)!important}:host([disabled]:hover){transform:none!important;background:var(--studio-bg-secondary)!important}:host(:active:not([disabled]):not(.studio-button--loading)){transform:scale(.98)}.studio-button__content{display:inline-flex;align-items:center;gap:var(--studio-spacing-sm)}.studio-button__spinner{animation:studio-spin 1s linear infinite}@keyframes studio-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-button__badge{position:absolute;top:-.375rem;right:-.375rem;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 .25rem;font-size:.625rem;font-weight:var(--studio-font-weight-semibold);line-height:1;color:#fff;border-radius:var(--studio-radius-full);box-shadow:0 0 0 2px var(--studio-bg-primary)}.studio-button__badge--primary{background:var(--studio-primary)}.studio-button__badge--error{background:var(--studio-error)}.studio-button__badge--warning{background:var(--studio-warning)}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
759
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;gap:var(--studio-spacing-sm);font-family:var(--studio-font-family);font-weight:var(--studio-font-weight-medium);border:none;cursor:pointer;-webkit-user-select:none;user-select:none;position:relative;white-space:nowrap;vertical-align:middle;transition:background-color var(--studio-transition-fast),color var(--studio-transition-fast),border-color var(--studio-transition-fast),box-shadow var(--studio-transition-fast),transform var(--studio-transition-fast)}:host:focus-visible{outline:2px solid var(--studio-primary);outline-offset:2px}:host(.studio-button--sm){padding:var(--studio-spacing-xs) var(--studio-spacing-sm);font-size:var(--studio-font-size-sm);height:2rem;min-width:2rem}:host(.studio-button--md){padding:var(--studio-spacing-sm) var(--studio-spacing-md);font-size:var(--studio-font-size-base);height:2.5rem;min-width:2.5rem}:host(.studio-button--lg){padding:var(--studio-spacing-md) var(--studio-spacing-lg);font-size:var(--studio-font-size-lg);height:3rem;min-width:3rem}:host(.studio-button--radius-none){border-radius:var(--studio-radius-none)}:host(.studio-button--radius-sm){border-radius:var(--studio-radius-sm)}:host(.studio-button--radius-md){border-radius:var(--studio-radius-md)}:host(.studio-button--radius-lg){border-radius:var(--studio-radius-lg)}:host(.studio-button--radius-xl){border-radius:var(--studio-radius-xl)}:host(.studio-button--radius-full){border-radius:var(--studio-radius-full)}:host(.studio-button--shadow-none){box-shadow:none}:host(.studio-button--shadow-sm){box-shadow:var(--studio-shadow-sm)}:host(.studio-button--shadow-md){box-shadow:var(--studio-shadow-md)}:host(.studio-button--shadow-lg){box-shadow:var(--studio-shadow-lg)}:host(.studio-button--compact.studio-button--sm){padding:var(--studio-spacing-xs) var(--studio-spacing-sm);height:1.75rem;min-width:1.75rem;font-size:.813rem}:host(.studio-button--compact.studio-button--md){padding:var(--studio-spacing-sm) var(--studio-spacing-md);height:2rem;min-width:2rem;font-size:.875rem}:host(.studio-button--compact.studio-button--lg){padding:var(--studio-spacing-sm) var(--studio-spacing-lg);height:2.5rem;min-width:2.5rem;font-size:1rem}:host(.studio-button--solid.studio-button--primary){background:var(--studio-primary);color:#fff}:host(.studio-button--solid.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-primary-hover)}:host(.studio-button--outline.studio-button--primary){background:transparent;border:1px solid var(--studio-primary);color:var(--studio-primary)}:host(.studio-button--outline.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-primary);color:#fff}:host(.studio-button--ghost.studio-button--primary){background:transparent;color:var(--studio-primary)}:host(.studio-button--ghost.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-primary-bg)}:host(.studio-button--solid.studio-button--secondary){background:var(--studio-secondary);color:#fff}:host(.studio-button--solid.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-secondary-hover)}:host(.studio-button--outline.studio-button--secondary){background:transparent;border:1px solid var(--studio-secondary);color:var(--studio-secondary)}:host(.studio-button--outline.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-secondary);color:#fff}:host(.studio-button--ghost.studio-button--secondary){background:transparent;color:var(--studio-secondary)}:host(.studio-button--ghost.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-secondary-bg)}:host(.studio-button--solid.studio-button--success){background:var(--studio-success);color:#fff}:host(.studio-button--solid.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success-hover)}:host(.studio-button--outline.studio-button--success){background:transparent;border:1px solid var(--studio-success);color:var(--studio-success)}:host(.studio-button--outline.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success);color:#fff}:host(.studio-button--ghost.studio-button--success){background:transparent;color:var(--studio-success)}:host(.studio-button--ghost.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success-bg)}:host(.studio-button--solid.studio-button--error){background:var(--studio-error);color:#fff}:host(.studio-button--solid.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error-hover)}:host(.studio-button--outline.studio-button--error){background:transparent;border:1px solid var(--studio-error);color:var(--studio-error)}:host(.studio-button--outline.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error);color:#fff}:host(.studio-button--ghost.studio-button--error){background:transparent;color:var(--studio-error)}:host(.studio-button--ghost.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error-bg)}:host(.studio-button--solid.studio-button--warning){background:var(--studio-warning);color:#fff}:host(.studio-button--solid.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning-hover)}:host(.studio-button--outline.studio-button--warning){background:transparent;border:1px solid var(--studio-warning);color:var(--studio-warning)}:host(.studio-button--outline.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning);color:#fff}:host(.studio-button--ghost.studio-button--warning){background:transparent;color:var(--studio-warning)}:host(.studio-button--ghost.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning-bg)}:host(.studio-button--full){width:100%}:host(.studio-button--icon-only){padding:0;aspect-ratio:1}:host(.studio-button--icon-only.studio-button--sm){width:2rem;padding:0}:host(.studio-button--icon-only.studio-button--md){width:2.5rem;padding:0}:host(.studio-button--icon-only.studio-button--lg){width:3rem;padding:0}:host(.studio-button--loading){cursor:wait;pointer-events:none}:host([disabled]){opacity:.6;cursor:not-allowed!important;background:var(--studio-bg-secondary)!important;color:var(--studio-text-tertiary)!important;border-color:var(--studio-border-primary)!important}:host([disabled]:hover){transform:none!important;background:var(--studio-bg-secondary)!important}:host(:active:not([disabled]):not(.studio-button--loading)){transform:scale(.98)}.studio-button__content{display:inline-flex;align-items:center;gap:var(--studio-spacing-sm)}.studio-button__spinner{animation:studio-spin 1s linear infinite}@keyframes studio-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-button__badge{position:absolute;top:-.375rem;right:-.375rem;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 .25rem;font-size:.625rem;font-weight:var(--studio-font-weight-semibold);line-height:1;color:#fff;border-radius:var(--studio-radius-full);box-shadow:0 0 0 2px var(--studio-bg-primary)}.studio-button__badge--primary{background:var(--studio-primary)}.studio-button__badge--error{background:var(--studio-error)}.studio-button__badge--warning{background:var(--studio-warning)}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
769
760
  }
770
761
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ButtonComponent, decorators: [{
771
762
  type: Component,
@@ -800,7 +791,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
800
791
  <studio-icon [name]="icon()!" [size]="iconSize()" />
801
792
  }
802
793
  @if (loading() && iconPosition() === 'only') {
803
- <!-- Empty, spinner already shown -->
804
794
  } @else if (loading()) {
805
795
  <span>{{ loadingText() }}</span>
806
796
  }
@@ -810,18 +800,213 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
810
800
  </span>
811
801
  }
812
802
  </span>
813
- `, styles: [":host{display:inline-flex;align-items:center;justify-content:center;gap:var(--studio-spacing-sm);font-family:var(--studio-font-family);font-weight:var(--studio-font-weight-medium);border:none;cursor:pointer;-webkit-user-select:none;user-select:none;position:relative;white-space:nowrap;vertical-align:middle;transition:background-color var(--studio-transition-fast),color var(--studio-transition-fast),border-color var(--studio-transition-fast),box-shadow var(--studio-transition-fast),transform var(--studio-transition-fast)}:host:focus-visible{outline:2px solid var(--studio-primary);outline-offset:2px}:host(.studio-button--sm){padding:var(--studio-spacing-xs) var(--studio-spacing-sm);font-size:var(--studio-font-size-sm);height:2rem;min-width:2rem}:host(.studio-button--md){padding:var(--studio-spacing-sm) var(--studio-spacing-md);font-size:var(--studio-font-size-base);height:2.5rem;min-width:2.5rem}:host(.studio-button--lg){padding:var(--studio-spacing-md) var(--studio-spacing-lg);font-size:var(--studio-font-size-lg);height:3rem;min-width:3rem}:host(.studio-button--radius-none){border-radius:var(--studio-radius-none)}:host(.studio-button--radius-sm){border-radius:var(--studio-radius-sm)}:host(.studio-button--radius-md){border-radius:var(--studio-radius-md)}:host(.studio-button--radius-lg){border-radius:var(--studio-radius-lg)}:host(.studio-button--radius-xl){border-radius:var(--studio-radius-xl)}:host(.studio-button--radius-full){border-radius:var(--studio-radius-full)}:host(.studio-button--shadow-none){box-shadow:none}:host(.studio-button--shadow-sm){box-shadow:var(--studio-shadow-sm)}:host(.studio-button--shadow-md){box-shadow:var(--studio-shadow-md)}:host(.studio-button--shadow-lg){box-shadow:var(--studio-shadow-lg)}:host(.studio-button--compact.studio-button--sm){padding:var(--studio-spacing-xs) var(--studio-spacing-sm);height:1.75rem;min-width:1.75rem;font-size:.813rem}:host(.studio-button--compact.studio-button--md){padding:var(--studio-spacing-sm) var(--studio-spacing-md);height:2rem;min-width:2rem;font-size:.875rem}:host(.studio-button--compact.studio-button--lg){padding:var(--studio-spacing-sm) var(--studio-spacing-lg);height:2.5rem;min-width:2.5rem;font-size:1rem}:host(.studio-button--solid.studio-button--primary){background:var(--studio-primary);color:#fff}:host(.studio-button--solid.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-primary-hover)}:host(.studio-button--outline.studio-button--primary){background:transparent;border:1px solid var(--studio-primary);color:var(--studio-primary)}:host(.studio-button--outline.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-primary);color:#fff}:host(.studio-button--ghost.studio-button--primary){background:transparent;color:var(--studio-primary)}:host(.studio-button--ghost.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:#3b82f61a}:host(.studio-button--solid.studio-button--secondary){background:var(--studio-secondary);color:#fff}:host(.studio-button--solid.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-secondary-hover)}:host(.studio-button--outline.studio-button--secondary){background:transparent;border:1px solid var(--studio-secondary);color:var(--studio-secondary)}:host(.studio-button--outline.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-secondary);color:#fff}:host(.studio-button--ghost.studio-button--secondary){background:transparent;color:var(--studio-secondary)}:host(.studio-button--ghost.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:#8b5cf61a}:host(.studio-button--solid.studio-button--success){background:var(--studio-success);color:#fff}:host(.studio-button--solid.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success-hover)}:host(.studio-button--outline.studio-button--success){background:transparent;border:1px solid var(--studio-success);color:var(--studio-success)}:host(.studio-button--outline.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success);color:#fff}:host(.studio-button--ghost.studio-button--success){background:transparent;color:var(--studio-success)}:host(.studio-button--ghost.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success-bg)}:host(.studio-button--solid.studio-button--error){background:var(--studio-error);color:#fff}:host(.studio-button--solid.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error-hover)}:host(.studio-button--outline.studio-button--error){background:transparent;border:1px solid var(--studio-error);color:var(--studio-error)}:host(.studio-button--outline.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error);color:#fff}:host(.studio-button--ghost.studio-button--error){background:transparent;color:var(--studio-error)}:host(.studio-button--ghost.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error-bg)}:host(.studio-button--solid.studio-button--warning){background:var(--studio-warning);color:#fff}:host(.studio-button--solid.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning-hover)}:host(.studio-button--outline.studio-button--warning){background:transparent;border:1px solid var(--studio-warning);color:var(--studio-warning)}:host(.studio-button--outline.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning);color:#fff}:host(.studio-button--ghost.studio-button--warning){background:transparent;color:var(--studio-warning)}:host(.studio-button--ghost.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning-bg)}:host(.studio-button--full){width:100%}:host(.studio-button--icon-only){padding:0;aspect-ratio:1}:host(.studio-button--icon-only.studio-button--sm){width:2rem;padding:0}:host(.studio-button--icon-only.studio-button--md){width:2.5rem;padding:0}:host(.studio-button--icon-only.studio-button--lg){width:3rem;padding:0}:host(.studio-button--loading){cursor:wait;pointer-events:none}:host([disabled]){opacity:.6;cursor:not-allowed!important;background:var(--studio-bg-secondary)!important;color:var(--studio-text-tertiary)!important;border-color:var(--studio-border-primary)!important}:host([disabled]:hover){transform:none!important;background:var(--studio-bg-secondary)!important}:host(:active:not([disabled]):not(.studio-button--loading)){transform:scale(.98)}.studio-button__content{display:inline-flex;align-items:center;gap:var(--studio-spacing-sm)}.studio-button__spinner{animation:studio-spin 1s linear infinite}@keyframes studio-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-button__badge{position:absolute;top:-.375rem;right:-.375rem;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 .25rem;font-size:.625rem;font-weight:var(--studio-font-weight-semibold);line-height:1;color:#fff;border-radius:var(--studio-radius-full);box-shadow:0 0 0 2px var(--studio-bg-primary)}.studio-button__badge--primary{background:var(--studio-primary)}.studio-button__badge--error{background:var(--studio-error)}.studio-button__badge--warning{background:var(--studio-warning)}\n"] }]
803
+ `, styles: [":host{display:inline-flex;align-items:center;justify-content:center;gap:var(--studio-spacing-sm);font-family:var(--studio-font-family);font-weight:var(--studio-font-weight-medium);border:none;cursor:pointer;-webkit-user-select:none;user-select:none;position:relative;white-space:nowrap;vertical-align:middle;transition:background-color var(--studio-transition-fast),color var(--studio-transition-fast),border-color var(--studio-transition-fast),box-shadow var(--studio-transition-fast),transform var(--studio-transition-fast)}:host:focus-visible{outline:2px solid var(--studio-primary);outline-offset:2px}:host(.studio-button--sm){padding:var(--studio-spacing-xs) var(--studio-spacing-sm);font-size:var(--studio-font-size-sm);height:2rem;min-width:2rem}:host(.studio-button--md){padding:var(--studio-spacing-sm) var(--studio-spacing-md);font-size:var(--studio-font-size-base);height:2.5rem;min-width:2.5rem}:host(.studio-button--lg){padding:var(--studio-spacing-md) var(--studio-spacing-lg);font-size:var(--studio-font-size-lg);height:3rem;min-width:3rem}:host(.studio-button--radius-none){border-radius:var(--studio-radius-none)}:host(.studio-button--radius-sm){border-radius:var(--studio-radius-sm)}:host(.studio-button--radius-md){border-radius:var(--studio-radius-md)}:host(.studio-button--radius-lg){border-radius:var(--studio-radius-lg)}:host(.studio-button--radius-xl){border-radius:var(--studio-radius-xl)}:host(.studio-button--radius-full){border-radius:var(--studio-radius-full)}:host(.studio-button--shadow-none){box-shadow:none}:host(.studio-button--shadow-sm){box-shadow:var(--studio-shadow-sm)}:host(.studio-button--shadow-md){box-shadow:var(--studio-shadow-md)}:host(.studio-button--shadow-lg){box-shadow:var(--studio-shadow-lg)}:host(.studio-button--compact.studio-button--sm){padding:var(--studio-spacing-xs) var(--studio-spacing-sm);height:1.75rem;min-width:1.75rem;font-size:.813rem}:host(.studio-button--compact.studio-button--md){padding:var(--studio-spacing-sm) var(--studio-spacing-md);height:2rem;min-width:2rem;font-size:.875rem}:host(.studio-button--compact.studio-button--lg){padding:var(--studio-spacing-sm) var(--studio-spacing-lg);height:2.5rem;min-width:2.5rem;font-size:1rem}:host(.studio-button--solid.studio-button--primary){background:var(--studio-primary);color:#fff}:host(.studio-button--solid.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-primary-hover)}:host(.studio-button--outline.studio-button--primary){background:transparent;border:1px solid var(--studio-primary);color:var(--studio-primary)}:host(.studio-button--outline.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-primary);color:#fff}:host(.studio-button--ghost.studio-button--primary){background:transparent;color:var(--studio-primary)}:host(.studio-button--ghost.studio-button--primary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-primary-bg)}:host(.studio-button--solid.studio-button--secondary){background:var(--studio-secondary);color:#fff}:host(.studio-button--solid.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-secondary-hover)}:host(.studio-button--outline.studio-button--secondary){background:transparent;border:1px solid var(--studio-secondary);color:var(--studio-secondary)}:host(.studio-button--outline.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-secondary);color:#fff}:host(.studio-button--ghost.studio-button--secondary){background:transparent;color:var(--studio-secondary)}:host(.studio-button--ghost.studio-button--secondary:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-secondary-bg)}:host(.studio-button--solid.studio-button--success){background:var(--studio-success);color:#fff}:host(.studio-button--solid.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success-hover)}:host(.studio-button--outline.studio-button--success){background:transparent;border:1px solid var(--studio-success);color:var(--studio-success)}:host(.studio-button--outline.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success);color:#fff}:host(.studio-button--ghost.studio-button--success){background:transparent;color:var(--studio-success)}:host(.studio-button--ghost.studio-button--success:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-success-bg)}:host(.studio-button--solid.studio-button--error){background:var(--studio-error);color:#fff}:host(.studio-button--solid.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error-hover)}:host(.studio-button--outline.studio-button--error){background:transparent;border:1px solid var(--studio-error);color:var(--studio-error)}:host(.studio-button--outline.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error);color:#fff}:host(.studio-button--ghost.studio-button--error){background:transparent;color:var(--studio-error)}:host(.studio-button--ghost.studio-button--error:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-error-bg)}:host(.studio-button--solid.studio-button--warning){background:var(--studio-warning);color:#fff}:host(.studio-button--solid.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning-hover)}:host(.studio-button--outline.studio-button--warning){background:transparent;border:1px solid var(--studio-warning);color:var(--studio-warning)}:host(.studio-button--outline.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning);color:#fff}:host(.studio-button--ghost.studio-button--warning){background:transparent;color:var(--studio-warning)}:host(.studio-button--ghost.studio-button--warning:hover:not(:disabled):not(.studio-button--loading)){background:var(--studio-warning-bg)}:host(.studio-button--full){width:100%}:host(.studio-button--icon-only){padding:0;aspect-ratio:1}:host(.studio-button--icon-only.studio-button--sm){width:2rem;padding:0}:host(.studio-button--icon-only.studio-button--md){width:2.5rem;padding:0}:host(.studio-button--icon-only.studio-button--lg){width:3rem;padding:0}:host(.studio-button--loading){cursor:wait;pointer-events:none}:host([disabled]){opacity:.6;cursor:not-allowed!important;background:var(--studio-bg-secondary)!important;color:var(--studio-text-tertiary)!important;border-color:var(--studio-border-primary)!important}:host([disabled]:hover){transform:none!important;background:var(--studio-bg-secondary)!important}:host(:active:not([disabled]):not(.studio-button--loading)){transform:scale(.98)}.studio-button__content{display:inline-flex;align-items:center;gap:var(--studio-spacing-sm)}.studio-button__spinner{animation:studio-spin 1s linear infinite}@keyframes studio-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-button__badge{position:absolute;top:-.375rem;right:-.375rem;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 .25rem;font-size:.625rem;font-weight:var(--studio-font-weight-semibold);line-height:1;color:#fff;border-radius:var(--studio-radius-full);box-shadow:0 0 0 2px var(--studio-bg-primary)}.studio-button__badge--primary{background:var(--studio-primary)}.studio-button__badge--error{background:var(--studio-error)}.studio-button__badge--warning{background:var(--studio-warning)}\n"] }]
814
804
  }], propDecorators: { variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], colorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], shadowInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], compactInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingText", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], badgeColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeColor", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
815
805
 
816
806
  /**
817
807
  * Button component
818
808
  */
819
809
 
810
+ /**
811
+ * Toggle switch component with customizable size and color
812
+ *
813
+ * @example
814
+ * <studio-switch [(checked)]="isEnabled" label="Enable feature" />
815
+ */
816
+ class SwitchComponent {
817
+ configService = inject(StudioConfigService);
818
+ switchDefaults = computed(() => this.configService.config().components?.switch, ...(ngDevMode ? [{ debugName: "switchDefaults" }] : []));
819
+ checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
820
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
821
+ label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
822
+ labelPosition = input('right', ...(ngDevMode ? [{ debugName: "labelPosition" }] : []));
823
+ showIcons = input(false, ...(ngDevMode ? [{ debugName: "showIcons" }] : []));
824
+ ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : []));
825
+ sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
826
+ colorInput = input(undefined, ...(ngDevMode ? [{ debugName: "colorInput", alias: 'color' }] : [{ alias: 'color' }]));
827
+ size = withConfigDefault(this.sizeInput, computed(() => this.switchDefaults()?.size), 'md');
828
+ color = withConfigDefault(this.colorInput, computed(() => this.switchDefaults()?.color), 'primary');
829
+ checkedChange = output();
830
+ iconSize = computed(() => {
831
+ const sizeMap = { sm: 10, md: 12, lg: 14 };
832
+ return sizeMap[this.size()];
833
+ }, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
834
+ hostClasses = computed(() => classNames('studio-switch', `studio-switch--${this.size()}`, `studio-switch--${this.color()}`, this.checked() && 'studio-switch--checked', this.disabled() && 'studio-switch--disabled'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
835
+ handleClick() {
836
+ if (this.disabled())
837
+ return;
838
+ this.toggle();
839
+ }
840
+ handleKeydown(event) {
841
+ if (this.disabled())
842
+ return;
843
+ event.preventDefault();
844
+ this.toggle();
845
+ }
846
+ toggle() {
847
+ const newValue = !this.checked();
848
+ this.checked.set(newValue);
849
+ this.checkedChange.emit(newValue);
850
+ }
851
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
852
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: SwitchComponent, isStandalone: true, selector: "studio-switch", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, colorInput: { classPropertyName: "colorInput", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", checkedChange: "checkedChange" }, host: { listeners: { "click": "handleClick()", "keydown.space": "handleKeydown($event)", "keydown.enter": "handleKeydown($event)" }, properties: { "class": "hostClasses()", "attr.role": "\"switch\"", "attr.aria-checked": "checked()", "attr.aria-disabled": "disabled() ? \"true\" : null", "attr.aria-label": "ariaLabel() || label()", "tabindex": "disabled() ? -1 : 0" } }, ngImport: i0, template: `
853
+ <span class="studio-switch__container">
854
+ @if (label() && labelPosition() === 'left') {
855
+ <span class="studio-switch__label studio-switch__label--left">
856
+ {{ label() }}
857
+ </span>
858
+ }
859
+
860
+ <span class="studio-switch__track">
861
+ <span class="studio-switch__thumb">
862
+ @if (showIcons()) {
863
+ @if (checked()) {
864
+ <studio-icon name="check" [size]="iconSize()" color="inherit" />
865
+ } @else {
866
+ <studio-icon name="x" [size]="iconSize()" color="inherit" />
867
+ }
868
+ }
869
+ </span>
870
+ </span>
871
+
872
+ @if (label() && labelPosition() === 'right') {
873
+ <span class="studio-switch__label studio-switch__label--right">
874
+ {{ label() }}
875
+ </span>
876
+ }
877
+ </span>
878
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;outline:none;transition:opacity var(--studio-transition-fast)}:host(:focus-visible) .studio-switch__track{outline:2px solid var(--studio-primary);outline-offset:2px}:host(.studio-switch--disabled){cursor:not-allowed;opacity:.5}.studio-switch__container{display:inline-flex;align-items:center;gap:var(--studio-spacing-sm)}.studio-switch__label{font-size:var(--studio-font-size-sm);color:var(--studio-text-primary);font-weight:var(--studio-font-weight-medium)}.studio-switch__track{position:relative;display:inline-flex;align-items:center;border-radius:var(--studio-radius-full);background:var(--studio-bg-tertiary);transition:background-color var(--studio-transition-base);flex-shrink:0}.studio-switch__thumb{position:absolute;display:inline-flex;align-items:center;justify-content:center;background:#fff;border-radius:var(--studio-radius-full);box-shadow:var(--studio-shadow-sm);transition:transform var(--studio-transition-base),background-color var(--studio-transition-base);color:var(--studio-text-tertiary)}:host(.studio-switch--sm) .studio-switch__track{width:2rem;height:1.25rem;padding:.125rem}:host(.studio-switch--sm) .studio-switch__thumb{width:1rem;height:1rem;left:.125rem}:host(.studio-switch--md) .studio-switch__track{width:2.5rem;height:1.5rem;padding:.125rem}:host(.studio-switch--md) .studio-switch__thumb{width:1.25rem;height:1.25rem;left:.125rem}:host(.studio-switch--lg) .studio-switch__track{width:3rem;height:1.75rem;padding:.125rem}:host(.studio-switch--lg) .studio-switch__thumb{width:1.5rem;height:1.5rem;left:.125rem}:host(.studio-switch--checked.studio-switch--primary) .studio-switch__track{background:var(--studio-primary)}:host(.studio-switch--checked.studio-switch--primary) .studio-switch__thumb{color:var(--studio-primary)}:host(.studio-switch--checked.studio-switch--sm.studio-switch--primary) .studio-switch__thumb{transform:translate(.75rem)}:host(.studio-switch--checked.studio-switch--md.studio-switch--primary) .studio-switch__thumb{transform:translate(1rem)}:host(.studio-switch--checked.studio-switch--lg.studio-switch--primary) .studio-switch__thumb{transform:translate(1.25rem)}:host(.studio-switch--checked.studio-switch--secondary) .studio-switch__track{background:var(--studio-secondary)}:host(.studio-switch--checked.studio-switch--secondary) .studio-switch__thumb{color:var(--studio-secondary)}:host(.studio-switch--checked.studio-switch--sm.studio-switch--secondary) .studio-switch__thumb{transform:translate(.75rem)}:host(.studio-switch--checked.studio-switch--md.studio-switch--secondary) .studio-switch__thumb{transform:translate(1rem)}:host(.studio-switch--checked.studio-switch--lg.studio-switch--secondary) .studio-switch__thumb{transform:translate(1.25rem)}:host(.studio-switch--checked.studio-switch--success) .studio-switch__track{background:var(--studio-success)}:host(.studio-switch--checked.studio-switch--success) .studio-switch__thumb{color:var(--studio-success)}:host(.studio-switch--checked.studio-switch--sm.studio-switch--success) .studio-switch__thumb{transform:translate(.75rem)}:host(.studio-switch--checked.studio-switch--md.studio-switch--success) .studio-switch__thumb{transform:translate(1rem)}:host(.studio-switch--checked.studio-switch--lg.studio-switch--success) .studio-switch__thumb{transform:translate(1.25rem)}:host(:not(.studio-switch--disabled):hover) .studio-switch__track{opacity:.9}:host(.studio-switch--disabled) .studio-switch__track{background:var(--studio-bg-secondary)!important}:host(.studio-switch--disabled) .studio-switch__thumb{box-shadow:none}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
879
+ }
880
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SwitchComponent, decorators: [{
881
+ type: Component,
882
+ args: [{ selector: 'studio-switch', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
883
+ '[class]': 'hostClasses()',
884
+ '[attr.role]': '"switch"',
885
+ '[attr.aria-checked]': 'checked()',
886
+ '[attr.aria-disabled]': 'disabled() ? "true" : null',
887
+ '[attr.aria-label]': 'ariaLabel() || label()',
888
+ '(click)': 'handleClick()',
889
+ '(keydown.space)': 'handleKeydown($event)',
890
+ '(keydown.enter)': 'handleKeydown($event)',
891
+ '[tabindex]': 'disabled() ? -1 : 0'
892
+ }, template: `
893
+ <span class="studio-switch__container">
894
+ @if (label() && labelPosition() === 'left') {
895
+ <span class="studio-switch__label studio-switch__label--left">
896
+ {{ label() }}
897
+ </span>
898
+ }
899
+
900
+ <span class="studio-switch__track">
901
+ <span class="studio-switch__thumb">
902
+ @if (showIcons()) {
903
+ @if (checked()) {
904
+ <studio-icon name="check" [size]="iconSize()" color="inherit" />
905
+ } @else {
906
+ <studio-icon name="x" [size]="iconSize()" color="inherit" />
907
+ }
908
+ }
909
+ </span>
910
+ </span>
911
+
912
+ @if (label() && labelPosition() === 'right') {
913
+ <span class="studio-switch__label studio-switch__label--right">
914
+ {{ label() }}
915
+ </span>
916
+ }
917
+ </span>
918
+ `, styles: [":host{display:inline-flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;outline:none;transition:opacity var(--studio-transition-fast)}:host(:focus-visible) .studio-switch__track{outline:2px solid var(--studio-primary);outline-offset:2px}:host(.studio-switch--disabled){cursor:not-allowed;opacity:.5}.studio-switch__container{display:inline-flex;align-items:center;gap:var(--studio-spacing-sm)}.studio-switch__label{font-size:var(--studio-font-size-sm);color:var(--studio-text-primary);font-weight:var(--studio-font-weight-medium)}.studio-switch__track{position:relative;display:inline-flex;align-items:center;border-radius:var(--studio-radius-full);background:var(--studio-bg-tertiary);transition:background-color var(--studio-transition-base);flex-shrink:0}.studio-switch__thumb{position:absolute;display:inline-flex;align-items:center;justify-content:center;background:#fff;border-radius:var(--studio-radius-full);box-shadow:var(--studio-shadow-sm);transition:transform var(--studio-transition-base),background-color var(--studio-transition-base);color:var(--studio-text-tertiary)}:host(.studio-switch--sm) .studio-switch__track{width:2rem;height:1.25rem;padding:.125rem}:host(.studio-switch--sm) .studio-switch__thumb{width:1rem;height:1rem;left:.125rem}:host(.studio-switch--md) .studio-switch__track{width:2.5rem;height:1.5rem;padding:.125rem}:host(.studio-switch--md) .studio-switch__thumb{width:1.25rem;height:1.25rem;left:.125rem}:host(.studio-switch--lg) .studio-switch__track{width:3rem;height:1.75rem;padding:.125rem}:host(.studio-switch--lg) .studio-switch__thumb{width:1.5rem;height:1.5rem;left:.125rem}:host(.studio-switch--checked.studio-switch--primary) .studio-switch__track{background:var(--studio-primary)}:host(.studio-switch--checked.studio-switch--primary) .studio-switch__thumb{color:var(--studio-primary)}:host(.studio-switch--checked.studio-switch--sm.studio-switch--primary) .studio-switch__thumb{transform:translate(.75rem)}:host(.studio-switch--checked.studio-switch--md.studio-switch--primary) .studio-switch__thumb{transform:translate(1rem)}:host(.studio-switch--checked.studio-switch--lg.studio-switch--primary) .studio-switch__thumb{transform:translate(1.25rem)}:host(.studio-switch--checked.studio-switch--secondary) .studio-switch__track{background:var(--studio-secondary)}:host(.studio-switch--checked.studio-switch--secondary) .studio-switch__thumb{color:var(--studio-secondary)}:host(.studio-switch--checked.studio-switch--sm.studio-switch--secondary) .studio-switch__thumb{transform:translate(.75rem)}:host(.studio-switch--checked.studio-switch--md.studio-switch--secondary) .studio-switch__thumb{transform:translate(1rem)}:host(.studio-switch--checked.studio-switch--lg.studio-switch--secondary) .studio-switch__thumb{transform:translate(1.25rem)}:host(.studio-switch--checked.studio-switch--success) .studio-switch__track{background:var(--studio-success)}:host(.studio-switch--checked.studio-switch--success) .studio-switch__thumb{color:var(--studio-success)}:host(.studio-switch--checked.studio-switch--sm.studio-switch--success) .studio-switch__thumb{transform:translate(.75rem)}:host(.studio-switch--checked.studio-switch--md.studio-switch--success) .studio-switch__thumb{transform:translate(1rem)}:host(.studio-switch--checked.studio-switch--lg.studio-switch--success) .studio-switch__thumb{transform:translate(1.25rem)}:host(:not(.studio-switch--disabled):hover) .studio-switch__track{opacity:.9}:host(.studio-switch--disabled) .studio-switch__track{background:var(--studio-bg-secondary)!important}:host(.studio-switch--disabled) .studio-switch__thumb{box-shadow:none}\n"] }]
919
+ }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], colorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], checkedChange: [{ type: i0.Output, args: ["checkedChange"] }] } });
920
+
921
+ /**
922
+ * Switch component
923
+ */
924
+
820
925
  /**
821
926
  * Primitives (Atoms)
822
927
  * Basic building blocks
823
928
  */
824
929
 
930
+ /**
931
+ * Theme toggle switch with sun/moon icons
932
+ *
933
+ * @example
934
+ * <studio-theme-switch />
935
+ * <studio-theme-switch [showLabel]="true" />
936
+ */
937
+ class ThemeSwitchComponent {
938
+ configService = inject(StudioConfigService);
939
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
940
+ showLabel = input(false, ...(ngDevMode ? [{ debugName: "showLabel" }] : []));
941
+ iconOnly = input(true, ...(ngDevMode ? [{ debugName: "iconOnly" }] : []));
942
+ isDark = computed(() => this.configService.themeMode() === 'dark', ...(ngDevMode ? [{ debugName: "isDark" }] : []));
943
+ iconSize = computed(() => {
944
+ const sizeMap = { sm: 16, md: 20, lg: 24 };
945
+ return sizeMap[this.size()];
946
+ }, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
947
+ toggleTheme() {
948
+ this.configService.toggleTheme();
949
+ }
950
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ThemeSwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
951
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: ThemeSwitchComponent, isStandalone: true, selector: "studio-theme-switch", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
952
+ <div class="studio-theme-switch">
953
+ @if (iconOnly()) {
954
+ <button
955
+ type="button"
956
+ class="studio-theme-switch__button studio-theme-switch__button--{{ size() }}"
957
+ [attr.aria-label]="isDark() ? 'Switch to light mode' : 'Switch to dark mode'"
958
+ (click)="toggleTheme()">
959
+ @if (isDark()) {
960
+ <studio-icon name="moon" [size]="iconSize()" color="inherit" />
961
+ } @else {
962
+ <studio-icon name="sun" [size]="iconSize()" color="inherit" />
963
+ }
964
+ </button>
965
+ } @else {
966
+ <studio-switch
967
+ [checked]="isDark()"
968
+ (checkedChange)="toggleTheme()"
969
+ [size]="size()"
970
+ [label]="showLabel() ? (isDark() ? 'Dark' : 'Light') : undefined"
971
+ labelPosition="left">
972
+ </studio-switch>
973
+ }
974
+ </div>
975
+ `, isInline: true, styles: [".studio-theme-switch{display:inline-flex;align-items:center}.studio-theme-switch__button{display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--studio-text-secondary);cursor:pointer;border-radius:var(--studio-radius-md);transition:background-color var(--studio-transition-fast),color var(--studio-transition-fast);padding:var(--studio-spacing-xs)}.studio-theme-switch__button:hover{background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-theme-switch__button:focus-visible{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-theme-switch__button--sm{width:2rem;height:2rem}.studio-theme-switch__button--md{width:2.5rem;height:2.5rem}.studio-theme-switch__button--lg{width:3rem;height:3rem}\n"], dependencies: [{ kind: "component", type: SwitchComponent, selector: "studio-switch", inputs: ["checked", "disabled", "label", "labelPosition", "showIcons", "ariaLabel", "size", "color"], outputs: ["checkedChange"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
976
+ }
977
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ThemeSwitchComponent, decorators: [{
978
+ type: Component,
979
+ args: [{ selector: 'studio-theme-switch', standalone: true, imports: [SwitchComponent, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
980
+ <div class="studio-theme-switch">
981
+ @if (iconOnly()) {
982
+ <button
983
+ type="button"
984
+ class="studio-theme-switch__button studio-theme-switch__button--{{ size() }}"
985
+ [attr.aria-label]="isDark() ? 'Switch to light mode' : 'Switch to dark mode'"
986
+ (click)="toggleTheme()">
987
+ @if (isDark()) {
988
+ <studio-icon name="moon" [size]="iconSize()" color="inherit" />
989
+ } @else {
990
+ <studio-icon name="sun" [size]="iconSize()" color="inherit" />
991
+ }
992
+ </button>
993
+ } @else {
994
+ <studio-switch
995
+ [checked]="isDark()"
996
+ (checkedChange)="toggleTheme()"
997
+ [size]="size()"
998
+ [label]="showLabel() ? (isDark() ? 'Dark' : 'Light') : undefined"
999
+ labelPosition="left">
1000
+ </studio-switch>
1001
+ }
1002
+ </div>
1003
+ `, styles: [".studio-theme-switch{display:inline-flex;align-items:center}.studio-theme-switch__button{display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--studio-text-secondary);cursor:pointer;border-radius:var(--studio-radius-md);transition:background-color var(--studio-transition-fast),color var(--studio-transition-fast);padding:var(--studio-spacing-xs)}.studio-theme-switch__button:hover{background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-theme-switch__button:focus-visible{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-theme-switch__button--sm{width:2rem;height:2rem}.studio-theme-switch__button--md{width:2.5rem;height:2.5rem}.studio-theme-switch__button--lg{width:3rem;height:3rem}\n"] }]
1004
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }] } });
1005
+
1006
+ /**
1007
+ * Theme switch component
1008
+ */
1009
+
825
1010
  /**
826
1011
  * Composites (Molecules + Organisms)
827
1012
  * Complex components built from primitives
@@ -843,5 +1028,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
843
1028
  * Generated bundle index. Do not edit.
844
1029
  */
845
1030
 
846
- export { BadgeComponent, ButtonComponent, IconComponent, STUDIO_CONFIG, StudioConfigService, classNames, isSafeUrl, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
1031
+ export { BadgeComponent, ButtonComponent, IconComponent, STUDIO_CONFIG, StudioConfigService, SwitchComponent, ThemeSwitchComponent, classNames, isSafeUrl, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
847
1032
  //# sourceMappingURL=eduboxpro-studio.mjs.map