@eduboxpro/studio 0.1.13 → 0.1.15

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,14 +1,16 @@
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, DOCUMENT as DOCUMENT$1, DestroyRef, contentChild, 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';
2
+ import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, PLATFORM_ID, ElementRef, forwardRef, viewChild, DOCUMENT as DOCUMENT$1, DestroyRef, Injector, contentChild, model, afterNextRender, HostListener, Renderer2, Directive } from '@angular/core';
3
+ import * as i1$1 from '@angular/common';
4
+ import { DOCUMENT, CommonModule, isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
5
5
  import * as LucideIcons from 'lucide-angular';
6
6
  import { icons, LucideAngularModule, LucideIconProvider, LUCIDE_ICONS } from 'lucide-angular';
7
- import * as i1$1 from '@angular/forms';
7
+ import * as i1 from '@angular/router';
8
+ import { Router, NavigationEnd, RouterModule, RouterLink, RouterLinkActive } from '@angular/router';
9
+ import { filter } from 'rxjs/operators';
10
+ import * as i1$2 from '@angular/forms';
8
11
  import { NG_VALUE_ACCESSOR, FormsModule, NG_VALIDATORS } from '@angular/forms';
9
- import { Router, RouterLink, RouterLinkActive, NavigationEnd } from '@angular/router';
12
+ import { autoUpdate, offset, flip, shift, arrow, computePosition } from '@floating-ui/dom';
10
13
  import { trigger, state, transition, style, animate } from '@angular/animations';
11
- import { filter } from 'rxjs/operators';
12
14
 
13
15
  /**
14
16
  * Injection token for Studio configuration
@@ -838,6 +840,227 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
838
840
  }, template: "<div class=\"studio-badge-wrapper__content\">\n <ng-content />\n</div>\n\n@if (shouldShowBadge()) {\n <studio-badge\n class=\"studio-badge-wrapper__badge\"\n [variant]=\"dot() ? 'dot' : variant()\"\n [color]=\"color()\"\n [size]=\"size()\"\n >\n {{ badgeContent() }}\n </studio-badge>\n}\n", styles: [":host{display:inline-flex;position:relative;vertical-align:middle;flex-shrink:0}.studio-badge-wrapper__content{display:flex;align-items:center;justify-content:center}.studio-badge-wrapper__badge{position:absolute;z-index:1;transform-origin:center;transition:transform .2s cubic-bezier(.4,0,.2,1)}:host(.studio-badge-wrapper--top-right) .studio-badge-wrapper__badge{top:0;right:0;transform:translate(50%,-50%)}:host(.studio-badge-wrapper--top-left) .studio-badge-wrapper__badge{top:0;left:0;transform:translate(-50%,-50%)}:host(.studio-badge-wrapper--bottom-right) .studio-badge-wrapper__badge{bottom:0;right:0;transform:translate(50%,50%)}:host(.studio-badge-wrapper--bottom-left) .studio-badge-wrapper__badge{bottom:0;left:0;transform:translate(-50%,50%)}:host(.studio-badge-wrapper--overlap.studio-badge-wrapper--top-right) .studio-badge-wrapper__badge{transform:translate(25%,-25%)}:host(.studio-badge-wrapper--overlap.studio-badge-wrapper--top-left) .studio-badge-wrapper__badge{transform:translate(-25%,-25%)}:host(.studio-badge-wrapper--overlap.studio-badge-wrapper--bottom-right) .studio-badge-wrapper__badge{transform:translate(25%,25%)}:host(.studio-badge-wrapper--overlap.studio-badge-wrapper--bottom-left) .studio-badge-wrapper__badge{transform:translate(-25%,25%)}\n"] }]
839
841
  }], propDecorators: { count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: false }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], showZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "showZero", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], dot: [{ type: i0.Input, args: [{ isSignal: true, alias: "dot", required: false }] }], overlap: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlap", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
840
842
 
843
+ /**
844
+ * Bottom Navigation component - Mobile-first navigation component
845
+ *
846
+ * @example
847
+ * <studio-bottom-navigation
848
+ * [items]="navItems"
849
+ * variant="default"
850
+ * showLabels="always"
851
+ * (itemClicked)="handleClick($event)"
852
+ * />
853
+ */
854
+ class BottomNavigationComponent {
855
+ router = inject(Router);
856
+ platformId = inject(PLATFORM_ID);
857
+ // ========== Items ==========
858
+ items = input.required(...(ngDevMode ? [{ debugName: "items" }] : []));
859
+ activeItem = input(...(ngDevMode ? [undefined, { debugName: "activeItem" }] : []));
860
+ // ========== Visual ==========
861
+ variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
862
+ showLabels = input('always', ...(ngDevMode ? [{ debugName: "showLabels" }] : []));
863
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
864
+ elevation = input('sm', ...(ngDevMode ? [{ debugName: "elevation" }] : []));
865
+ blur = input(false, ...(ngDevMode ? [{ debugName: "blur" }] : []));
866
+ // ========== FAB ==========
867
+ showFab = input(false, ...(ngDevMode ? [{ debugName: "showFab" }] : []));
868
+ fabIcon = input('plus', ...(ngDevMode ? [{ debugName: "fabIcon" }] : []));
869
+ fabPosition = input('center', ...(ngDevMode ? [{ debugName: "fabPosition" }] : []));
870
+ fabAriaLabel = input(...(ngDevMode ? [undefined, { debugName: "fabAriaLabel" }] : []));
871
+ // ========== Behavior ==========
872
+ fixed = input(false, ...(ngDevMode ? [{ debugName: "fixed" }] : []));
873
+ hideOnScroll = input(false, ...(ngDevMode ? [{ debugName: "hideOnScroll" }] : []));
874
+ scrollThreshold = input(10, ...(ngDevMode ? [{ debugName: "scrollThreshold" }] : []));
875
+ hideOnDesktop = input(false, ...(ngDevMode ? [{ debugName: "hideOnDesktop" }] : []));
876
+ // ========== Gestures ==========
877
+ enableSwipeGestures = input(false, ...(ngDevMode ? [{ debugName: "enableSwipeGestures" }] : []));
878
+ swipeThreshold = input(50, ...(ngDevMode ? [{ debugName: "swipeThreshold" }] : []));
879
+ enableHapticFeedback = input(false, ...(ngDevMode ? [{ debugName: "enableHapticFeedback" }] : []));
880
+ // ========== Router ==========
881
+ routerLinkActiveOptions = input({
882
+ paths: 'exact',
883
+ queryParams: 'exact',
884
+ fragment: 'ignored',
885
+ matrixParams: 'ignored'
886
+ }, ...(ngDevMode ? [{ debugName: "routerLinkActiveOptions" }] : []));
887
+ // ========== Accessibility ==========
888
+ ariaLabel = input('Bottom navigation', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
889
+ // ========== Customization ==========
890
+ class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
891
+ // ========== Outputs ==========
892
+ activeItemChange = output();
893
+ itemClicked = output();
894
+ fabClicked = output();
895
+ swipedLeft = output();
896
+ swipedRight = output();
897
+ // ========== State ==========
898
+ isHidden = signal(false, ...(ngDevMode ? [{ debugName: "isHidden" }] : []));
899
+ lastScrollY = 0;
900
+ routerSubscription;
901
+ touchStartX = 0;
902
+ touchStartY = 0;
903
+ isSwiping = false;
904
+ hostClasses = computed(() => {
905
+ const classes = ['studio-bottom-navigation'];
906
+ classes.push(`studio-bottom-navigation--${this.variant()}`);
907
+ classes.push(`studio-bottom-navigation--${this.size()}`);
908
+ classes.push(`studio-bottom-navigation--labels-${this.showLabels()}`);
909
+ if (this.elevation() !== 'none') {
910
+ classes.push(`studio-bottom-navigation--elevation-${this.elevation()}`);
911
+ }
912
+ if (this.blur())
913
+ classes.push('studio-bottom-navigation--blur');
914
+ if (this.showFab())
915
+ classes.push('studio-bottom-navigation--has-fab');
916
+ if (this.hideOnDesktop())
917
+ classes.push('studio-bottom-navigation--hide-desktop');
918
+ if (!this.fixed())
919
+ classes.push('studio-bottom-navigation--relative');
920
+ if (this.isHidden())
921
+ classes.push('studio-bottom-navigation--hidden');
922
+ if (this.class())
923
+ classes.push(this.class());
924
+ return classes.join(' ');
925
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
926
+ visibleItems = computed(() => this.items().filter(item => item.visible !== false), ...(ngDevMode ? [{ debugName: "visibleItems" }] : []));
927
+ centerIndex = computed(() => Math.floor(this.visibleItems().length / 2), ...(ngDevMode ? [{ debugName: "centerIndex" }] : []));
928
+ iconSize = computed(() => {
929
+ const sizes = {
930
+ sm: 20,
931
+ md: 24,
932
+ lg: 28
933
+ };
934
+ return sizes[this.size()];
935
+ }, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
936
+ ngOnInit() {
937
+ if (isPlatformBrowser(this.platformId)) {
938
+ this.routerSubscription = this.router.events
939
+ .pipe(filter(event => event instanceof NavigationEnd))
940
+ .subscribe(() => { });
941
+ if (this.hideOnScroll()) {
942
+ window.addEventListener('scroll', this.handleScroll, { passive: true });
943
+ }
944
+ }
945
+ }
946
+ ngOnDestroy() {
947
+ this.routerSubscription?.unsubscribe();
948
+ if (isPlatformBrowser(this.platformId) && this.hideOnScroll()) {
949
+ window.removeEventListener('scroll', this.handleScroll);
950
+ }
951
+ }
952
+ handleScroll = () => {
953
+ const currentScrollY = window.scrollY;
954
+ if (Math.abs(currentScrollY - this.lastScrollY) < this.scrollThreshold()) {
955
+ return;
956
+ }
957
+ if (currentScrollY > this.lastScrollY && currentScrollY > 100) {
958
+ this.isHidden.set(true);
959
+ }
960
+ else {
961
+ this.isHidden.set(false);
962
+ }
963
+ this.lastScrollY = currentScrollY;
964
+ };
965
+ isItemActive(item) {
966
+ if (this.activeItem()) {
967
+ return item.id === this.activeItem();
968
+ }
969
+ if (item.routerLink && isPlatformBrowser(this.platformId)) {
970
+ const url = Array.isArray(item.routerLink)
971
+ ? item.routerLink.join('/')
972
+ : item.routerLink;
973
+ return this.router.isActive(url, this.routerLinkActiveOptions());
974
+ }
975
+ return false;
976
+ }
977
+ shouldShowLabel(item) {
978
+ const mode = this.showLabels();
979
+ if (mode === 'never')
980
+ return false;
981
+ if (mode === 'always')
982
+ return true;
983
+ if (mode === 'selected')
984
+ return this.isItemActive(item);
985
+ return true;
986
+ }
987
+ onItemClick(item, event) {
988
+ if (item.disabled) {
989
+ event.preventDefault();
990
+ return;
991
+ }
992
+ this.triggerHapticFeedback('light');
993
+ if (item.command) {
994
+ item.command(item);
995
+ }
996
+ this.activeItemChange.emit(item.id);
997
+ this.itemClicked.emit(item);
998
+ }
999
+ onFabClick(event) {
1000
+ event.preventDefault();
1001
+ event.stopPropagation();
1002
+ this.triggerHapticFeedback('medium');
1003
+ this.fabClicked.emit();
1004
+ }
1005
+ onTouchStart(event) {
1006
+ if (!this.enableSwipeGestures())
1007
+ return;
1008
+ const touch = event.touches[0];
1009
+ this.touchStartX = touch.clientX;
1010
+ this.touchStartY = touch.clientY;
1011
+ this.isSwiping = false;
1012
+ }
1013
+ onTouchMove(event) {
1014
+ if (!this.enableSwipeGestures())
1015
+ return;
1016
+ const touch = event.touches[0];
1017
+ const deltaX = Math.abs(touch.clientX - this.touchStartX);
1018
+ const deltaY = Math.abs(touch.clientY - this.touchStartY);
1019
+ if (deltaX > deltaY && deltaX > 10) {
1020
+ this.isSwiping = true;
1021
+ }
1022
+ }
1023
+ onTouchEnd(event) {
1024
+ if (!this.enableSwipeGestures() || !this.isSwiping)
1025
+ return;
1026
+ const touch = event.changedTouches[0];
1027
+ const deltaX = touch.clientX - this.touchStartX;
1028
+ if (Math.abs(deltaX) > this.swipeThreshold()) {
1029
+ if (deltaX > 0) {
1030
+ this.triggerHapticFeedback('light');
1031
+ this.swipedRight.emit();
1032
+ }
1033
+ else {
1034
+ this.triggerHapticFeedback('light');
1035
+ this.swipedLeft.emit();
1036
+ }
1037
+ }
1038
+ this.isSwiping = false;
1039
+ }
1040
+ triggerHapticFeedback(style = 'light') {
1041
+ if (!this.enableHapticFeedback() || !isPlatformBrowser(this.platformId))
1042
+ return;
1043
+ if ('vibrate' in navigator) {
1044
+ const patterns = {
1045
+ light: 10,
1046
+ medium: 20,
1047
+ heavy: [30, 10, 30]
1048
+ };
1049
+ navigator.vibrate(patterns[style]);
1050
+ }
1051
+ }
1052
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BottomNavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1053
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: BottomNavigationComponent, isStandalone: true, selector: "studio-bottom-navigation", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, activeItem: { classPropertyName: "activeItem", publicName: "activeItem", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, showLabels: { classPropertyName: "showLabels", publicName: "showLabels", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, elevation: { classPropertyName: "elevation", publicName: "elevation", isSignal: true, isRequired: false, transformFunction: null }, blur: { classPropertyName: "blur", publicName: "blur", isSignal: true, isRequired: false, transformFunction: null }, showFab: { classPropertyName: "showFab", publicName: "showFab", isSignal: true, isRequired: false, transformFunction: null }, fabIcon: { classPropertyName: "fabIcon", publicName: "fabIcon", isSignal: true, isRequired: false, transformFunction: null }, fabPosition: { classPropertyName: "fabPosition", publicName: "fabPosition", isSignal: true, isRequired: false, transformFunction: null }, fabAriaLabel: { classPropertyName: "fabAriaLabel", publicName: "fabAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, fixed: { classPropertyName: "fixed", publicName: "fixed", isSignal: true, isRequired: false, transformFunction: null }, hideOnScroll: { classPropertyName: "hideOnScroll", publicName: "hideOnScroll", isSignal: true, isRequired: false, transformFunction: null }, scrollThreshold: { classPropertyName: "scrollThreshold", publicName: "scrollThreshold", isSignal: true, isRequired: false, transformFunction: null }, hideOnDesktop: { classPropertyName: "hideOnDesktop", publicName: "hideOnDesktop", isSignal: true, isRequired: false, transformFunction: null }, enableSwipeGestures: { classPropertyName: "enableSwipeGestures", publicName: "enableSwipeGestures", isSignal: true, isRequired: false, transformFunction: null }, swipeThreshold: { classPropertyName: "swipeThreshold", publicName: "swipeThreshold", isSignal: true, isRequired: false, transformFunction: null }, enableHapticFeedback: { classPropertyName: "enableHapticFeedback", publicName: "enableHapticFeedback", isSignal: true, isRequired: false, transformFunction: null }, routerLinkActiveOptions: { classPropertyName: "routerLinkActiveOptions", publicName: "routerLinkActiveOptions", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeItemChange: "activeItemChange", itemClicked: "itemClicked", fabClicked: "fabClicked", swipedLeft: "swipedLeft", swipedRight: "swipedRight" }, host: { properties: { "class": "hostClasses()", "attr.role": "\"navigation\"", "attr.aria-label": "ariaLabel()" } }, ngImport: i0, template: "<div\n class=\"bottom-navigation__container\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd($event)\"\n>\n <ng-content select=\"[bottomNavLeft]\" />\n\n <div class=\"bottom-navigation__items\">\n @for (item of visibleItems(); track item.id) {\n @if (!showFab() || fabPosition() !== 'center' || $index !== centerIndex()) {\n <a\n class=\"bottom-navigation__item\"\n [class.bottom-navigation__item--active]=\"isItemActive(item)\"\n [class.bottom-navigation__item--disabled]=\"item.disabled\"\n [routerLink]=\"item.routerLink || null\"\n [queryParams]=\"item.queryParams\"\n [attr.href]=\"item.href || null\"\n [attr.aria-current]=\"isItemActive(item) ? 'page' : null\"\n [attr.aria-disabled]=\"item.disabled || null\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"bottom-navigation__icon-wrapper\">\n <studio-icon\n [name]=\"item.icon\"\n [size]=\"iconSize()\"\n class=\"bottom-navigation__icon\"\n />\n\n @if (item.badge) {\n <studio-badge\n [value]=\"item.badge\"\n [color]=\"item.badgeColor || 'primary'\"\n size=\"sm\"\n class=\"bottom-navigation__badge\"\n />\n }\n </div>\n\n @if (shouldShowLabel(item)) {\n <span class=\"bottom-navigation__label\">{{ item.label }}</span>\n }\n </a>\n } @else {\n <div class=\"bottom-navigation__fab-spacer\"></div>\n }\n }\n </div>\n\n <ng-content select=\"[bottomNavRight]\" />\n\n @if (showFab()) {\n <button\n class=\"bottom-navigation__fab\"\n [class.bottom-navigation__fab--center]=\"fabPosition() === 'center'\"\n [class.bottom-navigation__fab--end]=\"fabPosition() === 'end'\"\n [attr.aria-label]=\"fabAriaLabel() || 'Action button'\"\n (click)=\"onFabClick($event)\"\n >\n <studio-icon\n [name]=\"fabIcon()\"\n [size]=\"24\"\n />\n </button>\n }\n</div>\n", styles: [":host{position:fixed;bottom:0;left:0;right:0;z-index:var(--studio-z-index-bottom-nav, 1000);display:block;transition:transform .3s ease}:host(.studio-bottom-navigation--hidden){transform:translateY(100%)}:host(.studio-bottom-navigation--relative){position:relative}@media (min-width: 768px){:host(.studio-bottom-navigation--hide-desktop){display:none}}.bottom-navigation__container{position:relative;display:flex;align-items:center;background:var(--studio-bg-primary);border-top:1px solid var(--studio-border-primary);padding-bottom:env(safe-area-inset-bottom,0);transition:all .3s ease}.bottom-navigation__items{flex:1;display:flex;align-items:stretch;justify-content:space-around;gap:.25rem}.bottom-navigation__item{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-decoration:none;color:var(--studio-text-secondary);transition:all .15s ease;cursor:pointer;position:relative;border-radius:var(--studio-radius-sm);min-height:56px;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.bottom-navigation__item:hover:not(.bottom-navigation__item--disabled):not(.bottom-navigation__item--active){background:var(--studio-bg-hover);color:var(--studio-text-primary)}.bottom-navigation__item:active:not(.bottom-navigation__item--disabled){transform:scale(.95)}.bottom-navigation__item--active{color:var(--studio-primary)}.bottom-navigation__item--active .bottom-navigation__icon{transform:scale(1.1)}.bottom-navigation__item--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.bottom-navigation__icon-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.bottom-navigation__icon{transition:transform .15s ease}.bottom-navigation__badge{position:absolute;top:-4px;right:-8px}.bottom-navigation__label{font-size:.75rem;font-weight:500;line-height:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;transition:opacity .15s ease;margin-top:.25rem}.bottom-navigation__fab-spacer{flex:1;min-width:56px}.bottom-navigation__fab{position:absolute;display:flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:50%;background:var(--studio-primary);color:#fff;border:none;cursor:pointer;box-shadow:0 4px 12px #00000026;transition:all .15s ease;z-index:1}.bottom-navigation__fab--center{left:50%;top:0;transform:translate(-50%) translateY(-50%)}.bottom-navigation__fab--center:hover{transform:translate(-50%) translateY(-50%) scale(1.1);box-shadow:0 6px 16px #0003}.bottom-navigation__fab--center:active{transform:translate(-50%) translateY(-50%) scale(.95)}.bottom-navigation__fab--end{right:16px}.bottom-navigation__fab--end:hover{transform:scale(1.1);box-shadow:0 6px 16px #0003}.bottom-navigation__fab--end:active{transform:scale(.95)}:host(.studio-bottom-navigation--relative) .bottom-navigation__fab--end{top:0;transform:translateY(-50%)}:host(.studio-bottom-navigation--relative) .bottom-navigation__fab--end:hover{transform:translateY(-50%) scale(1.1);box-shadow:0 6px 16px #0003}:host(.studio-bottom-navigation--relative) .bottom-navigation__fab--end:active{transform:translateY(-50%) scale(.95)}:host:not(.studio-bottom-navigation--relative) .bottom-navigation__fab--end{bottom:calc(16px + env(safe-area-inset-bottom,0))}:host(.studio-bottom-navigation--sm) .bottom-navigation__item{min-height:48px;padding:.375rem .5rem}:host(.studio-bottom-navigation--md) .bottom-navigation__item{min-height:56px;padding:.5rem .75rem}:host(.studio-bottom-navigation--lg) .bottom-navigation__item{min-height:64px;padding:.625rem 1rem}:host(.studio-bottom-navigation--filled) .bottom-navigation__container{background:var(--studio-primary);border-top-color:transparent}:host(.studio-bottom-navigation--filled) .bottom-navigation__item{color:#ffffffb3}:host(.studio-bottom-navigation--filled) .bottom-navigation__item--active{color:#fff}:host(.studio-bottom-navigation--filled) .bottom-navigation__item:hover:not(.bottom-navigation__item--disabled):not(.bottom-navigation__item--active){background:#ffffff1a}:host(.studio-bottom-navigation--minimal) .bottom-navigation__container{background:transparent;border-top:none;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}:host(.studio-bottom-navigation--labels-selected) .bottom-navigation__item:not(.bottom-navigation__item--active) .bottom-navigation__label{opacity:0;height:0;margin:0}:host(.studio-bottom-navigation--labels-never) .bottom-navigation__label{display:none}:host(.studio-bottom-navigation--elevation-sm) .bottom-navigation__container{box-shadow:0 -2px 4px #0000000d}:host(.studio-bottom-navigation--elevation-md) .bottom-navigation__container{box-shadow:0 -4px 8px #0000001a}:host(.studio-bottom-navigation--elevation-lg) .bottom-navigation__container{box-shadow:0 -8px 16px #00000026}:host(.studio-bottom-navigation--blur) .bottom-navigation__container{background:rgba(var(--studio-bg-primary-rgb),.8);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}@media (max-width: 640px){.bottom-navigation__label{font-size:.6875rem}:host(.studio-bottom-navigation--sm) .bottom-navigation__item{min-height:44px}}@media (prefers-reduced-motion: reduce){:host,.bottom-navigation__container,.bottom-navigation__item,.bottom-navigation__icon,.bottom-navigation__label,.bottom-navigation__fab{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1054
+ }
1055
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BottomNavigationComponent, decorators: [{
1056
+ type: Component,
1057
+ args: [{ selector: 'studio-bottom-navigation', standalone: true, imports: [CommonModule, RouterModule, IconComponent, BadgeComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1058
+ '[class]': 'hostClasses()',
1059
+ '[attr.role]': '"navigation"',
1060
+ '[attr.aria-label]': 'ariaLabel()'
1061
+ }, template: "<div\n class=\"bottom-navigation__container\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd($event)\"\n>\n <ng-content select=\"[bottomNavLeft]\" />\n\n <div class=\"bottom-navigation__items\">\n @for (item of visibleItems(); track item.id) {\n @if (!showFab() || fabPosition() !== 'center' || $index !== centerIndex()) {\n <a\n class=\"bottom-navigation__item\"\n [class.bottom-navigation__item--active]=\"isItemActive(item)\"\n [class.bottom-navigation__item--disabled]=\"item.disabled\"\n [routerLink]=\"item.routerLink || null\"\n [queryParams]=\"item.queryParams\"\n [attr.href]=\"item.href || null\"\n [attr.aria-current]=\"isItemActive(item) ? 'page' : null\"\n [attr.aria-disabled]=\"item.disabled || null\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"bottom-navigation__icon-wrapper\">\n <studio-icon\n [name]=\"item.icon\"\n [size]=\"iconSize()\"\n class=\"bottom-navigation__icon\"\n />\n\n @if (item.badge) {\n <studio-badge\n [value]=\"item.badge\"\n [color]=\"item.badgeColor || 'primary'\"\n size=\"sm\"\n class=\"bottom-navigation__badge\"\n />\n }\n </div>\n\n @if (shouldShowLabel(item)) {\n <span class=\"bottom-navigation__label\">{{ item.label }}</span>\n }\n </a>\n } @else {\n <div class=\"bottom-navigation__fab-spacer\"></div>\n }\n }\n </div>\n\n <ng-content select=\"[bottomNavRight]\" />\n\n @if (showFab()) {\n <button\n class=\"bottom-navigation__fab\"\n [class.bottom-navigation__fab--center]=\"fabPosition() === 'center'\"\n [class.bottom-navigation__fab--end]=\"fabPosition() === 'end'\"\n [attr.aria-label]=\"fabAriaLabel() || 'Action button'\"\n (click)=\"onFabClick($event)\"\n >\n <studio-icon\n [name]=\"fabIcon()\"\n [size]=\"24\"\n />\n </button>\n }\n</div>\n", styles: [":host{position:fixed;bottom:0;left:0;right:0;z-index:var(--studio-z-index-bottom-nav, 1000);display:block;transition:transform .3s ease}:host(.studio-bottom-navigation--hidden){transform:translateY(100%)}:host(.studio-bottom-navigation--relative){position:relative}@media (min-width: 768px){:host(.studio-bottom-navigation--hide-desktop){display:none}}.bottom-navigation__container{position:relative;display:flex;align-items:center;background:var(--studio-bg-primary);border-top:1px solid var(--studio-border-primary);padding-bottom:env(safe-area-inset-bottom,0);transition:all .3s ease}.bottom-navigation__items{flex:1;display:flex;align-items:stretch;justify-content:space-around;gap:.25rem}.bottom-navigation__item{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-decoration:none;color:var(--studio-text-secondary);transition:all .15s ease;cursor:pointer;position:relative;border-radius:var(--studio-radius-sm);min-height:56px;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.bottom-navigation__item:hover:not(.bottom-navigation__item--disabled):not(.bottom-navigation__item--active){background:var(--studio-bg-hover);color:var(--studio-text-primary)}.bottom-navigation__item:active:not(.bottom-navigation__item--disabled){transform:scale(.95)}.bottom-navigation__item--active{color:var(--studio-primary)}.bottom-navigation__item--active .bottom-navigation__icon{transform:scale(1.1)}.bottom-navigation__item--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.bottom-navigation__icon-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.bottom-navigation__icon{transition:transform .15s ease}.bottom-navigation__badge{position:absolute;top:-4px;right:-8px}.bottom-navigation__label{font-size:.75rem;font-weight:500;line-height:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;transition:opacity .15s ease;margin-top:.25rem}.bottom-navigation__fab-spacer{flex:1;min-width:56px}.bottom-navigation__fab{position:absolute;display:flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:50%;background:var(--studio-primary);color:#fff;border:none;cursor:pointer;box-shadow:0 4px 12px #00000026;transition:all .15s ease;z-index:1}.bottom-navigation__fab--center{left:50%;top:0;transform:translate(-50%) translateY(-50%)}.bottom-navigation__fab--center:hover{transform:translate(-50%) translateY(-50%) scale(1.1);box-shadow:0 6px 16px #0003}.bottom-navigation__fab--center:active{transform:translate(-50%) translateY(-50%) scale(.95)}.bottom-navigation__fab--end{right:16px}.bottom-navigation__fab--end:hover{transform:scale(1.1);box-shadow:0 6px 16px #0003}.bottom-navigation__fab--end:active{transform:scale(.95)}:host(.studio-bottom-navigation--relative) .bottom-navigation__fab--end{top:0;transform:translateY(-50%)}:host(.studio-bottom-navigation--relative) .bottom-navigation__fab--end:hover{transform:translateY(-50%) scale(1.1);box-shadow:0 6px 16px #0003}:host(.studio-bottom-navigation--relative) .bottom-navigation__fab--end:active{transform:translateY(-50%) scale(.95)}:host:not(.studio-bottom-navigation--relative) .bottom-navigation__fab--end{bottom:calc(16px + env(safe-area-inset-bottom,0))}:host(.studio-bottom-navigation--sm) .bottom-navigation__item{min-height:48px;padding:.375rem .5rem}:host(.studio-bottom-navigation--md) .bottom-navigation__item{min-height:56px;padding:.5rem .75rem}:host(.studio-bottom-navigation--lg) .bottom-navigation__item{min-height:64px;padding:.625rem 1rem}:host(.studio-bottom-navigation--filled) .bottom-navigation__container{background:var(--studio-primary);border-top-color:transparent}:host(.studio-bottom-navigation--filled) .bottom-navigation__item{color:#ffffffb3}:host(.studio-bottom-navigation--filled) .bottom-navigation__item--active{color:#fff}:host(.studio-bottom-navigation--filled) .bottom-navigation__item:hover:not(.bottom-navigation__item--disabled):not(.bottom-navigation__item--active){background:#ffffff1a}:host(.studio-bottom-navigation--minimal) .bottom-navigation__container{background:transparent;border-top:none;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}:host(.studio-bottom-navigation--labels-selected) .bottom-navigation__item:not(.bottom-navigation__item--active) .bottom-navigation__label{opacity:0;height:0;margin:0}:host(.studio-bottom-navigation--labels-never) .bottom-navigation__label{display:none}:host(.studio-bottom-navigation--elevation-sm) .bottom-navigation__container{box-shadow:0 -2px 4px #0000000d}:host(.studio-bottom-navigation--elevation-md) .bottom-navigation__container{box-shadow:0 -4px 8px #0000001a}:host(.studio-bottom-navigation--elevation-lg) .bottom-navigation__container{box-shadow:0 -8px 16px #00000026}:host(.studio-bottom-navigation--blur) .bottom-navigation__container{background:rgba(var(--studio-bg-primary-rgb),.8);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}@media (max-width: 640px){.bottom-navigation__label{font-size:.6875rem}:host(.studio-bottom-navigation--sm) .bottom-navigation__item{min-height:44px}}@media (prefers-reduced-motion: reduce){:host,.bottom-navigation__container,.bottom-navigation__item,.bottom-navigation__icon,.bottom-navigation__label,.bottom-navigation__fab{transition:none}}\n"] }]
1062
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], activeItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeItem", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], showLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabels", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], elevation: [{ type: i0.Input, args: [{ isSignal: true, alias: "elevation", required: false }] }], blur: [{ type: i0.Input, args: [{ isSignal: true, alias: "blur", required: false }] }], showFab: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFab", required: false }] }], fabIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "fabIcon", required: false }] }], fabPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "fabPosition", required: false }] }], fabAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "fabAriaLabel", required: false }] }], fixed: [{ type: i0.Input, args: [{ isSignal: true, alias: "fixed", required: false }] }], hideOnScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideOnScroll", required: false }] }], scrollThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollThreshold", required: false }] }], hideOnDesktop: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideOnDesktop", required: false }] }], enableSwipeGestures: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableSwipeGestures", required: false }] }], swipeThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "swipeThreshold", required: false }] }], enableHapticFeedback: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableHapticFeedback", required: false }] }], routerLinkActiveOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerLinkActiveOptions", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], activeItemChange: [{ type: i0.Output, args: ["activeItemChange"] }], itemClicked: [{ type: i0.Output, args: ["itemClicked"] }], fabClicked: [{ type: i0.Output, args: ["fabClicked"] }], swipedLeft: [{ type: i0.Output, args: ["swipedLeft"] }], swipedRight: [{ type: i0.Output, args: ["swipedRight"] }] } });
1063
+
841
1064
  /**
842
1065
  * Button component with multiple variants, sizes, colors and states
843
1066
  *
@@ -1262,7 +1485,7 @@ class CheckboxComponent {
1262
1485
  provide: NG_VALUE_ACCESSOR,
1263
1486
  useExisting: forwardRef(() => CheckboxComponent),
1264
1487
  multi: true
1265
- }], 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"] }] });
1488
+ }], 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"] }] });
1266
1489
  }
1267
1490
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: CheckboxComponent, decorators: [{
1268
1491
  type: Component,
@@ -1673,6 +1896,477 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1673
1896
  }, template: "@if (label()) {\n <label [for]=\"generatedId\" class=\"studio-color-picker__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-color-picker__required\">*</span>\n }\n </label>\n}\n\n<div class=\"studio-color-picker__picker\">\n <div class=\"studio-color-picker__preview\">\n <div\n class=\"studio-color-picker__preview-color\"\n [style.background-color]=\"displayColor()\"\n ></div>\n <div class=\"studio-color-picker__preview-info\">\n <span class=\"studio-color-picker__preview-value\">{{ displayColor() }}</span>\n @if (showFormatToggle()) {\n <button\n type=\"button\"\n class=\"studio-color-picker__format-btn\"\n (click)=\"toggleFormat()\"\n [disabled]=\"disabled() || readonly()\"\n >\n {{ currentFormat().toUpperCase() }}\n </button>\n }\n </div>\n @if (showCopyButton()) {\n <button\n type=\"button\"\n class=\"studio-color-picker__copy-btn\"\n (click)=\"copyColor()\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Copy color\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\n </svg>\n </button>\n }\n </div>\n\n <div class=\"studio-color-picker__area\">\n <canvas\n #colorArea\n class=\"studio-color-picker__canvas\"\n width=\"280\"\n height=\"180\"\n (mousedown)=\"onColorAreaMouseDown($event)\"\n ></canvas>\n <div\n class=\"studio-color-picker__cursor\"\n [style.left.%]=\"saturation()\"\n [style.top.%]=\"100 - lightness()\"\n ></div>\n </div>\n\n <div class=\"studio-color-picker__sliders\">\n <div class=\"studio-color-picker__slider\">\n <div class=\"studio-color-picker__slider-label\">Hue</div>\n <input\n type=\"range\"\n class=\"studio-color-picker__hue-slider\"\n min=\"0\"\n max=\"360\"\n [value]=\"hue()\"\n (input)=\"onHueChange($event)\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Hue\"\n />\n </div>\n\n @if (showAlpha()) {\n <div class=\"studio-color-picker__slider\">\n <div class=\"studio-color-picker__slider-label\">Opacity</div>\n <input\n type=\"range\"\n class=\"studio-color-picker__alpha-slider\"\n min=\"0\"\n max=\"100\"\n [value]=\"alpha() * 100\"\n (input)=\"onAlphaChange($event)\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Opacity\"\n />\n <span class=\"studio-color-picker__alpha-value\">{{ (alpha() * 100).toFixed(0) }}%</span>\n </div>\n }\n </div>\n\n @if (showPresets() && effectivePresets().length > 0) {\n <div class=\"studio-color-picker__presets\">\n @for (preset of effectivePresets(); track $index) {\n @if (isPresetGroup(preset)) {\n <div class=\"studio-color-picker__preset-group\">\n <div class=\"studio-color-picker__preset-group-label\">{{ preset.label }}</div>\n <div class=\"studio-color-picker__preset-swatches\">\n @for (color of preset.colors; track color.value) {\n <button\n type=\"button\"\n class=\"studio-color-picker__preset-swatch\"\n [style.background-color]=\"color.value\"\n [title]=\"color.label || color.value\"\n (click)=\"selectPreset(color)\"\n [disabled]=\"disabled() || readonly()\"\n ></button>\n }\n </div>\n </div>\n } @else {\n <button\n type=\"button\"\n class=\"studio-color-picker__preset-swatch\"\n [style.background-color]=\"preset.value\"\n [title]=\"preset.label || preset.value\"\n (click)=\"selectPreset(preset)\"\n [disabled]=\"disabled() || readonly()\"\n ></button>\n }\n }\n </div>\n }\n</div>\n\n@if (hint() && !error()) {\n <span class=\"studio-color-picker__hint\">\n {{ hint() }}\n </span>\n}\n\n@if (error() && errorMessage()) {\n <span class=\"studio-color-picker__error\" role=\"alert\">\n {{ errorMessage() }}\n </span>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:.5rem;font-family:var(--studio-font-family)}.studio-color-picker__label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-color-picker__label .studio-color-picker__required{color:var(--studio-error);margin-left:.125rem}.studio-color-picker__picker{display:flex;flex-direction:column;gap:1rem;padding:1rem;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md)}.studio-color-picker__preview{display:flex;align-items:center;gap:.75rem}.studio-color-picker__preview-color{width:3rem;height:3rem;border-radius:var(--studio-radius-sm);border:1px solid var(--studio-border-primary);flex-shrink:0}.studio-color-picker__preview-info{flex:1;display:flex;align-items:center;gap:.5rem}.studio-color-picker__preview-value{font-family:var(--studio-font-mono, monospace);font-size:.875rem;color:var(--studio-text-primary)}.studio-color-picker__format-btn{padding:.25rem .5rem;background:var(--studio-bg-secondary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary);cursor:pointer;transition:all var(--studio-transition-fast)}.studio-color-picker__format-btn:hover:not(:disabled){background:var(--studio-bg-tertiary);color:var(--studio-text-primary)}.studio-color-picker__format-btn:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__copy-btn{padding:.5rem;background:none;border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);color:var(--studio-text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--studio-transition-fast)}.studio-color-picker__copy-btn:hover:not(:disabled){background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-color-picker__copy-btn:active:not(:disabled){transform:scale(.95)}.studio-color-picker__copy-btn:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__area{position:relative;width:100%;aspect-ratio:28/18;border-radius:var(--studio-radius-sm);overflow:hidden;border:1px solid var(--studio-border-primary)}.studio-color-picker__canvas{display:block;width:100%;height:100%;cursor:crosshair}.studio-color-picker__cursor{position:absolute;width:16px;height:16px;border:2px solid white;border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003}.studio-color-picker__sliders{display:flex;flex-direction:column;gap:.75rem}.studio-color-picker__slider{display:flex;flex-direction:column;gap:.5rem}.studio-color-picker__slider-label{font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary)}.studio-color-picker__hue-slider{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:6px;background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red);outline:none;cursor:pointer}.studio-color-picker__hue-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__hue-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__hue-slider:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__alpha-slider{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:6px;background:linear-gradient(to right,transparent 0%,var(--studio-text-primary) 100%);outline:none;cursor:pointer;position:relative}.studio-color-picker__alpha-slider:before{content:\"\";position:absolute;inset:0;border-radius:6px;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:10px 10px;background-position:0 0,0 5px,5px -5px,-5px 0px;z-index:-1}.studio-color-picker__alpha-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__alpha-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__alpha-slider:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__alpha-value{font-size:.75rem;color:var(--studio-text-secondary);margin-left:auto}.studio-color-picker__presets{display:flex;flex-direction:column;gap:.75rem}.studio-color-picker__preset-group{display:flex;flex-direction:column;gap:.5rem}.studio-color-picker__preset-group-label{font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary)}.studio-color-picker__preset-swatches{display:flex;flex-wrap:wrap;gap:.375rem}.studio-color-picker__preset-swatch{width:2rem;height:2rem;border-radius:var(--studio-radius-sm);border:1px solid var(--studio-border-primary);cursor:pointer;transition:all var(--studio-transition-fast);padding:0}.studio-color-picker__preset-swatch:hover:not(:disabled){transform:scale(1.1);box-shadow:0 2px 8px #00000026}.studio-color-picker__preset-swatch:active:not(:disabled){transform:scale(1.05)}.studio-color-picker__preset-swatch:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-color-picker__error{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--studio-error);line-height:1.4}:host(.studio-color-picker--disabled) .studio-color-picker__picker{opacity:.6;pointer-events:none}:host(.studio-color-picker--error) .studio-color-picker__picker{border-color:var(--studio-error)}:host(.studio-color-picker--sm) .studio-color-picker__preview-color{width:2.5rem;height:2.5rem}:host(.studio-color-picker--sm) .studio-color-picker__picker{padding:.75rem}:host(.studio-color-picker--lg) .studio-color-picker__preview-color{width:3.5rem;height:3.5rem}:host(.studio-color-picker--lg) .studio-color-picker__picker{padding:1.25rem}\n"] }]
1674
1897
  }], ctorParameters: () => [], propDecorators: { colorAreaCanvas: [{ type: i0.ViewChild, args: ['colorArea', { isSignal: true }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], showAlpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAlpha", required: false }] }], showPresets: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPresets", required: false }] }], showFormatToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFormatToggle", required: false }] }], showCopyButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCopyButton", required: false }] }], presets: [{ type: i0.Input, args: [{ isSignal: true, alias: "presets", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", 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 }] }], colorChange: [{ type: i0.Output, args: ["colorChange"] }], colorValueChange: [{ type: i0.Output, args: ["colorValueChange"] }], copied: [{ type: i0.Output, args: ["copied"] }] } });
1675
1898
 
1899
+ class PopoverComponent {
1900
+ document = inject(DOCUMENT$1);
1901
+ destroyRef = inject(DestroyRef);
1902
+ injector = inject(Injector);
1903
+ configService = inject(StudioConfigService);
1904
+ popoverDefaults = computed(() => this.configService.config().components?.popover, ...(ngDevMode ? [{ debugName: "popoverDefaults" }] : []));
1905
+ headerTemplate = contentChild('popoverHeader', ...(ngDevMode ? [{ debugName: "headerTemplate" }] : []));
1906
+ footerTemplate = contentChild('popoverFooter', ...(ngDevMode ? [{ debugName: "footerTemplate" }] : []));
1907
+ contentTemplate = contentChild('popoverContent', ...(ngDevMode ? [{ debugName: "contentTemplate" }] : []));
1908
+ triggerEl = viewChild('popoverTrigger', ...(ngDevMode ? [{ debugName: "triggerEl" }] : []));
1909
+ panelEl = viewChild('popoverPanel', ...(ngDevMode ? [{ debugName: "panelEl" }] : []));
1910
+ arrowEl = viewChild('popoverArrow', ...(ngDevMode ? [{ debugName: "arrowEl" }] : []));
1911
+ id = input('studio-popover-' + Math.random().toString(36).substring(2, 11), ...(ngDevMode ? [{ debugName: "id" }] : []));
1912
+ visible = model(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
1913
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1914
+ triggerInput = input(undefined, ...(ngDevMode ? [{ debugName: "triggerInput", alias: 'trigger' }] : [{ alias: 'trigger' }]));
1915
+ openDelay = input(0, ...(ngDevMode ? [{ debugName: "openDelay" }] : []));
1916
+ closeDelay = input(200, ...(ngDevMode ? [{ debugName: "closeDelay" }] : []));
1917
+ trigger = withConfigDefault(this.triggerInput, computed(() => this.popoverDefaults()?.trigger), 'click');
1918
+ positionInput = input(undefined, ...(ngDevMode ? [{ debugName: "positionInput", alias: 'position' }] : [{ alias: 'position' }]));
1919
+ offset = input(8, ...(ngDevMode ? [{ debugName: "offset" }] : []));
1920
+ preventOverflow = input(true, ...(ngDevMode ? [{ debugName: "preventOverflow" }] : []));
1921
+ flipValue = input(true, ...(ngDevMode ? [{ debugName: "flipValue" }] : []));
1922
+ position = withConfigDefault(this.positionInput, computed(() => this.popoverDefaults()?.position), 'bottom');
1923
+ variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
1924
+ sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
1925
+ width = input('auto', ...(ngDevMode ? [{ debugName: "width" }] : []));
1926
+ minWidth = input(undefined, ...(ngDevMode ? [{ debugName: "minWidth" }] : []));
1927
+ maxWidth = input(undefined, ...(ngDevMode ? [{ debugName: "maxWidth" }] : []));
1928
+ maxHeight = input(undefined, ...(ngDevMode ? [{ debugName: "maxHeight" }] : []));
1929
+ padding = input(undefined, ...(ngDevMode ? [{ debugName: "padding" }] : []));
1930
+ variant = withConfigDefault(this.variantInput, computed(() => this.popoverDefaults()?.variant), 'default');
1931
+ size = withConfigDefault(this.sizeInput, computed(() => this.popoverDefaults()?.size), 'md');
1932
+ arrow = input(true, ...(ngDevMode ? [{ debugName: "arrow" }] : []));
1933
+ arrowSize = input(8, ...(ngDevMode ? [{ debugName: "arrowSize" }] : []));
1934
+ closeOnClickOutside = input(true, ...(ngDevMode ? [{ debugName: "closeOnClickOutside" }] : []));
1935
+ closeOnEscape = input(true, ...(ngDevMode ? [{ debugName: "closeOnEscape" }] : []));
1936
+ closeOnScroll = input(false, ...(ngDevMode ? [{ debugName: "closeOnScroll" }] : []));
1937
+ showOverlay = input(false, ...(ngDevMode ? [{ debugName: "showOverlay" }] : []));
1938
+ overlayOpacity = input(0.5, ...(ngDevMode ? [{ debugName: "overlayOpacity" }] : []));
1939
+ animationInput = input(undefined, ...(ngDevMode ? [{ debugName: "animationInput", alias: 'animation' }] : [{ alias: 'animation' }]));
1940
+ animationDuration = input(200, ...(ngDevMode ? [{ debugName: "animationDuration" }] : []));
1941
+ animation = withConfigDefault(this.animationInput, computed(() => this.popoverDefaults()?.animation), 'fade');
1942
+ showHeader = input(true, ...(ngDevMode ? [{ debugName: "showHeader" }] : []));
1943
+ showFooter = input(true, ...(ngDevMode ? [{ debugName: "showFooter" }] : []));
1944
+ showCloseButton = input(false, ...(ngDevMode ? [{ debugName: "showCloseButton" }] : []));
1945
+ content = input(undefined, ...(ngDevMode ? [{ debugName: "content" }] : []));
1946
+ zIndex = input(1000, ...(ngDevMode ? [{ debugName: "zIndex" }] : []));
1947
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
1948
+ role = input('dialog', ...(ngDevMode ? [{ debugName: "role" }] : []));
1949
+ visibleChange = output();
1950
+ opened = output();
1951
+ closed = output();
1952
+ positionChanged = output();
1953
+ cleanup;
1954
+ openTimeout;
1955
+ closeTimeout;
1956
+ isHovered = signal(false, ...(ngDevMode ? [{ debugName: "isHovered" }] : []));
1957
+ isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
1958
+ hostClasses = computed(() => classNames('studio-popover', 'studio-popover--' + this.variant(), 'studio-popover--' + this.size(), 'studio-popover--' + this.animation(), this.visible() && 'studio-popover--visible', this.showOverlay() && 'studio-popover--with-overlay'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
1959
+ constructor() {
1960
+ effect(() => {
1961
+ if (this.visible()) {
1962
+ this.handleOpen();
1963
+ }
1964
+ else {
1965
+ this.handleClose();
1966
+ }
1967
+ });
1968
+ afterNextRender(() => {
1969
+ this.setupPositioning();
1970
+ }, { injector: this.injector });
1971
+ this.destroyRef.onDestroy(() => {
1972
+ this.cleanup?.();
1973
+ this.clearTimeouts();
1974
+ });
1975
+ }
1976
+ setupPositioning() {
1977
+ const triggerElement = this.triggerEl()?.nativeElement;
1978
+ const panelElement = this.panelEl()?.nativeElement;
1979
+ if (!triggerElement || !panelElement)
1980
+ return;
1981
+ this.cleanup?.();
1982
+ this.cleanup = autoUpdate(triggerElement, panelElement, () => {
1983
+ this.updatePosition();
1984
+ });
1985
+ }
1986
+ async updatePosition() {
1987
+ const triggerElement = this.triggerEl()?.nativeElement;
1988
+ const panelElement = this.panelEl()?.nativeElement;
1989
+ const arrowElement = this.arrowEl()?.nativeElement;
1990
+ if (!triggerElement || !panelElement || !this.visible())
1991
+ return;
1992
+ const middleware = [
1993
+ offset(this.offset()),
1994
+ this.flipValue() && flip(),
1995
+ this.preventOverflow() && shift({ padding: 8 }),
1996
+ arrowElement && this.arrow() && arrow({ element: arrowElement })
1997
+ ].filter(Boolean);
1998
+ const { x, y, placement, middlewareData } = await computePosition(triggerElement, panelElement, {
1999
+ placement: this.position(),
2000
+ middleware
2001
+ });
2002
+ Object.assign(panelElement.style, {
2003
+ left: x + 'px',
2004
+ top: y + 'px',
2005
+ });
2006
+ if (arrowElement && middlewareData.arrow && this.arrow()) {
2007
+ const { x: arrowX, y: arrowY } = middlewareData.arrow;
2008
+ const staticSide = {
2009
+ top: 'bottom',
2010
+ right: 'left',
2011
+ bottom: 'top',
2012
+ left: 'right',
2013
+ }[placement.split('-')[0]];
2014
+ Object.assign(arrowElement.style, {
2015
+ left: arrowX != null ? arrowX + 'px' : '',
2016
+ top: arrowY != null ? arrowY + 'px' : '',
2017
+ right: '',
2018
+ bottom: '',
2019
+ [staticSide]: '-' + (this.arrowSize() / 2) + 'px',
2020
+ });
2021
+ }
2022
+ this.positionChanged.emit(placement);
2023
+ }
2024
+ handleOpen() {
2025
+ if (this.closeOnScroll()) {
2026
+ this.document.addEventListener('scroll', this.handleScrollBind, true);
2027
+ }
2028
+ this.opened.emit();
2029
+ setTimeout(() => this.updatePosition(), 0);
2030
+ }
2031
+ handleClose() {
2032
+ if (this.closeOnScroll()) {
2033
+ this.document.removeEventListener('scroll', this.handleScrollBind, true);
2034
+ }
2035
+ this.closed.emit();
2036
+ }
2037
+ handleScrollBind = this.handleScroll.bind(this);
2038
+ handleScroll() {
2039
+ if (this.visible()) {
2040
+ this.close();
2041
+ }
2042
+ }
2043
+ open() {
2044
+ if (this.disabled())
2045
+ return;
2046
+ this.visible.set(true);
2047
+ this.visibleChange.emit(true);
2048
+ }
2049
+ close() {
2050
+ this.visible.set(false);
2051
+ this.visibleChange.emit(false);
2052
+ }
2053
+ toggle() {
2054
+ if (this.visible()) {
2055
+ this.close();
2056
+ }
2057
+ else {
2058
+ this.open();
2059
+ }
2060
+ }
2061
+ handleTriggerClick() {
2062
+ if (this.trigger() === 'click' || this.trigger() === 'manual') {
2063
+ this.toggle();
2064
+ }
2065
+ }
2066
+ handleTriggerMouseEnter() {
2067
+ if (this.trigger() === 'hover') {
2068
+ this.clearTimeouts();
2069
+ this.isHovered.set(true);
2070
+ this.openTimeout = window.setTimeout(() => {
2071
+ this.open();
2072
+ }, this.openDelay());
2073
+ }
2074
+ }
2075
+ handleTriggerMouseLeave() {
2076
+ if (this.trigger() === 'hover') {
2077
+ this.clearTimeouts();
2078
+ this.isHovered.set(false);
2079
+ this.closeTimeout = window.setTimeout(() => {
2080
+ if (!this.isHovered()) {
2081
+ this.close();
2082
+ }
2083
+ }, this.closeDelay());
2084
+ }
2085
+ }
2086
+ handlePanelMouseEnter() {
2087
+ if (this.trigger() === 'hover') {
2088
+ this.clearTimeouts();
2089
+ this.isHovered.set(true);
2090
+ }
2091
+ }
2092
+ handlePanelMouseLeave() {
2093
+ if (this.trigger() === 'hover') {
2094
+ this.isHovered.set(false);
2095
+ this.closeTimeout = window.setTimeout(() => {
2096
+ if (!this.isHovered()) {
2097
+ this.close();
2098
+ }
2099
+ }, this.closeDelay());
2100
+ }
2101
+ }
2102
+ handleTriggerFocus() {
2103
+ if (this.trigger() === 'focus') {
2104
+ this.isFocused.set(true);
2105
+ this.open();
2106
+ }
2107
+ }
2108
+ handleTriggerBlur() {
2109
+ if (this.trigger() === 'focus') {
2110
+ this.isFocused.set(false);
2111
+ setTimeout(() => {
2112
+ if (!this.isFocused()) {
2113
+ this.close();
2114
+ }
2115
+ }, 100);
2116
+ }
2117
+ }
2118
+ handleBackdropClick() {
2119
+ if (this.closeOnClickOutside()) {
2120
+ this.close();
2121
+ }
2122
+ }
2123
+ handleDocumentClick(event) {
2124
+ if (!this.visible() || !this.closeOnClickOutside())
2125
+ return;
2126
+ const target = event.target;
2127
+ const panel = this.panelEl()?.nativeElement;
2128
+ const trigger = this.triggerEl()?.nativeElement;
2129
+ if (panel && !panel.contains(target) && trigger && !trigger.contains(target)) {
2130
+ this.close();
2131
+ }
2132
+ }
2133
+ handleEscapeKey(event) {
2134
+ if (this.visible() && this.closeOnEscape()) {
2135
+ event.preventDefault();
2136
+ this.close();
2137
+ }
2138
+ }
2139
+ clearTimeouts() {
2140
+ if (this.openTimeout) {
2141
+ window.clearTimeout(this.openTimeout);
2142
+ this.openTimeout = undefined;
2143
+ }
2144
+ if (this.closeTimeout) {
2145
+ window.clearTimeout(this.closeTimeout);
2146
+ this.closeTimeout = undefined;
2147
+ }
2148
+ }
2149
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2150
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: PopoverComponent, isStandalone: true, selector: "studio-popover", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, triggerInput: { classPropertyName: "triggerInput", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, openDelay: { classPropertyName: "openDelay", publicName: "openDelay", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", isSignal: true, isRequired: false, transformFunction: null }, positionInput: { classPropertyName: "positionInput", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, preventOverflow: { classPropertyName: "preventOverflow", publicName: "preventOverflow", isSignal: true, isRequired: false, transformFunction: null }, flipValue: { classPropertyName: "flipValue", publicName: "flipValue", isSignal: true, isRequired: false, transformFunction: null }, variantInput: { classPropertyName: "variantInput", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, arrow: { classPropertyName: "arrow", publicName: "arrow", isSignal: true, isRequired: false, transformFunction: null }, arrowSize: { classPropertyName: "arrowSize", publicName: "arrowSize", isSignal: true, isRequired: false, transformFunction: null }, closeOnClickOutside: { classPropertyName: "closeOnClickOutside", publicName: "closeOnClickOutside", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, closeOnScroll: { classPropertyName: "closeOnScroll", publicName: "closeOnScroll", isSignal: true, isRequired: false, transformFunction: null }, showOverlay: { classPropertyName: "showOverlay", publicName: "showOverlay", isSignal: true, isRequired: false, transformFunction: null }, overlayOpacity: { classPropertyName: "overlayOpacity", publicName: "overlayOpacity", isSignal: true, isRequired: false, transformFunction: null }, animationInput: { classPropertyName: "animationInput", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showCloseButton: { classPropertyName: "showCloseButton", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", 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 } }, outputs: { visible: "visibleChange", visibleChange: "visibleChange", opened: "opened", closed: "closed", positionChanged: "positionChanged" }, host: { listeners: { "document:click": "handleDocumentClick($event)", "document:keydown.escape": "handleEscapeKey($event)" }, properties: { "class": "hostClasses()", "attr.data-visible": "visible()" } }, queries: [{ propertyName: "headerTemplate", first: true, predicate: ["popoverHeader"], descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["popoverFooter"], descendants: true, isSignal: true }, { propertyName: "contentTemplate", first: true, predicate: ["popoverContent"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["popoverTrigger"], descendants: true, isSignal: true }, { propertyName: "panelEl", first: true, predicate: ["popoverPanel"], descendants: true, isSignal: true }, { propertyName: "arrowEl", first: true, predicate: ["popoverArrow"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (showOverlay() && visible()) {\n <div\n class=\"studio-popover__overlay\"\n [style.opacity]=\"overlayOpacity()\"\n [style.z-index]=\"zIndex()\"\n (click)=\"handleBackdropClick()\"\n ></div>\n}\n\n<div\n #popoverTrigger\n class=\"studio-popover__trigger\"\n (click)=\"handleTriggerClick()\"\n (mouseenter)=\"handleTriggerMouseEnter()\"\n (mouseleave)=\"handleTriggerMouseLeave()\"\n (focus)=\"handleTriggerFocus()\"\n (blur)=\"handleTriggerBlur()\"\n>\n <ng-content />\n</div>\n\n@if (visible()) {\n <div\n #popoverPanel\n class=\"studio-popover__panel\"\n [style.z-index]=\"zIndex() + 1\"\n [style.width]=\"width() === 'auto' ? 'auto' : width() === 'trigger' && triggerEl()?.nativeElement ? triggerEl()!.nativeElement.offsetWidth + 'px' : width()\"\n [style.min-width]=\"minWidth() ? (typeof minWidth() === 'number' ? minWidth() + 'px' : minWidth()) : undefined\"\n [style.max-width]=\"maxWidth() ? (typeof maxWidth() === 'number' ? maxWidth() + 'px' : maxWidth()) : undefined\"\n [style.max-height]=\"maxHeight() ? (typeof maxHeight() === 'number' ? maxHeight() + 'px' : maxHeight()) : undefined\"\n [style.padding]=\"padding()\"\n [attr.role]=\"role()\"\n [attr.aria-label]=\"ariaLabel()\"\n (mouseenter)=\"handlePanelMouseEnter()\"\n (mouseleave)=\"handlePanelMouseLeave()\"\n >\n @if (arrow()) {\n <div #popoverArrow class=\"studio-popover__arrow\" [style.width.px]=\"arrowSize()\" [style.height.px]=\"arrowSize()\"></div>\n }\n\n @if (showHeader() && (headerTemplate() || showCloseButton())) {\n <div class=\"studio-popover__header\">\n @if (headerTemplate()) {\n <ng-container *ngTemplateOutlet=\"headerTemplate()!\" />\n }\n \n @if (showCloseButton()) {\n <button\n type=\"button\"\n class=\"studio-popover__close\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\n <studio-icon name=\"x\" [size]=\"18\" />\n </button>\n }\n </div>\n }\n\n <div class=\"studio-popover__content\">\n @if (contentTemplate()) {\n <ng-container *ngTemplateOutlet=\"contentTemplate()!\" />\n } @else if (content()) {\n {{ content() }}\n } @else {\n <ng-content select=\"[popoverContent]\" />\n }\n </div>\n\n @if (showFooter() && footerTemplate()) {\n <div class=\"studio-popover__footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()!\" />\n </div>\n }\n </div>\n}\n", styles: [":host{display:inline-block;font-family:var(--studio-font-family)}.studio-popover__trigger{display:inline-flex;cursor:pointer}.studio-popover__overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--studio-transition-base)}:host(.studio-popover--visible) .studio-popover__overlay{opacity:var(--popover-overlay-opacity, .5)}.studio-popover__panel{position:absolute;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);box-shadow:var(--studio-shadow-lg);opacity:0;visibility:hidden;transition:opacity var(--popover-animation-duration, .2s) ease-out,transform var(--popover-animation-duration, .2s) ease-out,visibility 0ms var(--popover-animation-duration, .2s);will-change:transform,opacity}:host(.studio-popover--visible) .studio-popover__panel{opacity:1;visibility:visible;transition:opacity var(--popover-animation-duration, .2s) ease-out,transform var(--popover-animation-duration, .2s) ease-out,visibility 0ms}:host(.studio-popover--fade) .studio-popover__panel{transform:scale(.95)}:host(.studio-popover--fade.studio-popover--visible) .studio-popover__panel{transform:scale(1)}:host(.studio-popover--scale) .studio-popover__panel{transform:scale(.8)}:host(.studio-popover--scale.studio-popover--visible) .studio-popover__panel{transform:scale(1)}:host(.studio-popover--slide) .studio-popover__panel{transform:translateY(-8px)}:host(.studio-popover--slide.studio-popover--visible) .studio-popover__panel{transform:translateY(0)}:host(.studio-popover--none) .studio-popover__panel{transition:none}:host(.studio-popover--bordered) .studio-popover__panel{border:2px solid var(--studio-border-secondary);box-shadow:none}:host(.studio-popover--shadow) .studio-popover__panel{border:none;box-shadow:var(--studio-shadow-xl)}:host(.studio-popover--minimal) .studio-popover__panel{border:none;box-shadow:var(--studio-shadow-sm)}:host(.studio-popover--sm) .studio-popover__panel{font-size:var(--studio-font-size-sm)}:host(.studio-popover--md) .studio-popover__panel{font-size:var(--studio-font-size-base)}:host(.studio-popover--lg) .studio-popover__panel{font-size:var(--studio-font-size-lg)}.studio-popover__arrow{position:absolute;background:var(--studio-bg-primary);transform:rotate(45deg);border:1px solid var(--studio-border-primary);border-right:none;border-bottom:none;z-index:-1}:host(.studio-popover--bordered) .studio-popover__arrow{border-color:var(--studio-border-secondary);border-width:2px}:host(.studio-popover--shadow) .studio-popover__arrow,:host(.studio-popover--minimal) .studio-popover__arrow{border:none}.studio-popover__header{display:flex;align-items:center;justify-content:space-between;gap:var(--studio-spacing-md);padding:var(--studio-spacing-md) var(--studio-spacing-md) var(--studio-spacing-sm);border-bottom:1px solid var(--studio-border-primary)}.studio-popover__close{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:none;border:none;border-radius:var(--studio-radius-sm);color:var(--studio-text-secondary);cursor:pointer;transition:all var(--studio-transition-fast);flex-shrink:0}.studio-popover__close:hover{background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-popover__close:active{transform:scale(.95)}.studio-popover__content{padding:var(--studio-spacing-md);color:var(--studio-text-primary)}.studio-popover__header+.studio-popover__content{padding-top:var(--studio-spacing-md)}.studio-popover__footer{padding:var(--studio-spacing-sm) var(--studio-spacing-md) var(--studio-spacing-md);border-top:1px solid var(--studio-border-primary);display:flex;align-items:center;gap:var(--studio-spacing-sm)}:host(.studio-popover--sm) .studio-popover__content{padding:var(--studio-spacing-sm)}:host(.studio-popover--lg) .studio-popover__content{padding:var(--studio-spacing-lg)}\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 });
2151
+ }
2152
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: PopoverComponent, decorators: [{
2153
+ type: Component,
2154
+ args: [{ selector: 'studio-popover', standalone: true, imports: [NgTemplateOutlet, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
2155
+ '[class]': 'hostClasses()',
2156
+ '[attr.data-visible]': 'visible()',
2157
+ }, template: "@if (showOverlay() && visible()) {\n <div\n class=\"studio-popover__overlay\"\n [style.opacity]=\"overlayOpacity()\"\n [style.z-index]=\"zIndex()\"\n (click)=\"handleBackdropClick()\"\n ></div>\n}\n\n<div\n #popoverTrigger\n class=\"studio-popover__trigger\"\n (click)=\"handleTriggerClick()\"\n (mouseenter)=\"handleTriggerMouseEnter()\"\n (mouseleave)=\"handleTriggerMouseLeave()\"\n (focus)=\"handleTriggerFocus()\"\n (blur)=\"handleTriggerBlur()\"\n>\n <ng-content />\n</div>\n\n@if (visible()) {\n <div\n #popoverPanel\n class=\"studio-popover__panel\"\n [style.z-index]=\"zIndex() + 1\"\n [style.width]=\"width() === 'auto' ? 'auto' : width() === 'trigger' && triggerEl()?.nativeElement ? triggerEl()!.nativeElement.offsetWidth + 'px' : width()\"\n [style.min-width]=\"minWidth() ? (typeof minWidth() === 'number' ? minWidth() + 'px' : minWidth()) : undefined\"\n [style.max-width]=\"maxWidth() ? (typeof maxWidth() === 'number' ? maxWidth() + 'px' : maxWidth()) : undefined\"\n [style.max-height]=\"maxHeight() ? (typeof maxHeight() === 'number' ? maxHeight() + 'px' : maxHeight()) : undefined\"\n [style.padding]=\"padding()\"\n [attr.role]=\"role()\"\n [attr.aria-label]=\"ariaLabel()\"\n (mouseenter)=\"handlePanelMouseEnter()\"\n (mouseleave)=\"handlePanelMouseLeave()\"\n >\n @if (arrow()) {\n <div #popoverArrow class=\"studio-popover__arrow\" [style.width.px]=\"arrowSize()\" [style.height.px]=\"arrowSize()\"></div>\n }\n\n @if (showHeader() && (headerTemplate() || showCloseButton())) {\n <div class=\"studio-popover__header\">\n @if (headerTemplate()) {\n <ng-container *ngTemplateOutlet=\"headerTemplate()!\" />\n }\n \n @if (showCloseButton()) {\n <button\n type=\"button\"\n class=\"studio-popover__close\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\n <studio-icon name=\"x\" [size]=\"18\" />\n </button>\n }\n </div>\n }\n\n <div class=\"studio-popover__content\">\n @if (contentTemplate()) {\n <ng-container *ngTemplateOutlet=\"contentTemplate()!\" />\n } @else if (content()) {\n {{ content() }}\n } @else {\n <ng-content select=\"[popoverContent]\" />\n }\n </div>\n\n @if (showFooter() && footerTemplate()) {\n <div class=\"studio-popover__footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()!\" />\n </div>\n }\n </div>\n}\n", styles: [":host{display:inline-block;font-family:var(--studio-font-family)}.studio-popover__trigger{display:inline-flex;cursor:pointer}.studio-popover__overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--studio-transition-base)}:host(.studio-popover--visible) .studio-popover__overlay{opacity:var(--popover-overlay-opacity, .5)}.studio-popover__panel{position:absolute;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);box-shadow:var(--studio-shadow-lg);opacity:0;visibility:hidden;transition:opacity var(--popover-animation-duration, .2s) ease-out,transform var(--popover-animation-duration, .2s) ease-out,visibility 0ms var(--popover-animation-duration, .2s);will-change:transform,opacity}:host(.studio-popover--visible) .studio-popover__panel{opacity:1;visibility:visible;transition:opacity var(--popover-animation-duration, .2s) ease-out,transform var(--popover-animation-duration, .2s) ease-out,visibility 0ms}:host(.studio-popover--fade) .studio-popover__panel{transform:scale(.95)}:host(.studio-popover--fade.studio-popover--visible) .studio-popover__panel{transform:scale(1)}:host(.studio-popover--scale) .studio-popover__panel{transform:scale(.8)}:host(.studio-popover--scale.studio-popover--visible) .studio-popover__panel{transform:scale(1)}:host(.studio-popover--slide) .studio-popover__panel{transform:translateY(-8px)}:host(.studio-popover--slide.studio-popover--visible) .studio-popover__panel{transform:translateY(0)}:host(.studio-popover--none) .studio-popover__panel{transition:none}:host(.studio-popover--bordered) .studio-popover__panel{border:2px solid var(--studio-border-secondary);box-shadow:none}:host(.studio-popover--shadow) .studio-popover__panel{border:none;box-shadow:var(--studio-shadow-xl)}:host(.studio-popover--minimal) .studio-popover__panel{border:none;box-shadow:var(--studio-shadow-sm)}:host(.studio-popover--sm) .studio-popover__panel{font-size:var(--studio-font-size-sm)}:host(.studio-popover--md) .studio-popover__panel{font-size:var(--studio-font-size-base)}:host(.studio-popover--lg) .studio-popover__panel{font-size:var(--studio-font-size-lg)}.studio-popover__arrow{position:absolute;background:var(--studio-bg-primary);transform:rotate(45deg);border:1px solid var(--studio-border-primary);border-right:none;border-bottom:none;z-index:-1}:host(.studio-popover--bordered) .studio-popover__arrow{border-color:var(--studio-border-secondary);border-width:2px}:host(.studio-popover--shadow) .studio-popover__arrow,:host(.studio-popover--minimal) .studio-popover__arrow{border:none}.studio-popover__header{display:flex;align-items:center;justify-content:space-between;gap:var(--studio-spacing-md);padding:var(--studio-spacing-md) var(--studio-spacing-md) var(--studio-spacing-sm);border-bottom:1px solid var(--studio-border-primary)}.studio-popover__close{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:none;border:none;border-radius:var(--studio-radius-sm);color:var(--studio-text-secondary);cursor:pointer;transition:all var(--studio-transition-fast);flex-shrink:0}.studio-popover__close:hover{background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-popover__close:active{transform:scale(.95)}.studio-popover__content{padding:var(--studio-spacing-md);color:var(--studio-text-primary)}.studio-popover__header+.studio-popover__content{padding-top:var(--studio-spacing-md)}.studio-popover__footer{padding:var(--studio-spacing-sm) var(--studio-spacing-md) var(--studio-spacing-md);border-top:1px solid var(--studio-border-primary);display:flex;align-items:center;gap:var(--studio-spacing-sm)}:host(.studio-popover--sm) .studio-popover__content{padding:var(--studio-spacing-sm)}:host(.studio-popover--lg) .studio-popover__content{padding:var(--studio-spacing-lg)}\n"] }]
2158
+ }], ctorParameters: () => [], propDecorators: { headerTemplate: [{ type: i0.ContentChild, args: ['popoverHeader', { isSignal: true }] }], footerTemplate: [{ type: i0.ContentChild, args: ['popoverFooter', { isSignal: true }] }], contentTemplate: [{ type: i0.ContentChild, args: ['popoverContent', { isSignal: true }] }], triggerEl: [{ type: i0.ViewChild, args: ['popoverTrigger', { isSignal: true }] }], panelEl: [{ type: i0.ViewChild, args: ['popoverPanel', { isSignal: true }] }], arrowEl: [{ type: i0.ViewChild, args: ['popoverArrow', { 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"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], triggerInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], openDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "openDelay", required: false }] }], closeDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDelay", required: false }] }], positionInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], preventOverflow: [{ type: i0.Input, args: [{ isSignal: true, alias: "preventOverflow", required: false }] }], flipValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "flipValue", required: false }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }], arrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrow", required: false }] }], arrowSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrowSize", required: false }] }], closeOnClickOutside: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClickOutside", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], closeOnScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnScroll", required: false }] }], showOverlay: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOverlay", required: false }] }], overlayOpacity: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayOpacity", required: false }] }], animationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "animation", required: false }] }], animationDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationDuration", required: false }] }], showHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], showCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], zIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "zIndex", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], role: [{ 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"] }], positionChanged: [{ type: i0.Output, args: ["positionChanged"] }], handleDocumentClick: [{
2159
+ type: HostListener,
2160
+ args: ['document:click', ['$event']]
2161
+ }], handleEscapeKey: [{
2162
+ type: HostListener,
2163
+ args: ['document:keydown.escape', ['$event']]
2164
+ }] } });
2165
+
2166
+ class ColorPickerCompactComponent {
2167
+ configService = inject(StudioConfigService);
2168
+ trigger = input('click', ...(ngDevMode ? [{ debugName: "trigger" }] : []));
2169
+ position = input('bottom-start', ...(ngDevMode ? [{ debugName: "position" }] : []));
2170
+ popoverWidth = input('280px', ...(ngDevMode ? [{ debugName: "popoverWidth" }] : []));
2171
+ showArrow = input(false, ...(ngDevMode ? [{ debugName: "showArrow" }] : []));
2172
+ closeOnClickOutside = input(true, ...(ngDevMode ? [{ debugName: "closeOnClickOutside" }] : []));
2173
+ triggerSize = input('32px', ...(ngDevMode ? [{ debugName: "triggerSize" }] : []));
2174
+ triggerRadius = input('var(--studio-radius-sm)', ...(ngDevMode ? [{ debugName: "triggerRadius" }] : []));
2175
+ showCurrentColor = input(false, ...(ngDevMode ? [{ debugName: "showCurrentColor" }] : []));
2176
+ format = input('hex', ...(ngDevMode ? [{ debugName: "format" }] : []));
2177
+ showAlpha = input(false, ...(ngDevMode ? [{ debugName: "showAlpha" }] : []));
2178
+ showPresets = input(true, ...(ngDevMode ? [{ debugName: "showPresets" }] : []));
2179
+ showFormatToggle = input(false, ...(ngDevMode ? [{ debugName: "showFormatToggle" }] : []));
2180
+ showCopyButton = input(false, ...(ngDevMode ? [{ debugName: "showCopyButton" }] : []));
2181
+ presets = input(undefined, ...(ngDevMode ? [{ debugName: "presets" }] : []));
2182
+ showFooter = input(true, ...(ngDevMode ? [{ debugName: "showFooter" }] : []));
2183
+ applyLabel = input('OK', ...(ngDevMode ? [{ debugName: "applyLabel" }] : []));
2184
+ cancelLabel = input('Отмена', ...(ngDevMode ? [{ debugName: "cancelLabel" }] : []));
2185
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
2186
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
2187
+ colorChange = output();
2188
+ currentValue = signal('#000000', ...(ngDevMode ? [{ debugName: "currentValue" }] : []));
2189
+ tempValue = signal('#000000', ...(ngDevMode ? [{ debugName: "tempValue" }] : []));
2190
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
2191
+ hostClasses = computed(() => classNames('color-picker-compact', this.disabled() && 'color-picker-compact--disabled'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
2192
+ onChange = () => { };
2193
+ onTouched = () => { };
2194
+ constructor() {
2195
+ effect(() => {
2196
+ // Sync temp value when popover opens
2197
+ if (this.isOpen()) {
2198
+ this.tempValue.set(this.currentValue());
2199
+ }
2200
+ });
2201
+ }
2202
+ handleApply() {
2203
+ this.currentValue.set(this.tempValue());
2204
+ this.onChange(this.tempValue());
2205
+ this.colorChange.emit(this.tempValue());
2206
+ this.onTouched();
2207
+ this.isOpen.set(false);
2208
+ }
2209
+ handleCancel() {
2210
+ this.tempValue.set(this.currentValue());
2211
+ this.isOpen.set(false);
2212
+ }
2213
+ writeValue(value) {
2214
+ if (value) {
2215
+ this.currentValue.set(value);
2216
+ this.tempValue.set(value);
2217
+ }
2218
+ }
2219
+ registerOnChange(fn) {
2220
+ this.onChange = fn;
2221
+ }
2222
+ registerOnTouched(fn) {
2223
+ this.onTouched = fn;
2224
+ }
2225
+ setDisabledState(isDisabled) { }
2226
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ColorPickerCompactComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2227
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: ColorPickerCompactComponent, isStandalone: true, selector: "studio-color-picker-compact", inputs: { trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, popoverWidth: { classPropertyName: "popoverWidth", publicName: "popoverWidth", isSignal: true, isRequired: false, transformFunction: null }, showArrow: { classPropertyName: "showArrow", publicName: "showArrow", isSignal: true, isRequired: false, transformFunction: null }, closeOnClickOutside: { classPropertyName: "closeOnClickOutside", publicName: "closeOnClickOutside", isSignal: true, isRequired: false, transformFunction: null }, triggerSize: { classPropertyName: "triggerSize", publicName: "triggerSize", isSignal: true, isRequired: false, transformFunction: null }, triggerRadius: { classPropertyName: "triggerRadius", publicName: "triggerRadius", isSignal: true, isRequired: false, transformFunction: null }, showCurrentColor: { classPropertyName: "showCurrentColor", publicName: "showCurrentColor", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, showAlpha: { classPropertyName: "showAlpha", publicName: "showAlpha", isSignal: true, isRequired: false, transformFunction: null }, showPresets: { classPropertyName: "showPresets", publicName: "showPresets", isSignal: true, isRequired: false, transformFunction: null }, showFormatToggle: { classPropertyName: "showFormatToggle", publicName: "showFormatToggle", isSignal: true, isRequired: false, transformFunction: null }, showCopyButton: { classPropertyName: "showCopyButton", publicName: "showCopyButton", isSignal: true, isRequired: false, transformFunction: null }, presets: { classPropertyName: "presets", publicName: "presets", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, applyLabel: { classPropertyName: "applyLabel", publicName: "applyLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { colorChange: "colorChange" }, host: { properties: { "class": "hostClasses()" } }, providers: [
2228
+ {
2229
+ provide: NG_VALUE_ACCESSOR,
2230
+ useExisting: forwardRef(() => ColorPickerCompactComponent),
2231
+ multi: true
2232
+ }
2233
+ ], ngImport: i0, template: `
2234
+ <studio-popover
2235
+ [trigger]="trigger()"
2236
+ [position]="position()"
2237
+ [width]="popoverWidth()"
2238
+ [arrow]="showArrow()"
2239
+ [closeOnClickOutside]="false"
2240
+ [(visible)]="isOpen"
2241
+ [showFooter]="showFooter()"
2242
+ >
2243
+ <div
2244
+ class="color-picker-compact__trigger"
2245
+ [class.color-picker-compact__trigger--disabled]="disabled()"
2246
+ [style.width]="triggerSize()"
2247
+ [style.height]="triggerSize()"
2248
+ [style.border-radius]="triggerRadius()"
2249
+ [style.background]="currentValue()"
2250
+ [attr.aria-label]="ariaLabel() || 'Select color'"
2251
+ [attr.role]="'button'"
2252
+ [attr.tabindex]="disabled() ? -1 : 0"
2253
+ >
2254
+ @if (showCurrentColor()) {
2255
+ <span class="color-picker-compact__color-text">{{ currentValue() }}</span>
2256
+ }
2257
+ </div>
2258
+
2259
+ <div popoverContent>
2260
+ <studio-color-picker
2261
+ [(ngModel)]="tempValue"
2262
+ [format]="format()"
2263
+ [showAlpha]="showAlpha()"
2264
+ [showPresets]="showPresets()"
2265
+ [showFormatToggle]="showFormatToggle()"
2266
+ [showCopyButton]="showCopyButton()"
2267
+ [presets]="presets()"
2268
+ [disabled]="disabled()"
2269
+ />
2270
+ </div>
2271
+
2272
+ @if (showFooter()) {
2273
+ <ng-template #popoverFooter>
2274
+ <div class="color-picker-compact__footer">
2275
+ <studio-button
2276
+ variant="outline"
2277
+ size="sm"
2278
+ (click)="handleCancel()"
2279
+ [fullWidth]="true"
2280
+ >
2281
+ {{ cancelLabel() }}
2282
+ </studio-button>
2283
+ <studio-button
2284
+ size="sm"
2285
+ (click)="handleApply()"
2286
+ [fullWidth]="true"
2287
+ >
2288
+ {{ applyLabel() }}
2289
+ </studio-button>
2290
+ </div>
2291
+ </ng-template>
2292
+ }
2293
+ </studio-popover>
2294
+ `, isInline: true, styles: [":host{display:inline-block}.color-picker-compact__trigger{position:relative;cursor:pointer;border:2px solid var(--studio-border-primary);transition:all var(--studio-transition-fast);overflow:hidden;&--disabled{cursor:not-allowed;opacity:.5}}.color-picker-compact__trigger:hover:not(.color-picker-compact__trigger--disabled){border-color:var(--studio-border-secondary);transform:scale(1.05)}.color-picker-compact__trigger:active:not(.color-picker-compact__trigger--disabled){transform:scale(.95)}.color-picker-compact__trigger:focus-visible{outline:2px solid var(--studio-primary);outline-offset:2px}.color-picker-compact__color-text{position:absolute;bottom:0;left:0;right:0;padding:.125rem .25rem;background:#0009;color:#fff;font-size:.625rem;text-align:center;font-family:var(--studio-font-family-mono, monospace)}.color-picker-compact__footer{display:flex;gap:.75rem;padding:1rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: PopoverComponent, selector: "studio-popover", inputs: ["id", "visible", "disabled", "trigger", "openDelay", "closeDelay", "position", "offset", "preventOverflow", "flipValue", "variant", "size", "width", "minWidth", "maxWidth", "maxHeight", "padding", "arrow", "arrowSize", "closeOnClickOutside", "closeOnEscape", "closeOnScroll", "showOverlay", "overlayOpacity", "animation", "animationDuration", "showHeader", "showFooter", "showCloseButton", "content", "zIndex", "ariaLabel", "role"], outputs: ["visibleChange", "opened", "closed", "positionChanged"] }, { kind: "component", type: ColorPickerComponent, selector: "studio-color-picker", inputs: ["variant", "size", "format", "showAlpha", "showPresets", "showFormatToggle", "showCopyButton", "presets", "label", "hint", "required", "error", "errorMessage", "disabled", "readonly"], outputs: ["colorChange", "colorValueChange", "copied"] }, { kind: "component", type: ButtonComponent, selector: "studio-button", inputs: ["variant", "size", "color", "radius", "shadow", "compact", "disabled", "loading", "loadingText", "fullWidth", "type", "icon", "iconPosition", "href", "target", "badge", "badgeColor", "ariaLabel"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2295
+ }
2296
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ColorPickerCompactComponent, decorators: [{
2297
+ type: Component,
2298
+ args: [{ selector: 'studio-color-picker-compact', standalone: true, imports: [FormsModule, PopoverComponent, ColorPickerComponent, ButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
2299
+ {
2300
+ provide: NG_VALUE_ACCESSOR,
2301
+ useExisting: forwardRef(() => ColorPickerCompactComponent),
2302
+ multi: true
2303
+ }
2304
+ ], host: {
2305
+ '[class]': 'hostClasses()',
2306
+ }, template: `
2307
+ <studio-popover
2308
+ [trigger]="trigger()"
2309
+ [position]="position()"
2310
+ [width]="popoverWidth()"
2311
+ [arrow]="showArrow()"
2312
+ [closeOnClickOutside]="false"
2313
+ [(visible)]="isOpen"
2314
+ [showFooter]="showFooter()"
2315
+ >
2316
+ <div
2317
+ class="color-picker-compact__trigger"
2318
+ [class.color-picker-compact__trigger--disabled]="disabled()"
2319
+ [style.width]="triggerSize()"
2320
+ [style.height]="triggerSize()"
2321
+ [style.border-radius]="triggerRadius()"
2322
+ [style.background]="currentValue()"
2323
+ [attr.aria-label]="ariaLabel() || 'Select color'"
2324
+ [attr.role]="'button'"
2325
+ [attr.tabindex]="disabled() ? -1 : 0"
2326
+ >
2327
+ @if (showCurrentColor()) {
2328
+ <span class="color-picker-compact__color-text">{{ currentValue() }}</span>
2329
+ }
2330
+ </div>
2331
+
2332
+ <div popoverContent>
2333
+ <studio-color-picker
2334
+ [(ngModel)]="tempValue"
2335
+ [format]="format()"
2336
+ [showAlpha]="showAlpha()"
2337
+ [showPresets]="showPresets()"
2338
+ [showFormatToggle]="showFormatToggle()"
2339
+ [showCopyButton]="showCopyButton()"
2340
+ [presets]="presets()"
2341
+ [disabled]="disabled()"
2342
+ />
2343
+ </div>
2344
+
2345
+ @if (showFooter()) {
2346
+ <ng-template #popoverFooter>
2347
+ <div class="color-picker-compact__footer">
2348
+ <studio-button
2349
+ variant="outline"
2350
+ size="sm"
2351
+ (click)="handleCancel()"
2352
+ [fullWidth]="true"
2353
+ >
2354
+ {{ cancelLabel() }}
2355
+ </studio-button>
2356
+ <studio-button
2357
+ size="sm"
2358
+ (click)="handleApply()"
2359
+ [fullWidth]="true"
2360
+ >
2361
+ {{ applyLabel() }}
2362
+ </studio-button>
2363
+ </div>
2364
+ </ng-template>
2365
+ }
2366
+ </studio-popover>
2367
+ `, styles: [":host{display:inline-block}.color-picker-compact__trigger{position:relative;cursor:pointer;border:2px solid var(--studio-border-primary);transition:all var(--studio-transition-fast);overflow:hidden;&--disabled{cursor:not-allowed;opacity:.5}}.color-picker-compact__trigger:hover:not(.color-picker-compact__trigger--disabled){border-color:var(--studio-border-secondary);transform:scale(1.05)}.color-picker-compact__trigger:active:not(.color-picker-compact__trigger--disabled){transform:scale(.95)}.color-picker-compact__trigger:focus-visible{outline:2px solid var(--studio-primary);outline-offset:2px}.color-picker-compact__color-text{position:absolute;bottom:0;left:0;right:0;padding:.125rem .25rem;background:#0009;color:#fff;font-size:.625rem;text-align:center;font-family:var(--studio-font-family-mono, monospace)}.color-picker-compact__footer{display:flex;gap:.75rem;padding:1rem}\n"] }]
2368
+ }], ctorParameters: () => [], propDecorators: { trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], popoverWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverWidth", required: false }] }], showArrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "showArrow", required: false }] }], closeOnClickOutside: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClickOutside", required: false }] }], triggerSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerSize", required: false }] }], triggerRadius: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerRadius", required: false }] }], showCurrentColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCurrentColor", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], showAlpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAlpha", required: false }] }], showPresets: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPresets", required: false }] }], showFormatToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFormatToggle", required: false }] }], showCopyButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCopyButton", required: false }] }], presets: [{ type: i0.Input, args: [{ isSignal: true, alias: "presets", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], applyLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "applyLabel", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], colorChange: [{ type: i0.Output, args: ["colorChange"] }] } });
2369
+
1676
2370
  /**
1677
2371
  * Service for programmatic control of Drawer components
1678
2372
  *
@@ -2103,6 +2797,106 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2103
2797
  args: ['keydown', ['$event']]
2104
2798
  }] } });
2105
2799
 
2800
+ class DropdownComponent {
2801
+ items = input.required(...(ngDevMode ? [{ debugName: "items" }] : []));
2802
+ trigger = input('click', ...(ngDevMode ? [{ debugName: "trigger" }] : []));
2803
+ position = input('bottom-start', ...(ngDevMode ? [{ debugName: "position" }] : []));
2804
+ width = input('auto', ...(ngDevMode ? [{ debugName: "width" }] : []));
2805
+ minWidth = input('200px', ...(ngDevMode ? [{ debugName: "minWidth" }] : []));
2806
+ itemClick = output();
2807
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
2808
+ hostClasses = computed(() => classNames('studio-dropdown'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
2809
+ handleItemClick(item) {
2810
+ if (item.disabled)
2811
+ return;
2812
+ item.onClick?.();
2813
+ this.itemClick.emit(item);
2814
+ this.isOpen.set(false);
2815
+ }
2816
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: DropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2817
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: DropdownComponent, isStandalone: true, selector: "studio-dropdown", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
2818
+ <studio-popover
2819
+ [trigger]="trigger()"
2820
+ [position]="position()"
2821
+ [width]="width()"
2822
+ [minWidth]="minWidth()"
2823
+ [arrow]="false"
2824
+ [closeOnClickOutside]="true"
2825
+ [(visible)]="isOpen"
2826
+ >
2827
+ <ng-content />
2828
+
2829
+ <div popoverContent style="padding: 0.25rem;">
2830
+ @for (item of items(); track item.id) {
2831
+ @if (item.divider) {
2832
+ <div class="dropdown__divider"></div>
2833
+ } @else {
2834
+ <button
2835
+ type="button"
2836
+ class="dropdown__item"
2837
+ [class.dropdown__item--disabled]="item.disabled"
2838
+ [class.dropdown__item--danger]="item.danger"
2839
+ [disabled]="item.disabled"
2840
+ (click)="handleItemClick(item)"
2841
+ >
2842
+ @if (item.icon) {
2843
+ <studio-icon [name]="item.icon" [size]="16" class="dropdown__icon" />
2844
+ }
2845
+ <span class="dropdown__label">{{ item.label }}</span>
2846
+ @if (item.shortcut) {
2847
+ <span class="dropdown__shortcut">{{ item.shortcut }}</span>
2848
+ }
2849
+ </button>
2850
+ }
2851
+ }
2852
+ </div>
2853
+ </studio-popover>
2854
+ `, isInline: true, styles: [":host{display:inline-block}.dropdown__item{width:100%;display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;background:none;border:none;border-radius:var(--studio-radius-sm);color:var(--studio-text-primary);font-size:.875rem;cursor:pointer;transition:all var(--studio-transition-fast);text-align:left;&--disabled{opacity:.5;cursor:not-allowed}&--danger{color:var(--studio-error)}}.dropdown__item:hover:not(:disabled){background:var(--studio-bg-secondary)}.dropdown__item:active:not(:disabled){transform:scale(.98)}.dropdown__icon{flex-shrink:0;color:var(--studio-text-secondary)}.dropdown__label{flex:1}.dropdown__shortcut{font-size:.75rem;color:var(--studio-text-tertiary);font-family:var(--studio-font-family-mono, monospace)}.dropdown__divider{height:1px;background:var(--studio-border-primary);margin:.25rem 0}\n"], dependencies: [{ kind: "component", type: PopoverComponent, selector: "studio-popover", inputs: ["id", "visible", "disabled", "trigger", "openDelay", "closeDelay", "position", "offset", "preventOverflow", "flipValue", "variant", "size", "width", "minWidth", "maxWidth", "maxHeight", "padding", "arrow", "arrowSize", "closeOnClickOutside", "closeOnEscape", "closeOnScroll", "showOverlay", "overlayOpacity", "animation", "animationDuration", "showHeader", "showFooter", "showCloseButton", "content", "zIndex", "ariaLabel", "role"], outputs: ["visibleChange", "opened", "closed", "positionChanged"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2855
+ }
2856
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: DropdownComponent, decorators: [{
2857
+ type: Component,
2858
+ args: [{ selector: 'studio-dropdown', standalone: true, imports: [PopoverComponent, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
2859
+ '[class]': 'hostClasses()',
2860
+ }, template: `
2861
+ <studio-popover
2862
+ [trigger]="trigger()"
2863
+ [position]="position()"
2864
+ [width]="width()"
2865
+ [minWidth]="minWidth()"
2866
+ [arrow]="false"
2867
+ [closeOnClickOutside]="true"
2868
+ [(visible)]="isOpen"
2869
+ >
2870
+ <ng-content />
2871
+
2872
+ <div popoverContent style="padding: 0.25rem;">
2873
+ @for (item of items(); track item.id) {
2874
+ @if (item.divider) {
2875
+ <div class="dropdown__divider"></div>
2876
+ } @else {
2877
+ <button
2878
+ type="button"
2879
+ class="dropdown__item"
2880
+ [class.dropdown__item--disabled]="item.disabled"
2881
+ [class.dropdown__item--danger]="item.danger"
2882
+ [disabled]="item.disabled"
2883
+ (click)="handleItemClick(item)"
2884
+ >
2885
+ @if (item.icon) {
2886
+ <studio-icon [name]="item.icon" [size]="16" class="dropdown__icon" />
2887
+ }
2888
+ <span class="dropdown__label">{{ item.label }}</span>
2889
+ @if (item.shortcut) {
2890
+ <span class="dropdown__shortcut">{{ item.shortcut }}</span>
2891
+ }
2892
+ </button>
2893
+ }
2894
+ }
2895
+ </div>
2896
+ </studio-popover>
2897
+ `, styles: [":host{display:inline-block}.dropdown__item{width:100%;display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;background:none;border:none;border-radius:var(--studio-radius-sm);color:var(--studio-text-primary);font-size:.875rem;cursor:pointer;transition:all var(--studio-transition-fast);text-align:left;&--disabled{opacity:.5;cursor:not-allowed}&--danger{color:var(--studio-error)}}.dropdown__item:hover:not(:disabled){background:var(--studio-bg-secondary)}.dropdown__item:active:not(:disabled){transform:scale(.98)}.dropdown__icon{flex-shrink:0;color:var(--studio-text-secondary)}.dropdown__label{flex:1}.dropdown__shortcut{font-size:.75rem;color:var(--studio-text-tertiary);font-family:var(--studio-font-family-mono, monospace)}.dropdown__divider{height:1px;background:var(--studio-border-primary);margin:.25rem 0}\n"] }]
2898
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }] } });
2899
+
2106
2900
  /**
2107
2901
  * Input component with form control support, variants, and accessibility
2108
2902
  *
@@ -2604,7 +3398,7 @@ class MenuComponent {
2604
3398
  };
2605
3399
  }
2606
3400
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2607
- 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: [
3401
+ 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$1.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: [
2608
3402
  trigger('expandCollapse', [
2609
3403
  state('collapsed', style({
2610
3404
  height: '0',
@@ -2657,6 +3451,223 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2657
3451
  args: ['keydown', ['$event']]
2658
3452
  }] } });
2659
3453
 
3454
+ class ModalComponent {
3455
+ destroyRef = inject(DestroyRef);
3456
+ // Inputs
3457
+ visible = model(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
3458
+ title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
3459
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
3460
+ variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
3461
+ animation = input('scale', ...(ngDevMode ? [{ debugName: "animation" }] : []));
3462
+ position = input('center', ...(ngDevMode ? [{ debugName: "position" }] : []));
3463
+ showHeader = input(true, ...(ngDevMode ? [{ debugName: "showHeader" }] : []));
3464
+ showFooter = input(true, ...(ngDevMode ? [{ debugName: "showFooter" }] : []));
3465
+ showCloseButton = input(true, ...(ngDevMode ? [{ debugName: "showCloseButton" }] : []));
3466
+ closeOnOverlayClick = input(true, ...(ngDevMode ? [{ debugName: "closeOnOverlayClick" }] : []));
3467
+ closeOnEscape = input(true, ...(ngDevMode ? [{ debugName: "closeOnEscape" }] : []));
3468
+ // Outputs
3469
+ visibleChange = output();
3470
+ opened = output();
3471
+ closed = output();
3472
+ // Template refs
3473
+ headerTemplate = contentChild('modalHeader', ...(ngDevMode ? [{ debugName: "headerTemplate" }] : []));
3474
+ footerTemplate = contentChild('modalFooter', ...(ngDevMode ? [{ debugName: "footerTemplate" }] : []));
3475
+ modalPanel = viewChild('modalPanel', ...(ngDevMode ? [{ debugName: "modalPanel" }] : []));
3476
+ // Computed
3477
+ hostClasses = computed(() => classNames('studio-modal', 'modal--' + this.size(), 'modal--' + this.variant(), 'modal--' + this.animation(), 'modal--' + this.position()), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
3478
+ constructor() {
3479
+ afterNextRender(() => {
3480
+ this.setupFocusTrap();
3481
+ });
3482
+ effect(() => {
3483
+ if (this.visible()) {
3484
+ this.handleOpen();
3485
+ }
3486
+ else {
3487
+ this.handleClose();
3488
+ }
3489
+ });
3490
+ }
3491
+ handleEscape(event) {
3492
+ if (this.closeOnEscape() && this.visible()) {
3493
+ event.preventDefault();
3494
+ this.close();
3495
+ }
3496
+ }
3497
+ handleOverlayClick() {
3498
+ if (this.closeOnOverlayClick()) {
3499
+ this.close();
3500
+ }
3501
+ }
3502
+ close() {
3503
+ this.visible.set(false);
3504
+ }
3505
+ open() {
3506
+ this.visible.set(true);
3507
+ }
3508
+ handleOpen() {
3509
+ // Prevent body scroll
3510
+ document.body.style.overflow = 'hidden';
3511
+ this.opened.emit();
3512
+ // Focus first focusable element
3513
+ setTimeout(() => {
3514
+ const panel = this.modalPanel()?.nativeElement;
3515
+ if (panel) {
3516
+ const focusable = panel.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
3517
+ focusable?.focus();
3518
+ }
3519
+ }, 100);
3520
+ }
3521
+ handleClose() {
3522
+ // Restore body scroll
3523
+ document.body.style.overflow = '';
3524
+ this.closed.emit();
3525
+ }
3526
+ setupFocusTrap() {
3527
+ // Simple focus trap: keep focus within modal when it's open
3528
+ const handleTab = (e) => {
3529
+ if (!this.visible() || e.key !== 'Tab')
3530
+ return;
3531
+ const panel = this.modalPanel()?.nativeElement;
3532
+ if (!panel)
3533
+ return;
3534
+ const focusableElements = panel.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
3535
+ const firstElement = focusableElements[0];
3536
+ const lastElement = focusableElements[focusableElements.length - 1];
3537
+ if (e.shiftKey && document.activeElement === firstElement) {
3538
+ lastElement?.focus();
3539
+ e.preventDefault();
3540
+ }
3541
+ else if (!e.shiftKey && document.activeElement === lastElement) {
3542
+ firstElement?.focus();
3543
+ e.preventDefault();
3544
+ }
3545
+ };
3546
+ document.addEventListener('keydown', handleTab);
3547
+ this.destroyRef.onDestroy(() => {
3548
+ document.removeEventListener('keydown', handleTab);
3549
+ document.body.style.overflow = ''; // Cleanup on destroy
3550
+ });
3551
+ }
3552
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3553
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: ModalComponent, isStandalone: true, selector: "studio-modal", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showCloseButton: { classPropertyName: "showCloseButton", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, closeOnOverlayClick: { classPropertyName: "closeOnOverlayClick", publicName: "closeOnOverlayClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", visibleChange: "visibleChange", opened: "opened", closed: "closed" }, host: { listeners: { "document:keydown.escape": "handleEscape($event)" }, properties: { "class": "hostClasses()" } }, queries: [{ propertyName: "headerTemplate", first: true, predicate: ["modalHeader"], descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["modalFooter"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "modalPanel", first: true, predicate: ["modalPanel"], descendants: true, isSignal: true }], ngImport: i0, template: `
3554
+ @if (visible()) {
3555
+ <!-- Overlay -->
3556
+ <div
3557
+ class="studio-modal__overlay"
3558
+ [class.studio-modal__overlay--visible]="visible()"
3559
+ (click)="handleOverlayClick()"
3560
+ ></div>
3561
+
3562
+ <!-- Modal -->
3563
+ <div
3564
+ #modalPanel
3565
+ class="studio-modal__panel"
3566
+ [class.studio-modal__panel--visible]="visible()"
3567
+ role="dialog"
3568
+ [attr.aria-modal]="true"
3569
+ [attr.aria-labelledby]="showHeader() ? 'modal-title' : null"
3570
+ >
3571
+ <!-- Header -->
3572
+ @if (showHeader()) {
3573
+ <div class="studio-modal__header">
3574
+ @if (headerTemplate()) {
3575
+ <ng-container *ngTemplateOutlet="headerTemplate()!" />
3576
+ } @else {
3577
+ <h3 id="modal-title" class="studio-modal__title">{{ title() }}</h3>
3578
+ }
3579
+
3580
+ @if (showCloseButton()) {
3581
+ <button
3582
+ type="button"
3583
+ class="studio-modal__close"
3584
+ (click)="close()"
3585
+ aria-label="Close"
3586
+ >
3587
+ <studio-icon name="x" [size]="20" />
3588
+ </button>
3589
+ }
3590
+ </div>
3591
+ }
3592
+
3593
+ <!-- Content -->
3594
+ <div class="studio-modal__content">
3595
+ <ng-content />
3596
+ </div>
3597
+
3598
+ <!-- Footer -->
3599
+ @if (showFooter() && footerTemplate()) {
3600
+ <div class="studio-modal__footer">
3601
+ <ng-container *ngTemplateOutlet="footerTemplate()!" />
3602
+ </div>
3603
+ }
3604
+ </div>
3605
+ }
3606
+ `, isInline: true, styles: [":host{display:contents;font-family:var(--studio-font-family)}.studio-modal__overlay{position:fixed;inset:0;background:#00000080;z-index:1000;opacity:0;transition:opacity var(--studio-transition-normal);&--visible{opacity:1}}.studio-modal__panel{position:fixed;z-index:1001;background:var(--studio-bg-primary);border-radius:var(--studio-radius-lg);box-shadow:var(--studio-shadow-xl);display:flex;flex-direction:column;max-height:90vh;opacity:0;transform:scale(.95);transition:opacity var(--studio-transition-normal),transform var(--studio-transition-normal);&--visible{opacity:1;transform:scale(1)}}:host(.modal--center) .studio-modal__panel{top:50%;left:50%;transform:translate(-50%,-50%) scale(.95);&--visible{transform:translate(-50%,-50%) scale(1)}}:host(.modal--top) .studio-modal__panel{top:5vh;left:50%;transform:translate(-50%,-20px) scale(.95);&--visible{transform:translate(-50%) scale(1)}}:host(.modal--bottom) .studio-modal__panel{bottom:5vh;left:50%;transform:translate(-50%,20px) scale(.95);&--visible{transform:translate(-50%) scale(1)}}:host(.modal--sm) .studio-modal__panel{width:90%;max-width:400px}:host(.modal--md) .studio-modal__panel{width:90%;max-width:600px}:host(.modal--lg) .studio-modal__panel{width:90%;max-width:800px}:host(.modal--xl) .studio-modal__panel{width:90%;max-width:1200px}:host(.modal--full) .studio-modal__panel{width:95vw;height:95vh;max-width:none;max-height:none}:host(.modal--bordered) .studio-modal__panel{border:1px solid var(--studio-border-primary)}:host(.modal--minimal) .studio-modal__panel{box-shadow:var(--studio-shadow-md)}:host(.modal--fade) .studio-modal__panel{transform:translate(-50%,-50%);&--visible{transform:translate(-50%,-50%)}}:host(.modal--slide-down) .studio-modal__panel{transform:translate(-50%,-60%);&--visible{transform:translate(-50%,-50%)}}:host(.modal--none) .studio-modal__panel{transition:none}:host(.modal--none) .studio-modal__overlay{transition:none}.studio-modal__header{display:flex;align-items:center;justify-content:space-between;padding:1.5rem;border-bottom:1px solid var(--studio-border-primary);flex-shrink:0}.studio-modal__title{margin:0;font-size:1.25rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-modal__close{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:none;border:none;border-radius:var(--studio-radius-sm);color:var(--studio-text-secondary);cursor:pointer;transition:all var(--studio-transition-fast)}.studio-modal__close:hover{background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-modal__close:active{transform:scale(.95)}.studio-modal__content{padding:1.5rem;overflow-y:auto;flex:1}.studio-modal__footer{padding:1.5rem;border-top:1px solid var(--studio-border-primary);display:flex;gap:.75rem;justify-content:flex-end;flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.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 });
3607
+ }
3608
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ModalComponent, decorators: [{
3609
+ type: Component,
3610
+ args: [{ selector: 'studio-modal', standalone: true, imports: [CommonModule, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3611
+ '[class]': 'hostClasses()',
3612
+ }, template: `
3613
+ @if (visible()) {
3614
+ <!-- Overlay -->
3615
+ <div
3616
+ class="studio-modal__overlay"
3617
+ [class.studio-modal__overlay--visible]="visible()"
3618
+ (click)="handleOverlayClick()"
3619
+ ></div>
3620
+
3621
+ <!-- Modal -->
3622
+ <div
3623
+ #modalPanel
3624
+ class="studio-modal__panel"
3625
+ [class.studio-modal__panel--visible]="visible()"
3626
+ role="dialog"
3627
+ [attr.aria-modal]="true"
3628
+ [attr.aria-labelledby]="showHeader() ? 'modal-title' : null"
3629
+ >
3630
+ <!-- Header -->
3631
+ @if (showHeader()) {
3632
+ <div class="studio-modal__header">
3633
+ @if (headerTemplate()) {
3634
+ <ng-container *ngTemplateOutlet="headerTemplate()!" />
3635
+ } @else {
3636
+ <h3 id="modal-title" class="studio-modal__title">{{ title() }}</h3>
3637
+ }
3638
+
3639
+ @if (showCloseButton()) {
3640
+ <button
3641
+ type="button"
3642
+ class="studio-modal__close"
3643
+ (click)="close()"
3644
+ aria-label="Close"
3645
+ >
3646
+ <studio-icon name="x" [size]="20" />
3647
+ </button>
3648
+ }
3649
+ </div>
3650
+ }
3651
+
3652
+ <!-- Content -->
3653
+ <div class="studio-modal__content">
3654
+ <ng-content />
3655
+ </div>
3656
+
3657
+ <!-- Footer -->
3658
+ @if (showFooter() && footerTemplate()) {
3659
+ <div class="studio-modal__footer">
3660
+ <ng-container *ngTemplateOutlet="footerTemplate()!" />
3661
+ </div>
3662
+ }
3663
+ </div>
3664
+ }
3665
+ `, styles: [":host{display:contents;font-family:var(--studio-font-family)}.studio-modal__overlay{position:fixed;inset:0;background:#00000080;z-index:1000;opacity:0;transition:opacity var(--studio-transition-normal);&--visible{opacity:1}}.studio-modal__panel{position:fixed;z-index:1001;background:var(--studio-bg-primary);border-radius:var(--studio-radius-lg);box-shadow:var(--studio-shadow-xl);display:flex;flex-direction:column;max-height:90vh;opacity:0;transform:scale(.95);transition:opacity var(--studio-transition-normal),transform var(--studio-transition-normal);&--visible{opacity:1;transform:scale(1)}}:host(.modal--center) .studio-modal__panel{top:50%;left:50%;transform:translate(-50%,-50%) scale(.95);&--visible{transform:translate(-50%,-50%) scale(1)}}:host(.modal--top) .studio-modal__panel{top:5vh;left:50%;transform:translate(-50%,-20px) scale(.95);&--visible{transform:translate(-50%) scale(1)}}:host(.modal--bottom) .studio-modal__panel{bottom:5vh;left:50%;transform:translate(-50%,20px) scale(.95);&--visible{transform:translate(-50%) scale(1)}}:host(.modal--sm) .studio-modal__panel{width:90%;max-width:400px}:host(.modal--md) .studio-modal__panel{width:90%;max-width:600px}:host(.modal--lg) .studio-modal__panel{width:90%;max-width:800px}:host(.modal--xl) .studio-modal__panel{width:90%;max-width:1200px}:host(.modal--full) .studio-modal__panel{width:95vw;height:95vh;max-width:none;max-height:none}:host(.modal--bordered) .studio-modal__panel{border:1px solid var(--studio-border-primary)}:host(.modal--minimal) .studio-modal__panel{box-shadow:var(--studio-shadow-md)}:host(.modal--fade) .studio-modal__panel{transform:translate(-50%,-50%);&--visible{transform:translate(-50%,-50%)}}:host(.modal--slide-down) .studio-modal__panel{transform:translate(-50%,-60%);&--visible{transform:translate(-50%,-50%)}}:host(.modal--none) .studio-modal__panel{transition:none}:host(.modal--none) .studio-modal__overlay{transition:none}.studio-modal__header{display:flex;align-items:center;justify-content:space-between;padding:1.5rem;border-bottom:1px solid var(--studio-border-primary);flex-shrink:0}.studio-modal__title{margin:0;font-size:1.25rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-modal__close{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:none;border:none;border-radius:var(--studio-radius-sm);color:var(--studio-text-secondary);cursor:pointer;transition:all var(--studio-transition-fast)}.studio-modal__close:hover{background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-modal__close:active{transform:scale(.95)}.studio-modal__content{padding:1.5rem;overflow-y:auto;flex:1}.studio-modal__footer{padding:1.5rem;border-top:1px solid var(--studio-border-primary);display:flex;gap:.75rem;justify-content:flex-end;flex-shrink:0}\n"] }]
3666
+ }], ctorParameters: () => [], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], animation: [{ type: i0.Input, args: [{ isSignal: true, alias: "animation", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], showHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], showCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], closeOnOverlayClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnOverlayClick", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], visibleChange: [{ type: i0.Output, args: ["visibleChange"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], headerTemplate: [{ type: i0.ContentChild, args: ['modalHeader', { isSignal: true }] }], footerTemplate: [{ type: i0.ContentChild, args: ['modalFooter', { isSignal: true }] }], modalPanel: [{ type: i0.ViewChild, args: ['modalPanel', { isSignal: true }] }], handleEscape: [{
3667
+ type: HostListener,
3668
+ args: ['document:keydown.escape', ['$event']]
3669
+ }] } });
3670
+
2660
3671
  /**
2661
3672
  * Navbar component - Primitive component for navigation headers
2662
3673
  *
@@ -2811,7 +3822,7 @@ class RadioButtonComponent {
2811
3822
  provide: NG_VALUE_ACCESSOR,
2812
3823
  useExisting: forwardRef(() => RadioButtonComponent),
2813
3824
  multi: true
2814
- }], ngImport: i0, template: "<label\n [for]=\"radioId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <input\n type=\"radio\"\n [id]=\"radioId()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [checked]=\"isChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"isChecked() ? 'true' : 'false'\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? radioId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-radio__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <span [ngClass]=\"radioClasses()\">\n @if (isChecked()) {\n <span class=\"studio-radio__dot\"></span>\n }\n </span>\n\n @if (label() || description()) {\n <span class=\"studio-radio__label-wrapper\">\n @if (label()) {\n <span class=\"studio-radio__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-radio__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-radio__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n@if (showHint() || showError()) {\n <div\n [id]=\"radioId() + '-description'\"\n class=\"studio-radio__info\"\n >\n @if (showError()) {\n <span class=\"studio-radio__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-radio__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-radio-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-radio-wrapper--label-left{flex-direction:row-reverse}.studio-radio-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-radio-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-radio-wrapper--md{font-size:var(--studio-font-size-base)}.studio-radio-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-radio__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-radio{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);border-radius:var(--studio-radius-full)}.studio-radio--sm{width:1rem;height:1rem}.studio-radio--md{width:1.25rem;height:1.25rem}.studio-radio--lg{width:1.5rem;height:1.5rem}.studio-radio--radius-none{border-radius:0}.studio-radio--radius-sm{border-radius:var(--studio-radius-sm)}.studio-radio--radius-md{border-radius:var(--studio-radius-md)}.studio-radio--radius-lg{border-radius:var(--studio-radius-lg)}.studio-radio--radius-full{border-radius:var(--studio-radius-full)}.studio-radio--default.studio-radio--checked{border-color:transparent}.studio-radio--default.studio-radio--checked.studio-radio--primary{background-color:var(--studio-primary)}.studio-radio--default.studio-radio--checked.studio-radio--secondary{background-color:var(--studio-secondary)}.studio-radio--default.studio-radio--checked.studio-radio--success{background-color:var(--studio-success)}.studio-radio--default.studio-radio--checked.studio-radio--error{background-color:var(--studio-error)}.studio-radio--outlined.studio-radio--checked{background-color:transparent}.studio-radio--outlined.studio-radio--checked.studio-radio--primary{border-color:var(--studio-primary)}.studio-radio--outlined.studio-radio--checked.studio-radio--primary .studio-radio__dot{background-color:var(--studio-primary)}.studio-radio--outlined.studio-radio--checked.studio-radio--secondary{border-color:var(--studio-secondary)}.studio-radio--outlined.studio-radio--checked.studio-radio--secondary .studio-radio__dot{background-color:var(--studio-secondary)}.studio-radio--outlined.studio-radio--checked.studio-radio--success{border-color:var(--studio-success)}.studio-radio--outlined.studio-radio--checked.studio-radio--success .studio-radio__dot{background-color:var(--studio-success)}.studio-radio--outlined.studio-radio--checked.studio-radio--error{border-color:var(--studio-error)}.studio-radio--outlined.studio-radio--checked.studio-radio--error .studio-radio__dot{background-color:var(--studio-error)}.studio-radio--filled.studio-radio--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-radio--filled.studio-radio--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-radio--filled.studio-radio--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-radio--filled.studio-radio--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-radio--filled.studio-radio--checked.studio-radio--primary{background-color:var(--studio-primary);border-color:var(--studio-primary)}.studio-radio--filled.studio-radio--checked.studio-radio--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary)}.studio-radio--filled.studio-radio--checked.studio-radio--success{background-color:var(--studio-success);border-color:var(--studio-success)}.studio-radio--filled.studio-radio--checked.studio-radio--error{background-color:var(--studio-error);border-color:var(--studio-error)}.studio-radio--error:not(.studio-radio--checked){border-color:var(--studio-error)}.studio-radio:hover:not(.studio-radio--disabled){border-color:var(--studio-border-secondary)}.studio-radio__input:focus-visible+.studio-radio{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-radio__dot{border-radius:var(--studio-radius-full);background-color:var(--studio-text-inverse);opacity:0;transform:scale(.5);transition:all var(--studio-transition-fast)}.studio-radio--sm .studio-radio__dot{width:.375rem;height:.375rem}.studio-radio--md .studio-radio__dot{width:.5rem;height:.5rem}.studio-radio--lg .studio-radio__dot{width:.625rem;height:.625rem}.studio-radio--checked .studio-radio__dot{opacity:1;transform:scale(1)}.studio-radio__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-radio__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-radio__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-radio__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-radio__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-radio-wrapper--label-left+.studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-radio-wrapper--sm .studio-radio__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-radio-wrapper--sm.studio-radio-wrapper--label-left .studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-radio-wrapper--lg .studio-radio__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-radio-wrapper--lg.studio-radio-wrapper--label-left .studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-radio__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-radio__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"] }] });
3825
+ }], ngImport: i0, template: "<label\n [for]=\"radioId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <input\n type=\"radio\"\n [id]=\"radioId()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [checked]=\"isChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"isChecked() ? 'true' : 'false'\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? radioId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-radio__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <span [ngClass]=\"radioClasses()\">\n @if (isChecked()) {\n <span class=\"studio-radio__dot\"></span>\n }\n </span>\n\n @if (label() || description()) {\n <span class=\"studio-radio__label-wrapper\">\n @if (label()) {\n <span class=\"studio-radio__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-radio__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-radio__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n@if (showHint() || showError()) {\n <div\n [id]=\"radioId() + '-description'\"\n class=\"studio-radio__info\"\n >\n @if (showError()) {\n <span class=\"studio-radio__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-radio__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-radio-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-radio-wrapper--label-left{flex-direction:row-reverse}.studio-radio-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-radio-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-radio-wrapper--md{font-size:var(--studio-font-size-base)}.studio-radio-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-radio__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-radio{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);border-radius:var(--studio-radius-full)}.studio-radio--sm{width:1rem;height:1rem}.studio-radio--md{width:1.25rem;height:1.25rem}.studio-radio--lg{width:1.5rem;height:1.5rem}.studio-radio--radius-none{border-radius:0}.studio-radio--radius-sm{border-radius:var(--studio-radius-sm)}.studio-radio--radius-md{border-radius:var(--studio-radius-md)}.studio-radio--radius-lg{border-radius:var(--studio-radius-lg)}.studio-radio--radius-full{border-radius:var(--studio-radius-full)}.studio-radio--default.studio-radio--checked{border-color:transparent}.studio-radio--default.studio-radio--checked.studio-radio--primary{background-color:var(--studio-primary)}.studio-radio--default.studio-radio--checked.studio-radio--secondary{background-color:var(--studio-secondary)}.studio-radio--default.studio-radio--checked.studio-radio--success{background-color:var(--studio-success)}.studio-radio--default.studio-radio--checked.studio-radio--error{background-color:var(--studio-error)}.studio-radio--outlined.studio-radio--checked{background-color:transparent}.studio-radio--outlined.studio-radio--checked.studio-radio--primary{border-color:var(--studio-primary)}.studio-radio--outlined.studio-radio--checked.studio-radio--primary .studio-radio__dot{background-color:var(--studio-primary)}.studio-radio--outlined.studio-radio--checked.studio-radio--secondary{border-color:var(--studio-secondary)}.studio-radio--outlined.studio-radio--checked.studio-radio--secondary .studio-radio__dot{background-color:var(--studio-secondary)}.studio-radio--outlined.studio-radio--checked.studio-radio--success{border-color:var(--studio-success)}.studio-radio--outlined.studio-radio--checked.studio-radio--success .studio-radio__dot{background-color:var(--studio-success)}.studio-radio--outlined.studio-radio--checked.studio-radio--error{border-color:var(--studio-error)}.studio-radio--outlined.studio-radio--checked.studio-radio--error .studio-radio__dot{background-color:var(--studio-error)}.studio-radio--filled.studio-radio--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-radio--filled.studio-radio--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-radio--filled.studio-radio--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-radio--filled.studio-radio--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-radio--filled.studio-radio--checked.studio-radio--primary{background-color:var(--studio-primary);border-color:var(--studio-primary)}.studio-radio--filled.studio-radio--checked.studio-radio--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary)}.studio-radio--filled.studio-radio--checked.studio-radio--success{background-color:var(--studio-success);border-color:var(--studio-success)}.studio-radio--filled.studio-radio--checked.studio-radio--error{background-color:var(--studio-error);border-color:var(--studio-error)}.studio-radio--error:not(.studio-radio--checked){border-color:var(--studio-error)}.studio-radio:hover:not(.studio-radio--disabled){border-color:var(--studio-border-secondary)}.studio-radio__input:focus-visible+.studio-radio{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-radio__dot{border-radius:var(--studio-radius-full);background-color:var(--studio-text-inverse);opacity:0;transform:scale(.5);transition:all var(--studio-transition-fast)}.studio-radio--sm .studio-radio__dot{width:.375rem;height:.375rem}.studio-radio--md .studio-radio__dot{width:.5rem;height:.5rem}.studio-radio--lg .studio-radio__dot{width:.625rem;height:.625rem}.studio-radio--checked .studio-radio__dot{opacity:1;transform:scale(1)}.studio-radio__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-radio__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-radio__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-radio__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-radio__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-radio-wrapper--label-left+.studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-radio-wrapper--sm .studio-radio__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-radio-wrapper--sm.studio-radio-wrapper--label-left .studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-radio-wrapper--lg .studio-radio__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-radio-wrapper--lg.studio-radio-wrapper--label-left .studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-radio__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-radio__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"] }] });
2815
3826
  }
2816
3827
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: RadioButtonComponent, decorators: [{
2817
3828
  type: Component,
@@ -3368,6 +4379,86 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
3368
4379
  * Switch component
3369
4380
  */
3370
4381
 
4382
+ class TabsComponent {
4383
+ tabs = input.required(...(ngDevMode ? [{ debugName: "tabs" }] : []));
4384
+ activeTab = signal('', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
4385
+ variant = input('line', ...(ngDevMode ? [{ debugName: "variant" }] : []));
4386
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
4387
+ orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
4388
+ tabChange = output();
4389
+ hostClasses = computed(() => classNames('tabs', 'tabs--' + this.variant(), 'tabs--' + this.size(), this.orientation() === 'vertical' && 'tabs--vertical'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
4390
+ iconSize = computed(() => {
4391
+ const sizeMap = { sm: 14, md: 16, lg: 18 };
4392
+ return sizeMap[this.size()];
4393
+ }, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
4394
+ constructor() {
4395
+ effect(() => {
4396
+ // Set first tab as active by default when tabs change
4397
+ const tabsList = this.tabs();
4398
+ const firstTab = tabsList[0];
4399
+ if (firstTab && !this.activeTab()) {
4400
+ this.activeTab.set(firstTab.id);
4401
+ }
4402
+ });
4403
+ }
4404
+ selectTab(tabId) {
4405
+ this.activeTab.set(tabId);
4406
+ this.tabChange.emit(tabId);
4407
+ }
4408
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4409
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: TabsComponent, isStandalone: true, selector: "studio-tabs", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tabChange: "tabChange" }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
4410
+ <div class="tabs__header" [class.tabs__header--vertical]="orientation() === 'vertical'">
4411
+ @for (tab of tabs(); track tab.id) {
4412
+ <button
4413
+ type="button"
4414
+ class="tabs__tab"
4415
+ [class.tabs__tab--active]="activeTab() === tab.id"
4416
+ [class.tabs__tab--disabled]="tab.disabled"
4417
+ [disabled]="tab.disabled"
4418
+ (click)="selectTab(tab.id)"
4419
+ >
4420
+ @if (tab.icon) {
4421
+ <studio-icon [name]="tab.icon" [size]="iconSize()" />
4422
+ }
4423
+ <span>{{ tab.label }}</span>
4424
+ </button>
4425
+ }
4426
+ </div>
4427
+
4428
+ <div class="tabs__content">
4429
+ <ng-content />
4430
+ </div>
4431
+ `, isInline: true, styles: [":host{display:flex;flex-direction:column;font-family:var(--studio-font-family)}:host(.tabs--vertical){flex-direction:row}.tabs__header{display:flex;gap:.25rem;border-bottom:2px solid var(--studio-border-primary);&--vertical{flex-direction:column;border-bottom:none;border-right:2px solid var(--studio-border-primary);padding-right:1rem}}.tabs__tab{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem;background:none;border:none;border-bottom:2px solid transparent;color:var(--studio-text-secondary);font-size:.875rem;font-weight:var(--studio-font-weight-medium);cursor:pointer;transition:all var(--studio-transition-fast);position:relative;margin-bottom:-2px;&--active{color:var(--studio-primary);border-bottom-color:var(--studio-primary)}&--disabled{opacity:.5;cursor:not-allowed}}.tabs__tab:hover:not(:disabled){color:var(--studio-text-primary);background:var(--studio-bg-secondary)}:host(.tabs--pills) .tabs__header{border-bottom:none}:host(.tabs--pills) .tabs__tab{border-radius:var(--studio-radius-md);border-bottom:none;margin-bottom:0;&--active{background:var(--studio-primary);color:#fff}}:host(.tabs--enclosed) .tabs__tab{border:1px solid transparent;border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0;margin-bottom:-1px;&--active{border-color:var(--studio-border-primary);border-bottom-color:var(--studio-bg-primary);background:var(--studio-bg-primary)}}:host(.tabs--sm) .tabs__tab{padding:.5rem .75rem;font-size:.8125rem}:host(.tabs--lg) .tabs__tab{padding:1rem 1.25rem;font-size:1rem}.tabs__content{padding:1.5rem 0}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4432
+ }
4433
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: TabsComponent, decorators: [{
4434
+ type: Component,
4435
+ args: [{ selector: 'studio-tabs', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
4436
+ '[class]': 'hostClasses()',
4437
+ }, template: `
4438
+ <div class="tabs__header" [class.tabs__header--vertical]="orientation() === 'vertical'">
4439
+ @for (tab of tabs(); track tab.id) {
4440
+ <button
4441
+ type="button"
4442
+ class="tabs__tab"
4443
+ [class.tabs__tab--active]="activeTab() === tab.id"
4444
+ [class.tabs__tab--disabled]="tab.disabled"
4445
+ [disabled]="tab.disabled"
4446
+ (click)="selectTab(tab.id)"
4447
+ >
4448
+ @if (tab.icon) {
4449
+ <studio-icon [name]="tab.icon" [size]="iconSize()" />
4450
+ }
4451
+ <span>{{ tab.label }}</span>
4452
+ </button>
4453
+ }
4454
+ </div>
4455
+
4456
+ <div class="tabs__content">
4457
+ <ng-content />
4458
+ </div>
4459
+ `, styles: [":host{display:flex;flex-direction:column;font-family:var(--studio-font-family)}:host(.tabs--vertical){flex-direction:row}.tabs__header{display:flex;gap:.25rem;border-bottom:2px solid var(--studio-border-primary);&--vertical{flex-direction:column;border-bottom:none;border-right:2px solid var(--studio-border-primary);padding-right:1rem}}.tabs__tab{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem;background:none;border:none;border-bottom:2px solid transparent;color:var(--studio-text-secondary);font-size:.875rem;font-weight:var(--studio-font-weight-medium);cursor:pointer;transition:all var(--studio-transition-fast);position:relative;margin-bottom:-2px;&--active{color:var(--studio-primary);border-bottom-color:var(--studio-primary)}&--disabled{opacity:.5;cursor:not-allowed}}.tabs__tab:hover:not(:disabled){color:var(--studio-text-primary);background:var(--studio-bg-secondary)}:host(.tabs--pills) .tabs__header{border-bottom:none}:host(.tabs--pills) .tabs__tab{border-radius:var(--studio-radius-md);border-bottom:none;margin-bottom:0;&--active{background:var(--studio-primary);color:#fff}}:host(.tabs--enclosed) .tabs__tab{border:1px solid transparent;border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0;margin-bottom:-1px;&--active{border-color:var(--studio-border-primary);border-bottom-color:var(--studio-bg-primary);background:var(--studio-bg-primary)}}:host(.tabs--sm) .tabs__tab{padding:.5rem .75rem;font-size:.8125rem}:host(.tabs--lg) .tabs__tab{padding:1rem 1.25rem;font-size:1rem}.tabs__content{padding:1.5rem 0}\n"] }]
4460
+ }], ctorParameters: () => [], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }] } });
4461
+
3371
4462
  /**
3372
4463
  * Textarea component for multi-line text input
3373
4464
  *
@@ -3717,6 +4808,73 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
3717
4808
  }, template: "<div class=\"studio-textarea-container\">\n <!-- Label (static or floating) -->\n @if (label() && !floatingLabel()) {\n <label\n [for]=\"textareaId()\"\n class=\"studio-textarea-label\"\n [class.studio-textarea-label--required]=\"required()\"\n >\n {{ label() }}\n @if (required()) {\n <span class=\"studio-textarea-label__required\">*</span>\n }\n </label>\n }\n\n <!-- Textarea wrapper -->\n <div class=\"studio-textarea-input-wrapper\">\n <!-- Floating label -->\n @if (floatingLabel() && label()) {\n <label\n [for]=\"textareaId()\"\n class=\"studio-textarea-label studio-textarea-label--floating\"\n [class.studio-textarea-label--floating-up]=\"showFloatingLabelUp()\"\n [class.studio-textarea-label--required]=\"required()\"\n >\n {{ label() }}\n @if (required()) {\n <span class=\"studio-textarea-label__required\">*</span>\n }\n </label>\n }\n\n <!-- Textarea element -->\n <textarea\n #textarea\n [id]=\"textareaId()\"\n [class]=\"textareaClasses()\"\n [value]=\"internalValue()\"\n [placeholder]=\"computedPlaceholder()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [rows]=\"rows()\"\n [attr.maxlength]=\"maxLength()\"\n [attr.minlength]=\"minLength()\"\n [required]=\"required()\"\n [name]=\"name()\"\n [autocomplete]=\"autocomplete()\"\n [spellcheck]=\"spellcheck()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-describedby]=\"showHint() || showError() ? textareaId() + '-description' : undefined\"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\"\n (keypress)=\"handleKeyPress($event)\"\n ></textarea>\n\n <!-- Clear button -->\n @if (clearable() && internalValue().length > 0 && !disabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"studio-textarea-clear\"\n [attr.aria-label]=\"'Clear textarea'\"\n (click)=\"handleClear()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n\n <!-- Loading indicator -->\n @if (loading()) {\n <div class=\"studio-textarea-loading\">\n <svg\n class=\"studio-textarea-spinner\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n class=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n ></circle>\n <path\n class=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n </div>\n }\n\n <!-- Character counter -->\n @if (showCharCount()) {\n <div\n class=\"studio-textarea-char-count\"\n [class.studio-textarea-char-count--exceeded]=\"isCharLimitExceeded()\"\n [attr.data-position]=\"charCountPosition()\"\n >\n {{ charCountText() }}\n </div>\n }\n </div>\n\n <!-- Helper text / Error message -->\n @if (showError()) {\n <div\n class=\"studio-textarea-message studio-textarea-message--error\"\n [id]=\"textareaId() + '-description'\"\n role=\"alert\"\n >\n {{ errorMessage() }}\n </div>\n } @else if (showHint()) {\n <div\n class=\"studio-textarea-message studio-textarea-message--hint\"\n [id]=\"textareaId() + '-description'\"\n >\n {{ hint() }}\n </div>\n }\n</div>\n", styles: [":host{display:flex;flex-direction:column;gap:.375rem;font-family:var(--studio-font-family)}:host(.studio-textarea-wrapper--full-width){width:100%}.studio-textarea-label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);margin-bottom:.25rem}.studio-textarea-label__required{color:var(--studio-error);margin-left:.125rem}.studio-textarea-label--floating{position:absolute;top:.75rem;left:.75rem;pointer-events:none;background:transparent;padding:0 .25rem;z-index:1;transition:all .2s ease}.studio-textarea-label--floating-up{top:-.5rem;font-size:.75rem;background:var(--studio-background);color:var(--studio-primary)}.studio-textarea-input-wrapper{position:relative;display:flex;flex-direction:column;transition:all var(--studio-transition-fast)}.studio-textarea{width:100%;padding:.75rem;font-size:1rem;font-family:inherit;color:var(--studio-text-primary);background:transparent;border:none;outline:none;resize:vertical;transition:all var(--studio-transition-fast)}.studio-textarea::placeholder{color:var(--studio-text-tertiary)}.studio-textarea:disabled{cursor:not-allowed;opacity:.6}.studio-textarea:read-only{cursor:default}.studio-textarea-clear,.studio-textarea-loading{position:absolute;top:.5rem;right:.5rem;display:flex;align-items:center;justify-content:center}.studio-textarea-clear{padding:.25rem;background:none;border:none;color:var(--studio-text-secondary);cursor:pointer;border-radius:var(--studio-radius-sm);transition:all var(--studio-transition-fast)}.studio-textarea-clear:hover{background:var(--studio-background-hover);color:var(--studio-text-primary)}.studio-textarea-clear svg{width:1rem;height:1rem}.studio-textarea-spinner{width:1rem;height:1rem;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-textarea-char-count{position:absolute;bottom:.5rem;font-size:.75rem;color:var(--studio-text-muted);pointer-events:none}.studio-textarea-char-count[data-position=bottom-right]{right:.75rem}.studio-textarea-char-count[data-position=bottom-left]{left:.75rem}.studio-textarea-char-count--exceeded{color:var(--studio-error);font-weight:500}.studio-textarea-message{font-size:.75rem;line-height:1.4}.studio-textarea-message--hint{color:var(--studio-text-secondary)}.studio-textarea-message--error{color:var(--studio-error)}:host(.studio-textarea-wrapper--outline) .studio-textarea-input-wrapper{border:1px solid var(--studio-border-primary);background:var(--studio-bg-primary);border-radius:var(--studio-radius-md)}:host(.studio-textarea-wrapper--outline) .studio-textarea-input-wrapper:hover:not(:has(.studio-textarea:disabled)){border-color:var(--studio-primary)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--focused) .studio-textarea-input-wrapper{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--error) .studio-textarea-input-wrapper{border-color:var(--studio-error)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--error) .studio-textarea-input-wrapper:hover{border-color:var(--studio-error)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--disabled) .studio-textarea-input-wrapper{background:var(--studio-bg-secondary);border-color:var(--studio-border-secondary)}:host(.studio-textarea-wrapper--filled) .studio-textarea-input-wrapper{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-textarea-wrapper--filled) .studio-textarea-input-wrapper:hover:not(:has(.studio-textarea:disabled)){background:var(--studio-bg-tertiary)}:host(.studio-textarea-wrapper--filled.studio-textarea-wrapper--focused) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-primary);background:var(--studio-bg-tertiary)}:host(.studio-textarea-wrapper--filled.studio-textarea-wrapper--error) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-error)}:host(.studio-textarea-wrapper--filled.studio-textarea-wrapper--disabled) .studio-textarea-input-wrapper{background:var(--studio-bg-secondary);opacity:.6}:host(.studio-textarea-wrapper--underline) .studio-textarea-input-wrapper{background:transparent;border:none;border-bottom:2px solid var(--studio-border-primary);border-radius:0}:host(.studio-textarea-wrapper--underline) .studio-textarea-input-wrapper .studio-textarea{padding-left:0;padding-right:0}:host(.studio-textarea-wrapper--underline) .studio-textarea-input-wrapper:hover:not(:has(.studio-textarea:disabled)){border-bottom-color:var(--studio-primary)}:host(.studio-textarea-wrapper--underline.studio-textarea-wrapper--focused) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-primary)}:host(.studio-textarea-wrapper--underline.studio-textarea-wrapper--error) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-error)}:host(.studio-textarea-wrapper--sm) .studio-textarea{padding:.5rem .75rem;font-size:.875rem}:host(.studio-textarea-wrapper--md) .studio-textarea{padding:.75rem;font-size:1rem}:host(.studio-textarea-wrapper--lg) .studio-textarea{padding:1rem;font-size:1.125rem}\n"] }]
3718
4809
  }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], floatingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatingLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], minRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "minRows", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], autoResize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoResize", required: false }] }], resize: [{ type: i0.Input, args: [{ isSignal: true, alias: "resize", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], showCharCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCharCount", required: false }] }], charCountPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "charCountPosition", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", 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 }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], spellcheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellcheck", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }], focused: [{ type: i0.Output, args: ["focused"] }], blurred: [{ type: i0.Output, args: ["blurred"] }], keyPressed: [{ type: i0.Output, args: ["keyPressed"] }], textareaEl: [{ type: i0.ViewChild, args: ['textarea', { isSignal: true }] }] } });
3719
4810
 
4811
+ class TooltipComponent {
4812
+ content = input.required(...(ngDevMode ? [{ debugName: "content" }] : []));
4813
+ trigger = input('hover', ...(ngDevMode ? [{ debugName: "trigger" }] : []));
4814
+ position = input('top', ...(ngDevMode ? [{ debugName: "position" }] : []));
4815
+ openDelay = input(200, ...(ngDevMode ? [{ debugName: "openDelay" }] : []));
4816
+ closeDelay = input(100, ...(ngDevMode ? [{ debugName: "closeDelay" }] : []));
4817
+ arrow = input(true, ...(ngDevMode ? [{ debugName: "arrow" }] : []));
4818
+ arrowSize = input(6, ...(ngDevMode ? [{ debugName: "arrowSize" }] : []));
4819
+ maxWidth = input('300px', ...(ngDevMode ? [{ debugName: "maxWidth" }] : []));
4820
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
4821
+ hostClasses = computed(() => classNames('studio-tooltip'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
4822
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: TooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4823
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: TooltipComponent, isStandalone: true, selector: "studio-tooltip", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: true, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, openDelay: { classPropertyName: "openDelay", publicName: "openDelay", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", isSignal: true, isRequired: false, transformFunction: null }, arrow: { classPropertyName: "arrow", publicName: "arrow", isSignal: true, isRequired: false, transformFunction: null }, arrowSize: { classPropertyName: "arrowSize", publicName: "arrowSize", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
4824
+ <studio-popover
4825
+ [trigger]="trigger()"
4826
+ [position]="position()"
4827
+ [openDelay]="openDelay()"
4828
+ [closeDelay]="closeDelay()"
4829
+ [arrow]="arrow()"
4830
+ [arrowSize]="arrowSize()"
4831
+ [variant]="'minimal'"
4832
+ [size]="'sm'"
4833
+ [animation]="'fade'"
4834
+ [animationDuration]="150"
4835
+ [showHeader]="false"
4836
+ [showFooter]="false"
4837
+ [closeOnClickOutside]="false"
4838
+ [closeOnEscape]="false"
4839
+ [disabled]="disabled()"
4840
+ [maxWidth]="maxWidth()"
4841
+ [padding]="'0.5rem 0.75rem'"
4842
+ >
4843
+ <ng-content />
4844
+ <div popoverContent [innerHTML]="content() || ''"></div>
4845
+ </studio-popover>
4846
+ `, isInline: true, styles: [":host{display:inline-block}\n"], dependencies: [{ kind: "component", type: PopoverComponent, selector: "studio-popover", inputs: ["id", "visible", "disabled", "trigger", "openDelay", "closeDelay", "position", "offset", "preventOverflow", "flipValue", "variant", "size", "width", "minWidth", "maxWidth", "maxHeight", "padding", "arrow", "arrowSize", "closeOnClickOutside", "closeOnEscape", "closeOnScroll", "showOverlay", "overlayOpacity", "animation", "animationDuration", "showHeader", "showFooter", "showCloseButton", "content", "zIndex", "ariaLabel", "role"], outputs: ["visibleChange", "opened", "closed", "positionChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4847
+ }
4848
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: TooltipComponent, decorators: [{
4849
+ type: Component,
4850
+ args: [{ selector: 'studio-tooltip', standalone: true, imports: [PopoverComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
4851
+ '[class]': 'hostClasses()',
4852
+ }, template: `
4853
+ <studio-popover
4854
+ [trigger]="trigger()"
4855
+ [position]="position()"
4856
+ [openDelay]="openDelay()"
4857
+ [closeDelay]="closeDelay()"
4858
+ [arrow]="arrow()"
4859
+ [arrowSize]="arrowSize()"
4860
+ [variant]="'minimal'"
4861
+ [size]="'sm'"
4862
+ [animation]="'fade'"
4863
+ [animationDuration]="150"
4864
+ [showHeader]="false"
4865
+ [showFooter]="false"
4866
+ [closeOnClickOutside]="false"
4867
+ [closeOnEscape]="false"
4868
+ [disabled]="disabled()"
4869
+ [maxWidth]="maxWidth()"
4870
+ [padding]="'0.5rem 0.75rem'"
4871
+ >
4872
+ <ng-content />
4873
+ <div popoverContent [innerHTML]="content() || ''"></div>
4874
+ </studio-popover>
4875
+ `, styles: [":host{display:inline-block}\n"] }]
4876
+ }], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: true }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], openDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "openDelay", required: false }] }], closeDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDelay", required: false }] }], arrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrow", required: false }] }], arrowSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrowSize", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
4877
+
3720
4878
  /**
3721
4879
  * Primitives (Atoms)
3722
4880
  * Basic building blocks
@@ -4060,7 +5218,7 @@ class InspectorComponent {
4060
5218
  useExisting: forwardRef(() => InspectorComponent),
4061
5219
  multi: true
4062
5220
  }
4063
- ], ngImport: i0, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ButtonComponent, selector: "studio-button", inputs: ["variant", "size", "color", "radius", "shadow", "compact", "disabled", "loading", "loadingText", "fullWidth", "type", "icon", "iconPosition", "href", "target", "badge", "badgeColor", "ariaLabel"], outputs: ["clicked"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }, { kind: "component", type: InputComponent, selector: "studio-input", inputs: ["variant", "size", "radius", "disabled", "readonly", "loading", "type", "inputmode", "autocomplete", "placeholder", "maxLength", "minLength", "min", "max", "step", "pattern", "label", "floatingLabel", "hint", "required", "error", "errorMessage", "prefixIcon", "suffixIcon", "clearable", "showPasswordToggle", "fullWidth", "autoFocus", "name", "id", "ariaLabel"], outputs: ["valueChange", "focused", "blurred", "cleared", "entered"] }, { kind: "component", type: CheckboxComponent, selector: "studio-checkbox", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "indeterminate", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: RadioButtonComponent, selector: "studio-radio-button", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: ColorPickerComponent, selector: "studio-color-picker", inputs: ["variant", "size", "format", "showAlpha", "showPresets", "showFormatToggle", "showCopyButton", "presets", "label", "hint", "required", "error", "errorMessage", "disabled", "readonly"], outputs: ["colorChange", "colorValueChange", "copied"] }, { kind: "component", type: SelectComponent, selector: "studio-select", inputs: ["variant", "size", "radius", "options", "placeholder", "multiple", "searchable", "clearable", "disabled", "loading", "label", "floatingLabel", "hint", "error", "errorMessage", "required", "prefixIcon", "suffixIcon", "fullWidth", "maxHeight", "position", "searchPlaceholder"], outputs: ["valueChange", "searchChange", "opened", "closed", "optionSelected"] }, { kind: "component", type: TextareaComponent, selector: "studio-textarea", inputs: ["variant", "size", "color", "radius", "label", "floatingLabel", "placeholder", "hint", "rows", "minRows", "maxRows", "autoResize", "resize", "maxLength", "showCharCount", "charCountPosition", "required", "minLength", "error", "errorMessage", "disabled", "readonly", "fullWidth", "name", "autocomplete", "spellcheck", "clearable", "loading"], outputs: ["changed", "focused", "blurred", "keyPressed"] }, { kind: "component", type: SwitchComponent, selector: "studio-switch", inputs: ["checked", "disabled", "label", "labelPosition", "showIcons", "ariaLabel", "size", "color"], outputs: ["checkedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5221
+ ], ngImport: i0, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker-compact\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker-compact\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ButtonComponent, selector: "studio-button", inputs: ["variant", "size", "color", "radius", "shadow", "compact", "disabled", "loading", "loadingText", "fullWidth", "type", "icon", "iconPosition", "href", "target", "badge", "badgeColor", "ariaLabel"], outputs: ["clicked"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }, { kind: "component", type: InputComponent, selector: "studio-input", inputs: ["variant", "size", "radius", "disabled", "readonly", "loading", "type", "inputmode", "autocomplete", "placeholder", "maxLength", "minLength", "min", "max", "step", "pattern", "label", "floatingLabel", "hint", "required", "error", "errorMessage", "prefixIcon", "suffixIcon", "clearable", "showPasswordToggle", "fullWidth", "autoFocus", "name", "id", "ariaLabel"], outputs: ["valueChange", "focused", "blurred", "cleared", "entered"] }, { kind: "component", type: CheckboxComponent, selector: "studio-checkbox", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "indeterminate", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: RadioButtonComponent, selector: "studio-radio-button", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: ColorPickerCompactComponent, selector: "studio-color-picker-compact", inputs: ["trigger", "position", "popoverWidth", "showArrow", "closeOnClickOutside", "triggerSize", "triggerRadius", "showCurrentColor", "format", "showAlpha", "showPresets", "showFormatToggle", "showCopyButton", "presets", "showFooter", "applyLabel", "cancelLabel", "disabled", "ariaLabel"], outputs: ["colorChange"] }, { kind: "component", type: SelectComponent, selector: "studio-select", inputs: ["variant", "size", "radius", "options", "placeholder", "multiple", "searchable", "clearable", "disabled", "loading", "label", "floatingLabel", "hint", "error", "errorMessage", "required", "prefixIcon", "suffixIcon", "fullWidth", "maxHeight", "position", "searchPlaceholder"], outputs: ["valueChange", "searchChange", "opened", "closed", "optionSelected"] }, { kind: "component", type: TextareaComponent, selector: "studio-textarea", inputs: ["variant", "size", "color", "radius", "label", "floatingLabel", "placeholder", "hint", "rows", "minRows", "maxRows", "autoResize", "resize", "maxLength", "showCharCount", "charCountPosition", "required", "minLength", "error", "errorMessage", "disabled", "readonly", "fullWidth", "name", "autocomplete", "spellcheck", "clearable", "loading"], outputs: ["changed", "focused", "blurred", "keyPressed"] }, { kind: "component", type: SwitchComponent, selector: "studio-switch", inputs: ["checked", "disabled", "label", "labelPosition", "showIcons", "ariaLabel", "size", "color"], outputs: ["checkedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4064
5222
  }
4065
5223
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: InspectorComponent, decorators: [{
4066
5224
  type: Component,
@@ -4072,7 +5230,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
4072
5230
  InputComponent,
4073
5231
  CheckboxComponent,
4074
5232
  RadioButtonComponent,
4075
- ColorPickerComponent,
5233
+ ColorPickerCompactComponent,
4076
5234
  SelectComponent,
4077
5235
  TextareaComponent,
4078
5236
  SwitchComponent
@@ -4086,7 +5244,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
4086
5244
  '[class]': 'hostClasses()',
4087
5245
  '[attr.role]': '"region"',
4088
5246
  '[attr.aria-label]': 'ariaLabel()'
4089
- }, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"] }]
5247
+ }, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker-compact\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker-compact\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"] }]
4090
5248
  }], ctorParameters: () => [], propDecorators: { componentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentSize", required: false }] }], componentVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentVariant", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], showDefaultIndicator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDefaultIndicator", required: false }] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], expandedByDefault: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedByDefault", required: false }] }], expandedSectionsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedSections", required: false }] }], showGroupLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGroupLabels", required: false }] }], groupDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupDivider", required: false }] }], groupDividerSpacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupDividerSpacing", required: false }] }], labelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelWidth", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], sectionTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "sectionTemplate", required: false }] }], parameterTemplates: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterTemplates", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }], sectionToggled: [{ type: i0.Output, args: ["sectionToggled"] }], parameterFocused: [{ type: i0.Output, args: ["parameterFocused"] }], parameterBlurred: [{ type: i0.Output, args: ["parameterBlurred"] }] } });
4091
5249
 
4092
5250
  /**
@@ -4617,5 +5775,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
4617
5775
  * Generated bundle index. Do not edit.
4618
5776
  */
4619
5777
 
4620
- export { BadgeComponent, BadgeWrapperComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, CheckboxComponent, ColorPickerComponent, DEFAULT_COLOR_PRESETS, DrawerComponent, DrawerService, IconComponent, InputComponent, InspectorComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, NavbarComponent, RadioButtonComponent, STUDIO_CONFIG, SelectComponent, SidebarComponent, StudioConfigService, SwitchComponent, TextareaComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
5778
+ export { BadgeComponent, BadgeWrapperComponent, BottomNavigationComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, CheckboxComponent, ColorPickerCompactComponent, ColorPickerComponent, DEFAULT_COLOR_PRESETS, DrawerComponent, DrawerService, DropdownComponent, IconComponent, InputComponent, InspectorComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, ModalComponent, NavbarComponent, PopoverComponent, RadioButtonComponent, STUDIO_CONFIG, SelectComponent, SidebarComponent, StudioConfigService, SwitchComponent, TabsComponent, TextareaComponent, ThemeSwitchComponent, TooltipComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
4621
5779
  //# sourceMappingURL=eduboxpro-studio.mjs.map