@eduboxpro/studio 0.1.9 → 0.1.11

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,10 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, ElementRef, forwardRef, viewChild, model, Renderer2, DestroyRef, HostListener, Directive } from '@angular/core';
3
- import * as i1$1 from '@angular/common';
4
- import { DOCUMENT, CommonModule } from '@angular/common';
5
- import * as i1 from 'lucide-angular';
6
- import { icons, LucideAngularModule, LucideIconProvider, LUCIDE_ICONS, Circle, Apple, Globe, Laptop, MessageSquare, List, Grid3x3, Strikethrough, Underline, Italic, Bold, AlignJustify, AlignRight, AlignCenter, AlignLeft, 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';
2
+ import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, ElementRef, forwardRef, DOCUMENT as DOCUMENT$1, DestroyRef, contentChild, viewChild, model, HostListener, PLATFORM_ID, Renderer2, Directive } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { DOCUMENT, CommonModule, NgTemplateOutlet, isPlatformBrowser } from '@angular/common';
5
+ import * as LucideIcons from 'lucide-angular';
6
+ import { icons, LucideAngularModule, LucideIconProvider, LUCIDE_ICONS } from 'lucide-angular';
7
7
  import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
8
+ import { Router, RouterLink, RouterLinkActive } from '@angular/router';
9
+ import { trigger, state, transition, style, animate } from '@angular/animations';
8
10
 
9
11
  /**
10
12
  * Injection token for Studio configuration
@@ -327,7 +329,7 @@ class IconComponent {
327
329
  [absoluteStrokeWidth]="absoluteStrokeWidth()"
328
330
  />
329
331
  }
330
- `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
332
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: LucideIcons.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
331
333
  }
332
334
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: IconComponent, decorators: [{
333
335
  type: Component,
@@ -348,118 +350,140 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
348
350
  `, styles: [":host{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}\n"] }]
349
351
  }], 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 }] }] } });
350
352
 
353
+ // Минимальный набор - только для внутренних компонентов библиотеки
354
+ const MINIMAL_ICONS = {
355
+ X: LucideIcons.X,
356
+ ChevronDown: LucideIcons.ChevronDown,
357
+ ChevronUp: LucideIcons.ChevronUp,
358
+ ChevronLeft: LucideIcons.ChevronLeft,
359
+ ChevronRight: LucideIcons.ChevronRight,
360
+ Check: LucideIcons.Check,
361
+ Loader2: LucideIcons.Loader2,
362
+ Search: LucideIcons.Search,
363
+ };
364
+ // Расширенный набор - частоиспользуемые иконки для UI
365
+ const COMMON_ICONS = {
366
+ ...MINIMAL_ICONS,
367
+ ArrowRight: LucideIcons.ArrowRight,
368
+ ArrowLeft: LucideIcons.ArrowLeft,
369
+ Download: LucideIcons.Download,
370
+ Upload: LucideIcons.Upload,
371
+ Mail: LucideIcons.Mail,
372
+ Phone: LucideIcons.Phone,
373
+ Heart: LucideIcons.Heart,
374
+ Star: LucideIcons.Star,
375
+ Settings: LucideIcons.Settings,
376
+ User: LucideIcons.User,
377
+ Users: LucideIcons.Users,
378
+ Trash2: LucideIcons.Trash2,
379
+ Pen: LucideIcons.Pen,
380
+ Edit2: LucideIcons.Edit2,
381
+ Plus: LucideIcons.Plus,
382
+ Minus: LucideIcons.Minus,
383
+ Filter: LucideIcons.Filter,
384
+ ExternalLink: LucideIcons.ExternalLink,
385
+ Link: LucideIcons.Link,
386
+ Copy: LucideIcons.Copy,
387
+ Share2: LucideIcons.Share2,
388
+ House: LucideIcons.House,
389
+ Menu: LucideIcons.Menu,
390
+ MoreVertical: LucideIcons.MoreVertical,
391
+ MoreHorizontal: LucideIcons.MoreHorizontal,
392
+ Bell: LucideIcons.Bell,
393
+ Calendar: LucideIcons.Calendar,
394
+ Clock: LucideIcons.Clock,
395
+ Eye: LucideIcons.Eye,
396
+ EyeOff: LucideIcons.EyeOff,
397
+ Lock: LucideIcons.Lock,
398
+ LockOpen: LucideIcons.LockOpen,
399
+ LogIn: LucideIcons.LogIn,
400
+ LogOut: LucideIcons.LogOut,
401
+ CircleAlert: LucideIcons.CircleAlert,
402
+ TriangleAlert: LucideIcons.TriangleAlert,
403
+ Info: LucideIcons.Info,
404
+ CircleCheck: LucideIcons.CircleCheck,
405
+ CircleX: LucideIcons.CircleX,
406
+ CircleQuestionMark: LucideIcons.CircleQuestionMark,
407
+ File: LucideIcons.File,
408
+ FileText: LucideIcons.FileText,
409
+ Folder: LucideIcons.Folder,
410
+ FolderOpen: LucideIcons.FolderOpen,
411
+ Image: LucideIcons.Image,
412
+ Save: LucideIcons.Save,
413
+ Printer: LucideIcons.Printer,
414
+ RefreshCw: LucideIcons.RefreshCw,
415
+ RotateCw: LucideIcons.RotateCw,
416
+ Loader: LucideIcons.Loader,
417
+ ShoppingCart: LucideIcons.ShoppingCart,
418
+ Sun: LucideIcons.Sun,
419
+ Moon: LucideIcons.Moon,
420
+ TextAlignStart: LucideIcons.TextAlignStart,
421
+ TextAlignCenter: LucideIcons.TextAlignCenter,
422
+ TextAlignEnd: LucideIcons.TextAlignEnd,
423
+ TextAlignJustify: LucideIcons.TextAlignJustify,
424
+ Bold: LucideIcons.Bold,
425
+ Italic: LucideIcons.Italic,
426
+ Underline: LucideIcons.Underline,
427
+ Strikethrough: LucideIcons.Strikethrough,
428
+ Grid3x3: LucideIcons.Grid3x3,
429
+ List: LucideIcons.List,
430
+ MessageSquare: LucideIcons.MessageSquare,
431
+ Laptop: LucideIcons.Laptop,
432
+ Globe: LucideIcons.Globe,
433
+ Apple: LucideIcons.Apple,
434
+ Circle: LucideIcons.Circle,
435
+ };
351
436
  /**
352
- * Studio icon provider
353
- * Registers commonly used Lucide icons
437
+ * Studio icon provider с поддержкой preset'ов
354
438
  *
355
439
  * @example
356
440
  * ```typescript
357
- * // app.config.ts
358
- * import { provideStudioIcons } from '@eduboxpro/studio';
441
+ * // Минимальный набор (только для компонентов библиотеки)
442
+ * provideStudioIcons({ preset: 'minimal' });
359
443
  *
360
- * export const appConfig: ApplicationConfig = {
361
- * providers: [
362
- * provideStudioIcons()
363
- * ]
364
- * };
365
- * ```
444
+ * // Расширенный набор (рекомендуется)
445
+ * provideStudioIcons({ preset: 'common' });
366
446
  *
367
- * To add additional icons:
368
- * @example
369
- * ```typescript
370
- * import { LUCIDE_ICONS, LucideIconProvider } from 'lucide-angular';
371
- * import { Zap, Wifi } from 'lucide-angular';
447
+ * // Все иконки Lucide (~1400 штук)
448
+ * provideStudioIcons({ preset: 'full' });
372
449
  *
373
- * providers: [
374
- * provideStudioIcons(),
375
- * {
376
- * provide: LUCIDE_ICONS,
377
- * multi: true,
378
- * useValue: new LucideIconProvider({ Zap, Wifi })
379
- * }
380
- * ]
450
+ * // С кастомными иконками
451
+ * import { Zap, Wifi } from 'lucide-angular';
452
+ * provideStudioIcons({
453
+ * preset: 'common',
454
+ * customIcons: { Zap, Wifi }
455
+ * });
381
456
  * ```
382
457
  */
383
- function provideStudioIcons() {
458
+ function provideStudioIcons(config = { preset: 'common' }) {
459
+ let icons;
460
+ switch (config.preset) {
461
+ case 'minimal':
462
+ icons = MINIMAL_ICONS;
463
+ break;
464
+ case 'full':
465
+ // Все иконки из lucide-angular (кроме служебных)
466
+ icons = Object.keys(LucideIcons)
467
+ .filter(key => !key.startsWith('Lucide') && !key.startsWith('LUCIDE'))
468
+ .reduce((acc, key) => {
469
+ acc[key] = LucideIcons[key];
470
+ return acc;
471
+ }, {});
472
+ break;
473
+ case 'common':
474
+ default:
475
+ icons = COMMON_ICONS;
476
+ break;
477
+ }
478
+ // Добавляем кастомные иконки
479
+ if (config.customIcons) {
480
+ icons = { ...icons, ...config.customIcons };
481
+ }
384
482
  return makeEnvironmentProviders([
385
483
  {
386
484
  provide: LUCIDE_ICONS,
387
485
  multi: true,
388
- useValue: new LucideIconProvider({
389
- ArrowRight,
390
- ArrowLeft,
391
- ChevronDown,
392
- ChevronUp,
393
- ChevronLeft,
394
- ChevronRight,
395
- Download,
396
- Upload,
397
- Mail,
398
- Phone,
399
- Heart,
400
- Star,
401
- Settings,
402
- User,
403
- Trash2,
404
- Edit,
405
- Plus,
406
- Minus,
407
- Check,
408
- X,
409
- Search,
410
- Filter,
411
- ExternalLink,
412
- Link,
413
- Copy,
414
- Share2,
415
- Home,
416
- Menu,
417
- MoreVertical,
418
- MoreHorizontal,
419
- Bell,
420
- Calendar,
421
- Clock,
422
- Eye,
423
- EyeOff,
424
- Lock,
425
- Unlock,
426
- LogIn,
427
- LogOut,
428
- AlertCircle,
429
- AlertTriangle,
430
- Info,
431
- CheckCircle,
432
- XCircle,
433
- HelpCircle,
434
- File,
435
- FileText,
436
- Folder,
437
- Image,
438
- Save,
439
- Printer,
440
- RefreshCw,
441
- RotateCw,
442
- Loader,
443
- Loader2,
444
- ShoppingCart,
445
- Sun,
446
- Moon,
447
- AlignLeft,
448
- AlignCenter,
449
- AlignRight,
450
- AlignJustify,
451
- Bold,
452
- Italic,
453
- Underline,
454
- Strikethrough,
455
- Grid3x3,
456
- List,
457
- MessageSquare,
458
- Laptop,
459
- Globe,
460
- Apple,
461
- Circle
462
- })
486
+ useValue: new LucideIconProvider(icons)
463
487
  }
464
488
  ]);
465
489
  }
@@ -1163,7 +1187,7 @@ class CheckboxComponent {
1163
1187
  provide: NG_VALUE_ACCESSOR,
1164
1188
  useExisting: forwardRef(() => CheckboxComponent),
1165
1189
  multi: true
1166
- }], ngImport: i0, template: "<label\n [for]=\"checkboxId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <!-- Checkbox input -->\n <input\n type=\"checkbox\"\n [id]=\"checkboxId()\"\n [name]=\"name()\"\n [checked]=\"internalChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? checkboxId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-checkbox__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <!-- Custom checkbox -->\n <span [ngClass]=\"checkboxClasses()\">\n <!-- Checkmark icon -->\n @if (internalChecked() && !indeterminate()) {\n <svg\n class=\"studio-checkbox__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M13.3333 4L6 11.3333L2.66666 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n\n <!-- Indeterminate icon -->\n @if (indeterminate()) {\n <svg\n class=\"studio-checkbox__icon studio-checkbox__icon--indeterminate\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 8H12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n </span>\n\n <!-- Label content -->\n @if (label() || description()) {\n <span class=\"studio-checkbox__label-wrapper\">\n @if (label()) {\n <span class=\"studio-checkbox__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-checkbox__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-checkbox__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n<!-- Helper text / Error message -->\n@if (showHint() || showError()) {\n <div\n [id]=\"checkboxId() + '-description'\"\n class=\"studio-checkbox__info\"\n >\n @if (showError()) {\n <span class=\"studio-checkbox__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-checkbox__hint\">\n {{ hint() }}\n </span>\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-direction:column;font-family:var(--studio-font-family)!important}.studio-checkbox-wrapper{display:inline-flex;align-items:flex-start;gap:var(--studio-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.studio-checkbox-wrapper--label-left{flex-direction:row-reverse}.studio-checkbox-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-checkbox-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-checkbox-wrapper--md{font-size:var(--studio-font-size-base)}.studio-checkbox-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-checkbox__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-checkbox{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border:2px solid var(--studio-border-primary);background-color:var(--studio-bg-primary);transition:all var(--studio-transition-base)}.studio-checkbox--sm{width:1rem;height:1rem}.studio-checkbox--md{width:1.25rem;height:1.25rem}.studio-checkbox--lg{width:1.5rem;height:1.5rem}.studio-checkbox--radius-none{border-radius:0}.studio-checkbox--radius-sm{border-radius:var(--studio-radius-sm)}.studio-checkbox--radius-md{border-radius:var(--studio-radius-md)}.studio-checkbox--radius-lg{border-radius:var(--studio-radius-lg)}.studio-checkbox--radius-full{border-radius:var(--studio-radius-full)}.studio-checkbox--default.studio-checkbox--checked,.studio-checkbox--default.studio-checkbox--indeterminate{border-color:transparent}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--outlined.studio-checkbox--checked,.studio-checkbox--outlined.studio-checkbox--indeterminate{background-color:transparent}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--primary{border-color:var(--studio-primary);color:var(--studio-primary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--secondary{border-color:var(--studio-secondary);color:var(--studio-secondary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--success{border-color:var(--studio-success);color:var(--studio-success)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--error{border-color:var(--studio-error);color:var(--studio-error)}.studio-checkbox--filled.studio-checkbox--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-checkbox--filled.studio-checkbox--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-checkbox--filled.studio-checkbox--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-checkbox--filled.studio-checkbox--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);border-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);border-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);border-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--error:not(.studio-checkbox--checked):not(.studio-checkbox--indeterminate){border-color:var(--studio-error)}.studio-checkbox:hover:not(.studio-checkbox--disabled){border-color:var(--studio-border-secondary)}.studio-checkbox__input:focus-visible+.studio-checkbox{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-checkbox__icon{width:100%;height:100%;opacity:0;transform:scale(.8);transition:all var(--studio-transition-fast)}.studio-checkbox--checked .studio-checkbox__icon,.studio-checkbox--indeterminate .studio-checkbox__icon{opacity:1;transform:scale(1)}.studio-checkbox__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-checkbox__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-checkbox__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-checkbox__info{display:flex;flex-direction:column;gap:var(--studio-spacing-xs);margin-top:var(--studio-spacing-xs);padding-left:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--label-left+.studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--sm .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--sm.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--lg .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox-wrapper--lg.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__error{font-size:var(--studio-font-size-xs);color:var(--studio-error);line-height:var(--studio-line-height-normal)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1190
+ }], ngImport: i0, template: "<label\n [for]=\"checkboxId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <!-- Checkbox input -->\n <input\n type=\"checkbox\"\n [id]=\"checkboxId()\"\n [name]=\"name()\"\n [checked]=\"internalChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? checkboxId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-checkbox__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <!-- Custom checkbox -->\n <span [ngClass]=\"checkboxClasses()\">\n <!-- Checkmark icon -->\n @if (internalChecked() && !indeterminate()) {\n <svg\n class=\"studio-checkbox__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M13.3333 4L6 11.3333L2.66666 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n\n <!-- Indeterminate icon -->\n @if (indeterminate()) {\n <svg\n class=\"studio-checkbox__icon studio-checkbox__icon--indeterminate\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 8H12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n </span>\n\n <!-- Label content -->\n @if (label() || description()) {\n <span class=\"studio-checkbox__label-wrapper\">\n @if (label()) {\n <span class=\"studio-checkbox__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-checkbox__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-checkbox__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n<!-- Helper text / Error message -->\n@if (showHint() || showError()) {\n <div\n [id]=\"checkboxId() + '-description'\"\n class=\"studio-checkbox__info\"\n >\n @if (showError()) {\n <span class=\"studio-checkbox__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-checkbox__hint\">\n {{ hint() }}\n </span>\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-direction:column;font-family:var(--studio-font-family)!important}.studio-checkbox-wrapper{display:inline-flex;align-items:flex-start;gap:var(--studio-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.studio-checkbox-wrapper--label-left{flex-direction:row-reverse}.studio-checkbox-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-checkbox-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-checkbox-wrapper--md{font-size:var(--studio-font-size-base)}.studio-checkbox-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-checkbox__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-checkbox{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border:2px solid var(--studio-border-primary);background-color:var(--studio-bg-primary);transition:all var(--studio-transition-base)}.studio-checkbox--sm{width:1rem;height:1rem}.studio-checkbox--md{width:1.25rem;height:1.25rem}.studio-checkbox--lg{width:1.5rem;height:1.5rem}.studio-checkbox--radius-none{border-radius:0}.studio-checkbox--radius-sm{border-radius:var(--studio-radius-sm)}.studio-checkbox--radius-md{border-radius:var(--studio-radius-md)}.studio-checkbox--radius-lg{border-radius:var(--studio-radius-lg)}.studio-checkbox--radius-full{border-radius:var(--studio-radius-full)}.studio-checkbox--default.studio-checkbox--checked,.studio-checkbox--default.studio-checkbox--indeterminate{border-color:transparent}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--outlined.studio-checkbox--checked,.studio-checkbox--outlined.studio-checkbox--indeterminate{background-color:transparent}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--primary{border-color:var(--studio-primary);color:var(--studio-primary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--secondary{border-color:var(--studio-secondary);color:var(--studio-secondary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--success{border-color:var(--studio-success);color:var(--studio-success)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--error{border-color:var(--studio-error);color:var(--studio-error)}.studio-checkbox--filled.studio-checkbox--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-checkbox--filled.studio-checkbox--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-checkbox--filled.studio-checkbox--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-checkbox--filled.studio-checkbox--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);border-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);border-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);border-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--error:not(.studio-checkbox--checked):not(.studio-checkbox--indeterminate){border-color:var(--studio-error)}.studio-checkbox:hover:not(.studio-checkbox--disabled){border-color:var(--studio-border-secondary)}.studio-checkbox__input:focus-visible+.studio-checkbox{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-checkbox__icon{width:100%;height:100%;opacity:0;transform:scale(.8);transition:all var(--studio-transition-fast)}.studio-checkbox--checked .studio-checkbox__icon,.studio-checkbox--indeterminate .studio-checkbox__icon{opacity:1;transform:scale(1)}.studio-checkbox__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-checkbox__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-checkbox__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-checkbox__info{display:flex;flex-direction:column;gap:var(--studio-spacing-xs);margin-top:var(--studio-spacing-xs);padding-left:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--label-left+.studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--sm .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--sm.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--lg .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox-wrapper--lg.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__error{font-size:var(--studio-font-size-xs);color:var(--studio-error);line-height:var(--studio-line-height-normal)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1167
1191
  }
1168
1192
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: CheckboxComponent, decorators: [{
1169
1193
  type: Component,
@@ -1180,6 +1204,436 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1180
1204
  }, template: "<label\n [for]=\"checkboxId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <!-- Checkbox input -->\n <input\n type=\"checkbox\"\n [id]=\"checkboxId()\"\n [name]=\"name()\"\n [checked]=\"internalChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? checkboxId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-checkbox__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <!-- Custom checkbox -->\n <span [ngClass]=\"checkboxClasses()\">\n <!-- Checkmark icon -->\n @if (internalChecked() && !indeterminate()) {\n <svg\n class=\"studio-checkbox__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M13.3333 4L6 11.3333L2.66666 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n\n <!-- Indeterminate icon -->\n @if (indeterminate()) {\n <svg\n class=\"studio-checkbox__icon studio-checkbox__icon--indeterminate\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 8H12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n </span>\n\n <!-- Label content -->\n @if (label() || description()) {\n <span class=\"studio-checkbox__label-wrapper\">\n @if (label()) {\n <span class=\"studio-checkbox__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-checkbox__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-checkbox__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n<!-- Helper text / Error message -->\n@if (showHint() || showError()) {\n <div\n [id]=\"checkboxId() + '-description'\"\n class=\"studio-checkbox__info\"\n >\n @if (showError()) {\n <span class=\"studio-checkbox__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-checkbox__hint\">\n {{ hint() }}\n </span>\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-direction:column;font-family:var(--studio-font-family)!important}.studio-checkbox-wrapper{display:inline-flex;align-items:flex-start;gap:var(--studio-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.studio-checkbox-wrapper--label-left{flex-direction:row-reverse}.studio-checkbox-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-checkbox-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-checkbox-wrapper--md{font-size:var(--studio-font-size-base)}.studio-checkbox-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-checkbox__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-checkbox{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border:2px solid var(--studio-border-primary);background-color:var(--studio-bg-primary);transition:all var(--studio-transition-base)}.studio-checkbox--sm{width:1rem;height:1rem}.studio-checkbox--md{width:1.25rem;height:1.25rem}.studio-checkbox--lg{width:1.5rem;height:1.5rem}.studio-checkbox--radius-none{border-radius:0}.studio-checkbox--radius-sm{border-radius:var(--studio-radius-sm)}.studio-checkbox--radius-md{border-radius:var(--studio-radius-md)}.studio-checkbox--radius-lg{border-radius:var(--studio-radius-lg)}.studio-checkbox--radius-full{border-radius:var(--studio-radius-full)}.studio-checkbox--default.studio-checkbox--checked,.studio-checkbox--default.studio-checkbox--indeterminate{border-color:transparent}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--outlined.studio-checkbox--checked,.studio-checkbox--outlined.studio-checkbox--indeterminate{background-color:transparent}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--primary{border-color:var(--studio-primary);color:var(--studio-primary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--secondary{border-color:var(--studio-secondary);color:var(--studio-secondary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--success{border-color:var(--studio-success);color:var(--studio-success)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--error{border-color:var(--studio-error);color:var(--studio-error)}.studio-checkbox--filled.studio-checkbox--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-checkbox--filled.studio-checkbox--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-checkbox--filled.studio-checkbox--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-checkbox--filled.studio-checkbox--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);border-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);border-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);border-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--error:not(.studio-checkbox--checked):not(.studio-checkbox--indeterminate){border-color:var(--studio-error)}.studio-checkbox:hover:not(.studio-checkbox--disabled){border-color:var(--studio-border-secondary)}.studio-checkbox__input:focus-visible+.studio-checkbox{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-checkbox__icon{width:100%;height:100%;opacity:0;transform:scale(.8);transition:all var(--studio-transition-fast)}.studio-checkbox--checked .studio-checkbox__icon,.studio-checkbox--indeterminate .studio-checkbox__icon{opacity:1;transform:scale(1)}.studio-checkbox__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-checkbox__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-checkbox__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-checkbox__info{display:flex;flex-direction:column;gap:var(--studio-spacing-xs);margin-top:var(--studio-spacing-xs);padding-left:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--label-left+.studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--sm .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--sm.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--lg .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox-wrapper--lg.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__error{font-size:var(--studio-font-size-xs);color:var(--studio-error);line-height:var(--studio-line-height-normal)}\n"] }]
1181
1205
  }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
1182
1206
 
1207
+ /**
1208
+ * Service for programmatic control of Drawer components
1209
+ *
1210
+ * @example
1211
+ * ```typescript
1212
+ * // In component
1213
+ * private drawerService = inject(DrawerService);
1214
+ *
1215
+ * openSettings() {
1216
+ * this.drawerService.open('settings-drawer');
1217
+ * }
1218
+ * ```
1219
+ */
1220
+ class DrawerService {
1221
+ drawers = new Map();
1222
+ /**
1223
+ * Register a drawer with the service
1224
+ * Called automatically by DrawerComponent
1225
+ */
1226
+ register(id, signal) {
1227
+ this.drawers.set(id, signal);
1228
+ }
1229
+ /**
1230
+ * Unregister a drawer from the service
1231
+ * Called automatically on component destroy
1232
+ */
1233
+ unregister(id) {
1234
+ this.drawers.delete(id);
1235
+ }
1236
+ /**
1237
+ * Open a drawer by ID
1238
+ */
1239
+ open(id) {
1240
+ const drawer = this.drawers.get(id);
1241
+ if (drawer) {
1242
+ drawer.set(true);
1243
+ }
1244
+ else {
1245
+ console.warn(`[DrawerService] Drawer with id="${id}" not found`);
1246
+ }
1247
+ }
1248
+ /**
1249
+ * Close a drawer by ID
1250
+ */
1251
+ close(id) {
1252
+ const drawer = this.drawers.get(id);
1253
+ if (drawer) {
1254
+ drawer.set(false);
1255
+ }
1256
+ else {
1257
+ console.warn(`[DrawerService] Drawer with id="${id}" not found`);
1258
+ }
1259
+ }
1260
+ /**
1261
+ * Toggle a drawer by ID
1262
+ */
1263
+ toggle(id) {
1264
+ const drawer = this.drawers.get(id);
1265
+ if (drawer) {
1266
+ drawer.update(v => !v);
1267
+ }
1268
+ else {
1269
+ console.warn(`[DrawerService] Drawer with id="${id}" not found`);
1270
+ }
1271
+ }
1272
+ /**
1273
+ * Close all registered drawers
1274
+ */
1275
+ closeAll() {
1276
+ this.drawers.forEach(signal => signal.set(false));
1277
+ }
1278
+ /**
1279
+ * Check if a drawer is open
1280
+ */
1281
+ isOpen(id) {
1282
+ const drawer = this.drawers.get(id);
1283
+ return drawer ? drawer() : false;
1284
+ }
1285
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: DrawerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1286
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: DrawerService, providedIn: 'root' });
1287
+ }
1288
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: DrawerService, decorators: [{
1289
+ type: Injectable,
1290
+ args: [{ providedIn: 'root' }]
1291
+ }] });
1292
+
1293
+ class DrawerComponent {
1294
+ document = inject(DOCUMENT$1);
1295
+ destroyRef = inject(DestroyRef);
1296
+ configService = inject(StudioConfigService);
1297
+ drawerService = inject(DrawerService);
1298
+ drawerDefaults = computed(() => this.configService.config().components?.drawer, ...(ngDevMode ? [{ debugName: "drawerDefaults" }] : []));
1299
+ // Template references
1300
+ headerTemplate = contentChild('headerTemplate', ...(ngDevMode ? [{ debugName: "headerTemplate" }] : []));
1301
+ footerTemplate = contentChild('footerTemplate', ...(ngDevMode ? [{ debugName: "footerTemplate" }] : []));
1302
+ panelEl = viewChild('drawerPanel', ...(ngDevMode ? [{ debugName: "panelEl" }] : []));
1303
+ // Core
1304
+ id = input(`studio-drawer-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : []));
1305
+ visible = model(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
1306
+ // Position & Size
1307
+ positionInput = input(undefined, ...(ngDevMode ? [{ debugName: "positionInput", alias: 'position' }] : [{ alias: 'position' }]));
1308
+ sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
1309
+ customWidth = input(undefined, ...(ngDevMode ? [{ debugName: "customWidth" }] : []));
1310
+ customHeight = input(undefined, ...(ngDevMode ? [{ debugName: "customHeight" }] : []));
1311
+ position = withConfigDefault(this.positionInput, computed(() => this.drawerDefaults()?.position), 'right');
1312
+ size = withConfigDefault(this.sizeInput, computed(() => this.drawerDefaults()?.size), 'md');
1313
+ // Behavior
1314
+ modalInput = input(undefined, ...(ngDevMode ? [{ debugName: "modalInput", alias: 'modal' }] : [{ alias: 'modal' }]));
1315
+ closeOnEscapeInput = input(undefined, ...(ngDevMode ? [{ debugName: "closeOnEscapeInput", alias: 'closeOnEscape' }] : [{ alias: 'closeOnEscape' }]));
1316
+ closeOnBackdropClickInput = input(undefined, ...(ngDevMode ? [{ debugName: "closeOnBackdropClickInput", alias: 'closeOnBackdropClick' }] : [{ alias: 'closeOnBackdropClick' }]));
1317
+ blockScrollInput = input(undefined, ...(ngDevMode ? [{ debugName: "blockScrollInput", alias: 'blockScroll' }] : [{ alias: 'blockScroll' }]));
1318
+ modal = withConfigDefault(this.modalInput, computed(() => this.drawerDefaults()?.modal), true);
1319
+ closeOnEscape = withConfigDefault(this.closeOnEscapeInput, computed(() => this.drawerDefaults()?.closeOnEscape), true);
1320
+ closeOnBackdropClick = withConfigDefault(this.closeOnBackdropClickInput, computed(() => this.drawerDefaults()?.closeOnBackdropClick), true);
1321
+ blockScroll = withConfigDefault(this.blockScrollInput, computed(() => this.drawerDefaults()?.blockScroll), true);
1322
+ // UI Elements
1323
+ header = input(undefined, ...(ngDevMode ? [{ debugName: "header" }] : []));
1324
+ showHeaderInput = input(undefined, ...(ngDevMode ? [{ debugName: "showHeaderInput", alias: 'showHeader' }] : [{ alias: 'showHeader' }]));
1325
+ showCloseButtonInput = input(undefined, ...(ngDevMode ? [{ debugName: "showCloseButtonInput", alias: 'showCloseButton' }] : [{ alias: 'showCloseButton' }]));
1326
+ closeButtonPositionInput = input(undefined, ...(ngDevMode ? [{ debugName: "closeButtonPositionInput", alias: 'closeButtonPosition' }] : [{ alias: 'closeButtonPosition' }]));
1327
+ showFooter = input(true, ...(ngDevMode ? [{ debugName: "showFooter" }] : []));
1328
+ showHeader = withConfigDefault(this.showHeaderInput, computed(() => this.drawerDefaults()?.showHeader ?? true), true);
1329
+ showCloseButton = withConfigDefault(this.showCloseButtonInput, computed(() => this.drawerDefaults()?.showCloseButton), true);
1330
+ closeButtonPosition = withConfigDefault(this.closeButtonPositionInput, computed(() => this.drawerDefaults()?.closeButtonPosition), 'right');
1331
+ // Swipe Gestures
1332
+ swipeToCloseInput = input(undefined, ...(ngDevMode ? [{ debugName: "swipeToCloseInput", alias: 'swipeToClose' }] : [{ alias: 'swipeToClose' }]));
1333
+ swipeThresholdInput = input(undefined, ...(ngDevMode ? [{ debugName: "swipeThresholdInput", alias: 'swipeThreshold' }] : [{ alias: 'swipeThreshold' }]));
1334
+ swipeToClose = withConfigDefault(this.swipeToCloseInput, computed(() => this.drawerDefaults()?.swipeToClose), true);
1335
+ swipeThreshold = withConfigDefault(this.swipeThresholdInput, computed(() => this.drawerDefaults()?.swipeThreshold), 50);
1336
+ // Animation
1337
+ animationDurationInput = input(undefined, ...(ngDevMode ? [{ debugName: "animationDurationInput", alias: 'animationDuration' }] : [{ alias: 'animationDuration' }]));
1338
+ animationEasingInput = input(undefined, ...(ngDevMode ? [{ debugName: "animationEasingInput", alias: 'animationEasing' }] : [{ alias: 'animationEasing' }]));
1339
+ disableAnimationInput = input(undefined, ...(ngDevMode ? [{ debugName: "disableAnimationInput", alias: 'disableAnimation' }] : [{ alias: 'disableAnimation' }]));
1340
+ animationDuration = withConfigDefault(this.animationDurationInput, computed(() => this.drawerDefaults()?.animationDuration), 300);
1341
+ animationEasing = withConfigDefault(this.animationEasingInput, computed(() => this.drawerDefaults()?.animationEasing), 'ease-out');
1342
+ disableAnimation = withConfigDefault(this.disableAnimationInput, computed(() => this.drawerDefaults()?.disableAnimation), false);
1343
+ // Styling
1344
+ radiusInput = input(undefined, ...(ngDevMode ? [{ debugName: "radiusInput", alias: 'radius' }] : [{ alias: 'radius' }]));
1345
+ shadowInput = input(undefined, ...(ngDevMode ? [{ debugName: "shadowInput", alias: 'shadow' }] : [{ alias: 'shadow' }]));
1346
+ shadowSizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "shadowSizeInput", alias: 'shadowSize' }] : [{ alias: 'shadowSize' }]));
1347
+ radius = withConfigDefault(this.radiusInput, computed(() => this.drawerDefaults()?.radius), 'none');
1348
+ shadow = withConfigDefault(this.shadowInput, computed(() => this.drawerDefaults()?.shadow), true);
1349
+ shadowSize = withConfigDefault(this.shadowSizeInput, computed(() => this.drawerDefaults()?.shadowSize), 'lg');
1350
+ // Accessibility
1351
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
1352
+ ariaLabelledBy = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledBy" }] : []));
1353
+ ariaDescribedBy = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
1354
+ autoFocusInput = input(undefined, ...(ngDevMode ? [{ debugName: "autoFocusInput", alias: 'autoFocus' }] : [{ alias: 'autoFocus' }]));
1355
+ restoreFocusInput = input(undefined, ...(ngDevMode ? [{ debugName: "restoreFocusInput", alias: 'restoreFocus' }] : [{ alias: 'restoreFocus' }]));
1356
+ roleInput = input(undefined, ...(ngDevMode ? [{ debugName: "roleInput", alias: 'role' }] : [{ alias: 'role' }]));
1357
+ autoFocus = withConfigDefault(this.autoFocusInput, computed(() => this.drawerDefaults()?.autoFocus), true);
1358
+ restoreFocus = withConfigDefault(this.restoreFocusInput, computed(() => this.drawerDefaults()?.restoreFocus), true);
1359
+ role = withConfigDefault(this.roleInput, computed(() => this.drawerDefaults()?.role), 'dialog');
1360
+ // Outputs
1361
+ visibleChange = output();
1362
+ opened = output();
1363
+ closed = output();
1364
+ backdropClick = output();
1365
+ // Internal state
1366
+ previousActiveElement;
1367
+ touchStartX = 0;
1368
+ touchStartY = 0;
1369
+ isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
1370
+ scrollbarWidth = 0;
1371
+ hostClasses = computed(() => classNames('studio-drawer', `studio-drawer--${this.position()}`, `studio-drawer--${this.size()}`, this.visible() && 'studio-drawer--visible', this.modal() && 'studio-drawer--modal', this.shadow() && `studio-drawer--shadow-${this.shadowSize()}`, this.isDragging() && 'studio-drawer--dragging', (this.position() === 'left' || this.position() === 'right') && `studio-drawer--radius-${this.radius()}`), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
1372
+ constructor() {
1373
+ // Register with DrawerService
1374
+ effect(() => {
1375
+ this.drawerService.register(this.id(), this.visible);
1376
+ });
1377
+ // Handle visibility changes
1378
+ effect(() => {
1379
+ if (this.visible()) {
1380
+ this.handleOpen();
1381
+ }
1382
+ else {
1383
+ this.handleClose();
1384
+ }
1385
+ });
1386
+ // Cleanup on destroy
1387
+ this.destroyRef.onDestroy(() => {
1388
+ this.drawerService.unregister(this.id());
1389
+ this.unlockBodyScroll();
1390
+ });
1391
+ }
1392
+ handleOpen() {
1393
+ if (this.blockScroll() && this.modal()) {
1394
+ this.lockBodyScroll();
1395
+ }
1396
+ if (this.autoFocus()) {
1397
+ this.setupFocusTrap();
1398
+ }
1399
+ this.opened.emit();
1400
+ }
1401
+ handleClose() {
1402
+ if (this.blockScroll() && this.modal()) {
1403
+ this.unlockBodyScroll();
1404
+ }
1405
+ if (this.restoreFocus()) {
1406
+ this.restorePreviousFocus();
1407
+ }
1408
+ this.closed.emit();
1409
+ }
1410
+ open() {
1411
+ this.visible.set(true);
1412
+ this.visibleChange.emit(true);
1413
+ }
1414
+ close() {
1415
+ this.visible.set(false);
1416
+ this.visibleChange.emit(false);
1417
+ }
1418
+ toggle() {
1419
+ this.visible.update(v => !v);
1420
+ this.visibleChange.emit(this.visible());
1421
+ }
1422
+ handleBackdropClick() {
1423
+ this.backdropClick.emit();
1424
+ if (this.closeOnBackdropClick()) {
1425
+ this.close();
1426
+ }
1427
+ }
1428
+ handleEscapeKey(event) {
1429
+ if (this.visible() && this.closeOnEscape()) {
1430
+ event.preventDefault();
1431
+ this.close();
1432
+ }
1433
+ }
1434
+ // Touch gesture handling
1435
+ onTouchStart(event) {
1436
+ if (!this.swipeToClose() || !this.visible())
1437
+ return;
1438
+ const target = event.target;
1439
+ const panel = this.panelEl()?.nativeElement;
1440
+ // Only start drag if touching the panel
1441
+ if (!panel?.contains(target))
1442
+ return;
1443
+ this.touchStartX = event.touches[0].clientX;
1444
+ this.touchStartY = event.touches[0].clientY;
1445
+ this.isDragging.set(true);
1446
+ }
1447
+ onTouchMove(event) {
1448
+ if (!this.isDragging())
1449
+ return;
1450
+ const deltaX = event.touches[0].clientX - this.touchStartX;
1451
+ const deltaY = event.touches[0].clientY - this.touchStartY;
1452
+ const pos = this.position();
1453
+ // Apply drag transform based on position
1454
+ let shouldAllowDrag = false;
1455
+ if (pos === 'right' && deltaX > 0) {
1456
+ shouldAllowDrag = true;
1457
+ this.applyDragTransform(deltaX, 0);
1458
+ }
1459
+ else if (pos === 'left' && deltaX < 0) {
1460
+ shouldAllowDrag = true;
1461
+ this.applyDragTransform(deltaX, 0);
1462
+ }
1463
+ else if (pos === 'bottom' && deltaY > 0) {
1464
+ shouldAllowDrag = true;
1465
+ this.applyDragTransform(0, deltaY);
1466
+ }
1467
+ else if (pos === 'top' && deltaY < 0) {
1468
+ shouldAllowDrag = true;
1469
+ this.applyDragTransform(0, deltaY);
1470
+ }
1471
+ // Prevent scroll while dragging
1472
+ if (shouldAllowDrag && (Math.abs(deltaX) > 10 || Math.abs(deltaY) > 10)) {
1473
+ event.preventDefault();
1474
+ }
1475
+ }
1476
+ onTouchEnd(event) {
1477
+ if (!this.isDragging())
1478
+ return;
1479
+ const deltaX = event.changedTouches[0].clientX - this.touchStartX;
1480
+ const deltaY = event.changedTouches[0].clientY - this.touchStartY;
1481
+ const threshold = this.swipeThreshold();
1482
+ const pos = this.position();
1483
+ let shouldClose = false;
1484
+ if (pos === 'right' && deltaX > threshold)
1485
+ shouldClose = true;
1486
+ if (pos === 'left' && deltaX < -threshold)
1487
+ shouldClose = true;
1488
+ if (pos === 'bottom' && deltaY > threshold)
1489
+ shouldClose = true;
1490
+ if (pos === 'top' && deltaY < -threshold)
1491
+ shouldClose = true;
1492
+ if (shouldClose) {
1493
+ this.close();
1494
+ }
1495
+ else {
1496
+ this.resetTransform();
1497
+ }
1498
+ this.isDragging.set(false);
1499
+ }
1500
+ applyDragTransform(deltaX, deltaY) {
1501
+ const panel = this.panelEl()?.nativeElement;
1502
+ if (!panel)
1503
+ return;
1504
+ const pos = this.position();
1505
+ if (pos === 'right') {
1506
+ const translateX = Math.max(0, deltaX);
1507
+ panel.style.transform = `translateX(${translateX}px)`;
1508
+ panel.style.transition = 'none';
1509
+ }
1510
+ else if (pos === 'left') {
1511
+ const translateX = Math.min(0, deltaX);
1512
+ panel.style.transform = `translateX(${translateX}px)`;
1513
+ panel.style.transition = 'none';
1514
+ }
1515
+ else if (pos === 'bottom') {
1516
+ const translateY = Math.max(0, deltaY);
1517
+ panel.style.transform = `translateY(${translateY}px)`;
1518
+ panel.style.transition = 'none';
1519
+ }
1520
+ else if (pos === 'top') {
1521
+ const translateY = Math.min(0, deltaY);
1522
+ panel.style.transform = `translateY(${translateY}px)`;
1523
+ panel.style.transition = 'none';
1524
+ }
1525
+ }
1526
+ resetTransform() {
1527
+ const panel = this.panelEl()?.nativeElement;
1528
+ if (!panel)
1529
+ return;
1530
+ panel.style.transition = '';
1531
+ panel.style.transform = '';
1532
+ }
1533
+ // Body scroll lock
1534
+ lockBodyScroll() {
1535
+ this.scrollbarWidth = window.innerWidth - this.document.documentElement.clientWidth;
1536
+ this.document.body.style.overflow = 'hidden';
1537
+ this.document.body.style.paddingRight = `${this.scrollbarWidth}px`;
1538
+ }
1539
+ unlockBodyScroll() {
1540
+ this.document.body.style.overflow = '';
1541
+ this.document.body.style.paddingRight = '';
1542
+ }
1543
+ // Focus management
1544
+ setupFocusTrap() {
1545
+ this.previousActiveElement = this.document.activeElement;
1546
+ // Move focus to drawer after render
1547
+ setTimeout(() => {
1548
+ const panel = this.panelEl()?.nativeElement;
1549
+ if (!panel)
1550
+ return;
1551
+ const firstFocusable = this.getFirstFocusableElement(panel);
1552
+ if (firstFocusable) {
1553
+ firstFocusable.focus();
1554
+ }
1555
+ else {
1556
+ panel.focus();
1557
+ }
1558
+ }, 0);
1559
+ }
1560
+ restorePreviousFocus() {
1561
+ if (this.previousActiveElement) {
1562
+ this.previousActiveElement.focus();
1563
+ this.previousActiveElement = undefined;
1564
+ }
1565
+ }
1566
+ getFirstFocusableElement(container) {
1567
+ const focusableSelectors = [
1568
+ 'a[href]',
1569
+ 'button:not([disabled])',
1570
+ 'textarea:not([disabled])',
1571
+ 'input:not([disabled])',
1572
+ 'select:not([disabled])',
1573
+ '[tabindex]:not([tabindex="-1"])'
1574
+ ].join(', ');
1575
+ return container.querySelector(focusableSelectors);
1576
+ }
1577
+ handleKeydown(event) {
1578
+ if (!this.visible())
1579
+ return;
1580
+ if (event.key === 'Tab') {
1581
+ this.trapFocus(event);
1582
+ }
1583
+ }
1584
+ trapFocus(event) {
1585
+ const panel = this.panelEl()?.nativeElement;
1586
+ if (!panel)
1587
+ return;
1588
+ const focusableElements = panel.querySelectorAll([
1589
+ 'a[href]',
1590
+ 'button:not([disabled])',
1591
+ 'textarea:not([disabled])',
1592
+ 'input:not([disabled])',
1593
+ 'select:not([disabled])',
1594
+ '[tabindex]:not([tabindex="-1"])'
1595
+ ].join(', '));
1596
+ const firstElement = focusableElements[0];
1597
+ const lastElement = focusableElements[focusableElements.length - 1];
1598
+ if (event.shiftKey) {
1599
+ if (this.document.activeElement === firstElement) {
1600
+ event.preventDefault();
1601
+ lastElement?.focus();
1602
+ }
1603
+ }
1604
+ else {
1605
+ if (this.document.activeElement === lastElement) {
1606
+ event.preventDefault();
1607
+ firstElement?.focus();
1608
+ }
1609
+ }
1610
+ }
1611
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: DrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1612
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: DrawerComponent, isStandalone: true, selector: "studio-drawer", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, positionInput: { classPropertyName: "positionInput", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, customWidth: { classPropertyName: "customWidth", publicName: "customWidth", isSignal: true, isRequired: false, transformFunction: null }, customHeight: { classPropertyName: "customHeight", publicName: "customHeight", isSignal: true, isRequired: false, transformFunction: null }, modalInput: { classPropertyName: "modalInput", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscapeInput: { classPropertyName: "closeOnEscapeInput", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClickInput: { classPropertyName: "closeOnBackdropClickInput", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, blockScrollInput: { classPropertyName: "blockScrollInput", publicName: "blockScroll", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, showHeaderInput: { classPropertyName: "showHeaderInput", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showCloseButtonInput: { classPropertyName: "showCloseButtonInput", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, closeButtonPositionInput: { classPropertyName: "closeButtonPositionInput", publicName: "closeButtonPosition", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, swipeToCloseInput: { classPropertyName: "swipeToCloseInput", publicName: "swipeToClose", isSignal: true, isRequired: false, transformFunction: null }, swipeThresholdInput: { classPropertyName: "swipeThresholdInput", publicName: "swipeThreshold", isSignal: true, isRequired: false, transformFunction: null }, animationDurationInput: { classPropertyName: "animationDurationInput", publicName: "animationDuration", isSignal: true, isRequired: false, transformFunction: null }, animationEasingInput: { classPropertyName: "animationEasingInput", publicName: "animationEasing", isSignal: true, isRequired: false, transformFunction: null }, disableAnimationInput: { classPropertyName: "disableAnimationInput", publicName: "disableAnimation", isSignal: true, isRequired: false, transformFunction: null }, radiusInput: { classPropertyName: "radiusInput", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, shadowInput: { classPropertyName: "shadowInput", publicName: "shadow", isSignal: true, isRequired: false, transformFunction: null }, shadowSizeInput: { classPropertyName: "shadowSizeInput", publicName: "shadowSize", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "ariaLabelledBy", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, autoFocusInput: { classPropertyName: "autoFocusInput", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, restoreFocusInput: { classPropertyName: "restoreFocusInput", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null }, roleInput: { classPropertyName: "roleInput", publicName: "role", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", visibleChange: "visibleChange", opened: "opened", closed: "closed", backdropClick: "backdropClick" }, host: { listeners: { "document:keydown.escape": "handleEscapeKey($event)", "touchstart": "onTouchStart($event)", "touchmove": "onTouchMove($event)", "touchend": "onTouchEnd($event)", "keydown": "handleKeydown($event)" }, properties: { "class": "hostClasses()", "attr.data-visible": "visible()" } }, queries: [{ propertyName: "headerTemplate", first: true, predicate: ["headerTemplate"], descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["footerTemplate"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "panelEl", first: true, predicate: ["drawerPanel"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (visible()) {\n <!-- Backdrop -->\n @if (modal()) {\n <div\n class=\"studio-drawer__backdrop\"\n (click)=\"handleBackdropClick()\">\n </div>\n }\n\n <!-- Drawer Panel -->\n <div\n #drawerPanel\n class=\"studio-drawer__panel\"\n [attr.role]=\"role()\"\n [attr.aria-modal]=\"modal()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.tabindex]=\"-1\"\n [style.width]=\"customWidth()\"\n [style.height]=\"customHeight()\"\n [style.--drawer-animation-duration]=\"animationDuration() + 'ms'\"\n [style.--drawer-animation-timing]=\"animationEasing()\">\n\n <!-- Header -->\n @if (showHeader() && (headerTemplate() || header() || showCloseButton())) {\n <div class=\"studio-drawer__header\">\n @if (headerTemplate(); as tmpl) {\n <!-- Custom template -->\n <ng-container *ngTemplateOutlet=\"tmpl\" />\n } @else if (header()) {\n <!-- Simple string header -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <h2 class=\"studio-drawer__title\">{{ header() }}</h2>\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n } @else {\n <!-- Named slot fallback -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <ng-content select=\"[drawerHeader]\" />\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Content -->\n <div class=\"studio-drawer__content\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n @if (showFooter() && footerTemplate()) {\n <div class=\"studio-drawer__footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()!\" />\n </div>\n } @else if (showFooter()) {\n <div class=\"studio-drawer__footer\">\n <ng-content select=\"[drawerFooter]\" />\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;pointer-events:none;font-family:var(--studio-font-family)}:host(.studio-drawer--visible){pointer-events:auto}.studio-drawer__backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:var(--studio-drawer-backdrop-bg, rgba(0, 0, 0, .5));-webkit-backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));z-index:var(--studio-drawer-z-index, 1000);opacity:0;transition:opacity var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}:host(.studio-drawer--visible) .studio-drawer__backdrop{opacity:1}.studio-drawer__panel{position:fixed;background:var(--studio-drawer-bg, var(--studio-bg-primary));color:var(--studio-drawer-text-color, var(--studio-text-primary));z-index:calc(var(--studio-drawer-z-index, 1000) + 1);overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;outline:none;transition:transform var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}.studio-drawer__panel::-webkit-scrollbar{width:var(--studio-drawer-scrollbar-width, 8px)}.studio-drawer__panel::-webkit-scrollbar-track{background:var(--studio-drawer-scrollbar-track-bg, transparent)}.studio-drawer__panel::-webkit-scrollbar-thumb{background:var(--studio-drawer-scrollbar-thumb-bg, rgba(0, 0, 0, .2));border-radius:var(--studio-drawer-scrollbar-thumb-radius, 4px)}.studio-drawer__panel::-webkit-scrollbar-thumb:hover{background:var(--studio-drawer-scrollbar-thumb-hover-bg, rgba(0, 0, 0, .3))}:host(.studio-drawer--left) .studio-drawer__panel{top:0;left:0;height:100%;border-right:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(-100%)}:host(.studio-drawer--left.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--right) .studio-drawer__panel{top:0;right:0;height:100%;border-left:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(100%)}:host(.studio-drawer--right.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--top) .studio-drawer__panel{top:0;left:0;width:100%;border-bottom:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(-100%)}:host(.studio-drawer--top.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--bottom) .studio-drawer__panel{bottom:0;left:0;width:100%;border-top:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(100%)}:host(.studio-drawer--bottom.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--left.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--sm) .studio-drawer__panel{width:var(--studio-drawer-width-sm, 20rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel{width:var(--studio-drawer-width-md, 28rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel{width:var(--studio-drawer-width-lg, 36rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:var(--studio-drawer-width-xl, 48rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--full) .studio-drawer__panel{width:100vw;max-width:none}:host(.studio-drawer--top.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--sm) .studio-drawer__panel{height:var(--studio-drawer-height-sm, 12rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--md) .studio-drawer__panel{height:var(--studio-drawer-height-md, 20rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--lg) .studio-drawer__panel{height:var(--studio-drawer-height-lg, 32rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--xl) .studio-drawer__panel{height:var(--studio-drawer-height-xl, 48rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--full) .studio-drawer__panel{height:100vh;max-height:none}:host(.studio-drawer--left.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:0 var(--studio-radius-sm) var(--studio-radius-sm) 0}:host(.studio-drawer--left.studio-drawer--radius-md) .studio-drawer__panel{border-radius:0 var(--studio-radius-md) var(--studio-radius-md) 0}:host(.studio-drawer--left.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:0 var(--studio-radius-lg) var(--studio-radius-lg) 0}:host(.studio-drawer--right.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:var(--studio-radius-sm) 0 0 var(--studio-radius-sm)}:host(.studio-drawer--right.studio-drawer--radius-md) .studio-drawer__panel{border-radius:var(--studio-radius-md) 0 0 var(--studio-radius-md)}:host(.studio-drawer--right.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:var(--studio-radius-lg) 0 0 var(--studio-radius-lg)}:host(.studio-drawer--shadow-sm) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-sm, var(--studio-shadow-sm))}:host(.studio-drawer--shadow-md) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-md, var(--studio-shadow-md))}:host(.studio-drawer--shadow-lg) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-lg, var(--studio-shadow-lg))}:host(.studio-drawer--shadow-xl) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-xl, 0 12px 32px rgba(0, 0, 0, .2))}.studio-drawer__header{flex-shrink:0;padding:var(--studio-drawer-header-padding-y, var(--studio-spacing-md)) var(--studio-drawer-header-padding-x, var(--studio-spacing-lg));border-bottom:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary))}.studio-drawer__header-content{display:flex;align-items:center;gap:var(--studio-drawer-header-gap, var(--studio-spacing-md))}.studio-drawer__title{flex:1;margin:0;font-size:var(--studio-drawer-title-font-size, 1.25rem);font-weight:var(--studio-drawer-title-font-weight, var(--studio-font-weight-semibold, 600));line-height:var(--studio-drawer-title-line-height, 1.5);color:var(--studio-drawer-title-color, var(--studio-text-primary))}.studio-drawer__close{display:flex;align-items:center;justify-content:center;width:var(--studio-drawer-close-button-size, 2.5rem);height:var(--studio-drawer-close-button-size, 2.5rem);padding:0;background:none;border:none;border-radius:var(--studio-drawer-close-button-radius, var(--studio-radius-md));color:var(--studio-drawer-close-button-color, var(--studio-text-secondary));cursor:pointer;transition:all var(--studio-transition-fast);flex-shrink:0}.studio-drawer__close:hover{background:var(--studio-drawer-close-button-hover-bg, var(--studio-bg-secondary));color:var(--studio-drawer-close-button-hover-color, var(--studio-text-primary))}.studio-drawer__close:active{transform:scale(.95)}.studio-drawer__close:focus-visible{outline:2px solid var(--studio-drawer-focus-ring-color, var(--studio-primary));outline-offset:var(--studio-drawer-focus-ring-offset, 2px)}.studio-drawer__content{flex:1;padding:var(--studio-drawer-content-padding-y, var(--studio-spacing-lg)) var(--studio-drawer-content-padding-x, var(--studio-spacing-lg));overflow-y:auto;overflow-x:hidden}.studio-drawer__footer{flex-shrink:0;padding:var(--studio-drawer-footer-padding-y, var(--studio-spacing-md)) var(--studio-drawer-footer-padding-x, var(--studio-spacing-lg));border-top:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary));display:flex;align-items:center;gap:var(--studio-drawer-footer-gap, var(--studio-spacing-sm))}:host(.studio-drawer--dragging) .studio-drawer__panel{transition:none!important}@media (max-width: 640px){:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:100vw;max-width:none}.studio-drawer__header,.studio-drawer__content,.studio-drawer__footer{padding-left:var(--studio-spacing-md);padding-right:var(--studio-spacing-md)}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1613
+ }
1614
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: DrawerComponent, decorators: [{
1615
+ type: Component,
1616
+ args: [{ selector: 'studio-drawer', standalone: true, imports: [NgTemplateOutlet, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1617
+ '[class]': 'hostClasses()',
1618
+ '[attr.data-visible]': 'visible()',
1619
+ }, template: "@if (visible()) {\n <!-- Backdrop -->\n @if (modal()) {\n <div\n class=\"studio-drawer__backdrop\"\n (click)=\"handleBackdropClick()\">\n </div>\n }\n\n <!-- Drawer Panel -->\n <div\n #drawerPanel\n class=\"studio-drawer__panel\"\n [attr.role]=\"role()\"\n [attr.aria-modal]=\"modal()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.tabindex]=\"-1\"\n [style.width]=\"customWidth()\"\n [style.height]=\"customHeight()\"\n [style.--drawer-animation-duration]=\"animationDuration() + 'ms'\"\n [style.--drawer-animation-timing]=\"animationEasing()\">\n\n <!-- Header -->\n @if (showHeader() && (headerTemplate() || header() || showCloseButton())) {\n <div class=\"studio-drawer__header\">\n @if (headerTemplate(); as tmpl) {\n <!-- Custom template -->\n <ng-container *ngTemplateOutlet=\"tmpl\" />\n } @else if (header()) {\n <!-- Simple string header -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <h2 class=\"studio-drawer__title\">{{ header() }}</h2>\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n } @else {\n <!-- Named slot fallback -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <ng-content select=\"[drawerHeader]\" />\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Content -->\n <div class=\"studio-drawer__content\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n @if (showFooter() && footerTemplate()) {\n <div class=\"studio-drawer__footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()!\" />\n </div>\n } @else if (showFooter()) {\n <div class=\"studio-drawer__footer\">\n <ng-content select=\"[drawerFooter]\" />\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;pointer-events:none;font-family:var(--studio-font-family)}:host(.studio-drawer--visible){pointer-events:auto}.studio-drawer__backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:var(--studio-drawer-backdrop-bg, rgba(0, 0, 0, .5));-webkit-backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));z-index:var(--studio-drawer-z-index, 1000);opacity:0;transition:opacity var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}:host(.studio-drawer--visible) .studio-drawer__backdrop{opacity:1}.studio-drawer__panel{position:fixed;background:var(--studio-drawer-bg, var(--studio-bg-primary));color:var(--studio-drawer-text-color, var(--studio-text-primary));z-index:calc(var(--studio-drawer-z-index, 1000) + 1);overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;outline:none;transition:transform var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}.studio-drawer__panel::-webkit-scrollbar{width:var(--studio-drawer-scrollbar-width, 8px)}.studio-drawer__panel::-webkit-scrollbar-track{background:var(--studio-drawer-scrollbar-track-bg, transparent)}.studio-drawer__panel::-webkit-scrollbar-thumb{background:var(--studio-drawer-scrollbar-thumb-bg, rgba(0, 0, 0, .2));border-radius:var(--studio-drawer-scrollbar-thumb-radius, 4px)}.studio-drawer__panel::-webkit-scrollbar-thumb:hover{background:var(--studio-drawer-scrollbar-thumb-hover-bg, rgba(0, 0, 0, .3))}:host(.studio-drawer--left) .studio-drawer__panel{top:0;left:0;height:100%;border-right:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(-100%)}:host(.studio-drawer--left.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--right) .studio-drawer__panel{top:0;right:0;height:100%;border-left:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(100%)}:host(.studio-drawer--right.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--top) .studio-drawer__panel{top:0;left:0;width:100%;border-bottom:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(-100%)}:host(.studio-drawer--top.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--bottom) .studio-drawer__panel{bottom:0;left:0;width:100%;border-top:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(100%)}:host(.studio-drawer--bottom.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--left.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--sm) .studio-drawer__panel{width:var(--studio-drawer-width-sm, 20rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel{width:var(--studio-drawer-width-md, 28rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel{width:var(--studio-drawer-width-lg, 36rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:var(--studio-drawer-width-xl, 48rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--full) .studio-drawer__panel{width:100vw;max-width:none}:host(.studio-drawer--top.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--sm) .studio-drawer__panel{height:var(--studio-drawer-height-sm, 12rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--md) .studio-drawer__panel{height:var(--studio-drawer-height-md, 20rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--lg) .studio-drawer__panel{height:var(--studio-drawer-height-lg, 32rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--xl) .studio-drawer__panel{height:var(--studio-drawer-height-xl, 48rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--full) .studio-drawer__panel{height:100vh;max-height:none}:host(.studio-drawer--left.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:0 var(--studio-radius-sm) var(--studio-radius-sm) 0}:host(.studio-drawer--left.studio-drawer--radius-md) .studio-drawer__panel{border-radius:0 var(--studio-radius-md) var(--studio-radius-md) 0}:host(.studio-drawer--left.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:0 var(--studio-radius-lg) var(--studio-radius-lg) 0}:host(.studio-drawer--right.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:var(--studio-radius-sm) 0 0 var(--studio-radius-sm)}:host(.studio-drawer--right.studio-drawer--radius-md) .studio-drawer__panel{border-radius:var(--studio-radius-md) 0 0 var(--studio-radius-md)}:host(.studio-drawer--right.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:var(--studio-radius-lg) 0 0 var(--studio-radius-lg)}:host(.studio-drawer--shadow-sm) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-sm, var(--studio-shadow-sm))}:host(.studio-drawer--shadow-md) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-md, var(--studio-shadow-md))}:host(.studio-drawer--shadow-lg) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-lg, var(--studio-shadow-lg))}:host(.studio-drawer--shadow-xl) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-xl, 0 12px 32px rgba(0, 0, 0, .2))}.studio-drawer__header{flex-shrink:0;padding:var(--studio-drawer-header-padding-y, var(--studio-spacing-md)) var(--studio-drawer-header-padding-x, var(--studio-spacing-lg));border-bottom:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary))}.studio-drawer__header-content{display:flex;align-items:center;gap:var(--studio-drawer-header-gap, var(--studio-spacing-md))}.studio-drawer__title{flex:1;margin:0;font-size:var(--studio-drawer-title-font-size, 1.25rem);font-weight:var(--studio-drawer-title-font-weight, var(--studio-font-weight-semibold, 600));line-height:var(--studio-drawer-title-line-height, 1.5);color:var(--studio-drawer-title-color, var(--studio-text-primary))}.studio-drawer__close{display:flex;align-items:center;justify-content:center;width:var(--studio-drawer-close-button-size, 2.5rem);height:var(--studio-drawer-close-button-size, 2.5rem);padding:0;background:none;border:none;border-radius:var(--studio-drawer-close-button-radius, var(--studio-radius-md));color:var(--studio-drawer-close-button-color, var(--studio-text-secondary));cursor:pointer;transition:all var(--studio-transition-fast);flex-shrink:0}.studio-drawer__close:hover{background:var(--studio-drawer-close-button-hover-bg, var(--studio-bg-secondary));color:var(--studio-drawer-close-button-hover-color, var(--studio-text-primary))}.studio-drawer__close:active{transform:scale(.95)}.studio-drawer__close:focus-visible{outline:2px solid var(--studio-drawer-focus-ring-color, var(--studio-primary));outline-offset:var(--studio-drawer-focus-ring-offset, 2px)}.studio-drawer__content{flex:1;padding:var(--studio-drawer-content-padding-y, var(--studio-spacing-lg)) var(--studio-drawer-content-padding-x, var(--studio-spacing-lg));overflow-y:auto;overflow-x:hidden}.studio-drawer__footer{flex-shrink:0;padding:var(--studio-drawer-footer-padding-y, var(--studio-spacing-md)) var(--studio-drawer-footer-padding-x, var(--studio-spacing-lg));border-top:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary));display:flex;align-items:center;gap:var(--studio-drawer-footer-gap, var(--studio-spacing-sm))}:host(.studio-drawer--dragging) .studio-drawer__panel{transition:none!important}@media (max-width: 640px){:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:100vw;max-width:none}.studio-drawer__header,.studio-drawer__content,.studio-drawer__footer{padding-left:var(--studio-spacing-md);padding-right:var(--studio-spacing-md)}}\n"] }]
1620
+ }], ctorParameters: () => [], propDecorators: { headerTemplate: [{ type: i0.ContentChild, args: ['headerTemplate', { isSignal: true }] }], footerTemplate: [{ type: i0.ContentChild, args: ['footerTemplate', { isSignal: true }] }], panelEl: [{ type: i0.ViewChild, args: ['drawerPanel', { isSignal: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], positionInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], customWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "customWidth", required: false }] }], customHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "customHeight", required: false }] }], modalInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], closeOnEscapeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], closeOnBackdropClickInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdropClick", required: false }] }], blockScrollInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "blockScroll", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], showHeaderInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], showCloseButtonInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], closeButtonPositionInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeButtonPosition", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], swipeToCloseInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "swipeToClose", required: false }] }], swipeThresholdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "swipeThreshold", required: false }] }], animationDurationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationDuration", required: false }] }], animationEasingInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationEasing", required: false }] }], disableAnimationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableAnimation", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], shadowInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], shadowSizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadowSize", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledBy", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }], autoFocusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], restoreFocusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreFocus", required: false }] }], roleInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], visibleChange: [{ type: i0.Output, args: ["visibleChange"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], backdropClick: [{ type: i0.Output, args: ["backdropClick"] }], handleEscapeKey: [{
1621
+ type: HostListener,
1622
+ args: ['document:keydown.escape', ['$event']]
1623
+ }], onTouchStart: [{
1624
+ type: HostListener,
1625
+ args: ['touchstart', ['$event']]
1626
+ }], onTouchMove: [{
1627
+ type: HostListener,
1628
+ args: ['touchmove', ['$event']]
1629
+ }], onTouchEnd: [{
1630
+ type: HostListener,
1631
+ args: ['touchend', ['$event']]
1632
+ }], handleKeydown: [{
1633
+ type: HostListener,
1634
+ args: ['keydown', ['$event']]
1635
+ }] } });
1636
+
1183
1637
  /**
1184
1638
  * Input component with form control support, variants, and accessibility
1185
1639
  *
@@ -1335,6 +1789,405 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1335
1789
  }, template: "@if (label() && !floatingLabel()) {\n <label [for]=\"id() || generatedId\" class=\"studio-input__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-input__required\">*</span>\n }\n </label>\n}\n\n<div class=\"studio-input__container\">\n @if (prefixIcon()) {\n <span class=\"studio-input__prefix\">\n <studio-icon [name]=\"prefixIcon()!\" [size]=\"16\" />\n </span>\n }\n\n @if (label() && floatingLabel()) {\n <label [for]=\"id() || generatedId\" class=\"studio-input__label--floating\">\n {{ label() }}\n @if (required()) {\n <span>*</span>\n }\n </label>\n }\n\n <input\n #inputElement\n class=\"studio-input__field\"\n [type]=\"computedType()\"\n [value]=\"value()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [placeholder]=\"computedPlaceholder()\"\n [required]=\"required()\"\n [attr.maxlength]=\"maxLength()\"\n [attr.minlength]=\"minLength()\"\n [min]=\"min()\"\n [max]=\"max()\"\n [step]=\"step()\"\n [pattern]=\"pattern()\"\n [attr.inputmode]=\"inputmode()\"\n [attr.autocomplete]=\"autocomplete()\"\n [name]=\"name()\"\n [id]=\"id() || generatedId\"\n [attr.aria-label]=\"ariaLabel() || (!label() ? placeholder() : null)\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n [attr.aria-describedby]=\"ariaDescribedByValue()\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\"\n (keydown.enter)=\"handleEnter($event)\"\n />\n\n @if (loading()) {\n <span class=\"studio-input__loading\">\n <studio-icon name=\"loader-2\" [size]=\"16\" class=\"studio-icon--spin\" />\n </span>\n }\n\n @if (clearable() && value() && !disabled() && !loading()) {\n <button\n type=\"button\"\n class=\"studio-input__clear\"\n (click)=\"handleClear()\"\n [attr.aria-label]=\"'Clear input'\"\n tabindex=\"-1\"\n >\n <studio-icon name=\"x\" [size]=\"14\" />\n </button>\n }\n\n @if (type() === 'password' && showPasswordToggle() && !loading()) {\n <button\n type=\"button\"\n class=\"studio-input__toggle-password\"\n (click)=\"togglePasswordVisibility()\"\n [attr.aria-label]=\"isPasswordVisible() ? 'Hide password' : 'Show password'\"\n tabindex=\"-1\"\n >\n <studio-icon [name]=\"isPasswordVisible() ? 'eye-off' : 'eye'\" [size]=\"16\" />\n </button>\n }\n\n @if (suffixIcon() && !loading() && !clearable() && !(type() === 'password' && showPasswordToggle())) {\n <span class=\"studio-input__suffix\">\n <studio-icon [name]=\"suffixIcon()!\" [size]=\"16\" />\n </span>\n }\n </div>\n\n@if (hint() && !error()) {\n <span class=\"studio-input__hint\" [id]=\"hintId\">\n {{ hint() }}\n </span>\n}\n\n@if (error() && errorMessage()) {\n <span class=\"studio-input__error\" [id]=\"errorId\" role=\"alert\">\n <studio-icon name=\"alert-circle\" [size]=\"14\" />\n {{ errorMessage() }}\n </span>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:.375rem;font-family:var(--studio-font-family)}:host(.studio-input--full-width){width:100%}.studio-input__label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);margin-bottom:.25rem}.studio-input__label .studio-input__required{color:var(--studio-error);margin-left:.125rem}.studio-input__container{position:relative;display:flex;align-items:center;transition:all var(--studio-transition-fast)}.studio-input__field{flex:1;width:100%;font-family:inherit;font-size:1rem;color:var(--studio-text-primary);background:transparent;border:none;outline:none;transition:all var(--studio-transition-fast)}.studio-input__field::placeholder{color:var(--studio-text-tertiary)}.studio-input__field:disabled{cursor:not-allowed;opacity:.6}.studio-input__field:read-only{cursor:default}.studio-input__prefix,.studio-input__suffix{display:flex;align-items:center;justify-content:center;color:var(--studio-text-secondary);flex-shrink:0}.studio-input__clear,.studio-input__toggle-password{display:flex;align-items:center;justify-content:center;background:none;border:none;padding:.25rem;color:var(--studio-text-secondary);cursor:pointer;border-radius:var(--studio-radius-sm);transition:all var(--studio-transition-fast);flex-shrink:0}.studio-input__clear:hover,.studio-input__toggle-password:hover{color:var(--studio-text-primary);background:var(--studio-bg-secondary)}.studio-input__clear:active,.studio-input__toggle-password:active{transform:scale(.95)}.studio-input__loading{display:flex;align-items:center;color:var(--studio-primary);flex-shrink:0}.studio-input__loading .studio-icon--spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-input__hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-input__error{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--studio-error);line-height:1.4}:host(.studio-input--outline) .studio-input__container{border:1px solid var(--studio-border-primary);background:var(--studio-bg-primary);border-radius:var(--studio-radius-md)}:host(.studio-input--outline) .studio-input__container:hover:not(:has(.studio-input__field:disabled)){border-color:var(--studio-primary)}:host(.studio-input--outline.studio-input--focused) .studio-input__container{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}:host(.studio-input--outline.studio-input--error) .studio-input__container{border-color:var(--studio-error)}:host(.studio-input--outline.studio-input--error) .studio-input__container:hover{border-color:var(--studio-error)}:host(.studio-input--outline.studio-input--error.studio-input--focused) .studio-input__container{box-shadow:0 0 0 3px #ef44441a}:host(.studio-input--outline.studio-input--disabled) .studio-input__container{background:var(--studio-bg-secondary);border-color:var(--studio-border-secondary)}:host(.studio-input--filled) .studio-input__container{background:var(--studio-bg-secondary);border:none;border-bottom:2px solid var(--studio-border-primary);border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-input--filled) .studio-input__container:hover:not(:has(.studio-input__field:disabled)){background:var(--studio-bg-tertiary)}:host(.studio-input--filled.studio-input--focused) .studio-input__container{border-bottom-color:var(--studio-primary);background:var(--studio-bg-tertiary)}:host(.studio-input--filled.studio-input--error) .studio-input__container{border-bottom-color:var(--studio-error)}:host(.studio-input--filled.studio-input--disabled) .studio-input__container{background:var(--studio-bg-secondary);opacity:.6}:host(.studio-input--underline) .studio-input__container{background:transparent;border:none;border-bottom:1px solid var(--studio-border-primary);border-radius:0}:host(.studio-input--underline) .studio-input__container:hover:not(:has(.studio-input__field:disabled)){border-bottom-color:var(--studio-primary)}:host(.studio-input--underline.studio-input--focused) .studio-input__container{border-bottom:2px solid var(--studio-primary)}:host(.studio-input--underline.studio-input--error) .studio-input__container{border-bottom-color:var(--studio-error)}:host(.studio-input--underline.studio-input--disabled) .studio-input__container{border-bottom-style:dashed;opacity:.6}:host(.studio-input--sm) .studio-input__field{height:2rem;font-size:.875rem;padding:0 .75rem}:host(.studio-input--sm) .studio-input__prefix{padding-left:.75rem}:host(.studio-input--sm) .studio-input__suffix,:host(.studio-input--sm) .studio-input__clear,:host(.studio-input--sm) .studio-input__toggle-password,:host(.studio-input--sm) .studio-input__loading{padding-right:.5rem}:host(.studio-input--md) .studio-input__field{height:2.5rem;font-size:1rem;padding:0 1rem}:host(.studio-input--md) .studio-input__prefix{padding-left:1rem}:host(.studio-input--md) .studio-input__suffix,:host(.studio-input--md) .studio-input__clear,:host(.studio-input--md) .studio-input__toggle-password,:host(.studio-input--md) .studio-input__loading{padding-right:.75rem}:host(.studio-input--lg) .studio-input__field{height:3rem;font-size:1.125rem;padding:0 1.25rem}:host(.studio-input--lg) .studio-input__prefix{padding-left:1.25rem}:host(.studio-input--lg) .studio-input__suffix,:host(.studio-input--lg) .studio-input__clear,:host(.studio-input--lg) .studio-input__toggle-password,:host(.studio-input--lg) .studio-input__loading{padding-right:1rem}.studio-input__label--floating{position:absolute;top:50%;left:1rem;transform:translateY(-50%);font-size:1rem;color:var(--studio-text-tertiary);pointer-events:none;transition:all var(--studio-transition-fast);background:var(--studio-bg-primary);padding:0 .25rem}:host(.studio-input--filled) .studio-input__label--floating{background:transparent}:host(.studio-input--focused) .studio-input__label--floating,:host(.studio-input--has-value) .studio-input__label--floating{top:0;font-size:.75rem;color:var(--studio-primary)}:host(.studio-input--error) .studio-input__label--floating{color:var(--studio-error)}:host(.studio-input--radius-none) .studio-input__container{border-radius:0}:host(.studio-input--radius-sm) .studio-input__container{border-radius:var(--studio-radius-sm)}:host(.studio-input--radius-md) .studio-input__container{border-radius:var(--studio-radius-md)}:host(.studio-input--radius-lg) .studio-input__container{border-radius:var(--studio-radius-lg)}:host(.studio-input--radius-full) .studio-input__container{border-radius:9999px}:host(.studio-input--filled.studio-input--radius-none) .studio-input__container{border-radius:0}:host(.studio-input--filled.studio-input--radius-sm) .studio-input__container{border-radius:var(--studio-radius-sm) var(--studio-radius-sm) 0 0}:host(.studio-input--filled.studio-input--radius-md) .studio-input__container{border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-input--filled.studio-input--radius-lg) .studio-input__container{border-radius:var(--studio-radius-lg) var(--studio-radius-lg) 0 0}:host(.studio-input--filled.studio-input--radius-full) .studio-input__container{border-radius:9999px 9999px 0 0}\n"] }]
1336
1790
  }], ctorParameters: () => [], propDecorators: { inputEl: [{ type: i0.ViewChild, args: ['inputElement', { isSignal: true }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], inputmode: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputmode", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], floatingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatingLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], prefixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefixIcon", required: false }] }], suffixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixIcon", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], showPasswordToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPasswordToggle", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], focused: [{ type: i0.Output, args: ["focused"] }], blurred: [{ type: i0.Output, args: ["blurred"] }], cleared: [{ type: i0.Output, args: ["cleared"] }], entered: [{ type: i0.Output, args: ["entered"] }] } });
1337
1791
 
1792
+ /**
1793
+ * Menu component - Primitive component for navigation menus
1794
+ *
1795
+ * @example
1796
+ * <studio-menu
1797
+ * [items]="menuItems"
1798
+ * size="md"
1799
+ * variant="default"
1800
+ * (itemClick)="handleClick($event)"
1801
+ * />
1802
+ */
1803
+ class MenuComponent {
1804
+ router = inject(Router, { optional: true });
1805
+ platformId = inject(PLATFORM_ID);
1806
+ // ========== Основные параметры ==========
1807
+ items = input.required(...(ngDevMode ? [{ debugName: "items" }] : []));
1808
+ orientation = input('vertical', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
1809
+ // ========== Поведение ==========
1810
+ mode = input('static', ...(ngDevMode ? [{ debugName: "mode" }] : []));
1811
+ collapsible = input(true, ...(ngDevMode ? [{ debugName: "collapsible" }] : []));
1812
+ defaultExpanded = input([], ...(ngDevMode ? [{ debugName: "defaultExpanded" }] : []));
1813
+ expandOnHover = input(false, ...(ngDevMode ? [{ debugName: "expandOnHover" }] : []));
1814
+ // ========== Навигация ==========
1815
+ activeItem = input(...(ngDevMode ? [undefined, { debugName: "activeItem" }] : []));
1816
+ routerLinkActive = input(true, ...(ngDevMode ? [{ debugName: "routerLinkActive" }] : []));
1817
+ selectOnNavigate = input(true, ...(ngDevMode ? [{ debugName: "selectOnNavigate" }] : []));
1818
+ routerLinkActiveOptions = input({
1819
+ paths: 'subset',
1820
+ queryParams: 'subset',
1821
+ fragment: 'ignored',
1822
+ matrixParams: 'ignored'
1823
+ }, ...(ngDevMode ? [{ debugName: "routerLinkActiveOptions" }] : []));
1824
+ // ========== Клавиатурная навигация ==========
1825
+ keyboardNavigation = input(true, ...(ngDevMode ? [{ debugName: "keyboardNavigation" }] : []));
1826
+ arrowNavigation = input(true, ...(ngDevMode ? [{ debugName: "arrowNavigation" }] : []));
1827
+ homeEndNavigation = input(true, ...(ngDevMode ? [{ debugName: "homeEndNavigation" }] : []));
1828
+ // ========== Анимации ==========
1829
+ animated = input(true, ...(ngDevMode ? [{ debugName: "animated" }] : []));
1830
+ animationDuration = input(200, ...(ngDevMode ? [{ debugName: "animationDuration" }] : []));
1831
+ // ========== Доступность ==========
1832
+ ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : []));
1833
+ role = input('navigation', ...(ngDevMode ? [{ debugName: "role" }] : []));
1834
+ // ========== Стилевые параметры ==========
1835
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1836
+ compact = input(false, ...(ngDevMode ? [{ debugName: "compact" }] : []));
1837
+ fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
1838
+ variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
1839
+ color = input('inherit', ...(ngDevMode ? [{ debugName: "color" }] : []));
1840
+ radius = input('md', ...(ngDevMode ? [{ debugName: "radius" }] : []));
1841
+ spacing = input('sm', ...(ngDevMode ? [{ debugName: "spacing" }] : []));
1842
+ showDividers = input(false, ...(ngDevMode ? [{ debugName: "showDividers" }] : []));
1843
+ // ========== Иконки ==========
1844
+ iconSize = input(20, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
1845
+ iconOnly = input(false, ...(ngDevMode ? [{ debugName: "iconOnly" }] : []));
1846
+ // ========== Подменю ==========
1847
+ indentLevel = input(16, ...(ngDevMode ? [{ debugName: "indentLevel" }] : []));
1848
+ showExpandIcon = input(true, ...(ngDevMode ? [{ debugName: "showExpandIcon" }] : []));
1849
+ expandIconPosition = input('right', ...(ngDevMode ? [{ debugName: "expandIconPosition" }] : []));
1850
+ expandIcon = input('chevron-down', ...(ngDevMode ? [{ debugName: "expandIcon" }] : []));
1851
+ // ========== Кастомизация ==========
1852
+ class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
1853
+ itemClass = input('', ...(ngDevMode ? [{ debugName: "itemClass" }] : []));
1854
+ // ========== Internal state (for nested menus) ==========
1855
+ level = input(0, ...(ngDevMode ? [{ debugName: "level" }] : []));
1856
+ parentExpanded = input(true, ...(ngDevMode ? [{ debugName: "parentExpanded" }] : []));
1857
+ // ========== Outputs ==========
1858
+ itemClick = output();
1859
+ itemSelect = output();
1860
+ expandChange = output();
1861
+ activeChange = output();
1862
+ // ========== Signals for state management ==========
1863
+ expandedItems = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedItems" }] : []));
1864
+ activeItemId = signal(undefined, ...(ngDevMode ? [{ debugName: "activeItemId" }] : []));
1865
+ focusedIndex = signal(-1, ...(ngDevMode ? [{ debugName: "focusedIndex" }] : []));
1866
+ flattenedItems = computed(() => this.flattenMenuItems(this.items()), ...(ngDevMode ? [{ debugName: "flattenedItems" }] : []));
1867
+ // ========== Computed values ==========
1868
+ hostClasses = computed(() => {
1869
+ const classes = ['studio-menu'];
1870
+ classes.push(`studio-menu--${this.orientation()}`);
1871
+ classes.push(`studio-menu--${this.size()}`);
1872
+ classes.push(`studio-menu--${this.variant()}`);
1873
+ classes.push(`studio-menu--${this.mode()}`);
1874
+ if (this.compact())
1875
+ classes.push('studio-menu--compact');
1876
+ if (this.fullWidth())
1877
+ classes.push('studio-menu--full-width');
1878
+ if (this.iconOnly())
1879
+ classes.push('studio-menu--icon-only');
1880
+ if (this.color() !== 'inherit')
1881
+ classes.push(`studio-menu--${this.color()}`);
1882
+ if (this.class())
1883
+ classes.push(this.class());
1884
+ return classes.join(' ');
1885
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
1886
+ constructor() {
1887
+ // Initialize expanded items from defaultExpanded
1888
+ effect(() => {
1889
+ const defaultExp = this.defaultExpanded();
1890
+ if (defaultExp.length > 0) {
1891
+ this.expandedItems.set(new Set(defaultExp));
1892
+ }
1893
+ });
1894
+ // Track active item
1895
+ effect(() => {
1896
+ const active = this.activeItem();
1897
+ if (active) {
1898
+ this.activeItemId.set(active);
1899
+ }
1900
+ });
1901
+ }
1902
+ ngOnInit() {
1903
+ if (this.routerLinkActive() && this.router && isPlatformBrowser(this.platformId)) {
1904
+ this.updateActiveFromRouter();
1905
+ }
1906
+ }
1907
+ // ========== Item state methods ==========
1908
+ isExpanded(item) {
1909
+ if (!item.id)
1910
+ return false;
1911
+ return this.expandedItems().has(item.id);
1912
+ }
1913
+ isActive(item) {
1914
+ // Check explicit active item
1915
+ if (item.id && item.id === this.activeItemId()) {
1916
+ return true;
1917
+ }
1918
+ // Router-based active state is handled by RouterLinkActive directive
1919
+ return false;
1920
+ }
1921
+ isDisabled(item) {
1922
+ return item.disabled === true;
1923
+ }
1924
+ isVisible(item) {
1925
+ return item.visible !== false;
1926
+ }
1927
+ hasChildren(item) {
1928
+ return !!(item.items && item.items.length > 0);
1929
+ }
1930
+ getItemId(item, index) {
1931
+ return item.id || `menu-item-${this.level()}-${index}`;
1932
+ }
1933
+ // ========== Interaction methods ==========
1934
+ handleItemClick(event, item) {
1935
+ if (this.isDisabled(item) || item.separator) {
1936
+ event.preventDefault();
1937
+ event.stopPropagation();
1938
+ return;
1939
+ }
1940
+ // Emit click event
1941
+ this.itemClick.emit({ originalEvent: event, item });
1942
+ // Execute command if provided
1943
+ if (item.command) {
1944
+ item.command({ originalEvent: event, item });
1945
+ }
1946
+ // Handle expansion for items with children
1947
+ if (this.hasChildren(item) && this.collapsible()) {
1948
+ event.preventDefault();
1949
+ this.toggleExpand(item);
1950
+ }
1951
+ // Handle selection
1952
+ if (this.selectOnNavigate() && item.id) {
1953
+ this.activeItemId.set(item.id);
1954
+ this.itemSelect.emit(item);
1955
+ this.activeChange.emit(item.id);
1956
+ }
1957
+ // Navigation is handled by RouterLink directive if routerLink is set
1958
+ }
1959
+ handleItemMouseEnter(item) {
1960
+ if (this.expandOnHover() && this.hasChildren(item) && !this.isDisabled(item)) {
1961
+ this.expand(item);
1962
+ }
1963
+ }
1964
+ handleItemMouseLeave(item) {
1965
+ if (this.expandOnHover() && this.hasChildren(item)) {
1966
+ this.collapse(item);
1967
+ }
1968
+ }
1969
+ toggleExpand(item) {
1970
+ if (!item.id)
1971
+ return;
1972
+ const expanded = this.expandedItems();
1973
+ const newExpanded = new Set(expanded);
1974
+ if (newExpanded.has(item.id)) {
1975
+ newExpanded.delete(item.id);
1976
+ this.expandChange.emit({ itemId: item.id, expanded: false });
1977
+ }
1978
+ else {
1979
+ // In accordion mode, collapse others at the same level
1980
+ if (this.mode() === 'accordion') {
1981
+ this.items().forEach(i => {
1982
+ if (i.id && i.id !== item.id) {
1983
+ newExpanded.delete(i.id);
1984
+ }
1985
+ });
1986
+ }
1987
+ newExpanded.add(item.id);
1988
+ this.expandChange.emit({ itemId: item.id, expanded: true });
1989
+ }
1990
+ this.expandedItems.set(newExpanded);
1991
+ }
1992
+ expand(item) {
1993
+ if (!item.id || this.isExpanded(item))
1994
+ return;
1995
+ const newExpanded = new Set(this.expandedItems());
1996
+ newExpanded.add(item.id);
1997
+ this.expandedItems.set(newExpanded);
1998
+ this.expandChange.emit({ itemId: item.id, expanded: true });
1999
+ }
2000
+ collapse(item) {
2001
+ if (!item.id || !this.isExpanded(item))
2002
+ return;
2003
+ const newExpanded = new Set(this.expandedItems());
2004
+ newExpanded.delete(item.id);
2005
+ this.expandedItems.set(newExpanded);
2006
+ this.expandChange.emit({ itemId: item.id, expanded: false });
2007
+ }
2008
+ // ========== Keyboard navigation ==========
2009
+ handleKeyDown(event) {
2010
+ if (!this.keyboardNavigation())
2011
+ return;
2012
+ const items = this.flattenedItems();
2013
+ const currentIndex = this.focusedIndex();
2014
+ switch (event.key) {
2015
+ case 'ArrowDown':
2016
+ if (this.arrowNavigation() && this.orientation() === 'vertical') {
2017
+ event.preventDefault();
2018
+ this.focusNextItem(items, currentIndex);
2019
+ }
2020
+ break;
2021
+ case 'ArrowUp':
2022
+ if (this.arrowNavigation() && this.orientation() === 'vertical') {
2023
+ event.preventDefault();
2024
+ this.focusPreviousItem(items, currentIndex);
2025
+ }
2026
+ break;
2027
+ case 'ArrowRight':
2028
+ if (this.arrowNavigation()) {
2029
+ event.preventDefault();
2030
+ if (this.orientation() === 'horizontal') {
2031
+ this.focusNextItem(items, currentIndex);
2032
+ }
2033
+ else {
2034
+ this.expandFocusedItem(items, currentIndex);
2035
+ }
2036
+ }
2037
+ break;
2038
+ case 'ArrowLeft':
2039
+ if (this.arrowNavigation()) {
2040
+ event.preventDefault();
2041
+ if (this.orientation() === 'horizontal') {
2042
+ this.focusPreviousItem(items, currentIndex);
2043
+ }
2044
+ else {
2045
+ this.collapseFocusedItem(items, currentIndex);
2046
+ }
2047
+ }
2048
+ break;
2049
+ case 'Home':
2050
+ if (this.homeEndNavigation()) {
2051
+ event.preventDefault();
2052
+ this.focusedIndex.set(0);
2053
+ }
2054
+ break;
2055
+ case 'End':
2056
+ if (this.homeEndNavigation()) {
2057
+ event.preventDefault();
2058
+ this.focusedIndex.set(items.length - 1);
2059
+ }
2060
+ break;
2061
+ case 'Enter':
2062
+ case ' ':
2063
+ event.preventDefault();
2064
+ this.activateFocusedItem(items, currentIndex);
2065
+ break;
2066
+ case 'Escape':
2067
+ event.preventDefault();
2068
+ this.collapseAll();
2069
+ break;
2070
+ }
2071
+ }
2072
+ focusNextItem(items, currentIndex) {
2073
+ const nextIndex = (currentIndex + 1) % items.length;
2074
+ this.focusedIndex.set(nextIndex);
2075
+ }
2076
+ focusPreviousItem(items, currentIndex) {
2077
+ const prevIndex = currentIndex <= 0 ? items.length - 1 : currentIndex - 1;
2078
+ this.focusedIndex.set(prevIndex);
2079
+ }
2080
+ expandFocusedItem(items, currentIndex) {
2081
+ if (currentIndex >= 0 && currentIndex < items.length) {
2082
+ const item = items[currentIndex];
2083
+ if (this.hasChildren(item)) {
2084
+ this.expand(item);
2085
+ }
2086
+ }
2087
+ }
2088
+ collapseFocusedItem(items, currentIndex) {
2089
+ if (currentIndex >= 0 && currentIndex < items.length) {
2090
+ const item = items[currentIndex];
2091
+ if (this.hasChildren(item) && this.isExpanded(item)) {
2092
+ this.collapse(item);
2093
+ }
2094
+ }
2095
+ }
2096
+ activateFocusedItem(items, currentIndex) {
2097
+ if (currentIndex >= 0 && currentIndex < items.length) {
2098
+ const item = items[currentIndex];
2099
+ const fakeEvent = new Event('click');
2100
+ this.handleItemClick(fakeEvent, item);
2101
+ }
2102
+ }
2103
+ collapseAll() {
2104
+ this.expandedItems.set(new Set());
2105
+ }
2106
+ // ========== Helper methods ==========
2107
+ flattenMenuItems(items) {
2108
+ const result = [];
2109
+ const flatten = (itemList) => {
2110
+ itemList.forEach(item => {
2111
+ if (this.isVisible(item) && !item.separator) {
2112
+ result.push(item);
2113
+ if (item.items && this.isExpanded(item)) {
2114
+ flatten(item.items);
2115
+ }
2116
+ }
2117
+ });
2118
+ };
2119
+ flatten(items);
2120
+ return result;
2121
+ }
2122
+ updateActiveFromRouter() {
2123
+ if (!this.router)
2124
+ return;
2125
+ // This would require checking current route against menu items
2126
+ // Implementation depends on routing setup
2127
+ // For now, RouterLinkActive directive handles this
2128
+ }
2129
+ getIndentStyle(itemLevel = 0) {
2130
+ const indent = this.level() + itemLevel;
2131
+ if (indent === 0)
2132
+ return {};
2133
+ return {
2134
+ 'padding-left': `calc(var(--menu-padding) + ${indent * this.indentLevel()}px)`
2135
+ };
2136
+ }
2137
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2138
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: MenuComponent, isStandalone: true, selector: "studio-menu", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, defaultExpanded: { classPropertyName: "defaultExpanded", publicName: "defaultExpanded", isSignal: true, isRequired: false, transformFunction: null }, expandOnHover: { classPropertyName: "expandOnHover", publicName: "expandOnHover", isSignal: true, isRequired: false, transformFunction: null }, activeItem: { classPropertyName: "activeItem", publicName: "activeItem", isSignal: true, isRequired: false, transformFunction: null }, routerLinkActive: { classPropertyName: "routerLinkActive", publicName: "routerLinkActive", isSignal: true, isRequired: false, transformFunction: null }, selectOnNavigate: { classPropertyName: "selectOnNavigate", publicName: "selectOnNavigate", isSignal: true, isRequired: false, transformFunction: null }, routerLinkActiveOptions: { classPropertyName: "routerLinkActiveOptions", publicName: "routerLinkActiveOptions", isSignal: true, isRequired: false, transformFunction: null }, keyboardNavigation: { classPropertyName: "keyboardNavigation", publicName: "keyboardNavigation", isSignal: true, isRequired: false, transformFunction: null }, arrowNavigation: { classPropertyName: "arrowNavigation", publicName: "arrowNavigation", isSignal: true, isRequired: false, transformFunction: null }, homeEndNavigation: { classPropertyName: "homeEndNavigation", publicName: "homeEndNavigation", isSignal: true, isRequired: false, transformFunction: null }, animated: { classPropertyName: "animated", publicName: "animated", isSignal: true, isRequired: false, transformFunction: null }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, spacing: { classPropertyName: "spacing", publicName: "spacing", isSignal: true, isRequired: false, transformFunction: null }, showDividers: { classPropertyName: "showDividers", publicName: "showDividers", isSignal: true, isRequired: false, transformFunction: null }, iconSize: { classPropertyName: "iconSize", publicName: "iconSize", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null }, indentLevel: { classPropertyName: "indentLevel", publicName: "indentLevel", isSignal: true, isRequired: false, transformFunction: null }, showExpandIcon: { classPropertyName: "showExpandIcon", publicName: "showExpandIcon", isSignal: true, isRequired: false, transformFunction: null }, expandIconPosition: { classPropertyName: "expandIconPosition", publicName: "expandIconPosition", isSignal: true, isRequired: false, transformFunction: null }, expandIcon: { classPropertyName: "expandIcon", publicName: "expandIcon", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, itemClass: { classPropertyName: "itemClass", publicName: "itemClass", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, parentExpanded: { classPropertyName: "parentExpanded", publicName: "parentExpanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick", itemSelect: "itemSelect", expandChange: "expandChange", activeChange: "activeChange" }, host: { listeners: { "keydown": "handleKeyDown($event)" }, properties: { "class": "hostClasses()", "attr.role": "role()", "attr.aria-label": "ariaLabel()", "attr.aria-orientation": "orientation()" } }, ngImport: i0, template: "<div class=\"studio-menu__list\">\n @for (item of items(); track getItemId(item, $index)) {\n @if (isVisible(item)) {\n @if (item.separator) {\n <!-- Separator -->\n <div class=\"studio-menu__separator\"></div>\n } @else {\n <!-- Menu Item -->\n <div\n class=\"studio-menu-item\"\n [class.studio-menu-item--disabled]=\"isDisabled(item)\"\n [class.studio-menu-item--active]=\"isActive(item)\"\n [class.studio-menu-item--has-children]=\"hasChildren(item)\"\n [class.studio-menu-item--expanded]=\"isExpanded(item)\"\n [class]=\"itemClass() + ' ' + (item.class || '')\"\n [style]=\"getIndentStyle()\"\n [attr.role]=\"role() === 'menu' ? 'menuitem' : undefined\"\n [attr.aria-disabled]=\"isDisabled(item)\"\n [attr.aria-expanded]=\"hasChildren(item) ? isExpanded(item) : undefined\"\n [attr.title]=\"item.tooltip\"\n (click)=\"handleItemClick($event, item)\"\n (mouseenter)=\"handleItemMouseEnter(item)\"\n (mouseleave)=\"handleItemMouseLeave(item)\"\n >\n <!-- Router Link -->\n @if (item.routerLink && !isDisabled(item)) {\n <a\n class=\"studio-menu-item__link\"\n [routerLink]=\"item.routerLink\"\n [queryParams]=\"item.queryParams\"\n [fragment]=\"item.fragment\"\n [target]=\"item.target\"\n routerLinkActive=\"studio-menu-item__link--active\"\n [attr.aria-current]=\"isActive(item) ? 'page' : undefined\"\n >\n <ng-container *ngTemplateOutlet=\"itemContent; context: { $implicit: item }\" />\n </a>\n }\n <!-- External Link -->\n @else if (item.href && !isDisabled(item)) {\n <a\n class=\"studio-menu-item__link\"\n [href]=\"item.href\"\n [target]=\"item.target\"\n >\n <ng-container *ngTemplateOutlet=\"itemContent; context: { $implicit: item }\" />\n </a>\n }\n <!-- Button (no navigation) -->\n @else {\n <div class=\"studio-menu-item__content\">\n <ng-container *ngTemplateOutlet=\"itemContent; context: { $implicit: item }\" />\n </div>\n }\n </div>\n\n <!-- Submenu (recursive) -->\n @if (hasChildren(item) && isExpanded(item)) {\n <div\n class=\"studio-menu__submenu\"\n [@expandCollapse]=\"animated() ? 'expanded' : undefined\"\n >\n <studio-menu\n [items]=\"item.items!\"\n [orientation]=\"orientation()\"\n [mode]=\"mode()\"\n [collapsible]=\"collapsible()\"\n [expandOnHover]=\"expandOnHover()\"\n [selectOnNavigate]=\"selectOnNavigate()\"\n [keyboardNavigation]=\"keyboardNavigation()\"\n [arrowNavigation]=\"arrowNavigation()\"\n [homeEndNavigation]=\"homeEndNavigation()\"\n [animated]=\"animated()\"\n [animationDuration]=\"animationDuration()\"\n [size]=\"size()\"\n [compact]=\"compact()\"\n [fullWidth]=\"fullWidth()\"\n [variant]=\"variant()\"\n [color]=\"color()\"\n [radius]=\"radius()\"\n [spacing]=\"spacing()\"\n [showDividers]=\"showDividers()\"\n [iconSize]=\"iconSize()\"\n [iconOnly]=\"iconOnly()\"\n [indentLevel]=\"indentLevel()\"\n [showExpandIcon]=\"showExpandIcon()\"\n [expandIconPosition]=\"expandIconPosition()\"\n [expandIcon]=\"expandIcon()\"\n [itemClass]=\"itemClass()\"\n [level]=\"level() + 1\"\n [parentExpanded]=\"isExpanded(item)\"\n (itemClick)=\"itemClick.emit($event)\"\n (itemSelect)=\"itemSelect.emit($event)\"\n (expandChange)=\"expandChange.emit($event)\"\n (activeChange)=\"activeChange.emit($event)\"\n />\n </div>\n }\n\n <!-- Divider (if enabled) -->\n @if (showDividers() && $index < items().length - 1) {\n <div class=\"studio-menu__divider\"></div>\n }\n }\n }\n }\n</div>\n\n<!-- Item Content Template -->\n<ng-template #itemContent let-item>\n <div class=\"studio-menu-item__inner\">\n <!-- Left Icon -->\n @if (item.icon && (!item.iconPosition || item.iconPosition === 'left')) {\n <studio-icon\n class=\"studio-menu-item__icon studio-menu-item__icon--left\"\n [name]=\"item.icon\"\n [size]=\"iconSize()\"\n />\n }\n\n <!-- Label -->\n @if (!iconOnly()) {\n <span class=\"studio-menu-item__label\">{{ item.label }}</span>\n }\n\n <!-- Badge -->\n @if (item.badge && !iconOnly()) {\n <studio-badge\n class=\"studio-menu-item__badge\"\n [value]=\"item.badge\"\n [color]=\"item.badgeColor || 'primary'\"\n size=\"sm\"\n />\n }\n\n <!-- Right Icon -->\n @if (item.icon && item.iconPosition === 'right') {\n <studio-icon\n class=\"studio-menu-item__icon studio-menu-item__icon--right\"\n [name]=\"item.icon\"\n [size]=\"iconSize()\"\n />\n }\n\n <!-- Expand Icon -->\n @if (hasChildren(item) && showExpandIcon() && !iconOnly()) {\n <studio-icon\n class=\"studio-menu-item__expand-icon\"\n [class.studio-menu-item__expand-icon--expanded]=\"isExpanded(item)\"\n [name]=\"expandIcon()\"\n [size]=\"16\"\n />\n }\n </div>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;width:100%;--menu-padding-y: .5rem;--menu-padding-x: .75rem;--menu-font-size: .875rem;--menu-line-height: 1.25rem;--menu-gap: .25rem;--menu-indent: 1rem;--menu-transition: all .2s cubic-bezier(.4, 0, .2, 1);--menu-item-height: auto;--menu-item-min-height: 2.5rem;--menu-border-radius: .375rem;--menu-icon-size: 1rem}:host(.studio-menu--horizontal){flex-direction:row;overflow-x:auto}:host(.studio-menu--horizontal) .studio-menu__list{flex-direction:row;flex-wrap:nowrap}:host(.studio-menu--sm){--menu-padding-y: .375rem;--menu-padding-x: .625rem;--menu-font-size: .8125rem;--menu-line-height: 1.125rem;--menu-gap: .125rem;--menu-item-min-height: 2rem;--menu-border-radius: .25rem;--menu-icon-size: .875rem}:host(.studio-menu--md){--menu-padding-y: .5rem;--menu-padding-x: .75rem;--menu-font-size: .875rem;--menu-line-height: 1.25rem;--menu-gap: .25rem;--menu-item-min-height: 2.5rem;--menu-border-radius: .375rem;--menu-icon-size: 1rem}:host(.studio-menu--lg){--menu-padding-y: .625rem;--menu-padding-x: 1rem;--menu-font-size: .9375rem;--menu-line-height: 1.375rem;--menu-gap: .375rem;--menu-item-min-height: 3rem;--menu-border-radius: .5rem;--menu-icon-size: 1.125rem}:host(.studio-menu--compact){--menu-padding-y: .25rem;--menu-gap: .0625rem}:host(.studio-menu--full-width){width:100%}:host(.studio-menu--full-width) .studio-menu-item{width:100%}:host(.studio-menu--icon-only) .studio-menu-item__label,:host(.studio-menu--icon-only) .studio-menu-item__badge,:host(.studio-menu--icon-only) .studio-menu-item__expand-icon{display:none}:host(.studio-menu--icon-only) .studio-menu-item{justify-content:center;padding:var(--menu-padding-y)}:host(.studio-menu--filled){padding:.5rem;background:var(--studio-bg-secondary);border-radius:calc(var(--menu-border-radius) + .25rem);box-shadow:0 1px 2px #0000000d}:host(.studio-menu--outlined){padding:.5rem;border:1px solid var(--studio-border-primary);border-radius:calc(var(--menu-border-radius) + .25rem);background:var(--studio-bg-primary)}:host(.studio-menu--ghost){padding:0}:host(.studio-menu--primary) .studio-menu-item--active{background:hsl(var(--studio-primary-hsl)/.1);color:var(--studio-primary);font-weight:500}:host(.studio-menu--secondary) .studio-menu-item--active{background:hsl(var(--studio-secondary-hsl)/.1);color:var(--studio-secondary);font-weight:500}:host(.studio-menu--radius-none){--menu-border-radius: 0}:host(.studio-menu--radius-none.studio-menu--filled),:host(.studio-menu--radius-none.studio-menu--outlined){border-radius:0}:host(.studio-menu--radius-sm){--menu-border-radius: .25rem}:host(.studio-menu--radius-sm.studio-menu--filled),:host(.studio-menu--radius-sm.studio-menu--outlined){border-radius:.5rem}:host(.studio-menu--radius-md){--menu-border-radius: .375rem}:host(.studio-menu--radius-md.studio-menu--filled),:host(.studio-menu--radius-md.studio-menu--outlined){border-radius:.625rem}:host(.studio-menu--radius-lg){--menu-border-radius: .5rem}:host(.studio-menu--radius-lg.studio-menu--filled),:host(.studio-menu--radius-lg.studio-menu--outlined){border-radius:.75rem}:host(.studio-menu--spacing-none){--menu-gap: 0}:host(.studio-menu--spacing-sm){--menu-gap: .125rem}:host(.studio-menu--spacing-md){--menu-gap: .25rem}:host(.studio-menu--spacing-lg){--menu-gap: .5rem}.studio-menu__list{display:flex;flex-direction:column;gap:var(--menu-gap);list-style:none;margin:0;padding:0}.studio-menu-item{position:relative;display:flex;align-items:center;width:100%;min-height:var(--menu-item-min-height);padding:0;border:none;background:transparent;color:var(--studio-text-primary);font-size:var(--menu-font-size);line-height:var(--menu-line-height);font-family:inherit;font-weight:400;text-align:left;cursor:pointer;transition:var(--menu-transition);border-radius:var(--menu-border-radius);outline:none;-webkit-user-select:none;user-select:none}.studio-menu-item:hover:not(.studio-menu-item--disabled):not(.studio-menu-item--active){background:hsl(var(--studio-primary-hsl)/.04);color:var(--studio-text-primary)}.studio-menu-item--active{background:hsl(var(--studio-primary-hsl)/.1);color:var(--studio-text-primary);font-weight:500}.studio-menu-item--active .studio-menu-item__icon{color:var(--studio-text-primary)}.studio-menu-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.studio-menu-item--has-children .studio-menu-item__expand-icon{transition:transform .2s cubic-bezier(.4,0,.2,1)}.studio-menu-item--expanded .studio-menu-item__expand-icon{transform:rotate(180deg)}.studio-menu-item:focus-visible{outline:2px solid var(--studio-primary);outline-offset:-1px;z-index:1}:host(.studio-menu--filled) .studio-menu-item:hover:not(.studio-menu-item--disabled):not(.studio-menu-item--active){background:var(--studio-bg-hover)}:host(.studio-menu--filled) .studio-menu-item.studio-menu-item--active{background:var(--studio-bg-primary);box-shadow:0 1px 2px #0000000d}:host(.studio-menu--outlined) .studio-menu-item{border:1px solid transparent}:host(.studio-menu--outlined) .studio-menu-item:hover:not(.studio-menu-item--disabled):not(.studio-menu-item--active){border-color:var(--studio-border-secondary);background:var(--studio-bg-secondary)}:host(.studio-menu--outlined) .studio-menu-item.studio-menu-item--active{border-color:var(--studio-primary);background:hsl(var(--studio-primary-hsl)/.05)}:host(.studio-menu--ghost) .studio-menu-item:hover:not(.studio-menu-item--disabled):not(.studio-menu-item--active){background:transparent;color:var(--studio-primary)}:host(.studio-menu--ghost) .studio-menu-item.studio-menu-item--active{background:transparent;color:var(--studio-primary);text-decoration:underline;text-underline-offset:4px}.studio-menu-item__link,.studio-menu-item__content{display:flex;align-items:center;width:100%;padding:var(--menu-padding-y) var(--menu-padding-x);color:inherit;text-decoration:none;gap:.5rem}.studio-menu-item__link:visited{color:inherit}.studio-menu-item__link:hover{text-decoration:none}.studio-menu-item__inner{display:flex;align-items:center;gap:.5rem;width:100%}.studio-menu-item__icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:var(--menu-icon-size);height:var(--menu-icon-size);color:var(--studio-text-secondary);transition:var(--menu-transition)}.studio-menu-item__icon--left{order:-1}.studio-menu-item__icon--right{order:1;margin-left:auto}.studio-menu-item:hover .studio-menu-item__icon,.studio-menu-item--active .studio-menu-item__icon{color:var(--studio-text-primary)}.studio-menu-item__label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--menu-font-size);line-height:var(--menu-line-height)}.studio-menu-item__badge{flex-shrink:0;margin-left:auto}.studio-menu-item__expand-icon{flex-shrink:0;margin-left:auto;width:1rem;height:1rem;color:var(--studio-text-secondary);opacity:.7;transition:transform .2s cubic-bezier(.4,0,.2,1),opacity var(--menu-transition)}.studio-menu-item:hover .studio-menu-item__expand-icon{opacity:1}.studio-menu__submenu{overflow:hidden;margin-top:var(--menu-gap);margin-left:calc(var(--menu-indent) - .25rem)}.studio-menu__submenu studio-menu{padding-left:0}.studio-menu__submenu .studio-menu__list{padding-left:.75rem;border-left:1px solid var(--studio-border-secondary);margin-left:.75rem}.studio-menu__separator{height:1px;margin:.375rem 0;background:var(--studio-border-secondary);opacity:.6}.studio-menu__divider{height:1px;margin:.125rem 0;background:var(--studio-border-secondary);opacity:.4}@keyframes expandCollapse{0%{opacity:0;max-height:0;transform:translateY(-4px)}to{opacity:1;max-height:1000px;transform:translateY(0)}}@media (max-width: 768px){:host(.studio-menu--horizontal){flex-direction:column}:host(.studio-menu--horizontal) .studio-menu__list{flex-direction:column}}\n"], dependencies: [{ kind: "component", type: MenuComponent, selector: "studio-menu", inputs: ["items", "orientation", "mode", "collapsible", "defaultExpanded", "expandOnHover", "activeItem", "routerLinkActive", "selectOnNavigate", "routerLinkActiveOptions", "keyboardNavigation", "arrowNavigation", "homeEndNavigation", "animated", "animationDuration", "ariaLabel", "role", "size", "compact", "fullWidth", "variant", "color", "radius", "spacing", "showDividers", "iconSize", "iconOnly", "indentLevel", "showExpandIcon", "expandIconPosition", "expandIcon", "class", "itemClass", "level", "parentExpanded"], outputs: ["itemClick", "itemSelect", "expandChange", "activeChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }, { kind: "component", type: BadgeComponent, selector: "studio-badge", inputs: ["variant", "size", "color", "radius", "icon", "iconPosition", "dot", "dotColor", "removable", "href", "target", "disabled", "value", "max", "showZero", "uppercase", "bold", "pulse", "autoColor"], outputs: ["removed", "clicked"] }], animations: [
2139
+ trigger('expandCollapse', [
2140
+ state('collapsed', style({
2141
+ height: '0',
2142
+ opacity: '0',
2143
+ overflow: 'hidden'
2144
+ })),
2145
+ state('expanded', style({
2146
+ height: '*',
2147
+ opacity: '1',
2148
+ overflow: 'visible'
2149
+ })),
2150
+ transition('collapsed <=> expanded', [
2151
+ animate('200ms ease-in-out')
2152
+ ])
2153
+ ])
2154
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2155
+ }
2156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: MenuComponent, decorators: [{
2157
+ type: Component,
2158
+ args: [{ selector: 'studio-menu', standalone: true, imports: [
2159
+ CommonModule,
2160
+ RouterLink,
2161
+ RouterLinkActive,
2162
+ IconComponent,
2163
+ BadgeComponent
2164
+ ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
2165
+ '[class]': 'hostClasses()',
2166
+ '[attr.role]': 'role()',
2167
+ '[attr.aria-label]': 'ariaLabel()',
2168
+ '[attr.aria-orientation]': 'orientation()'
2169
+ }, animations: [
2170
+ trigger('expandCollapse', [
2171
+ state('collapsed', style({
2172
+ height: '0',
2173
+ opacity: '0',
2174
+ overflow: 'hidden'
2175
+ })),
2176
+ state('expanded', style({
2177
+ height: '*',
2178
+ opacity: '1',
2179
+ overflow: 'visible'
2180
+ })),
2181
+ transition('collapsed <=> expanded', [
2182
+ animate('200ms ease-in-out')
2183
+ ])
2184
+ ])
2185
+ ], template: "<div class=\"studio-menu__list\">\n @for (item of items(); track getItemId(item, $index)) {\n @if (isVisible(item)) {\n @if (item.separator) {\n <!-- Separator -->\n <div class=\"studio-menu__separator\"></div>\n } @else {\n <!-- Menu Item -->\n <div\n class=\"studio-menu-item\"\n [class.studio-menu-item--disabled]=\"isDisabled(item)\"\n [class.studio-menu-item--active]=\"isActive(item)\"\n [class.studio-menu-item--has-children]=\"hasChildren(item)\"\n [class.studio-menu-item--expanded]=\"isExpanded(item)\"\n [class]=\"itemClass() + ' ' + (item.class || '')\"\n [style]=\"getIndentStyle()\"\n [attr.role]=\"role() === 'menu' ? 'menuitem' : undefined\"\n [attr.aria-disabled]=\"isDisabled(item)\"\n [attr.aria-expanded]=\"hasChildren(item) ? isExpanded(item) : undefined\"\n [attr.title]=\"item.tooltip\"\n (click)=\"handleItemClick($event, item)\"\n (mouseenter)=\"handleItemMouseEnter(item)\"\n (mouseleave)=\"handleItemMouseLeave(item)\"\n >\n <!-- Router Link -->\n @if (item.routerLink && !isDisabled(item)) {\n <a\n class=\"studio-menu-item__link\"\n [routerLink]=\"item.routerLink\"\n [queryParams]=\"item.queryParams\"\n [fragment]=\"item.fragment\"\n [target]=\"item.target\"\n routerLinkActive=\"studio-menu-item__link--active\"\n [attr.aria-current]=\"isActive(item) ? 'page' : undefined\"\n >\n <ng-container *ngTemplateOutlet=\"itemContent; context: { $implicit: item }\" />\n </a>\n }\n <!-- External Link -->\n @else if (item.href && !isDisabled(item)) {\n <a\n class=\"studio-menu-item__link\"\n [href]=\"item.href\"\n [target]=\"item.target\"\n >\n <ng-container *ngTemplateOutlet=\"itemContent; context: { $implicit: item }\" />\n </a>\n }\n <!-- Button (no navigation) -->\n @else {\n <div class=\"studio-menu-item__content\">\n <ng-container *ngTemplateOutlet=\"itemContent; context: { $implicit: item }\" />\n </div>\n }\n </div>\n\n <!-- Submenu (recursive) -->\n @if (hasChildren(item) && isExpanded(item)) {\n <div\n class=\"studio-menu__submenu\"\n [@expandCollapse]=\"animated() ? 'expanded' : undefined\"\n >\n <studio-menu\n [items]=\"item.items!\"\n [orientation]=\"orientation()\"\n [mode]=\"mode()\"\n [collapsible]=\"collapsible()\"\n [expandOnHover]=\"expandOnHover()\"\n [selectOnNavigate]=\"selectOnNavigate()\"\n [keyboardNavigation]=\"keyboardNavigation()\"\n [arrowNavigation]=\"arrowNavigation()\"\n [homeEndNavigation]=\"homeEndNavigation()\"\n [animated]=\"animated()\"\n [animationDuration]=\"animationDuration()\"\n [size]=\"size()\"\n [compact]=\"compact()\"\n [fullWidth]=\"fullWidth()\"\n [variant]=\"variant()\"\n [color]=\"color()\"\n [radius]=\"radius()\"\n [spacing]=\"spacing()\"\n [showDividers]=\"showDividers()\"\n [iconSize]=\"iconSize()\"\n [iconOnly]=\"iconOnly()\"\n [indentLevel]=\"indentLevel()\"\n [showExpandIcon]=\"showExpandIcon()\"\n [expandIconPosition]=\"expandIconPosition()\"\n [expandIcon]=\"expandIcon()\"\n [itemClass]=\"itemClass()\"\n [level]=\"level() + 1\"\n [parentExpanded]=\"isExpanded(item)\"\n (itemClick)=\"itemClick.emit($event)\"\n (itemSelect)=\"itemSelect.emit($event)\"\n (expandChange)=\"expandChange.emit($event)\"\n (activeChange)=\"activeChange.emit($event)\"\n />\n </div>\n }\n\n <!-- Divider (if enabled) -->\n @if (showDividers() && $index < items().length - 1) {\n <div class=\"studio-menu__divider\"></div>\n }\n }\n }\n }\n</div>\n\n<!-- Item Content Template -->\n<ng-template #itemContent let-item>\n <div class=\"studio-menu-item__inner\">\n <!-- Left Icon -->\n @if (item.icon && (!item.iconPosition || item.iconPosition === 'left')) {\n <studio-icon\n class=\"studio-menu-item__icon studio-menu-item__icon--left\"\n [name]=\"item.icon\"\n [size]=\"iconSize()\"\n />\n }\n\n <!-- Label -->\n @if (!iconOnly()) {\n <span class=\"studio-menu-item__label\">{{ item.label }}</span>\n }\n\n <!-- Badge -->\n @if (item.badge && !iconOnly()) {\n <studio-badge\n class=\"studio-menu-item__badge\"\n [value]=\"item.badge\"\n [color]=\"item.badgeColor || 'primary'\"\n size=\"sm\"\n />\n }\n\n <!-- Right Icon -->\n @if (item.icon && item.iconPosition === 'right') {\n <studio-icon\n class=\"studio-menu-item__icon studio-menu-item__icon--right\"\n [name]=\"item.icon\"\n [size]=\"iconSize()\"\n />\n }\n\n <!-- Expand Icon -->\n @if (hasChildren(item) && showExpandIcon() && !iconOnly()) {\n <studio-icon\n class=\"studio-menu-item__expand-icon\"\n [class.studio-menu-item__expand-icon--expanded]=\"isExpanded(item)\"\n [name]=\"expandIcon()\"\n [size]=\"16\"\n />\n }\n </div>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;width:100%;--menu-padding-y: .5rem;--menu-padding-x: .75rem;--menu-font-size: .875rem;--menu-line-height: 1.25rem;--menu-gap: .25rem;--menu-indent: 1rem;--menu-transition: all .2s cubic-bezier(.4, 0, .2, 1);--menu-item-height: auto;--menu-item-min-height: 2.5rem;--menu-border-radius: .375rem;--menu-icon-size: 1rem}:host(.studio-menu--horizontal){flex-direction:row;overflow-x:auto}:host(.studio-menu--horizontal) .studio-menu__list{flex-direction:row;flex-wrap:nowrap}:host(.studio-menu--sm){--menu-padding-y: .375rem;--menu-padding-x: .625rem;--menu-font-size: .8125rem;--menu-line-height: 1.125rem;--menu-gap: .125rem;--menu-item-min-height: 2rem;--menu-border-radius: .25rem;--menu-icon-size: .875rem}:host(.studio-menu--md){--menu-padding-y: .5rem;--menu-padding-x: .75rem;--menu-font-size: .875rem;--menu-line-height: 1.25rem;--menu-gap: .25rem;--menu-item-min-height: 2.5rem;--menu-border-radius: .375rem;--menu-icon-size: 1rem}:host(.studio-menu--lg){--menu-padding-y: .625rem;--menu-padding-x: 1rem;--menu-font-size: .9375rem;--menu-line-height: 1.375rem;--menu-gap: .375rem;--menu-item-min-height: 3rem;--menu-border-radius: .5rem;--menu-icon-size: 1.125rem}:host(.studio-menu--compact){--menu-padding-y: .25rem;--menu-gap: .0625rem}:host(.studio-menu--full-width){width:100%}:host(.studio-menu--full-width) .studio-menu-item{width:100%}:host(.studio-menu--icon-only) .studio-menu-item__label,:host(.studio-menu--icon-only) .studio-menu-item__badge,:host(.studio-menu--icon-only) .studio-menu-item__expand-icon{display:none}:host(.studio-menu--icon-only) .studio-menu-item{justify-content:center;padding:var(--menu-padding-y)}:host(.studio-menu--filled){padding:.5rem;background:var(--studio-bg-secondary);border-radius:calc(var(--menu-border-radius) + .25rem);box-shadow:0 1px 2px #0000000d}:host(.studio-menu--outlined){padding:.5rem;border:1px solid var(--studio-border-primary);border-radius:calc(var(--menu-border-radius) + .25rem);background:var(--studio-bg-primary)}:host(.studio-menu--ghost){padding:0}:host(.studio-menu--primary) .studio-menu-item--active{background:hsl(var(--studio-primary-hsl)/.1);color:var(--studio-primary);font-weight:500}:host(.studio-menu--secondary) .studio-menu-item--active{background:hsl(var(--studio-secondary-hsl)/.1);color:var(--studio-secondary);font-weight:500}:host(.studio-menu--radius-none){--menu-border-radius: 0}:host(.studio-menu--radius-none.studio-menu--filled),:host(.studio-menu--radius-none.studio-menu--outlined){border-radius:0}:host(.studio-menu--radius-sm){--menu-border-radius: .25rem}:host(.studio-menu--radius-sm.studio-menu--filled),:host(.studio-menu--radius-sm.studio-menu--outlined){border-radius:.5rem}:host(.studio-menu--radius-md){--menu-border-radius: .375rem}:host(.studio-menu--radius-md.studio-menu--filled),:host(.studio-menu--radius-md.studio-menu--outlined){border-radius:.625rem}:host(.studio-menu--radius-lg){--menu-border-radius: .5rem}:host(.studio-menu--radius-lg.studio-menu--filled),:host(.studio-menu--radius-lg.studio-menu--outlined){border-radius:.75rem}:host(.studio-menu--spacing-none){--menu-gap: 0}:host(.studio-menu--spacing-sm){--menu-gap: .125rem}:host(.studio-menu--spacing-md){--menu-gap: .25rem}:host(.studio-menu--spacing-lg){--menu-gap: .5rem}.studio-menu__list{display:flex;flex-direction:column;gap:var(--menu-gap);list-style:none;margin:0;padding:0}.studio-menu-item{position:relative;display:flex;align-items:center;width:100%;min-height:var(--menu-item-min-height);padding:0;border:none;background:transparent;color:var(--studio-text-primary);font-size:var(--menu-font-size);line-height:var(--menu-line-height);font-family:inherit;font-weight:400;text-align:left;cursor:pointer;transition:var(--menu-transition);border-radius:var(--menu-border-radius);outline:none;-webkit-user-select:none;user-select:none}.studio-menu-item:hover:not(.studio-menu-item--disabled):not(.studio-menu-item--active){background:hsl(var(--studio-primary-hsl)/.04);color:var(--studio-text-primary)}.studio-menu-item--active{background:hsl(var(--studio-primary-hsl)/.1);color:var(--studio-text-primary);font-weight:500}.studio-menu-item--active .studio-menu-item__icon{color:var(--studio-text-primary)}.studio-menu-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.studio-menu-item--has-children .studio-menu-item__expand-icon{transition:transform .2s cubic-bezier(.4,0,.2,1)}.studio-menu-item--expanded .studio-menu-item__expand-icon{transform:rotate(180deg)}.studio-menu-item:focus-visible{outline:2px solid var(--studio-primary);outline-offset:-1px;z-index:1}:host(.studio-menu--filled) .studio-menu-item:hover:not(.studio-menu-item--disabled):not(.studio-menu-item--active){background:var(--studio-bg-hover)}:host(.studio-menu--filled) .studio-menu-item.studio-menu-item--active{background:var(--studio-bg-primary);box-shadow:0 1px 2px #0000000d}:host(.studio-menu--outlined) .studio-menu-item{border:1px solid transparent}:host(.studio-menu--outlined) .studio-menu-item:hover:not(.studio-menu-item--disabled):not(.studio-menu-item--active){border-color:var(--studio-border-secondary);background:var(--studio-bg-secondary)}:host(.studio-menu--outlined) .studio-menu-item.studio-menu-item--active{border-color:var(--studio-primary);background:hsl(var(--studio-primary-hsl)/.05)}:host(.studio-menu--ghost) .studio-menu-item:hover:not(.studio-menu-item--disabled):not(.studio-menu-item--active){background:transparent;color:var(--studio-primary)}:host(.studio-menu--ghost) .studio-menu-item.studio-menu-item--active{background:transparent;color:var(--studio-primary);text-decoration:underline;text-underline-offset:4px}.studio-menu-item__link,.studio-menu-item__content{display:flex;align-items:center;width:100%;padding:var(--menu-padding-y) var(--menu-padding-x);color:inherit;text-decoration:none;gap:.5rem}.studio-menu-item__link:visited{color:inherit}.studio-menu-item__link:hover{text-decoration:none}.studio-menu-item__inner{display:flex;align-items:center;gap:.5rem;width:100%}.studio-menu-item__icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:var(--menu-icon-size);height:var(--menu-icon-size);color:var(--studio-text-secondary);transition:var(--menu-transition)}.studio-menu-item__icon--left{order:-1}.studio-menu-item__icon--right{order:1;margin-left:auto}.studio-menu-item:hover .studio-menu-item__icon,.studio-menu-item--active .studio-menu-item__icon{color:var(--studio-text-primary)}.studio-menu-item__label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--menu-font-size);line-height:var(--menu-line-height)}.studio-menu-item__badge{flex-shrink:0;margin-left:auto}.studio-menu-item__expand-icon{flex-shrink:0;margin-left:auto;width:1rem;height:1rem;color:var(--studio-text-secondary);opacity:.7;transition:transform .2s cubic-bezier(.4,0,.2,1),opacity var(--menu-transition)}.studio-menu-item:hover .studio-menu-item__expand-icon{opacity:1}.studio-menu__submenu{overflow:hidden;margin-top:var(--menu-gap);margin-left:calc(var(--menu-indent) - .25rem)}.studio-menu__submenu studio-menu{padding-left:0}.studio-menu__submenu .studio-menu__list{padding-left:.75rem;border-left:1px solid var(--studio-border-secondary);margin-left:.75rem}.studio-menu__separator{height:1px;margin:.375rem 0;background:var(--studio-border-secondary);opacity:.6}.studio-menu__divider{height:1px;margin:.125rem 0;background:var(--studio-border-secondary);opacity:.4}@keyframes expandCollapse{0%{opacity:0;max-height:0;transform:translateY(-4px)}to{opacity:1;max-height:1000px;transform:translateY(0)}}@media (max-width: 768px){:host(.studio-menu--horizontal){flex-direction:column}:host(.studio-menu--horizontal) .studio-menu__list{flex-direction:column}}\n"] }]
2186
+ }], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], defaultExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultExpanded", required: false }] }], expandOnHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandOnHover", required: false }] }], activeItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeItem", required: false }] }], routerLinkActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerLinkActive", required: false }] }], selectOnNavigate: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectOnNavigate", required: false }] }], routerLinkActiveOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerLinkActiveOptions", required: false }] }], keyboardNavigation: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyboardNavigation", required: false }] }], arrowNavigation: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrowNavigation", required: false }] }], homeEndNavigation: [{ type: i0.Input, args: [{ isSignal: true, alias: "homeEndNavigation", required: false }] }], animated: [{ type: i0.Input, args: [{ isSignal: true, alias: "animated", required: false }] }], animationDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationDuration", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], showDividers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDividers", required: false }] }], iconSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconSize", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], indentLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "indentLevel", required: false }] }], showExpandIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExpandIcon", required: false }] }], expandIconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandIconPosition", required: false }] }], expandIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandIcon", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], itemClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemClass", required: false }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], parentExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentExpanded", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }], itemSelect: [{ type: i0.Output, args: ["itemSelect"] }], expandChange: [{ type: i0.Output, args: ["expandChange"] }], activeChange: [{ type: i0.Output, args: ["activeChange"] }], handleKeyDown: [{
2187
+ type: HostListener,
2188
+ args: ['keydown', ['$event']]
2189
+ }] } });
2190
+
1338
2191
  class SelectComponent {
1339
2192
  configService = inject(StudioConfigService);
1340
2193
  selectDefaults = computed(() => this.configService.config().components?.select, ...(ngDevMode ? [{ debugName: "selectDefaults" }] : []));
@@ -2765,5 +3618,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2765
3618
  * Generated bundle index. Do not edit.
2766
3619
  */
2767
3620
 
2768
- export { BadgeComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, CheckboxComponent, IconComponent, InputComponent, MASK_PRESETS, MaskDirective, MaskEngine, STUDIO_CONFIG, SelectComponent, StudioConfigService, SwitchComponent, TextareaComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
3621
+ export { BadgeComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, CheckboxComponent, DrawerComponent, DrawerService, IconComponent, InputComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, STUDIO_CONFIG, SelectComponent, StudioConfigService, SwitchComponent, TextareaComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
2769
3622
  //# sourceMappingURL=eduboxpro-studio.mjs.map