@eduboxpro/studio 0.1.14 → 0.1.16

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,15 +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, Injector, contentChild, model, afterNextRender, 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, contentChild, viewChild, forwardRef, DOCUMENT as DOCUMENT$1, DestroyRef, Injector, 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';
8
- import { NG_VALUE_ACCESSOR, FormsModule, NG_VALIDATORS } 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';
11
+ import { FormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
9
12
  import { autoUpdate, offset, flip, shift, arrow, computePosition } from '@floating-ui/dom';
10
- import { Router, RouterLink, RouterLinkActive, NavigationEnd } from '@angular/router';
11
13
  import { trigger, state, transition, style, animate } from '@angular/animations';
12
- import { filter } from 'rxjs/operators';
13
14
 
14
15
  /**
15
16
  * Injection token for Studio configuration
@@ -839,6 +840,227 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
839
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"] }]
840
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 }] }] } });
841
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
+
842
1064
  /**
843
1065
  * Button component with multiple variants, sizes, colors and states
844
1066
  *
@@ -1045,6 +1267,656 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1045
1267
  }, template: `<ng-content select="studio-button" />`, styles: [":host{display:inline-flex;align-items:center;position:relative}:host(.studio-button-group--horizontal){flex-direction:row}:host(.studio-button-group--vertical){flex-direction:column}:host(.studio-button-group--spacing-none){gap:0}:host(.studio-button-group--spacing-xs){gap:var(--studio-spacing-xs)}:host(.studio-button-group--spacing-sm){gap:var(--studio-spacing-sm)}:host(.studio-button-group--spacing-md){gap:var(--studio-spacing-md)}:host(.studio-button-group--spacing-lg){gap:var(--studio-spacing-lg)}:host(.studio-button-group--align-start){justify-content:flex-start}:host(.studio-button-group--align-center){justify-content:center}:host(.studio-button-group--align-end){justify-content:flex-end}:host(.studio-button-group--align-stretch){align-items:stretch}:host(.studio-button-group--align-stretch) ::ng-deep studio-button{flex:1}:host(.studio-button-group--full){width:100%}:host(.studio-button-group--full) ::ng-deep studio-button{flex:1}:host(.studio-button-group--attached){gap:0}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--attached{margin:0;position:relative}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--middle{border-radius:0}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--first:not(.studio-button-group__item--last){border-top-right-radius:0;border-bottom-right-radius:0}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--last:not(.studio-button-group__item--first){border-top-left-radius:0;border-bottom-left-radius:0}:host(.studio-button-group--attached).studio-button-group--horizontal ::ng-deep studio-button.studio-button-group__item--attached:not(:last-child){border-right:1px solid rgba(0,0,0,.1)}:host(.studio-button-group--attached).studio-button-group--horizontal ::ng-deep studio-button.studio-button-group__item--attached.studio-button--outline:not(:last-child){margin-right:-1px}:host(.studio-button-group--vertical){align-items:stretch}:host(.studio-button-group--vertical) ::ng-deep studio-button{width:100%;justify-content:flex-start}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--first:not(.studio-button-group__item--last){border-top-right-radius:var(--studio-radius-sm);border-bottom-right-radius:0;border-top-left-radius:var(--studio-radius-sm);border-bottom-left-radius:0}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--last:not(.studio-button-group__item--first){border-top-left-radius:0;border-bottom-left-radius:var(--studio-radius-sm);border-top-right-radius:0;border-bottom-right-radius:var(--studio-radius-sm)}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--attached:not(:last-child){border-right:none;border-bottom:1px solid rgba(255,255,255,.2)}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--middle{border-radius:0}:host(.studio-button-group--vertical.studio-button-group--full) ::ng-deep studio-button{width:100%}\n"] }]
1046
1268
  }], ctorParameters: () => [], propDecorators: { orientationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], colorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], attached: [{ type: i0.Input, args: [{ isSignal: true, alias: "attached", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }] } });
1047
1269
 
1270
+ /**
1271
+ * Card component for displaying content in a container
1272
+ *
1273
+ * @example
1274
+ * <studio-card variant="elevated" color="primary">
1275
+ * <div card-header>Header</div>
1276
+ * <div card-body>Content</div>
1277
+ * <div card-footer>Footer</div>
1278
+ * </studio-card>
1279
+ */
1280
+ class CardComponent {
1281
+ configService = inject(StudioConfigService);
1282
+ cardDefaults = computed(() => this.configService.config().components?.card, ...(ngDevMode ? [{ debugName: "cardDefaults" }] : []));
1283
+ // Style inputs with config defaults
1284
+ variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
1285
+ sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
1286
+ colorInput = input(undefined, ...(ngDevMode ? [{ debugName: "colorInput", alias: 'color' }] : [{ alias: 'color' }]));
1287
+ radiusInput = input(undefined, ...(ngDevMode ? [{ debugName: "radiusInput", alias: 'radius' }] : [{ alias: 'radius' }]));
1288
+ shadowInput = input(undefined, ...(ngDevMode ? [{ debugName: "shadowInput", alias: 'shadow' }] : [{ alias: 'shadow' }]));
1289
+ paddingInput = input(undefined, ...(ngDevMode ? [{ debugName: "paddingInput", alias: 'padding' }] : [{ alias: 'padding' }]));
1290
+ variant = withConfigDefault(this.variantInput, computed(() => this.cardDefaults()?.variant), 'elevated');
1291
+ size = withConfigDefault(this.sizeInput, computed(() => this.cardDefaults()?.size), 'md');
1292
+ color = withConfigDefault(this.colorInput, computed(() => this.cardDefaults()?.color), 'default');
1293
+ radius = withConfigDefault(this.radiusInput, computed(() => this.cardDefaults()?.radius), 'lg');
1294
+ shadow = withConfigDefault(this.shadowInput, computed(() => this.cardDefaults()?.shadow), 'md');
1295
+ padding = withConfigDefault(this.paddingInput, computed(() => this.cardDefaults()?.padding), 'md');
1296
+ // Layout inputs
1297
+ orientation = input('vertical', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
1298
+ imagePosition = input('top', ...(ngDevMode ? [{ debugName: "imagePosition" }] : []));
1299
+ fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
1300
+ fullHeight = input(false, ...(ngDevMode ? [{ debugName: "fullHeight" }] : []));
1301
+ // Content inputs
1302
+ title = input(...(ngDevMode ? [undefined, { debugName: "title" }] : []));
1303
+ subtitle = input(...(ngDevMode ? [undefined, { debugName: "subtitle" }] : []));
1304
+ avatar = input(...(ngDevMode ? [undefined, { debugName: "avatar" }] : []));
1305
+ icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : []));
1306
+ image = input(...(ngDevMode ? [undefined, { debugName: "image" }] : []));
1307
+ imageAlt = input('', ...(ngDevMode ? [{ debugName: "imageAlt" }] : []));
1308
+ imageFit = input('cover', ...(ngDevMode ? [{ debugName: "imageFit" }] : []));
1309
+ // Visibility inputs
1310
+ showHeader = input(true, ...(ngDevMode ? [{ debugName: "showHeader" }] : []));
1311
+ showMedia = input(true, ...(ngDevMode ? [{ debugName: "showMedia" }] : []));
1312
+ showFooter = input(true, ...(ngDevMode ? [{ debugName: "showFooter" }] : []));
1313
+ divider = input(false, ...(ngDevMode ? [{ debugName: "divider" }] : []));
1314
+ // Interaction inputs
1315
+ hoverable = input(false, ...(ngDevMode ? [{ debugName: "hoverable" }] : []));
1316
+ pressable = input(false, ...(ngDevMode ? [{ debugName: "pressable" }] : []));
1317
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1318
+ loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1319
+ href = input(...(ngDevMode ? [undefined, { debugName: "href" }] : []));
1320
+ target = input('_self', ...(ngDevMode ? [{ debugName: "target" }] : []));
1321
+ // Effects
1322
+ blurred = input(false, ...(ngDevMode ? [{ debugName: "blurred" }] : []));
1323
+ blurredFooter = input(false, ...(ngDevMode ? [{ debugName: "blurredFooter" }] : []));
1324
+ animated = input(false, ...(ngDevMode ? [{ debugName: "animated" }] : []));
1325
+ // Outputs
1326
+ clicked = output();
1327
+ headerAction = output();
1328
+ // Template refs
1329
+ headerTemplate = contentChild('cardHeader', ...(ngDevMode ? [{ debugName: "headerTemplate" }] : []));
1330
+ headerActionsTemplate = contentChild('cardHeaderActions', ...(ngDevMode ? [{ debugName: "headerActionsTemplate" }] : []));
1331
+ mediaTemplate = contentChild('cardMedia', ...(ngDevMode ? [{ debugName: "mediaTemplate" }] : []));
1332
+ bodyTemplate = contentChild('cardBody', ...(ngDevMode ? [{ debugName: "bodyTemplate" }] : []));
1333
+ footerTemplate = contentChild('cardFooter', ...(ngDevMode ? [{ debugName: "footerTemplate" }] : []));
1334
+ // Computed
1335
+ iconSize = computed(() => {
1336
+ const sizeMap = { sm: 18, md: 20, lg: 24 };
1337
+ return sizeMap[this.size()];
1338
+ }, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
1339
+ hostClasses = computed(() => classNames('studio-card', `studio-card--${this.variant()}`, `studio-card--${this.size()}`, `studio-card--${this.color()}`, `studio-card--radius-${this.radius()}`, `studio-card--shadow-${this.shadow()}`, `studio-card--padding-${this.padding()}`, `studio-card--${this.orientation()}`, this.imagePosition() !== 'top' && `studio-card--image-${this.imagePosition()}`, this.fullWidth() && 'studio-card--full-width', this.fullHeight() && 'studio-card--full-height', this.hoverable() && 'studio-card--hoverable', this.pressable() && 'studio-card--pressable', this.disabled() && 'studio-card--disabled', this.loading() && 'studio-card--loading', this.blurred() && 'studio-card--blurred', this.blurredFooter() && 'studio-card--blurred-footer', this.animated() && 'studio-card--animated', this.divider() && 'studio-card--divider', this.href() && 'studio-card--clickable'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
1340
+ handleClick(event) {
1341
+ if (this.disabled() || this.loading()) {
1342
+ event.preventDefault();
1343
+ event.stopPropagation();
1344
+ return;
1345
+ }
1346
+ const url = this.href();
1347
+ if (url) {
1348
+ const safeUrl = sanitizeUrl(url);
1349
+ if (safeUrl === '#') {
1350
+ return;
1351
+ }
1352
+ const target = this.target();
1353
+ if (target === '_blank') {
1354
+ window.open(safeUrl, '_blank', 'noopener,noreferrer');
1355
+ }
1356
+ else {
1357
+ window.location.href = safeUrl;
1358
+ }
1359
+ }
1360
+ this.clicked.emit(event);
1361
+ }
1362
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1363
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: CardComponent, isStandalone: true, selector: "studio-card", inputs: { variantInput: { classPropertyName: "variantInput", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, colorInput: { classPropertyName: "colorInput", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, radiusInput: { classPropertyName: "radiusInput", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, shadowInput: { classPropertyName: "shadowInput", publicName: "shadow", isSignal: true, isRequired: false, transformFunction: null }, paddingInput: { classPropertyName: "paddingInput", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, imagePosition: { classPropertyName: "imagePosition", publicName: "imagePosition", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, fullHeight: { classPropertyName: "fullHeight", publicName: "fullHeight", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, avatar: { classPropertyName: "avatar", publicName: "avatar", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, image: { classPropertyName: "image", publicName: "image", isSignal: true, isRequired: false, transformFunction: null }, imageAlt: { classPropertyName: "imageAlt", publicName: "imageAlt", isSignal: true, isRequired: false, transformFunction: null }, imageFit: { classPropertyName: "imageFit", publicName: "imageFit", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showMedia: { classPropertyName: "showMedia", publicName: "showMedia", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, divider: { classPropertyName: "divider", publicName: "divider", isSignal: true, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: true, isRequired: false, transformFunction: null }, pressable: { classPropertyName: "pressable", publicName: "pressable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: false, transformFunction: null }, blurred: { classPropertyName: "blurred", publicName: "blurred", isSignal: true, isRequired: false, transformFunction: null }, blurredFooter: { classPropertyName: "blurredFooter", publicName: "blurredFooter", isSignal: true, isRequired: false, transformFunction: null }, animated: { classPropertyName: "animated", publicName: "animated", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked", headerAction: "headerAction" }, host: { listeners: { "click": "handleClick($event)" }, properties: { "class": "hostClasses()", "attr.href": "href()", "attr.target": "href() ? target() : null", "attr.rel": "href() && target() === \"_blank\" ? \"noopener noreferrer\" : null", "attr.disabled": "disabled() ? \"\" : null" } }, queries: [{ propertyName: "headerTemplate", first: true, predicate: ["cardHeader"], descendants: true, isSignal: true }, { propertyName: "headerActionsTemplate", first: true, predicate: ["cardHeaderActions"], descendants: true, isSignal: true }, { propertyName: "mediaTemplate", first: true, predicate: ["cardMedia"], descendants: true, isSignal: true }, { propertyName: "bodyTemplate", first: true, predicate: ["cardBody"], descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["cardFooter"], descendants: true, isSignal: true }], ngImport: i0, template: `
1364
+ <div class="studio-card__container">
1365
+ <!-- Header -->
1366
+ @if (showHeader() && (headerTemplate() || title() || subtitle())) {
1367
+ <div class="studio-card__header">
1368
+ @if (headerTemplate()) {
1369
+ <ng-container *ngTemplateOutlet="headerTemplate()!" />
1370
+ } @else {
1371
+ <div class="studio-card__header-content">
1372
+ @if (avatar()) {
1373
+ <img [src]="avatar()!" alt="" class="studio-card__avatar" />
1374
+ }
1375
+ @if (icon() && !avatar()) {
1376
+ <div class="studio-card__icon-wrapper">
1377
+ <studio-icon [name]="icon()!" [size]="iconSize()" />
1378
+ </div>
1379
+ }
1380
+ <div class="studio-card__header-text">
1381
+ @if (title()) {
1382
+ <h3 class="studio-card__title">{{ title() }}</h3>
1383
+ }
1384
+ @if (subtitle()) {
1385
+ <p class="studio-card__subtitle">{{ subtitle() }}</p>
1386
+ }
1387
+ </div>
1388
+ </div>
1389
+ @if (headerActionsTemplate()) {
1390
+ <div class="studio-card__header-actions">
1391
+ <ng-container *ngTemplateOutlet="headerActionsTemplate()!" />
1392
+ </div>
1393
+ }
1394
+ }
1395
+ </div>
1396
+ }
1397
+
1398
+ <!-- Media -->
1399
+ @if (showMedia() && (mediaTemplate() || image())) {
1400
+ <div class="studio-card__media">
1401
+ @if (mediaTemplate()) {
1402
+ <ng-container *ngTemplateOutlet="mediaTemplate()!" />
1403
+ } @else if (image()) {
1404
+ <img
1405
+ [src]="image()!"
1406
+ [alt]="imageAlt()"
1407
+ class="studio-card__image"
1408
+ [class.studio-card__image--cover]="imageFit() === 'cover'"
1409
+ [class.studio-card__image--contain]="imageFit() === 'contain'"
1410
+ />
1411
+ }
1412
+ </div>
1413
+ }
1414
+
1415
+ <!-- Body -->
1416
+ <div class="studio-card__body">
1417
+ @if (bodyTemplate()) {
1418
+ <ng-container *ngTemplateOutlet="bodyTemplate()!" />
1419
+ } @else {
1420
+ <ng-content />
1421
+ }
1422
+ </div>
1423
+
1424
+ <!-- Footer -->
1425
+ @if (showFooter() && footerTemplate()) {
1426
+ <div class="studio-card__footer">
1427
+ <ng-container *ngTemplateOutlet="footerTemplate()!" />
1428
+ </div>
1429
+ }
1430
+
1431
+ <!-- Loading overlay -->
1432
+ @if (loading()) {
1433
+ <div class="studio-card__loading">
1434
+ <studio-icon name="loader-2" [size]="24" class="studio-card__spinner" />
1435
+ </div>
1436
+ }
1437
+ </div>
1438
+ `, isInline: true, styles: [":host{display:block;font-family:var(--studio-font-family);position:relative;transition:all var(--studio-transition-normal)}.studio-card__container{display:flex;flex-direction:column;height:100%;overflow:hidden;position:relative}:host(.studio-card--sm) .studio-card__container{min-height:8rem}:host(.studio-card--md) .studio-card__container{min-height:12rem}:host(.studio-card--lg) .studio-card__container{min-height:16rem}:host(.studio-card--radius-none) .studio-card__container{border-radius:var(--studio-radius-none)}:host(.studio-card--radius-sm) .studio-card__container{border-radius:var(--studio-radius-sm)}:host(.studio-card--radius-md) .studio-card__container{border-radius:var(--studio-radius-md)}:host(.studio-card--radius-lg) .studio-card__container{border-radius:var(--studio-radius-lg)}:host(.studio-card--radius-xl) .studio-card__container{border-radius:var(--studio-radius-xl)}:host(.studio-card--shadow-none) .studio-card__container{box-shadow:none}:host(.studio-card--shadow-sm) .studio-card__container{box-shadow:var(--studio-shadow-sm)}:host(.studio-card--shadow-md) .studio-card__container{box-shadow:var(--studio-shadow-md)}:host(.studio-card--shadow-lg) .studio-card__container{box-shadow:var(--studio-shadow-lg)}:host(.studio-card--shadow-xl) .studio-card__container{box-shadow:var(--studio-shadow-xl)}:host(.studio-card--elevated.studio-card--default) .studio-card__container{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary)}:host(.studio-card--filled.studio-card--default) .studio-card__container{background:var(--studio-bg-secondary);border:1px solid transparent}:host(.studio-card--outlined.studio-card--default) .studio-card__container{background:transparent;border:2px solid var(--studio-border-primary)}:host(.studio-card--ghost.studio-card--default) .studio-card__container{background:transparent;border:1px solid transparent}:host(.studio-card--elevated.studio-card--primary) .studio-card__container{background:var(--studio-primary-bg);border:1px solid var(--studio-primary)}:host(.studio-card--filled.studio-card--primary) .studio-card__container{background:var(--studio-primary);color:#fff;border:1px solid transparent}:host(.studio-card--outlined.studio-card--primary) .studio-card__container{background:transparent;border:2px solid var(--studio-primary);color:var(--studio-primary)}:host(.studio-card--ghost.studio-card--primary) .studio-card__container{background:var(--studio-primary-bg);border:1px solid transparent;color:var(--studio-primary)}:host(.studio-card--elevated.studio-card--secondary) .studio-card__container{background:var(--studio-bg-primary);border:1px solid var(--studio-text-secondary)}:host(.studio-card--filled.studio-card--secondary) .studio-card__container{background:var(--studio-text-secondary);color:#fff;border:1px solid transparent}:host(.studio-card--outlined.studio-card--secondary) .studio-card__container{background:transparent;border:2px solid var(--studio-text-secondary);color:var(--studio-text-secondary)}:host(.studio-card--ghost.studio-card--secondary) .studio-card__container{background:var(--studio-bg-secondary);border:1px solid transparent;color:var(--studio-text-secondary)}:host(.studio-card--elevated.studio-card--success) .studio-card__container{background:var(--studio-success-bg);border:1px solid var(--studio-success)}:host(.studio-card--filled.studio-card--success) .studio-card__container{background:var(--studio-success);color:#fff;border:1px solid transparent}:host(.studio-card--outlined.studio-card--success) .studio-card__container{background:transparent;border:2px solid var(--studio-success);color:var(--studio-success)}:host(.studio-card--ghost.studio-card--success) .studio-card__container{background:var(--studio-success-bg);border:1px solid transparent;color:var(--studio-success)}:host(.studio-card--elevated.studio-card--error) .studio-card__container{background:var(--studio-error-bg);border:1px solid var(--studio-error)}:host(.studio-card--filled.studio-card--error) .studio-card__container{background:var(--studio-error);color:#fff;border:1px solid transparent}:host(.studio-card--outlined.studio-card--error) .studio-card__container{background:transparent;border:2px solid var(--studio-error);color:var(--studio-error)}:host(.studio-card--ghost.studio-card--error) .studio-card__container{background:var(--studio-error-bg);border:1px solid transparent;color:var(--studio-error)}:host(.studio-card--elevated.studio-card--warning) .studio-card__container{background:var(--studio-warning-bg);border:1px solid var(--studio-warning)}:host(.studio-card--filled.studio-card--warning) .studio-card__container{background:var(--studio-warning);color:#fff;border:1px solid transparent}:host(.studio-card--outlined.studio-card--warning) .studio-card__container{background:transparent;border:2px solid var(--studio-warning);color:var(--studio-warning)}:host(.studio-card--ghost.studio-card--warning) .studio-card__container{background:var(--studio-warning-bg);border:1px solid transparent;color:var(--studio-warning)}:host(.studio-card--elevated.studio-card--neutral) .studio-card__container{background:var(--studio-bg-tertiary);border:1px solid var(--studio-border-secondary)}:host(.studio-card--filled.studio-card--neutral) .studio-card__container{background:var(--studio-bg-secondary);border:1px solid transparent}:host(.studio-card--outlined.studio-card--neutral) .studio-card__container{background:transparent;border:2px solid var(--studio-border-secondary)}:host(.studio-card--ghost.studio-card--neutral) .studio-card__container{background:transparent;border:1px solid transparent}:host(.studio-card--padding-none) .studio-card__header,:host(.studio-card--padding-none) .studio-card__body,:host(.studio-card--padding-none) .studio-card__footer{padding:0}:host(.studio-card--padding-sm) .studio-card__header,:host(.studio-card--padding-sm) .studio-card__footer{padding:var(--studio-spacing-sm)}:host(.studio-card--padding-sm) .studio-card__body{padding:var(--studio-spacing-sm)}:host(.studio-card--padding-md) .studio-card__header,:host(.studio-card--padding-md) .studio-card__footer{padding:var(--studio-spacing-md)}:host(.studio-card--padding-md) .studio-card__body{padding:var(--studio-spacing-md)}:host(.studio-card--padding-lg) .studio-card__header,:host(.studio-card--padding-lg) .studio-card__footer{padding:var(--studio-spacing-lg)}:host(.studio-card--padding-lg) .studio-card__body{padding:var(--studio-spacing-lg)}.studio-card__header{display:flex;align-items:center;justify-content:space-between;gap:var(--studio-spacing-md);flex-shrink:0}:host(.studio-card--divider) .studio-card__header{border-bottom:1px solid var(--studio-border-primary)}.studio-card__header-content{display:flex;align-items:center;gap:var(--studio-spacing-md);flex:1;min-width:0}.studio-card__avatar{width:2.5rem;height:2.5rem;border-radius:50%;object-fit:cover;flex-shrink:0}.studio-card__icon-wrapper{display:flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;border-radius:50%;background:var(--studio-bg-secondary);flex-shrink:0}.studio-card__header-text{flex:1;min-width:0}.studio-card__title{margin:0;font-size:var(--studio-font-size-lg);font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.studio-card__subtitle{margin:.25rem 0 0;font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.studio-card__header-actions{display:flex;align-items:center;gap:var(--studio-spacing-sm);flex-shrink:0}.studio-card__media{flex-shrink:0;overflow:hidden;position:relative}:host(.studio-card--padding-none) .studio-card__media{margin:0}:host(.studio-card--padding-sm) .studio-card__media{margin:var(--studio-spacing-sm);margin-top:0}:host(.studio-card--padding-md) .studio-card__media{margin:var(--studio-spacing-md);margin-top:0}:host(.studio-card--padding-lg) .studio-card__media{margin:var(--studio-spacing-lg);margin-top:0}.studio-card__image{width:100%;height:auto;display:block;border-radius:var(--studio-radius-sm)}.studio-card__image--cover{object-fit:cover;height:12rem}.studio-card__image--contain{object-fit:contain;max-height:16rem}.studio-card__body{flex:1;overflow-y:auto}.studio-card__footer{display:flex;align-items:center;gap:var(--studio-spacing-md);flex-shrink:0}:host(.studio-card--divider) .studio-card__footer{border-top:1px solid var(--studio-border-primary)}:host(.studio-card--blurred-footer) .studio-card__footer{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:#ffffff1a;border-top:1px solid rgba(255,255,255,.2)}:host(.studio-card--horizontal) .studio-card__container{flex-direction:row}:host(.studio-card--horizontal) .studio-card__media{width:40%;margin:0}:host(.studio-card--horizontal) .studio-card__body{flex:1}:host(.studio-card--full-width){width:100%}:host(.studio-card--full-height){height:100%}:host(.studio-card--full-height) .studio-card__container{height:100%}:host(.studio-card--hoverable) .studio-card__container{cursor:pointer;transition:all var(--studio-transition-normal)}:host(.studio-card--hoverable:hover:not(.studio-card--disabled)) .studio-card__container{transform:translateY(-2px);box-shadow:var(--studio-shadow-lg)}:host(.studio-card--pressable) .studio-card__container{cursor:pointer;transition:all var(--studio-transition-fast)}:host(.studio-card--pressable:active:not(.studio-card--disabled)) .studio-card__container{transform:scale(.98)}:host(.studio-card--clickable) .studio-card__container{cursor:pointer}:host(.studio-card--disabled){pointer-events:none;opacity:.5}:host(.studio-card--blurred) .studio-card__container{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:#ffffff1a!important;border:1px solid rgba(255,255,255,.2)}:host(.studio-card--animated){animation:cardFadeIn .3s ease-out}@keyframes cardFadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.studio-card__loading{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#ffffffe6;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);z-index:10}.studio-card__spinner{animation:spin 1s linear infinite;color:var(--studio-primary)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}:host(.studio-card--loading) .studio-card__container{pointer-events:none}\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 });
1439
+ }
1440
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: CardComponent, decorators: [{
1441
+ type: Component,
1442
+ args: [{ selector: 'studio-card', standalone: true, imports: [CommonModule, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1443
+ '[class]': 'hostClasses()',
1444
+ '[attr.href]': 'href()',
1445
+ '[attr.target]': 'href() ? target() : null',
1446
+ '[attr.rel]': 'href() && target() === "_blank" ? "noopener noreferrer" : null',
1447
+ '[attr.disabled]': 'disabled() ? "" : null',
1448
+ '(click)': 'handleClick($event)'
1449
+ }, template: `
1450
+ <div class="studio-card__container">
1451
+ <!-- Header -->
1452
+ @if (showHeader() && (headerTemplate() || title() || subtitle())) {
1453
+ <div class="studio-card__header">
1454
+ @if (headerTemplate()) {
1455
+ <ng-container *ngTemplateOutlet="headerTemplate()!" />
1456
+ } @else {
1457
+ <div class="studio-card__header-content">
1458
+ @if (avatar()) {
1459
+ <img [src]="avatar()!" alt="" class="studio-card__avatar" />
1460
+ }
1461
+ @if (icon() && !avatar()) {
1462
+ <div class="studio-card__icon-wrapper">
1463
+ <studio-icon [name]="icon()!" [size]="iconSize()" />
1464
+ </div>
1465
+ }
1466
+ <div class="studio-card__header-text">
1467
+ @if (title()) {
1468
+ <h3 class="studio-card__title">{{ title() }}</h3>
1469
+ }
1470
+ @if (subtitle()) {
1471
+ <p class="studio-card__subtitle">{{ subtitle() }}</p>
1472
+ }
1473
+ </div>
1474
+ </div>
1475
+ @if (headerActionsTemplate()) {
1476
+ <div class="studio-card__header-actions">
1477
+ <ng-container *ngTemplateOutlet="headerActionsTemplate()!" />
1478
+ </div>
1479
+ }
1480
+ }
1481
+ </div>
1482
+ }
1483
+
1484
+ <!-- Media -->
1485
+ @if (showMedia() && (mediaTemplate() || image())) {
1486
+ <div class="studio-card__media">
1487
+ @if (mediaTemplate()) {
1488
+ <ng-container *ngTemplateOutlet="mediaTemplate()!" />
1489
+ } @else if (image()) {
1490
+ <img
1491
+ [src]="image()!"
1492
+ [alt]="imageAlt()"
1493
+ class="studio-card__image"
1494
+ [class.studio-card__image--cover]="imageFit() === 'cover'"
1495
+ [class.studio-card__image--contain]="imageFit() === 'contain'"
1496
+ />
1497
+ }
1498
+ </div>
1499
+ }
1500
+
1501
+ <!-- Body -->
1502
+ <div class="studio-card__body">
1503
+ @if (bodyTemplate()) {
1504
+ <ng-container *ngTemplateOutlet="bodyTemplate()!" />
1505
+ } @else {
1506
+ <ng-content />
1507
+ }
1508
+ </div>
1509
+
1510
+ <!-- Footer -->
1511
+ @if (showFooter() && footerTemplate()) {
1512
+ <div class="studio-card__footer">
1513
+ <ng-container *ngTemplateOutlet="footerTemplate()!" />
1514
+ </div>
1515
+ }
1516
+
1517
+ <!-- Loading overlay -->
1518
+ @if (loading()) {
1519
+ <div class="studio-card__loading">
1520
+ <studio-icon name="loader-2" [size]="24" class="studio-card__spinner" />
1521
+ </div>
1522
+ }
1523
+ </div>
1524
+ `, styles: [":host{display:block;font-family:var(--studio-font-family);position:relative;transition:all var(--studio-transition-normal)}.studio-card__container{display:flex;flex-direction:column;height:100%;overflow:hidden;position:relative}:host(.studio-card--sm) .studio-card__container{min-height:8rem}:host(.studio-card--md) .studio-card__container{min-height:12rem}:host(.studio-card--lg) .studio-card__container{min-height:16rem}:host(.studio-card--radius-none) .studio-card__container{border-radius:var(--studio-radius-none)}:host(.studio-card--radius-sm) .studio-card__container{border-radius:var(--studio-radius-sm)}:host(.studio-card--radius-md) .studio-card__container{border-radius:var(--studio-radius-md)}:host(.studio-card--radius-lg) .studio-card__container{border-radius:var(--studio-radius-lg)}:host(.studio-card--radius-xl) .studio-card__container{border-radius:var(--studio-radius-xl)}:host(.studio-card--shadow-none) .studio-card__container{box-shadow:none}:host(.studio-card--shadow-sm) .studio-card__container{box-shadow:var(--studio-shadow-sm)}:host(.studio-card--shadow-md) .studio-card__container{box-shadow:var(--studio-shadow-md)}:host(.studio-card--shadow-lg) .studio-card__container{box-shadow:var(--studio-shadow-lg)}:host(.studio-card--shadow-xl) .studio-card__container{box-shadow:var(--studio-shadow-xl)}:host(.studio-card--elevated.studio-card--default) .studio-card__container{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary)}:host(.studio-card--filled.studio-card--default) .studio-card__container{background:var(--studio-bg-secondary);border:1px solid transparent}:host(.studio-card--outlined.studio-card--default) .studio-card__container{background:transparent;border:2px solid var(--studio-border-primary)}:host(.studio-card--ghost.studio-card--default) .studio-card__container{background:transparent;border:1px solid transparent}:host(.studio-card--elevated.studio-card--primary) .studio-card__container{background:var(--studio-primary-bg);border:1px solid var(--studio-primary)}:host(.studio-card--filled.studio-card--primary) .studio-card__container{background:var(--studio-primary);color:#fff;border:1px solid transparent}:host(.studio-card--outlined.studio-card--primary) .studio-card__container{background:transparent;border:2px solid var(--studio-primary);color:var(--studio-primary)}:host(.studio-card--ghost.studio-card--primary) .studio-card__container{background:var(--studio-primary-bg);border:1px solid transparent;color:var(--studio-primary)}:host(.studio-card--elevated.studio-card--secondary) .studio-card__container{background:var(--studio-bg-primary);border:1px solid var(--studio-text-secondary)}:host(.studio-card--filled.studio-card--secondary) .studio-card__container{background:var(--studio-text-secondary);color:#fff;border:1px solid transparent}:host(.studio-card--outlined.studio-card--secondary) .studio-card__container{background:transparent;border:2px solid var(--studio-text-secondary);color:var(--studio-text-secondary)}:host(.studio-card--ghost.studio-card--secondary) .studio-card__container{background:var(--studio-bg-secondary);border:1px solid transparent;color:var(--studio-text-secondary)}:host(.studio-card--elevated.studio-card--success) .studio-card__container{background:var(--studio-success-bg);border:1px solid var(--studio-success)}:host(.studio-card--filled.studio-card--success) .studio-card__container{background:var(--studio-success);color:#fff;border:1px solid transparent}:host(.studio-card--outlined.studio-card--success) .studio-card__container{background:transparent;border:2px solid var(--studio-success);color:var(--studio-success)}:host(.studio-card--ghost.studio-card--success) .studio-card__container{background:var(--studio-success-bg);border:1px solid transparent;color:var(--studio-success)}:host(.studio-card--elevated.studio-card--error) .studio-card__container{background:var(--studio-error-bg);border:1px solid var(--studio-error)}:host(.studio-card--filled.studio-card--error) .studio-card__container{background:var(--studio-error);color:#fff;border:1px solid transparent}:host(.studio-card--outlined.studio-card--error) .studio-card__container{background:transparent;border:2px solid var(--studio-error);color:var(--studio-error)}:host(.studio-card--ghost.studio-card--error) .studio-card__container{background:var(--studio-error-bg);border:1px solid transparent;color:var(--studio-error)}:host(.studio-card--elevated.studio-card--warning) .studio-card__container{background:var(--studio-warning-bg);border:1px solid var(--studio-warning)}:host(.studio-card--filled.studio-card--warning) .studio-card__container{background:var(--studio-warning);color:#fff;border:1px solid transparent}:host(.studio-card--outlined.studio-card--warning) .studio-card__container{background:transparent;border:2px solid var(--studio-warning);color:var(--studio-warning)}:host(.studio-card--ghost.studio-card--warning) .studio-card__container{background:var(--studio-warning-bg);border:1px solid transparent;color:var(--studio-warning)}:host(.studio-card--elevated.studio-card--neutral) .studio-card__container{background:var(--studio-bg-tertiary);border:1px solid var(--studio-border-secondary)}:host(.studio-card--filled.studio-card--neutral) .studio-card__container{background:var(--studio-bg-secondary);border:1px solid transparent}:host(.studio-card--outlined.studio-card--neutral) .studio-card__container{background:transparent;border:2px solid var(--studio-border-secondary)}:host(.studio-card--ghost.studio-card--neutral) .studio-card__container{background:transparent;border:1px solid transparent}:host(.studio-card--padding-none) .studio-card__header,:host(.studio-card--padding-none) .studio-card__body,:host(.studio-card--padding-none) .studio-card__footer{padding:0}:host(.studio-card--padding-sm) .studio-card__header,:host(.studio-card--padding-sm) .studio-card__footer{padding:var(--studio-spacing-sm)}:host(.studio-card--padding-sm) .studio-card__body{padding:var(--studio-spacing-sm)}:host(.studio-card--padding-md) .studio-card__header,:host(.studio-card--padding-md) .studio-card__footer{padding:var(--studio-spacing-md)}:host(.studio-card--padding-md) .studio-card__body{padding:var(--studio-spacing-md)}:host(.studio-card--padding-lg) .studio-card__header,:host(.studio-card--padding-lg) .studio-card__footer{padding:var(--studio-spacing-lg)}:host(.studio-card--padding-lg) .studio-card__body{padding:var(--studio-spacing-lg)}.studio-card__header{display:flex;align-items:center;justify-content:space-between;gap:var(--studio-spacing-md);flex-shrink:0}:host(.studio-card--divider) .studio-card__header{border-bottom:1px solid var(--studio-border-primary)}.studio-card__header-content{display:flex;align-items:center;gap:var(--studio-spacing-md);flex:1;min-width:0}.studio-card__avatar{width:2.5rem;height:2.5rem;border-radius:50%;object-fit:cover;flex-shrink:0}.studio-card__icon-wrapper{display:flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;border-radius:50%;background:var(--studio-bg-secondary);flex-shrink:0}.studio-card__header-text{flex:1;min-width:0}.studio-card__title{margin:0;font-size:var(--studio-font-size-lg);font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.studio-card__subtitle{margin:.25rem 0 0;font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.studio-card__header-actions{display:flex;align-items:center;gap:var(--studio-spacing-sm);flex-shrink:0}.studio-card__media{flex-shrink:0;overflow:hidden;position:relative}:host(.studio-card--padding-none) .studio-card__media{margin:0}:host(.studio-card--padding-sm) .studio-card__media{margin:var(--studio-spacing-sm);margin-top:0}:host(.studio-card--padding-md) .studio-card__media{margin:var(--studio-spacing-md);margin-top:0}:host(.studio-card--padding-lg) .studio-card__media{margin:var(--studio-spacing-lg);margin-top:0}.studio-card__image{width:100%;height:auto;display:block;border-radius:var(--studio-radius-sm)}.studio-card__image--cover{object-fit:cover;height:12rem}.studio-card__image--contain{object-fit:contain;max-height:16rem}.studio-card__body{flex:1;overflow-y:auto}.studio-card__footer{display:flex;align-items:center;gap:var(--studio-spacing-md);flex-shrink:0}:host(.studio-card--divider) .studio-card__footer{border-top:1px solid var(--studio-border-primary)}:host(.studio-card--blurred-footer) .studio-card__footer{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:#ffffff1a;border-top:1px solid rgba(255,255,255,.2)}:host(.studio-card--horizontal) .studio-card__container{flex-direction:row}:host(.studio-card--horizontal) .studio-card__media{width:40%;margin:0}:host(.studio-card--horizontal) .studio-card__body{flex:1}:host(.studio-card--full-width){width:100%}:host(.studio-card--full-height){height:100%}:host(.studio-card--full-height) .studio-card__container{height:100%}:host(.studio-card--hoverable) .studio-card__container{cursor:pointer;transition:all var(--studio-transition-normal)}:host(.studio-card--hoverable:hover:not(.studio-card--disabled)) .studio-card__container{transform:translateY(-2px);box-shadow:var(--studio-shadow-lg)}:host(.studio-card--pressable) .studio-card__container{cursor:pointer;transition:all var(--studio-transition-fast)}:host(.studio-card--pressable:active:not(.studio-card--disabled)) .studio-card__container{transform:scale(.98)}:host(.studio-card--clickable) .studio-card__container{cursor:pointer}:host(.studio-card--disabled){pointer-events:none;opacity:.5}:host(.studio-card--blurred) .studio-card__container{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:#ffffff1a!important;border:1px solid rgba(255,255,255,.2)}:host(.studio-card--animated){animation:cardFadeIn .3s ease-out}@keyframes cardFadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.studio-card__loading{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#ffffffe6;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);z-index:10}.studio-card__spinner{animation:spin 1s linear infinite;color:var(--studio-primary)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}:host(.studio-card--loading) .studio-card__container{pointer-events:none}\n"] }]
1525
+ }], propDecorators: { variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], colorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], shadowInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], paddingInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], imagePosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "imagePosition", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], fullHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullHeight", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], avatar: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatar", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], image: [{ type: i0.Input, args: [{ isSignal: true, alias: "image", required: false }] }], imageAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageAlt", required: false }] }], imageFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageFit", required: false }] }], showHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], showMedia: [{ type: i0.Input, args: [{ isSignal: true, alias: "showMedia", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], divider: [{ type: i0.Input, args: [{ isSignal: true, alias: "divider", required: false }] }], hoverable: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverable", required: false }] }], pressable: [{ type: i0.Input, args: [{ isSignal: true, alias: "pressable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: false }] }], blurred: [{ type: i0.Input, args: [{ isSignal: true, alias: "blurred", required: false }] }], blurredFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "blurredFooter", required: false }] }], animated: [{ type: i0.Input, args: [{ isSignal: true, alias: "animated", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }], headerAction: [{ type: i0.Output, args: ["headerAction"] }], headerTemplate: [{ type: i0.ContentChild, args: ['cardHeader', { isSignal: true }] }], headerActionsTemplate: [{ type: i0.ContentChild, args: ['cardHeaderActions', { isSignal: true }] }], mediaTemplate: [{ type: i0.ContentChild, args: ['cardMedia', { isSignal: true }] }], bodyTemplate: [{ type: i0.ContentChild, args: ['cardBody', { isSignal: true }] }], footerTemplate: [{ type: i0.ContentChild, args: ['cardFooter', { isSignal: true }] }] } });
1526
+
1527
+ /**
1528
+ * Card component types
1529
+ */
1530
+
1531
+ class ChatMessageComponent {
1532
+ message = input.required(...(ngDevMode ? [{ debugName: "message" }] : []));
1533
+ currentUserId = input.required(...(ngDevMode ? [{ debugName: "currentUserId" }] : []));
1534
+ showAvatar = input(true, ...(ngDevMode ? [{ debugName: "showAvatar" }] : []));
1535
+ showTimestamp = input(true, ...(ngDevMode ? [{ debugName: "showTimestamp" }] : []));
1536
+ showUserName = input(true, ...(ngDevMode ? [{ debugName: "showUserName" }] : []));
1537
+ compact = input(false, ...(ngDevMode ? [{ debugName: "compact" }] : []));
1538
+ isOwn = computed(() => this.message().userId === this.currentUserId(), ...(ngDevMode ? [{ debugName: "isOwn" }] : []));
1539
+ hostClasses = computed(() => {
1540
+ const classes = ['studio-chat-message'];
1541
+ if (this.isOwn())
1542
+ classes.push('chat-message--own');
1543
+ if (this.message().type === 'system')
1544
+ classes.push('chat-message--system');
1545
+ if (this.compact())
1546
+ classes.push('chat-message--compact');
1547
+ if (this.message().status === 'read')
1548
+ classes.push('chat-message--status-read');
1549
+ if (this.message().status === 'error')
1550
+ classes.push('chat-message--status-error');
1551
+ return classes.join(' ');
1552
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
1553
+ getInitials(name) {
1554
+ return name
1555
+ .split(' ')
1556
+ .map(n => n[0])
1557
+ .slice(0, 2)
1558
+ .join('')
1559
+ .toUpperCase();
1560
+ }
1561
+ formatTime(date) {
1562
+ const now = new Date();
1563
+ const messageDate = new Date(date);
1564
+ const diff = now.getTime() - messageDate.getTime();
1565
+ const minutes = Math.floor(diff / 60000);
1566
+ const hours = Math.floor(diff / 3600000);
1567
+ const days = Math.floor(diff / 86400000);
1568
+ if (minutes < 1)
1569
+ return 'Just now';
1570
+ if (minutes < 60)
1571
+ return `${minutes}m ago`;
1572
+ if (hours < 24)
1573
+ return `${hours}h ago`;
1574
+ if (days === 1)
1575
+ return 'Yesterday';
1576
+ if (days < 7)
1577
+ return `${days}d ago`;
1578
+ return messageDate.toLocaleDateString('en-US', {
1579
+ month: 'short',
1580
+ day: 'numeric'
1581
+ });
1582
+ }
1583
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1584
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: ChatMessageComponent, isStandalone: true, selector: "studio-chat-message", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, currentUserId: { classPropertyName: "currentUserId", publicName: "currentUserId", isSignal: true, isRequired: true, transformFunction: null }, showAvatar: { classPropertyName: "showAvatar", publicName: "showAvatar", isSignal: true, isRequired: false, transformFunction: null }, showTimestamp: { classPropertyName: "showTimestamp", publicName: "showTimestamp", isSignal: true, isRequired: false, transformFunction: null }, showUserName: { classPropertyName: "showUserName", publicName: "showUserName", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
1585
+ <div class="chat-message__container">
1586
+ @if (showAvatar() && !isOwn()) {
1587
+ <div class="chat-message__avatar">
1588
+ @if (message().userAvatar) {
1589
+ <img [src]="message().userAvatar" [alt]="message().userName" />
1590
+ } @else {
1591
+ <div class="chat-message__avatar-fallback">
1592
+ {{ getInitials(message().userName) }}
1593
+ </div>
1594
+ }
1595
+ </div>
1596
+ }
1597
+
1598
+ <div class="chat-message__content-wrapper">
1599
+ @if (!isOwn() && showUserName()) {
1600
+ <div class="chat-message__user-name">{{ message().userName }}</div>
1601
+ }
1602
+
1603
+ <div class="chat-message__bubble">
1604
+ @if (message().type === 'system') {
1605
+ <div class="chat-message__system">{{ message().content }}</div>
1606
+ } @else {
1607
+ <div class="chat-message__text">{{ message().content }}</div>
1608
+ }
1609
+
1610
+ @if (message().edited) {
1611
+ <span class="chat-message__edited">(edited)</span>
1612
+ }
1613
+ </div>
1614
+
1615
+ <div class="chat-message__meta">
1616
+ @if (showTimestamp()) {
1617
+ <span class="chat-message__time">{{ formatTime(message().timestamp) }}</span>
1618
+ }
1619
+
1620
+ @if (isOwn() && message().status && message().status !== 'sending') {
1621
+ <span class="chat-message__status">
1622
+ @if (message().status === 'sent') {
1623
+ <studio-icon name="check" [size]="12" />
1624
+ }
1625
+ @if (message().status === 'delivered' || message().status === 'read') {
1626
+ <studio-icon name="check-check" [size]="12" />
1627
+ }
1628
+ @if (message().status === 'error') {
1629
+ <studio-icon name="alert-circle" [size]="12" />
1630
+ }
1631
+ </span>
1632
+ }
1633
+ </div>
1634
+ </div>
1635
+ </div>
1636
+ `, isInline: true, styles: [":host{display:block;margin-bottom:.75rem}:host(.chat-message--own) .chat-message__container{justify-content:flex-end}:host(.chat-message--own) .chat-message__bubble{background:var(--studio-primary);color:#fff}:host(.chat-message--own) .chat-message__meta{justify-content:flex-end}:host(.chat-message--system){text-align:center;margin:1rem 0}:host(.chat-message--system) .chat-message__system{display:inline-block;padding:.25rem .75rem;background:var(--studio-bg-secondary);color:var(--studio-text-secondary);border-radius:var(--studio-radius-full);font-size:.75rem}:host(.chat-message--compact){margin-bottom:.25rem}.chat-message__container{display:flex;gap:.75rem;align-items:flex-end}.chat-message__avatar{width:32px;height:32px;border-radius:50%;overflow:hidden;flex-shrink:0}.chat-message__avatar img{width:100%;height:100%;object-fit:cover}.chat-message__avatar-fallback{width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:var(--studio-primary);color:#fff;font-size:.75rem;font-weight:600}.chat-message__content-wrapper{max-width:70%;display:flex;flex-direction:column;gap:.25rem}.chat-message__user-name{font-size:.75rem;font-weight:500;color:var(--studio-text-secondary);padding-left:.75rem}.chat-message__bubble{padding:.625rem .875rem;border-radius:var(--studio-radius-lg);background:var(--studio-bg-secondary);color:var(--studio-text-primary);word-wrap:break-word;position:relative}.chat-message__text{white-space:pre-wrap;line-height:1.5}.chat-message__edited{font-size:.6875rem;color:var(--studio-text-tertiary);margin-left:.25rem}.chat-message__meta{display:flex;align-items:center;gap:.25rem;padding:0 .75rem}.chat-message__time{font-size:.6875rem;color:var(--studio-text-tertiary)}.chat-message__status{display:flex;align-items:center;color:var(--studio-text-tertiary)}:host(.chat-message--own) .chat-message__status{color:var(--studio-text-tertiary)}:host(.chat-message--status-read) .chat-message__status{color:var(--studio-primary)}:host(.chat-message--status-error) .chat-message__status{color:var(--studio-error)}:host(.chat-message--compact) .chat-message__avatar{width:24px;height:24px}:host(.chat-message--compact) .chat-message__bubble{padding:.5rem .75rem;font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1637
+ }
1638
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ChatMessageComponent, decorators: [{
1639
+ type: Component,
1640
+ args: [{ selector: 'studio-chat-message', standalone: true, imports: [CommonModule, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1641
+ '[class]': 'hostClasses()'
1642
+ }, template: `
1643
+ <div class="chat-message__container">
1644
+ @if (showAvatar() && !isOwn()) {
1645
+ <div class="chat-message__avatar">
1646
+ @if (message().userAvatar) {
1647
+ <img [src]="message().userAvatar" [alt]="message().userName" />
1648
+ } @else {
1649
+ <div class="chat-message__avatar-fallback">
1650
+ {{ getInitials(message().userName) }}
1651
+ </div>
1652
+ }
1653
+ </div>
1654
+ }
1655
+
1656
+ <div class="chat-message__content-wrapper">
1657
+ @if (!isOwn() && showUserName()) {
1658
+ <div class="chat-message__user-name">{{ message().userName }}</div>
1659
+ }
1660
+
1661
+ <div class="chat-message__bubble">
1662
+ @if (message().type === 'system') {
1663
+ <div class="chat-message__system">{{ message().content }}</div>
1664
+ } @else {
1665
+ <div class="chat-message__text">{{ message().content }}</div>
1666
+ }
1667
+
1668
+ @if (message().edited) {
1669
+ <span class="chat-message__edited">(edited)</span>
1670
+ }
1671
+ </div>
1672
+
1673
+ <div class="chat-message__meta">
1674
+ @if (showTimestamp()) {
1675
+ <span class="chat-message__time">{{ formatTime(message().timestamp) }}</span>
1676
+ }
1677
+
1678
+ @if (isOwn() && message().status && message().status !== 'sending') {
1679
+ <span class="chat-message__status">
1680
+ @if (message().status === 'sent') {
1681
+ <studio-icon name="check" [size]="12" />
1682
+ }
1683
+ @if (message().status === 'delivered' || message().status === 'read') {
1684
+ <studio-icon name="check-check" [size]="12" />
1685
+ }
1686
+ @if (message().status === 'error') {
1687
+ <studio-icon name="alert-circle" [size]="12" />
1688
+ }
1689
+ </span>
1690
+ }
1691
+ </div>
1692
+ </div>
1693
+ </div>
1694
+ `, styles: [":host{display:block;margin-bottom:.75rem}:host(.chat-message--own) .chat-message__container{justify-content:flex-end}:host(.chat-message--own) .chat-message__bubble{background:var(--studio-primary);color:#fff}:host(.chat-message--own) .chat-message__meta{justify-content:flex-end}:host(.chat-message--system){text-align:center;margin:1rem 0}:host(.chat-message--system) .chat-message__system{display:inline-block;padding:.25rem .75rem;background:var(--studio-bg-secondary);color:var(--studio-text-secondary);border-radius:var(--studio-radius-full);font-size:.75rem}:host(.chat-message--compact){margin-bottom:.25rem}.chat-message__container{display:flex;gap:.75rem;align-items:flex-end}.chat-message__avatar{width:32px;height:32px;border-radius:50%;overflow:hidden;flex-shrink:0}.chat-message__avatar img{width:100%;height:100%;object-fit:cover}.chat-message__avatar-fallback{width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:var(--studio-primary);color:#fff;font-size:.75rem;font-weight:600}.chat-message__content-wrapper{max-width:70%;display:flex;flex-direction:column;gap:.25rem}.chat-message__user-name{font-size:.75rem;font-weight:500;color:var(--studio-text-secondary);padding-left:.75rem}.chat-message__bubble{padding:.625rem .875rem;border-radius:var(--studio-radius-lg);background:var(--studio-bg-secondary);color:var(--studio-text-primary);word-wrap:break-word;position:relative}.chat-message__text{white-space:pre-wrap;line-height:1.5}.chat-message__edited{font-size:.6875rem;color:var(--studio-text-tertiary);margin-left:.25rem}.chat-message__meta{display:flex;align-items:center;gap:.25rem;padding:0 .75rem}.chat-message__time{font-size:.6875rem;color:var(--studio-text-tertiary)}.chat-message__status{display:flex;align-items:center;color:var(--studio-text-tertiary)}:host(.chat-message--own) .chat-message__status{color:var(--studio-text-tertiary)}:host(.chat-message--status-read) .chat-message__status{color:var(--studio-primary)}:host(.chat-message--status-error) .chat-message__status{color:var(--studio-error)}:host(.chat-message--compact) .chat-message__avatar{width:24px;height:24px}:host(.chat-message--compact) .chat-message__bubble{padding:.5rem .75rem;font-size:.875rem}\n"] }]
1695
+ }], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], currentUserId: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentUserId", required: true }] }], showAvatar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAvatar", required: false }] }], showTimestamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTimestamp", required: false }] }], showUserName: [{ type: i0.Input, args: [{ isSignal: true, alias: "showUserName", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }] } });
1696
+
1697
+ class ChatInputComponent {
1698
+ placeholder = input('Type a message...', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
1699
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1700
+ compact = input(false, ...(ngDevMode ? [{ debugName: "compact" }] : []));
1701
+ messageSubmit = output();
1702
+ typing = output();
1703
+ inputValue = signal('', ...(ngDevMode ? [{ debugName: "inputValue" }] : []));
1704
+ textareaRef = viewChild('textareaRef', ...(ngDevMode ? [{ debugName: "textareaRef" }] : []));
1705
+ typingTimeout;
1706
+ canSend = computed(() => this.inputValue().trim().length > 0 && !this.disabled(), ...(ngDevMode ? [{ debugName: "canSend" }] : []));
1707
+ hostClasses = computed(() => {
1708
+ const classes = ['studio-chat-input'];
1709
+ if (this.compact())
1710
+ classes.push('chat-input--compact');
1711
+ return classes.join(' ');
1712
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
1713
+ constructor() {
1714
+ // Auto-resize textarea
1715
+ effect(() => {
1716
+ const textarea = this.textareaRef()?.nativeElement;
1717
+ if (textarea) {
1718
+ textarea.style.height = 'auto';
1719
+ textarea.style.height = textarea.scrollHeight + 'px';
1720
+ }
1721
+ });
1722
+ }
1723
+ onKeyDown(event) {
1724
+ if (event.key === 'Enter' && !event.shiftKey) {
1725
+ event.preventDefault();
1726
+ this.handleSubmit();
1727
+ }
1728
+ }
1729
+ onInput() {
1730
+ // Emit typing indicator
1731
+ this.typing.emit(true);
1732
+ // Clear previous timeout
1733
+ if (this.typingTimeout) {
1734
+ clearTimeout(this.typingTimeout);
1735
+ }
1736
+ // Set new timeout to stop typing after 1 second
1737
+ this.typingTimeout = setTimeout(() => {
1738
+ this.typing.emit(false);
1739
+ }, 1000);
1740
+ // Auto-resize
1741
+ const textarea = this.textareaRef()?.nativeElement;
1742
+ if (textarea) {
1743
+ textarea.style.height = 'auto';
1744
+ textarea.style.height = textarea.scrollHeight + 'px';
1745
+ }
1746
+ }
1747
+ handleSubmit() {
1748
+ const content = this.inputValue().trim();
1749
+ if (content && !this.disabled()) {
1750
+ this.messageSubmit.emit({ content });
1751
+ this.inputValue.set('');
1752
+ // Reset textarea height
1753
+ const textarea = this.textareaRef()?.nativeElement;
1754
+ if (textarea) {
1755
+ textarea.style.height = 'auto';
1756
+ }
1757
+ // Stop typing indicator
1758
+ if (this.typingTimeout) {
1759
+ clearTimeout(this.typingTimeout);
1760
+ }
1761
+ this.typing.emit(false);
1762
+ }
1763
+ }
1764
+ focus() {
1765
+ this.textareaRef()?.nativeElement.focus();
1766
+ }
1767
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ChatInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1768
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.12", type: ChatInputComponent, isStandalone: true, selector: "studio-chat-input", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { messageSubmit: "messageSubmit", typing: "typing" }, host: { properties: { "class": "hostClasses()" } }, viewQueries: [{ propertyName: "textareaRef", first: true, predicate: ["textareaRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
1769
+ <div class="chat-input__container">
1770
+ <textarea
1771
+ #textareaRef
1772
+ class="chat-input__textarea"
1773
+ [placeholder]="placeholder()"
1774
+ [disabled]="disabled()"
1775
+ [(ngModel)]="inputValue"
1776
+ (keydown)="onKeyDown($event)"
1777
+ (input)="onInput()"
1778
+ rows="1"
1779
+ ></textarea>
1780
+
1781
+ <studio-button
1782
+ variant="ghost"
1783
+ size="sm"
1784
+ [disabled]="!canSend()"
1785
+ (click)="handleSubmit()"
1786
+ class="chat-input__send-button"
1787
+ >
1788
+ <studio-icon name="send" [size]="20" />
1789
+ </studio-button>
1790
+ </div>
1791
+ `, isInline: true, styles: [":host{display:block}.chat-input__container{display:flex;align-items:flex-end;gap:.5rem;padding:1rem;background:var(--studio-bg-primary);border-top:1px solid var(--studio-border-primary)}.chat-input__textarea{flex:1;min-height:40px;max-height:120px;padding:.625rem .875rem;border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);background:var(--studio-bg-primary);color:var(--studio-text-primary);font-family:inherit;font-size:.875rem;line-height:1.5;resize:none;overflow-y:auto;transition:border-color .15s ease}.chat-input__textarea:focus{outline:none;border-color:var(--studio-primary)}.chat-input__textarea:disabled{opacity:.5;cursor:not-allowed}.chat-input__textarea::placeholder{color:var(--studio-text-tertiary)}.chat-input__send-button{flex-shrink:0}:host(.chat-input--compact) .chat-input__container{padding:.75rem}:host(.chat-input--compact) .chat-input__textarea{padding:.5rem .75rem;font-size:.8125rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { 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: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }, { 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 });
1792
+ }
1793
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ChatInputComponent, decorators: [{
1794
+ type: Component,
1795
+ args: [{ selector: 'studio-chat-input', standalone: true, imports: [CommonModule, FormsModule, IconComponent, ButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1796
+ '[class]': 'hostClasses()'
1797
+ }, template: `
1798
+ <div class="chat-input__container">
1799
+ <textarea
1800
+ #textareaRef
1801
+ class="chat-input__textarea"
1802
+ [placeholder]="placeholder()"
1803
+ [disabled]="disabled()"
1804
+ [(ngModel)]="inputValue"
1805
+ (keydown)="onKeyDown($event)"
1806
+ (input)="onInput()"
1807
+ rows="1"
1808
+ ></textarea>
1809
+
1810
+ <studio-button
1811
+ variant="ghost"
1812
+ size="sm"
1813
+ [disabled]="!canSend()"
1814
+ (click)="handleSubmit()"
1815
+ class="chat-input__send-button"
1816
+ >
1817
+ <studio-icon name="send" [size]="20" />
1818
+ </studio-button>
1819
+ </div>
1820
+ `, styles: [":host{display:block}.chat-input__container{display:flex;align-items:flex-end;gap:.5rem;padding:1rem;background:var(--studio-bg-primary);border-top:1px solid var(--studio-border-primary)}.chat-input__textarea{flex:1;min-height:40px;max-height:120px;padding:.625rem .875rem;border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);background:var(--studio-bg-primary);color:var(--studio-text-primary);font-family:inherit;font-size:.875rem;line-height:1.5;resize:none;overflow-y:auto;transition:border-color .15s ease}.chat-input__textarea:focus{outline:none;border-color:var(--studio-primary)}.chat-input__textarea:disabled{opacity:.5;cursor:not-allowed}.chat-input__textarea::placeholder{color:var(--studio-text-tertiary)}.chat-input__send-button{flex-shrink:0}:host(.chat-input--compact) .chat-input__container{padding:.75rem}:host(.chat-input--compact) .chat-input__textarea{padding:.5rem .75rem;font-size:.8125rem}\n"] }]
1821
+ }], ctorParameters: () => [], propDecorators: { placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], messageSubmit: [{ type: i0.Output, args: ["messageSubmit"] }], typing: [{ type: i0.Output, args: ["typing"] }], textareaRef: [{ type: i0.ViewChild, args: ['textareaRef', { isSignal: true }] }] } });
1822
+
1823
+ /**
1824
+ * Chat component - Flexible chat/messaging component
1825
+ *
1826
+ * @example
1827
+ * <studio-chat
1828
+ * [messages]="messages"
1829
+ * [currentUserId]="currentUser.id"
1830
+ * variant="default"
1831
+ * (messageSubmit)="handleMessage($event)"
1832
+ * />
1833
+ */
1834
+ class ChatComponent {
1835
+ // ========== Required ==========
1836
+ messages = input.required(...(ngDevMode ? [{ debugName: "messages" }] : []));
1837
+ currentUserId = input.required(...(ngDevMode ? [{ debugName: "currentUserId" }] : []));
1838
+ // ========== Appearance ==========
1839
+ variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
1840
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1841
+ height = input('600px', ...(ngDevMode ? [{ debugName: "height" }] : []));
1842
+ // ========== Behavior ==========
1843
+ placeholder = input('Type a message...', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
1844
+ showAvatars = input(true, ...(ngDevMode ? [{ debugName: "showAvatars" }] : []));
1845
+ showTimestamps = input(true, ...(ngDevMode ? [{ debugName: "showTimestamps" }] : []));
1846
+ showUserNames = input(true, ...(ngDevMode ? [{ debugName: "showUserNames" }] : []));
1847
+ enableAutoScroll = input(true, ...(ngDevMode ? [{ debugName: "enableAutoScroll" }] : []));
1848
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1849
+ // ========== Customization ==========
1850
+ class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
1851
+ // ========== Outputs ==========
1852
+ messageSubmit = output();
1853
+ typing = output();
1854
+ // ========== State ==========
1855
+ messagesContainerRef = viewChild('messagesContainer', ...(ngDevMode ? [{ debugName: "messagesContainerRef" }] : []));
1856
+ isScrolledUp = signal(false, ...(ngDevMode ? [{ debugName: "isScrolledUp" }] : []));
1857
+ shouldAutoScroll = signal(true, ...(ngDevMode ? [{ debugName: "shouldAutoScroll" }] : []));
1858
+ hostClasses = computed(() => {
1859
+ const classes = ['studio-chat'];
1860
+ classes.push(`studio-chat--${this.variant()}`);
1861
+ classes.push(`studio-chat--${this.size()}`);
1862
+ if (this.disabled())
1863
+ classes.push('studio-chat--disabled');
1864
+ if (this.class())
1865
+ classes.push(this.class());
1866
+ return classes.join(' ');
1867
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
1868
+ isCompact = computed(() => this.variant() === 'compact' || this.variant() === 'minimal', ...(ngDevMode ? [{ debugName: "isCompact" }] : []));
1869
+ constructor() {
1870
+ // Auto-scroll when new messages arrive
1871
+ effect(() => {
1872
+ const messages = this.messages();
1873
+ if (messages.length > 0 && this.shouldAutoScroll() && this.enableAutoScroll()) {
1874
+ setTimeout(() => this.scrollToBottom(), 0);
1875
+ }
1876
+ });
1877
+ }
1878
+ ngAfterViewInit() {
1879
+ this.scrollToBottom();
1880
+ }
1881
+ onScroll() {
1882
+ const container = this.messagesContainerRef()?.nativeElement;
1883
+ if (!container)
1884
+ return;
1885
+ const isAtBottom = container.scrollHeight - container.scrollTop - container.clientHeight < 50;
1886
+ this.isScrolledUp.set(!isAtBottom);
1887
+ this.shouldAutoScroll.set(isAtBottom);
1888
+ }
1889
+ onMessageSubmit(event) {
1890
+ this.messageSubmit.emit(event);
1891
+ this.shouldAutoScroll.set(true);
1892
+ }
1893
+ scrollToBottom() {
1894
+ const container = this.messagesContainerRef()?.nativeElement;
1895
+ if (container) {
1896
+ container.scrollTop = container.scrollHeight;
1897
+ this.isScrolledUp.set(false);
1898
+ this.shouldAutoScroll.set(true);
1899
+ }
1900
+ }
1901
+ onTyping(typing) {
1902
+ this.typing.emit(typing);
1903
+ }
1904
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1905
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: ChatComponent, isStandalone: true, selector: "studio-chat", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: true, transformFunction: null }, currentUserId: { classPropertyName: "currentUserId", publicName: "currentUserId", 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 }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, showAvatars: { classPropertyName: "showAvatars", publicName: "showAvatars", isSignal: true, isRequired: false, transformFunction: null }, showTimestamps: { classPropertyName: "showTimestamps", publicName: "showTimestamps", isSignal: true, isRequired: false, transformFunction: null }, showUserNames: { classPropertyName: "showUserNames", publicName: "showUserNames", isSignal: true, isRequired: false, transformFunction: null }, enableAutoScroll: { classPropertyName: "enableAutoScroll", publicName: "enableAutoScroll", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { messageSubmit: "messageSubmit", typing: "typing" }, host: { properties: { "class": "hostClasses()", "style.height": "height()" } }, viewQueries: [{ propertyName: "messagesContainerRef", first: true, predicate: ["messagesContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"chat__container\">\n <div\n #messagesContainer\n class=\"chat__messages\"\n (scroll)=\"onScroll()\"\n >\n @if (messages().length === 0) {\n <div class=\"chat__empty\">\n <studio-icon name=\"message-circle\" [size]=\"48\" />\n <p>No messages yet</p>\n <small>Start a conversation</small>\n </div>\n } @else {\n @for (message of messages(); track message.id || $index) {\n <studio-chat-message\n [message]=\"message\"\n [currentUserId]=\"currentUserId()\"\n [showAvatar]=\"showAvatars()\"\n [showTimestamp]=\"showTimestamps()\"\n [showUserName]=\"showUserNames()\"\n [compact]=\"isCompact()\"\n />\n }\n }\n </div>\n\n @if (isScrolledUp()) {\n <button\n class=\"chat__scroll-button\"\n (click)=\"scrollToBottom()\"\n type=\"button\"\n >\n <studio-icon name=\"arrow-down\" [size]=\"20\" />\n </button>\n }\n\n <studio-chat-input\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [compact]=\"isCompact()\"\n (messageSubmit)=\"onMessageSubmit($event)\"\n (typing)=\"onTyping($event)\"\n />\n</div>\n", styles: [":host{display:block;position:relative;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-lg);overflow:hidden}.chat__container{display:flex;flex-direction:column;height:100%}.chat__messages{flex:1;overflow-y:auto;padding:1.5rem;display:flex;flex-direction:column;scroll-behavior:smooth}.chat__messages::-webkit-scrollbar{width:6px}.chat__messages::-webkit-scrollbar-track{background:var(--studio-bg-secondary)}.chat__messages::-webkit-scrollbar-thumb{background:var(--studio-border-primary);border-radius:var(--studio-radius-full)}.chat__messages::-webkit-scrollbar-thumb:hover{background:var(--studio-text-tertiary)}.chat__empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;color:var(--studio-text-secondary);padding:3rem 1.5rem}.chat__empty p{margin:0;font-size:1rem;font-weight:500}.chat__empty small{font-size:.875rem;color:var(--studio-text-tertiary)}.chat__scroll-button{position:absolute;bottom:100px;right:1.5rem;width:40px;height:40px;display:flex;align-items:center;justify-content:center;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:50%;box-shadow:0 2px 8px #0000001a;cursor:pointer;transition:all .15s ease;color:var(--studio-text-primary);z-index:10}.chat__scroll-button:hover{background:var(--studio-bg-hover);transform:scale(1.05)}.chat__scroll-button:active{transform:scale(.95)}:host(.studio-chat--compact) .chat__messages{padding:1rem}:host(.studio-chat--compact) .chat__scroll-button{bottom:80px}:host(.studio-chat--minimal){border:none;background:transparent}:host(.studio-chat--minimal) .chat__messages{padding:1rem}:host(.studio-chat--bubbles) .chat__messages{padding:1rem}:host(.studio-chat--sm) .chat__messages{padding:1rem;font-size:.875rem}:host(.studio-chat--sm) .chat__scroll-button{width:36px;height:36px;bottom:90px}:host(.studio-chat--lg) .chat__messages{padding:2rem;font-size:1rem}:host(.studio-chat--lg) .chat__scroll-button{width:44px;height:44px;bottom:110px}:host(.studio-chat--disabled){opacity:.6;pointer-events:none}@media (max-width: 640px){.chat__messages{padding:1rem}.chat__scroll-button{bottom:90px;right:1rem}}@media (prefers-reduced-motion: reduce){.chat__messages{scroll-behavior:auto}.chat__scroll-button{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ChatMessageComponent, selector: "studio-chat-message", inputs: ["message", "currentUserId", "showAvatar", "showTimestamp", "showUserName", "compact"] }, { kind: "component", type: ChatInputComponent, selector: "studio-chat-input", inputs: ["placeholder", "disabled", "compact"], outputs: ["messageSubmit", "typing"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1906
+ }
1907
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ChatComponent, decorators: [{
1908
+ type: Component,
1909
+ args: [{ selector: 'studio-chat', standalone: true, imports: [
1910
+ CommonModule,
1911
+ ChatMessageComponent,
1912
+ ChatInputComponent,
1913
+ IconComponent
1914
+ ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1915
+ '[class]': 'hostClasses()',
1916
+ '[style.height]': 'height()'
1917
+ }, template: "<div class=\"chat__container\">\n <div\n #messagesContainer\n class=\"chat__messages\"\n (scroll)=\"onScroll()\"\n >\n @if (messages().length === 0) {\n <div class=\"chat__empty\">\n <studio-icon name=\"message-circle\" [size]=\"48\" />\n <p>No messages yet</p>\n <small>Start a conversation</small>\n </div>\n } @else {\n @for (message of messages(); track message.id || $index) {\n <studio-chat-message\n [message]=\"message\"\n [currentUserId]=\"currentUserId()\"\n [showAvatar]=\"showAvatars()\"\n [showTimestamp]=\"showTimestamps()\"\n [showUserName]=\"showUserNames()\"\n [compact]=\"isCompact()\"\n />\n }\n }\n </div>\n\n @if (isScrolledUp()) {\n <button\n class=\"chat__scroll-button\"\n (click)=\"scrollToBottom()\"\n type=\"button\"\n >\n <studio-icon name=\"arrow-down\" [size]=\"20\" />\n </button>\n }\n\n <studio-chat-input\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [compact]=\"isCompact()\"\n (messageSubmit)=\"onMessageSubmit($event)\"\n (typing)=\"onTyping($event)\"\n />\n</div>\n", styles: [":host{display:block;position:relative;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-lg);overflow:hidden}.chat__container{display:flex;flex-direction:column;height:100%}.chat__messages{flex:1;overflow-y:auto;padding:1.5rem;display:flex;flex-direction:column;scroll-behavior:smooth}.chat__messages::-webkit-scrollbar{width:6px}.chat__messages::-webkit-scrollbar-track{background:var(--studio-bg-secondary)}.chat__messages::-webkit-scrollbar-thumb{background:var(--studio-border-primary);border-radius:var(--studio-radius-full)}.chat__messages::-webkit-scrollbar-thumb:hover{background:var(--studio-text-tertiary)}.chat__empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;color:var(--studio-text-secondary);padding:3rem 1.5rem}.chat__empty p{margin:0;font-size:1rem;font-weight:500}.chat__empty small{font-size:.875rem;color:var(--studio-text-tertiary)}.chat__scroll-button{position:absolute;bottom:100px;right:1.5rem;width:40px;height:40px;display:flex;align-items:center;justify-content:center;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:50%;box-shadow:0 2px 8px #0000001a;cursor:pointer;transition:all .15s ease;color:var(--studio-text-primary);z-index:10}.chat__scroll-button:hover{background:var(--studio-bg-hover);transform:scale(1.05)}.chat__scroll-button:active{transform:scale(.95)}:host(.studio-chat--compact) .chat__messages{padding:1rem}:host(.studio-chat--compact) .chat__scroll-button{bottom:80px}:host(.studio-chat--minimal){border:none;background:transparent}:host(.studio-chat--minimal) .chat__messages{padding:1rem}:host(.studio-chat--bubbles) .chat__messages{padding:1rem}:host(.studio-chat--sm) .chat__messages{padding:1rem;font-size:.875rem}:host(.studio-chat--sm) .chat__scroll-button{width:36px;height:36px;bottom:90px}:host(.studio-chat--lg) .chat__messages{padding:2rem;font-size:1rem}:host(.studio-chat--lg) .chat__scroll-button{width:44px;height:44px;bottom:110px}:host(.studio-chat--disabled){opacity:.6;pointer-events:none}@media (max-width: 640px){.chat__messages{padding:1rem}.chat__scroll-button{bottom:90px;right:1rem}}@media (prefers-reduced-motion: reduce){.chat__messages{scroll-behavior:auto}.chat__scroll-button{transition:none}}\n"] }]
1918
+ }], ctorParameters: () => [], propDecorators: { messages: [{ type: i0.Input, args: [{ isSignal: true, alias: "messages", required: true }] }], currentUserId: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentUserId", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], showAvatars: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAvatars", required: false }] }], showTimestamps: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTimestamps", required: false }] }], showUserNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "showUserNames", required: false }] }], enableAutoScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableAutoScroll", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], messageSubmit: [{ type: i0.Output, args: ["messageSubmit"] }], typing: [{ type: i0.Output, args: ["typing"] }], messagesContainerRef: [{ type: i0.ViewChild, args: ['messagesContainer', { isSignal: true }] }] } });
1919
+
1048
1920
  /**
1049
1921
  * Checkbox component for selecting boolean values
1050
1922
  *
@@ -1263,7 +2135,7 @@ class CheckboxComponent {
1263
2135
  provide: NG_VALUE_ACCESSOR,
1264
2136
  useExisting: forwardRef(() => CheckboxComponent),
1265
2137
  multi: true
1266
- }], 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"] }] });
2138
+ }], 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"] }] });
1267
2139
  }
1268
2140
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: CheckboxComponent, decorators: [{
1269
2141
  type: Component,
@@ -2069,7 +2941,7 @@ class ColorPickerCompactComponent {
2069
2941
  </ng-template>
2070
2942
  }
2071
2943
  </studio-popover>
2072
- `, 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$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: 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 });
2944
+ `, 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 });
2073
2945
  }
2074
2946
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ColorPickerCompactComponent, decorators: [{
2075
2947
  type: Component,
@@ -3176,7 +4048,7 @@ class MenuComponent {
3176
4048
  };
3177
4049
  }
3178
4050
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3179
- 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: [
4051
+ 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: [
3180
4052
  trigger('expandCollapse', [
3181
4053
  state('collapsed', style({
3182
4054
  height: '0',
@@ -3381,7 +4253,7 @@ class ModalComponent {
3381
4253
  }
3382
4254
  </div>
3383
4255
  }
3384
- `, 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.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 });
4256
+ `, 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 });
3385
4257
  }
3386
4258
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ModalComponent, decorators: [{
3387
4259
  type: Component,
@@ -3600,7 +4472,7 @@ class RadioButtonComponent {
3600
4472
  provide: NG_VALUE_ACCESSOR,
3601
4473
  useExisting: forwardRef(() => RadioButtonComponent),
3602
4474
  multi: true
3603
- }], 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"] }] });
4475
+ }], 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"] }] });
3604
4476
  }
3605
4477
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: RadioButtonComponent, decorators: [{
3606
4478
  type: Component,
@@ -4996,7 +5868,7 @@ class InspectorComponent {
4996
5868
  useExisting: forwardRef(() => InspectorComponent),
4997
5869
  multi: true
4998
5870
  }
4999
- ], 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$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: 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 });
5871
+ ], 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 });
5000
5872
  }
5001
5873
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: InspectorComponent, decorators: [{
5002
5874
  type: Component,
@@ -5553,5 +6425,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
5553
6425
  * Generated bundle index. Do not edit.
5554
6426
  */
5555
6427
 
5556
- export { BadgeComponent, BadgeWrapperComponent, 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 };
6428
+ export { BadgeComponent, BadgeWrapperComponent, BottomNavigationComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, CardComponent, ChatComponent, ChatInputComponent, ChatMessageComponent, 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 };
5557
6429
  //# sourceMappingURL=eduboxpro-studio.mjs.map