@eduboxpro/studio 0.1.11 → 0.1.13

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,12 +1,14 @@
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, DOCUMENT as DOCUMENT$1, DestroyRef, contentChild, viewChild, model, HostListener, PLATFORM_ID, Renderer2, Directive } from '@angular/core';
2
+ import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, ElementRef, forwardRef, viewChild, DOCUMENT as DOCUMENT$1, DestroyRef, contentChild, model, HostListener, PLATFORM_ID, Renderer2, Directive } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { DOCUMENT, CommonModule, NgTemplateOutlet, isPlatformBrowser } from '@angular/common';
5
5
  import * as LucideIcons from 'lucide-angular';
6
6
  import { icons, LucideAngularModule, LucideIconProvider, LUCIDE_ICONS } from 'lucide-angular';
7
- import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
8
- import { Router, RouterLink, RouterLinkActive } from '@angular/router';
7
+ import * as i1$1 from '@angular/forms';
8
+ import { NG_VALUE_ACCESSOR, FormsModule, NG_VALIDATORS } from '@angular/forms';
9
+ import { Router, RouterLink, RouterLinkActive, NavigationEnd } from '@angular/router';
9
10
  import { trigger, state, transition, style, animate } from '@angular/animations';
11
+ import { filter } from 'rxjs/operators';
10
12
 
11
13
  /**
12
14
  * Injection token for Studio configuration
@@ -759,10 +761,83 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
759
761
  `, styles: [":host{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;font-family:var(--studio-font-family);font-weight:var(--studio-badge-font-weight, 500);line-height:1;white-space:nowrap;transition:all .2s ease;cursor:default;-webkit-user-select:none;user-select:none}.studio-badge__content{display:inline-flex;align-items:center;gap:var(--studio-badge-gap);padding:var(--studio-badge-padding-y) var(--studio-badge-padding-x);border-radius:var(--studio-badge-radius);background:var(--studio-badge-bg);color:var(--studio-badge-color);border:var(--studio-badge-border-width, 1px) solid var(--studio-badge-border-color, transparent);font-size:var(--studio-badge-font-size)}.studio-badge__text{display:inline-block}.studio-badge__dot{width:var(--studio-badge-dot-size, 6px);height:var(--studio-badge-dot-size, 6px);border-radius:50%;background:var(--studio-badge-dot-bg);flex-shrink:0}.studio-badge__remove{all:unset;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;opacity:.7;transition:opacity .2s ease}.studio-badge__remove:hover{opacity:1}.studio-badge__remove:focus-visible{outline:2px solid currentColor;outline-offset:2px;border-radius:2px}:host(.studio-badge--solid){--studio-badge-bg: var(--studio-primary);--studio-badge-color: white}:host(.studio-badge--solid).studio-badge--primary{--studio-badge-bg: var(--studio-primary)}:host(.studio-badge--solid).studio-badge--secondary{--studio-badge-bg: var(--studio-secondary)}:host(.studio-badge--solid).studio-badge--success{--studio-badge-bg: var(--studio-success)}:host(.studio-badge--solid).studio-badge--error{--studio-badge-bg: var(--studio-error)}:host(.studio-badge--solid).studio-badge--warning{--studio-badge-bg: var(--studio-warning)}:host(.studio-badge--solid).studio-badge--info{--studio-badge-bg: var(--studio-info)}:host(.studio-badge--solid).studio-badge--neutral{--studio-badge-bg: var(--studio-border-secondary);--studio-badge-color: var(--studio-text-primary)}:host(.studio-badge--outline){--studio-badge-bg: transparent;--studio-badge-color: var(--studio-primary);--studio-badge-border-color: var(--studio-primary)}:host(.studio-badge--outline).studio-badge--primary{--studio-badge-color: var(--studio-primary);--studio-badge-border-color: var(--studio-primary)}:host(.studio-badge--outline).studio-badge--secondary{--studio-badge-color: var(--studio-secondary);--studio-badge-border-color: var(--studio-secondary)}:host(.studio-badge--outline).studio-badge--success{--studio-badge-color: var(--studio-success);--studio-badge-border-color: var(--studio-success)}:host(.studio-badge--outline).studio-badge--error{--studio-badge-color: var(--studio-error);--studio-badge-border-color: var(--studio-error)}:host(.studio-badge--outline).studio-badge--warning{--studio-badge-color: var(--studio-warning);--studio-badge-border-color: var(--studio-warning)}:host(.studio-badge--outline).studio-badge--info{--studio-badge-color: var(--studio-info);--studio-badge-border-color: var(--studio-info)}:host(.studio-badge--outline).studio-badge--neutral{--studio-badge-color: var(--studio-text-secondary);--studio-badge-border-color: var(--studio-border-secondary)}:host(.studio-badge--soft){--studio-badge-bg: rgba(124, 58, 237, .1);--studio-badge-color: var(--studio-primary)}:host(.studio-badge--soft).studio-badge--primary{--studio-badge-bg: rgba(124, 58, 237, .1);--studio-badge-color: var(--studio-primary)}:host(.studio-badge--soft).studio-badge--secondary{--studio-badge-bg: rgba(99, 102, 241, .1);--studio-badge-color: var(--studio-secondary)}:host(.studio-badge--soft).studio-badge--success{--studio-badge-bg: var(--studio-success-bg);--studio-badge-color: var(--studio-success)}:host(.studio-badge--soft).studio-badge--error{--studio-badge-bg: var(--studio-error-bg);--studio-badge-color: var(--studio-error)}:host(.studio-badge--soft).studio-badge--warning{--studio-badge-bg: var(--studio-warning-bg);--studio-badge-color: var(--studio-warning)}:host(.studio-badge--soft).studio-badge--info{--studio-badge-bg: var(--studio-info-bg);--studio-badge-color: var(--studio-info)}:host(.studio-badge--soft).studio-badge--neutral{--studio-badge-bg: var(--studio-bg-secondary);--studio-badge-color: var(--studio-text-secondary)}:host(.studio-badge--dot){--studio-badge-bg: transparent;--studio-badge-color: var(--studio-text-primary);--studio-badge-border-width: 0}:host(.studio-badge--sm){--studio-badge-padding-y: .125rem;--studio-badge-padding-x: .5rem;--studio-badge-font-size: .6875rem;--studio-badge-gap: .25rem}:host(.studio-badge--md){--studio-badge-padding-y: .25rem;--studio-badge-padding-x: .625rem;--studio-badge-font-size: .75rem;--studio-badge-gap: .375rem}:host(.studio-badge--lg){--studio-badge-padding-y: .375rem;--studio-badge-padding-x: .75rem;--studio-badge-font-size: .875rem;--studio-badge-gap: .5rem}:host(.studio-badge--radius-sm){--studio-badge-radius: 2px}:host(.studio-badge--radius-md){--studio-badge-radius: 4px}:host(.studio-badge--radius-lg){--studio-badge-radius: 8px}:host(.studio-badge--radius-full){--studio-badge-radius: 9999px}.studio-badge__dot--primary{--studio-badge-dot-bg: var(--studio-primary)}.studio-badge__dot--secondary{--studio-badge-dot-bg: var(--studio-secondary)}.studio-badge__dot--success{--studio-badge-dot-bg: var(--studio-success)}.studio-badge__dot--error{--studio-badge-dot-bg: var(--studio-error)}.studio-badge__dot--warning{--studio-badge-dot-bg: var(--studio-warning)}.studio-badge__dot--info{--studio-badge-dot-bg: var(--studio-info)}.studio-badge__dot--neutral{--studio-badge-dot-bg: var(--studio-text-secondary)}:host(.studio-badge--clickable){cursor:pointer}:host(.studio-badge--clickable):hover{opacity:.9;transform:translateY(-1px)}:host(.studio-badge--clickable):active{transform:translateY(0)}:host(.studio-badge--disabled){opacity:.5;cursor:not-allowed;pointer-events:none}:host(.studio-badge--uppercase){text-transform:uppercase;letter-spacing:.5px}:host(.studio-badge--bold){--studio-badge-font-weight: 600}@keyframes badge-pulse{0%,to{opacity:1}50%{opacity:.5}}:host(.studio-badge--pulse) .studio-badge__dot{animation:badge-pulse 2s cubic-bezier(.4,0,.6,1) infinite}\n"] }]
760
762
  }], 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 }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], dot: [{ type: i0.Input, args: [{ isSignal: true, alias: "dot", required: false }] }], dotColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "dotColor", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], showZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "showZero", required: false }] }], uppercase: [{ type: i0.Input, args: [{ isSignal: true, alias: "uppercase", required: false }] }], bold: [{ type: i0.Input, args: [{ isSignal: true, alias: "bold", required: false }] }], pulse: [{ type: i0.Input, args: [{ isSignal: true, alias: "pulse", required: false }] }], autoColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoColor", required: false }] }] } });
761
763
 
764
+ /**
765
+ * Badge component types
766
+ */
767
+
762
768
  /**
763
769
  * Badge component
764
770
  */
765
771
 
772
+ /**
773
+ * BadgeWrapper component - Wraps content with a positioned badge
774
+ *
775
+ * @example
776
+ * <studio-badge-wrapper [count]="5" color="error">
777
+ * <studio-button variant="ghost">
778
+ * <studio-icon name="bell" />
779
+ * </studio-button>
780
+ * </studio-badge-wrapper>
781
+ */
782
+ class BadgeWrapperComponent {
783
+ // ========== Content ==========
784
+ count = input(...(ngDevMode ? [undefined, { debugName: "count" }] : []));
785
+ content = input(...(ngDevMode ? [undefined, { debugName: "content" }] : []));
786
+ // ========== Badge style ==========
787
+ variant = input('solid', ...(ngDevMode ? [{ debugName: "variant" }] : []));
788
+ color = input('error', ...(ngDevMode ? [{ debugName: "color" }] : []));
789
+ size = input('sm', ...(ngDevMode ? [{ debugName: "size" }] : []));
790
+ // ========== Position ==========
791
+ position = input('top-right', ...(ngDevMode ? [{ debugName: "position" }] : []));
792
+ // ========== Behavior ==========
793
+ showZero = input(false, ...(ngDevMode ? [{ debugName: "showZero" }] : []));
794
+ max = input(99, ...(ngDevMode ? [{ debugName: "max" }] : []));
795
+ dot = input(false, ...(ngDevMode ? [{ debugName: "dot" }] : []));
796
+ overlap = input(false, ...(ngDevMode ? [{ debugName: "overlap" }] : []));
797
+ // ========== Customization ==========
798
+ class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
799
+ // ========== Computed values ==========
800
+ hostClasses = computed(() => {
801
+ const classes = ['studio-badge-wrapper'];
802
+ classes.push(`studio-badge-wrapper--${this.position()}`);
803
+ classes.push(`studio-badge-wrapper--${this.size()}`);
804
+ if (this.overlap())
805
+ classes.push('studio-badge-wrapper--overlap');
806
+ if (this.dot())
807
+ classes.push('studio-badge-wrapper--dot');
808
+ if (this.class())
809
+ classes.push(this.class());
810
+ return classes.join(' ');
811
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
812
+ badgeContent = computed(() => {
813
+ if (this.content())
814
+ return this.content();
815
+ const count = this.count();
816
+ if (count === undefined || count === null)
817
+ return undefined;
818
+ const numCount = typeof count === 'number' ? count : parseInt(count, 10);
819
+ if (numCount === 0 && !this.showZero())
820
+ return undefined;
821
+ const max = this.max();
822
+ if (numCount > max)
823
+ return `${max}+`;
824
+ return count.toString();
825
+ }, ...(ngDevMode ? [{ debugName: "badgeContent" }] : []));
826
+ shouldShowBadge = computed(() => {
827
+ if (this.dot())
828
+ return true;
829
+ return this.badgeContent() !== undefined;
830
+ }, ...(ngDevMode ? [{ debugName: "shouldShowBadge" }] : []));
831
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BadgeWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
832
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: BadgeWrapperComponent, isStandalone: true, selector: "studio-badge-wrapper", inputs: { count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: false, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", 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 }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, showZero: { classPropertyName: "showZero", publicName: "showZero", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, dot: { classPropertyName: "dot", publicName: "dot", isSignal: true, isRequired: false, transformFunction: null }, overlap: { classPropertyName: "overlap", publicName: "overlap", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, 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"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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 });
833
+ }
834
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BadgeWrapperComponent, decorators: [{
835
+ type: Component,
836
+ args: [{ selector: 'studio-badge-wrapper', standalone: true, imports: [CommonModule, BadgeComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
837
+ '[class]': 'hostClasses()'
838
+ }, template: "<div class=\"studio-badge-wrapper__content\">\n <ng-content />\n</div>\n\n@if (shouldShowBadge()) {\n <studio-badge\n class=\"studio-badge-wrapper__badge\"\n [variant]=\"dot() ? 'dot' : variant()\"\n [color]=\"color()\"\n [size]=\"size()\"\n >\n {{ badgeContent() }}\n </studio-badge>\n}\n", styles: [":host{display:inline-flex;position:relative;vertical-align:middle;flex-shrink:0}.studio-badge-wrapper__content{display:flex;align-items:center;justify-content:center}.studio-badge-wrapper__badge{position:absolute;z-index:1;transform-origin:center;transition:transform .2s cubic-bezier(.4,0,.2,1)}:host(.studio-badge-wrapper--top-right) .studio-badge-wrapper__badge{top:0;right:0;transform:translate(50%,-50%)}:host(.studio-badge-wrapper--top-left) .studio-badge-wrapper__badge{top:0;left:0;transform:translate(-50%,-50%)}:host(.studio-badge-wrapper--bottom-right) .studio-badge-wrapper__badge{bottom:0;right:0;transform:translate(50%,50%)}:host(.studio-badge-wrapper--bottom-left) .studio-badge-wrapper__badge{bottom:0;left:0;transform:translate(-50%,50%)}:host(.studio-badge-wrapper--overlap.studio-badge-wrapper--top-right) .studio-badge-wrapper__badge{transform:translate(25%,-25%)}:host(.studio-badge-wrapper--overlap.studio-badge-wrapper--top-left) .studio-badge-wrapper__badge{transform:translate(-25%,-25%)}:host(.studio-badge-wrapper--overlap.studio-badge-wrapper--bottom-right) .studio-badge-wrapper__badge{transform:translate(25%,25%)}:host(.studio-badge-wrapper--overlap.studio-badge-wrapper--bottom-left) .studio-badge-wrapper__badge{transform:translate(-25%,25%)}\n"] }]
839
+ }], propDecorators: { count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: false }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], showZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "showZero", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], dot: [{ type: i0.Input, args: [{ isSignal: true, alias: "dot", required: false }] }], overlap: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlap", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
840
+
766
841
  /**
767
842
  * Button component with multiple variants, sizes, colors and states
768
843
  *
@@ -1204,6 +1279,400 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1204
1279
  }, 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"] }]
1205
1280
  }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
1206
1281
 
1282
+ class ColorConverter {
1283
+ static hexToRgb(hex) {
1284
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
1285
+ return result ? {
1286
+ r: parseInt(result[1], 16),
1287
+ g: parseInt(result[2], 16),
1288
+ b: parseInt(result[3], 16)
1289
+ } : null;
1290
+ }
1291
+ static rgbToHex(r, g, b) {
1292
+ return "#" + [r, g, b]
1293
+ .map(x => {
1294
+ const hex = Math.round(x).toString(16);
1295
+ return hex.length === 1 ? "0" + hex : hex;
1296
+ })
1297
+ .join("");
1298
+ }
1299
+ static rgbToHsl(r, g, b) {
1300
+ r /= 255;
1301
+ g /= 255;
1302
+ b /= 255;
1303
+ const max = Math.max(r, g, b);
1304
+ const min = Math.min(r, g, b);
1305
+ let h = 0, s = 0;
1306
+ const l = (max + min) / 2;
1307
+ if (max !== min) {
1308
+ const d = max - min;
1309
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1310
+ switch (max) {
1311
+ case r:
1312
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
1313
+ break;
1314
+ case g:
1315
+ h = ((b - r) / d + 2) / 6;
1316
+ break;
1317
+ case b:
1318
+ h = ((r - g) / d + 4) / 6;
1319
+ break;
1320
+ }
1321
+ }
1322
+ return {
1323
+ h: Math.round(h * 360),
1324
+ s: Math.round(s * 100),
1325
+ l: Math.round(l * 100)
1326
+ };
1327
+ }
1328
+ static hslToRgb(h, s, l) {
1329
+ h = h / 360;
1330
+ s = s / 100;
1331
+ l = l / 100;
1332
+ let r, g, b;
1333
+ if (s === 0) {
1334
+ r = g = b = l;
1335
+ }
1336
+ else {
1337
+ const hue2rgb = (p, q, t) => {
1338
+ if (t < 0)
1339
+ t += 1;
1340
+ if (t > 1)
1341
+ t -= 1;
1342
+ if (t < 1 / 6)
1343
+ return p + (q - p) * 6 * t;
1344
+ if (t < 1 / 2)
1345
+ return q;
1346
+ if (t < 2 / 3)
1347
+ return p + (q - p) * (2 / 3 - t) * 6;
1348
+ return p;
1349
+ };
1350
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
1351
+ const p = 2 * l - q;
1352
+ r = hue2rgb(p, q, h + 1 / 3);
1353
+ g = hue2rgb(p, q, h);
1354
+ b = hue2rgb(p, q, h - 1 / 3);
1355
+ }
1356
+ return {
1357
+ r: Math.round(r * 255),
1358
+ g: Math.round(g * 255),
1359
+ b: Math.round(b * 255)
1360
+ };
1361
+ }
1362
+ static format(color, format) {
1363
+ switch (format) {
1364
+ case 'hex':
1365
+ return color.hex;
1366
+ case 'rgb':
1367
+ if (color.alpha < 1) {
1368
+ return `rgba(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b}, ${color.alpha})`;
1369
+ }
1370
+ return `rgb(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b})`;
1371
+ case 'hsl':
1372
+ if (color.alpha < 1) {
1373
+ return `hsla(${color.hsl.h}, ${color.hsl.s}%, ${color.hsl.l}%, ${color.alpha})`;
1374
+ }
1375
+ return `hsl(${color.hsl.h}, ${color.hsl.s}%, ${color.hsl.l}%)`;
1376
+ default:
1377
+ return color.hex;
1378
+ }
1379
+ }
1380
+ static parse(colorString) {
1381
+ const trimmed = colorString.trim();
1382
+ const hexMatch = /^#?([a-f\d]{6})$/i.exec(trimmed);
1383
+ if (hexMatch) {
1384
+ const hex = '#' + hexMatch[1];
1385
+ const rgb = this.hexToRgb(hex);
1386
+ if (!rgb)
1387
+ return null;
1388
+ return {
1389
+ hex,
1390
+ rgb,
1391
+ hsl: this.rgbToHsl(rgb.r, rgb.g, rgb.b),
1392
+ alpha: 1
1393
+ };
1394
+ }
1395
+ const rgbMatch = /^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)$/i.exec(trimmed);
1396
+ if (rgbMatch) {
1397
+ const r = parseInt(rgbMatch[1]);
1398
+ const g = parseInt(rgbMatch[2]);
1399
+ const b = parseInt(rgbMatch[3]);
1400
+ const alpha = rgbMatch[4] ? parseFloat(rgbMatch[4]) : 1;
1401
+ return {
1402
+ hex: this.rgbToHex(r, g, b),
1403
+ rgb: { r, g, b },
1404
+ hsl: this.rgbToHsl(r, g, b),
1405
+ alpha
1406
+ };
1407
+ }
1408
+ const hslMatch = /^hsla?\((\d+),\s*(\d+)%?,\s*(\d+)%?(?:,\s*([\d.]+))?\)$/i.exec(trimmed);
1409
+ if (hslMatch) {
1410
+ const h = parseInt(hslMatch[1]);
1411
+ const s = parseInt(hslMatch[2]);
1412
+ const l = parseInt(hslMatch[3]);
1413
+ const alpha = hslMatch[4] ? parseFloat(hslMatch[4]) : 1;
1414
+ const rgb = this.hslToRgb(h, s, l);
1415
+ return {
1416
+ hex: this.rgbToHex(rgb.r, rgb.g, rgb.b),
1417
+ rgb,
1418
+ hsl: { h, s, l },
1419
+ alpha
1420
+ };
1421
+ }
1422
+ return null;
1423
+ }
1424
+ static isValid(colorString) {
1425
+ return this.parse(colorString) !== null;
1426
+ }
1427
+ }
1428
+
1429
+ const DEFAULT_COLOR_PRESETS = [
1430
+ {
1431
+ label: 'Brand Colors',
1432
+ colors: [
1433
+ { label: 'Primary', value: '#7c3aed' },
1434
+ { label: 'Secondary', value: '#6366f1' },
1435
+ { label: 'Success', value: '#10b981' },
1436
+ { label: 'Error', value: '#ef4444' },
1437
+ { label: 'Warning', value: '#f59e0b' },
1438
+ { label: 'Info', value: '#3b82f6' }
1439
+ ]
1440
+ },
1441
+ {
1442
+ label: 'Grays',
1443
+ colors: [
1444
+ { value: '#ffffff' },
1445
+ { value: '#f3f4f6' },
1446
+ { value: '#d1d5db' },
1447
+ { value: '#9ca3af' },
1448
+ { value: '#6b7280' },
1449
+ { value: '#374151' },
1450
+ { value: '#1f2937' },
1451
+ { value: '#000000' }
1452
+ ]
1453
+ },
1454
+ {
1455
+ label: 'Common',
1456
+ colors: [
1457
+ { value: '#ff0000' },
1458
+ { value: '#ff7f00' },
1459
+ { value: '#ffff00' },
1460
+ { value: '#00ff00' },
1461
+ { value: '#0000ff' },
1462
+ { value: '#4b0082' },
1463
+ { value: '#9400d3' },
1464
+ { value: '#ff1493' }
1465
+ ]
1466
+ }
1467
+ ];
1468
+
1469
+ class ColorPickerComponent {
1470
+ configService = inject(StudioConfigService);
1471
+ pickerDefaults = computed(() => this.configService.config().components?.colorPicker, ...(ngDevMode ? [{ debugName: "pickerDefaults" }] : []));
1472
+ colorAreaCanvas = viewChild('colorArea', ...(ngDevMode ? [{ debugName: "colorAreaCanvas" }] : []));
1473
+ variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
1474
+ sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
1475
+ variant = withConfigDefault(this.variantInput, computed(() => this.pickerDefaults()?.variant), 'inline');
1476
+ size = withConfigDefault(this.sizeInput, computed(() => this.pickerDefaults()?.size), 'md');
1477
+ format = input('hex', ...(ngDevMode ? [{ debugName: "format" }] : []));
1478
+ showAlpha = input(false, ...(ngDevMode ? [{ debugName: "showAlpha" }] : []));
1479
+ showPresets = input(true, ...(ngDevMode ? [{ debugName: "showPresets" }] : []));
1480
+ showFormatToggle = input(true, ...(ngDevMode ? [{ debugName: "showFormatToggle" }] : []));
1481
+ showCopyButton = input(true, ...(ngDevMode ? [{ debugName: "showCopyButton" }] : []));
1482
+ presets = input(...(ngDevMode ? [undefined, { debugName: "presets" }] : []));
1483
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : []));
1484
+ hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : []));
1485
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
1486
+ error = input(false, ...(ngDevMode ? [{ debugName: "error" }] : []));
1487
+ errorMessage = input(undefined, ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
1488
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1489
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
1490
+ colorChange = output();
1491
+ colorValueChange = output();
1492
+ copied = output();
1493
+ currentColor = signal(this.createColorValue('#000000'), ...(ngDevMode ? [{ debugName: "currentColor" }] : []));
1494
+ hue = signal(0, ...(ngDevMode ? [{ debugName: "hue" }] : []));
1495
+ saturation = signal(100, ...(ngDevMode ? [{ debugName: "saturation" }] : []));
1496
+ lightness = signal(50, ...(ngDevMode ? [{ debugName: "lightness" }] : []));
1497
+ alpha = signal(1, ...(ngDevMode ? [{ debugName: "alpha" }] : []));
1498
+ currentFormat = signal('hex', ...(ngDevMode ? [{ debugName: "currentFormat" }] : []));
1499
+ generatedId = `studio-color-picker-${Math.random().toString(36).substr(2, 9)}`;
1500
+ onChange = () => { };
1501
+ onTouched = () => { };
1502
+ isDragging = false;
1503
+ constructor() {
1504
+ effect(() => {
1505
+ this.currentFormat.set(this.format());
1506
+ });
1507
+ effect(() => {
1508
+ this.renderColorArea();
1509
+ });
1510
+ }
1511
+ ngAfterViewInit() {
1512
+ this.renderColorArea();
1513
+ }
1514
+ displayColor = computed(() => {
1515
+ const color = this.currentColor();
1516
+ return ColorConverter.format(color, this.currentFormat());
1517
+ }, ...(ngDevMode ? [{ debugName: "displayColor" }] : []));
1518
+ effectivePresets = computed(() => {
1519
+ const custom = this.presets();
1520
+ return custom && custom.length > 0 ? custom : DEFAULT_COLOR_PRESETS;
1521
+ }, ...(ngDevMode ? [{ debugName: "effectivePresets" }] : []));
1522
+ hostClasses = computed(() => classNames('studio-color-picker', `studio-color-picker--${this.variant()}`, `studio-color-picker--${this.size()}`, this.error() && 'studio-color-picker--error', this.disabled() && 'studio-color-picker--disabled'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
1523
+ writeValue(value) {
1524
+ if (!value)
1525
+ return;
1526
+ const colorValue = ColorConverter.parse(value);
1527
+ if (colorValue) {
1528
+ this.currentColor.set(colorValue);
1529
+ this.hue.set(colorValue.hsl.h);
1530
+ this.saturation.set(colorValue.hsl.s);
1531
+ this.lightness.set(colorValue.hsl.l);
1532
+ this.alpha.set(colorValue.alpha);
1533
+ }
1534
+ }
1535
+ registerOnChange(fn) {
1536
+ this.onChange = fn;
1537
+ }
1538
+ registerOnTouched(fn) {
1539
+ this.onTouched = fn;
1540
+ }
1541
+ setDisabledState(isDisabled) { }
1542
+ onHueChange(event) {
1543
+ const value = +event.target.value;
1544
+ this.hue.set(value);
1545
+ this.updateColor();
1546
+ }
1547
+ onAlphaChange(event) {
1548
+ const value = +event.target.value;
1549
+ this.alpha.set(value / 100);
1550
+ this.updateColor();
1551
+ }
1552
+ onColorAreaMouseDown(event) {
1553
+ if (this.disabled() || this.readonly())
1554
+ return;
1555
+ this.isDragging = true;
1556
+ this.updateColorArea(event);
1557
+ const onMouseMove = (e) => {
1558
+ if (this.isDragging) {
1559
+ this.updateColorArea(e);
1560
+ }
1561
+ };
1562
+ const onMouseUp = () => {
1563
+ this.isDragging = false;
1564
+ document.removeEventListener('mousemove', onMouseMove);
1565
+ document.removeEventListener('mouseup', onMouseUp);
1566
+ };
1567
+ document.addEventListener('mousemove', onMouseMove);
1568
+ document.addEventListener('mouseup', onMouseUp);
1569
+ }
1570
+ updateColorArea(event) {
1571
+ const canvas = this.colorAreaCanvas()?.nativeElement;
1572
+ if (!canvas)
1573
+ return;
1574
+ const rect = canvas.getBoundingClientRect();
1575
+ const x = Math.max(0, Math.min(event.clientX - rect.left, rect.width));
1576
+ const y = Math.max(0, Math.min(event.clientY - rect.top, rect.height));
1577
+ this.saturation.set((x / rect.width) * 100);
1578
+ this.lightness.set(100 - (y / rect.height) * 100);
1579
+ this.updateColor();
1580
+ }
1581
+ updateColor() {
1582
+ const h = this.hue();
1583
+ const s = this.saturation();
1584
+ const l = this.lightness();
1585
+ const rgb = ColorConverter.hslToRgb(h, s, l);
1586
+ const hex = ColorConverter.rgbToHex(rgb.r, rgb.g, rgb.b);
1587
+ const colorValue = {
1588
+ hex,
1589
+ rgb,
1590
+ hsl: { h, s, l },
1591
+ alpha: this.alpha()
1592
+ };
1593
+ this.currentColor.set(colorValue);
1594
+ const formatted = ColorConverter.format(colorValue, this.currentFormat());
1595
+ this.onChange(formatted);
1596
+ this.colorChange.emit(formatted);
1597
+ this.colorValueChange.emit(colorValue);
1598
+ }
1599
+ renderColorArea() {
1600
+ const canvas = this.colorAreaCanvas()?.nativeElement;
1601
+ if (!canvas)
1602
+ return;
1603
+ const ctx = canvas.getContext('2d');
1604
+ if (!ctx)
1605
+ return;
1606
+ const width = canvas.width;
1607
+ const height = canvas.height;
1608
+ const hue = this.hue();
1609
+ const horizGradient = ctx.createLinearGradient(0, 0, width, 0);
1610
+ horizGradient.addColorStop(0, 'white');
1611
+ horizGradient.addColorStop(1, `hsl(${hue}, 100%, 50%)`);
1612
+ ctx.fillStyle = horizGradient;
1613
+ ctx.fillRect(0, 0, width, height);
1614
+ const vertGradient = ctx.createLinearGradient(0, 0, 0, height);
1615
+ vertGradient.addColorStop(0, 'transparent');
1616
+ vertGradient.addColorStop(1, 'black');
1617
+ ctx.fillStyle = vertGradient;
1618
+ ctx.fillRect(0, 0, width, height);
1619
+ }
1620
+ toggleFormat() {
1621
+ const formats = ['hex', 'rgb', 'hsl'];
1622
+ const current = this.currentFormat();
1623
+ const index = formats.indexOf(current);
1624
+ const next = formats[(index + 1) % formats.length];
1625
+ this.currentFormat.set(next);
1626
+ }
1627
+ async copyColor() {
1628
+ const color = this.displayColor();
1629
+ try {
1630
+ await navigator.clipboard.writeText(color);
1631
+ this.copied.emit(color);
1632
+ }
1633
+ catch (error) {
1634
+ console.error('Copy failed:', error);
1635
+ }
1636
+ }
1637
+ selectPreset(preset) {
1638
+ this.writeValue(preset.value);
1639
+ this.updateColor();
1640
+ }
1641
+ isPresetGroup(item) {
1642
+ return item && 'colors' in item && Array.isArray(item.colors);
1643
+ }
1644
+ createColorValue(hex) {
1645
+ const rgb = ColorConverter.hexToRgb(hex) || { r: 0, g: 0, b: 0 };
1646
+ const hsl = ColorConverter.rgbToHsl(rgb.r, rgb.g, rgb.b);
1647
+ return {
1648
+ hex,
1649
+ rgb,
1650
+ hsl,
1651
+ alpha: 1
1652
+ };
1653
+ }
1654
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1655
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: ColorPickerComponent, isStandalone: true, selector: "studio-color-picker", inputs: { variantInput: { classPropertyName: "variantInput", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, showAlpha: { classPropertyName: "showAlpha", publicName: "showAlpha", isSignal: true, isRequired: false, transformFunction: null }, showPresets: { classPropertyName: "showPresets", publicName: "showPresets", isSignal: true, isRequired: false, transformFunction: null }, showFormatToggle: { classPropertyName: "showFormatToggle", publicName: "showFormatToggle", isSignal: true, isRequired: false, transformFunction: null }, showCopyButton: { classPropertyName: "showCopyButton", publicName: "showCopyButton", isSignal: true, isRequired: false, transformFunction: null }, presets: { classPropertyName: "presets", publicName: "presets", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { colorChange: "colorChange", colorValueChange: "colorValueChange", copied: "copied" }, host: { properties: { "class": "hostClasses()" } }, providers: [
1656
+ {
1657
+ provide: NG_VALUE_ACCESSOR,
1658
+ useExisting: forwardRef(() => ColorPickerComponent),
1659
+ multi: true
1660
+ }
1661
+ ], viewQueries: [{ propertyName: "colorAreaCanvas", first: true, predicate: ["colorArea"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <label [for]=\"generatedId\" class=\"studio-color-picker__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-color-picker__required\">*</span>\n }\n </label>\n}\n\n<div class=\"studio-color-picker__picker\">\n <div class=\"studio-color-picker__preview\">\n <div\n class=\"studio-color-picker__preview-color\"\n [style.background-color]=\"displayColor()\"\n ></div>\n <div class=\"studio-color-picker__preview-info\">\n <span class=\"studio-color-picker__preview-value\">{{ displayColor() }}</span>\n @if (showFormatToggle()) {\n <button\n type=\"button\"\n class=\"studio-color-picker__format-btn\"\n (click)=\"toggleFormat()\"\n [disabled]=\"disabled() || readonly()\"\n >\n {{ currentFormat().toUpperCase() }}\n </button>\n }\n </div>\n @if (showCopyButton()) {\n <button\n type=\"button\"\n class=\"studio-color-picker__copy-btn\"\n (click)=\"copyColor()\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Copy color\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\n </svg>\n </button>\n }\n </div>\n\n <div class=\"studio-color-picker__area\">\n <canvas\n #colorArea\n class=\"studio-color-picker__canvas\"\n width=\"280\"\n height=\"180\"\n (mousedown)=\"onColorAreaMouseDown($event)\"\n ></canvas>\n <div\n class=\"studio-color-picker__cursor\"\n [style.left.%]=\"saturation()\"\n [style.top.%]=\"100 - lightness()\"\n ></div>\n </div>\n\n <div class=\"studio-color-picker__sliders\">\n <div class=\"studio-color-picker__slider\">\n <div class=\"studio-color-picker__slider-label\">Hue</div>\n <input\n type=\"range\"\n class=\"studio-color-picker__hue-slider\"\n min=\"0\"\n max=\"360\"\n [value]=\"hue()\"\n (input)=\"onHueChange($event)\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Hue\"\n />\n </div>\n\n @if (showAlpha()) {\n <div class=\"studio-color-picker__slider\">\n <div class=\"studio-color-picker__slider-label\">Opacity</div>\n <input\n type=\"range\"\n class=\"studio-color-picker__alpha-slider\"\n min=\"0\"\n max=\"100\"\n [value]=\"alpha() * 100\"\n (input)=\"onAlphaChange($event)\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Opacity\"\n />\n <span class=\"studio-color-picker__alpha-value\">{{ (alpha() * 100).toFixed(0) }}%</span>\n </div>\n }\n </div>\n\n @if (showPresets() && effectivePresets().length > 0) {\n <div class=\"studio-color-picker__presets\">\n @for (preset of effectivePresets(); track $index) {\n @if (isPresetGroup(preset)) {\n <div class=\"studio-color-picker__preset-group\">\n <div class=\"studio-color-picker__preset-group-label\">{{ preset.label }}</div>\n <div class=\"studio-color-picker__preset-swatches\">\n @for (color of preset.colors; track color.value) {\n <button\n type=\"button\"\n class=\"studio-color-picker__preset-swatch\"\n [style.background-color]=\"color.value\"\n [title]=\"color.label || color.value\"\n (click)=\"selectPreset(color)\"\n [disabled]=\"disabled() || readonly()\"\n ></button>\n }\n </div>\n </div>\n } @else {\n <button\n type=\"button\"\n class=\"studio-color-picker__preset-swatch\"\n [style.background-color]=\"preset.value\"\n [title]=\"preset.label || preset.value\"\n (click)=\"selectPreset(preset)\"\n [disabled]=\"disabled() || readonly()\"\n ></button>\n }\n }\n </div>\n }\n</div>\n\n@if (hint() && !error()) {\n <span class=\"studio-color-picker__hint\">\n {{ hint() }}\n </span>\n}\n\n@if (error() && errorMessage()) {\n <span class=\"studio-color-picker__error\" role=\"alert\">\n {{ errorMessage() }}\n </span>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:.5rem;font-family:var(--studio-font-family)}.studio-color-picker__label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-color-picker__label .studio-color-picker__required{color:var(--studio-error);margin-left:.125rem}.studio-color-picker__picker{display:flex;flex-direction:column;gap:1rem;padding:1rem;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md)}.studio-color-picker__preview{display:flex;align-items:center;gap:.75rem}.studio-color-picker__preview-color{width:3rem;height:3rem;border-radius:var(--studio-radius-sm);border:1px solid var(--studio-border-primary);flex-shrink:0}.studio-color-picker__preview-info{flex:1;display:flex;align-items:center;gap:.5rem}.studio-color-picker__preview-value{font-family:var(--studio-font-mono, monospace);font-size:.875rem;color:var(--studio-text-primary)}.studio-color-picker__format-btn{padding:.25rem .5rem;background:var(--studio-bg-secondary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary);cursor:pointer;transition:all var(--studio-transition-fast)}.studio-color-picker__format-btn:hover:not(:disabled){background:var(--studio-bg-tertiary);color:var(--studio-text-primary)}.studio-color-picker__format-btn:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__copy-btn{padding:.5rem;background:none;border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);color:var(--studio-text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--studio-transition-fast)}.studio-color-picker__copy-btn:hover:not(:disabled){background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-color-picker__copy-btn:active:not(:disabled){transform:scale(.95)}.studio-color-picker__copy-btn:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__area{position:relative;width:100%;aspect-ratio:28/18;border-radius:var(--studio-radius-sm);overflow:hidden;border:1px solid var(--studio-border-primary)}.studio-color-picker__canvas{display:block;width:100%;height:100%;cursor:crosshair}.studio-color-picker__cursor{position:absolute;width:16px;height:16px;border:2px solid white;border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003}.studio-color-picker__sliders{display:flex;flex-direction:column;gap:.75rem}.studio-color-picker__slider{display:flex;flex-direction:column;gap:.5rem}.studio-color-picker__slider-label{font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary)}.studio-color-picker__hue-slider{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:6px;background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red);outline:none;cursor:pointer}.studio-color-picker__hue-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__hue-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__hue-slider:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__alpha-slider{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:6px;background:linear-gradient(to right,transparent 0%,var(--studio-text-primary) 100%);outline:none;cursor:pointer;position:relative}.studio-color-picker__alpha-slider:before{content:\"\";position:absolute;inset:0;border-radius:6px;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:10px 10px;background-position:0 0,0 5px,5px -5px,-5px 0px;z-index:-1}.studio-color-picker__alpha-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__alpha-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__alpha-slider:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__alpha-value{font-size:.75rem;color:var(--studio-text-secondary);margin-left:auto}.studio-color-picker__presets{display:flex;flex-direction:column;gap:.75rem}.studio-color-picker__preset-group{display:flex;flex-direction:column;gap:.5rem}.studio-color-picker__preset-group-label{font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary)}.studio-color-picker__preset-swatches{display:flex;flex-wrap:wrap;gap:.375rem}.studio-color-picker__preset-swatch{width:2rem;height:2rem;border-radius:var(--studio-radius-sm);border:1px solid var(--studio-border-primary);cursor:pointer;transition:all var(--studio-transition-fast);padding:0}.studio-color-picker__preset-swatch:hover:not(:disabled){transform:scale(1.1);box-shadow:0 2px 8px #00000026}.studio-color-picker__preset-swatch:active:not(:disabled){transform:scale(1.05)}.studio-color-picker__preset-swatch:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-color-picker__error{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--studio-error);line-height:1.4}:host(.studio-color-picker--disabled) .studio-color-picker__picker{opacity:.6;pointer-events:none}:host(.studio-color-picker--error) .studio-color-picker__picker{border-color:var(--studio-error)}:host(.studio-color-picker--sm) .studio-color-picker__preview-color{width:2.5rem;height:2.5rem}:host(.studio-color-picker--sm) .studio-color-picker__picker{padding:.75rem}:host(.studio-color-picker--lg) .studio-color-picker__preview-color{width:3.5rem;height:3.5rem}:host(.studio-color-picker--lg) .studio-color-picker__picker{padding:1.25rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1662
+ }
1663
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ColorPickerComponent, decorators: [{
1664
+ type: Component,
1665
+ args: [{ selector: 'studio-color-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
1666
+ {
1667
+ provide: NG_VALUE_ACCESSOR,
1668
+ useExisting: forwardRef(() => ColorPickerComponent),
1669
+ multi: true
1670
+ }
1671
+ ], host: {
1672
+ '[class]': 'hostClasses()',
1673
+ }, template: "@if (label()) {\n <label [for]=\"generatedId\" class=\"studio-color-picker__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-color-picker__required\">*</span>\n }\n </label>\n}\n\n<div class=\"studio-color-picker__picker\">\n <div class=\"studio-color-picker__preview\">\n <div\n class=\"studio-color-picker__preview-color\"\n [style.background-color]=\"displayColor()\"\n ></div>\n <div class=\"studio-color-picker__preview-info\">\n <span class=\"studio-color-picker__preview-value\">{{ displayColor() }}</span>\n @if (showFormatToggle()) {\n <button\n type=\"button\"\n class=\"studio-color-picker__format-btn\"\n (click)=\"toggleFormat()\"\n [disabled]=\"disabled() || readonly()\"\n >\n {{ currentFormat().toUpperCase() }}\n </button>\n }\n </div>\n @if (showCopyButton()) {\n <button\n type=\"button\"\n class=\"studio-color-picker__copy-btn\"\n (click)=\"copyColor()\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Copy color\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\n </svg>\n </button>\n }\n </div>\n\n <div class=\"studio-color-picker__area\">\n <canvas\n #colorArea\n class=\"studio-color-picker__canvas\"\n width=\"280\"\n height=\"180\"\n (mousedown)=\"onColorAreaMouseDown($event)\"\n ></canvas>\n <div\n class=\"studio-color-picker__cursor\"\n [style.left.%]=\"saturation()\"\n [style.top.%]=\"100 - lightness()\"\n ></div>\n </div>\n\n <div class=\"studio-color-picker__sliders\">\n <div class=\"studio-color-picker__slider\">\n <div class=\"studio-color-picker__slider-label\">Hue</div>\n <input\n type=\"range\"\n class=\"studio-color-picker__hue-slider\"\n min=\"0\"\n max=\"360\"\n [value]=\"hue()\"\n (input)=\"onHueChange($event)\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Hue\"\n />\n </div>\n\n @if (showAlpha()) {\n <div class=\"studio-color-picker__slider\">\n <div class=\"studio-color-picker__slider-label\">Opacity</div>\n <input\n type=\"range\"\n class=\"studio-color-picker__alpha-slider\"\n min=\"0\"\n max=\"100\"\n [value]=\"alpha() * 100\"\n (input)=\"onAlphaChange($event)\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Opacity\"\n />\n <span class=\"studio-color-picker__alpha-value\">{{ (alpha() * 100).toFixed(0) }}%</span>\n </div>\n }\n </div>\n\n @if (showPresets() && effectivePresets().length > 0) {\n <div class=\"studio-color-picker__presets\">\n @for (preset of effectivePresets(); track $index) {\n @if (isPresetGroup(preset)) {\n <div class=\"studio-color-picker__preset-group\">\n <div class=\"studio-color-picker__preset-group-label\">{{ preset.label }}</div>\n <div class=\"studio-color-picker__preset-swatches\">\n @for (color of preset.colors; track color.value) {\n <button\n type=\"button\"\n class=\"studio-color-picker__preset-swatch\"\n [style.background-color]=\"color.value\"\n [title]=\"color.label || color.value\"\n (click)=\"selectPreset(color)\"\n [disabled]=\"disabled() || readonly()\"\n ></button>\n }\n </div>\n </div>\n } @else {\n <button\n type=\"button\"\n class=\"studio-color-picker__preset-swatch\"\n [style.background-color]=\"preset.value\"\n [title]=\"preset.label || preset.value\"\n (click)=\"selectPreset(preset)\"\n [disabled]=\"disabled() || readonly()\"\n ></button>\n }\n }\n </div>\n }\n</div>\n\n@if (hint() && !error()) {\n <span class=\"studio-color-picker__hint\">\n {{ hint() }}\n </span>\n}\n\n@if (error() && errorMessage()) {\n <span class=\"studio-color-picker__error\" role=\"alert\">\n {{ errorMessage() }}\n </span>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:.5rem;font-family:var(--studio-font-family)}.studio-color-picker__label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-color-picker__label .studio-color-picker__required{color:var(--studio-error);margin-left:.125rem}.studio-color-picker__picker{display:flex;flex-direction:column;gap:1rem;padding:1rem;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md)}.studio-color-picker__preview{display:flex;align-items:center;gap:.75rem}.studio-color-picker__preview-color{width:3rem;height:3rem;border-radius:var(--studio-radius-sm);border:1px solid var(--studio-border-primary);flex-shrink:0}.studio-color-picker__preview-info{flex:1;display:flex;align-items:center;gap:.5rem}.studio-color-picker__preview-value{font-family:var(--studio-font-mono, monospace);font-size:.875rem;color:var(--studio-text-primary)}.studio-color-picker__format-btn{padding:.25rem .5rem;background:var(--studio-bg-secondary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary);cursor:pointer;transition:all var(--studio-transition-fast)}.studio-color-picker__format-btn:hover:not(:disabled){background:var(--studio-bg-tertiary);color:var(--studio-text-primary)}.studio-color-picker__format-btn:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__copy-btn{padding:.5rem;background:none;border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);color:var(--studio-text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--studio-transition-fast)}.studio-color-picker__copy-btn:hover:not(:disabled){background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-color-picker__copy-btn:active:not(:disabled){transform:scale(.95)}.studio-color-picker__copy-btn:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__area{position:relative;width:100%;aspect-ratio:28/18;border-radius:var(--studio-radius-sm);overflow:hidden;border:1px solid var(--studio-border-primary)}.studio-color-picker__canvas{display:block;width:100%;height:100%;cursor:crosshair}.studio-color-picker__cursor{position:absolute;width:16px;height:16px;border:2px solid white;border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003}.studio-color-picker__sliders{display:flex;flex-direction:column;gap:.75rem}.studio-color-picker__slider{display:flex;flex-direction:column;gap:.5rem}.studio-color-picker__slider-label{font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary)}.studio-color-picker__hue-slider{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:6px;background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red);outline:none;cursor:pointer}.studio-color-picker__hue-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__hue-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__hue-slider:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__alpha-slider{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:6px;background:linear-gradient(to right,transparent 0%,var(--studio-text-primary) 100%);outline:none;cursor:pointer;position:relative}.studio-color-picker__alpha-slider:before{content:\"\";position:absolute;inset:0;border-radius:6px;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:10px 10px;background-position:0 0,0 5px,5px -5px,-5px 0px;z-index:-1}.studio-color-picker__alpha-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__alpha-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__alpha-slider:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__alpha-value{font-size:.75rem;color:var(--studio-text-secondary);margin-left:auto}.studio-color-picker__presets{display:flex;flex-direction:column;gap:.75rem}.studio-color-picker__preset-group{display:flex;flex-direction:column;gap:.5rem}.studio-color-picker__preset-group-label{font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary)}.studio-color-picker__preset-swatches{display:flex;flex-wrap:wrap;gap:.375rem}.studio-color-picker__preset-swatch{width:2rem;height:2rem;border-radius:var(--studio-radius-sm);border:1px solid var(--studio-border-primary);cursor:pointer;transition:all var(--studio-transition-fast);padding:0}.studio-color-picker__preset-swatch:hover:not(:disabled){transform:scale(1.1);box-shadow:0 2px 8px #00000026}.studio-color-picker__preset-swatch:active:not(:disabled){transform:scale(1.05)}.studio-color-picker__preset-swatch:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-color-picker__error{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--studio-error);line-height:1.4}:host(.studio-color-picker--disabled) .studio-color-picker__picker{opacity:.6;pointer-events:none}:host(.studio-color-picker--error) .studio-color-picker__picker{border-color:var(--studio-error)}:host(.studio-color-picker--sm) .studio-color-picker__preview-color{width:2.5rem;height:2.5rem}:host(.studio-color-picker--sm) .studio-color-picker__picker{padding:.75rem}:host(.studio-color-picker--lg) .studio-color-picker__preview-color{width:3.5rem;height:3.5rem}:host(.studio-color-picker--lg) .studio-color-picker__picker{padding:1.25rem}\n"] }]
1674
+ }], ctorParameters: () => [], propDecorators: { colorAreaCanvas: [{ type: i0.ViewChild, args: ['colorArea', { isSignal: true }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], showAlpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAlpha", required: false }] }], showPresets: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPresets", required: false }] }], showFormatToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFormatToggle", required: false }] }], showCopyButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCopyButton", required: false }] }], presets: [{ type: i0.Input, args: [{ isSignal: true, alias: "presets", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], colorChange: [{ type: i0.Output, args: ["colorChange"] }], colorValueChange: [{ type: i0.Output, args: ["colorValueChange"] }], copied: [{ type: i0.Output, args: ["copied"] }] } });
1675
+
1207
1676
  /**
1208
1677
  * Service for programmatic control of Drawer components
1209
1678
  *
@@ -1609,14 +2078,14 @@ class DrawerComponent {
1609
2078
  }
1610
2079
  }
1611
2080
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: DrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1612
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: DrawerComponent, isStandalone: true, selector: "studio-drawer", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, positionInput: { classPropertyName: "positionInput", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, customWidth: { classPropertyName: "customWidth", publicName: "customWidth", isSignal: true, isRequired: false, transformFunction: null }, customHeight: { classPropertyName: "customHeight", publicName: "customHeight", isSignal: true, isRequired: false, transformFunction: null }, modalInput: { classPropertyName: "modalInput", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscapeInput: { classPropertyName: "closeOnEscapeInput", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClickInput: { classPropertyName: "closeOnBackdropClickInput", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, blockScrollInput: { classPropertyName: "blockScrollInput", publicName: "blockScroll", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, showHeaderInput: { classPropertyName: "showHeaderInput", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showCloseButtonInput: { classPropertyName: "showCloseButtonInput", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, closeButtonPositionInput: { classPropertyName: "closeButtonPositionInput", publicName: "closeButtonPosition", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, swipeToCloseInput: { classPropertyName: "swipeToCloseInput", publicName: "swipeToClose", isSignal: true, isRequired: false, transformFunction: null }, swipeThresholdInput: { classPropertyName: "swipeThresholdInput", publicName: "swipeThreshold", isSignal: true, isRequired: false, transformFunction: null }, animationDurationInput: { classPropertyName: "animationDurationInput", publicName: "animationDuration", isSignal: true, isRequired: false, transformFunction: null }, animationEasingInput: { classPropertyName: "animationEasingInput", publicName: "animationEasing", isSignal: true, isRequired: false, transformFunction: null }, disableAnimationInput: { classPropertyName: "disableAnimationInput", publicName: "disableAnimation", isSignal: true, isRequired: false, transformFunction: null }, radiusInput: { classPropertyName: "radiusInput", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, shadowInput: { classPropertyName: "shadowInput", publicName: "shadow", isSignal: true, isRequired: false, transformFunction: null }, shadowSizeInput: { classPropertyName: "shadowSizeInput", publicName: "shadowSize", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "ariaLabelledBy", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, autoFocusInput: { classPropertyName: "autoFocusInput", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, restoreFocusInput: { classPropertyName: "restoreFocusInput", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null }, roleInput: { classPropertyName: "roleInput", publicName: "role", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", visibleChange: "visibleChange", opened: "opened", closed: "closed", backdropClick: "backdropClick" }, host: { listeners: { "document:keydown.escape": "handleEscapeKey($event)", "touchstart": "onTouchStart($event)", "touchmove": "onTouchMove($event)", "touchend": "onTouchEnd($event)", "keydown": "handleKeydown($event)" }, properties: { "class": "hostClasses()", "attr.data-visible": "visible()" } }, queries: [{ propertyName: "headerTemplate", first: true, predicate: ["headerTemplate"], descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["footerTemplate"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "panelEl", first: true, predicate: ["drawerPanel"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (visible()) {\n <!-- Backdrop -->\n @if (modal()) {\n <div\n class=\"studio-drawer__backdrop\"\n (click)=\"handleBackdropClick()\">\n </div>\n }\n\n <!-- Drawer Panel -->\n <div\n #drawerPanel\n class=\"studio-drawer__panel\"\n [attr.role]=\"role()\"\n [attr.aria-modal]=\"modal()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.tabindex]=\"-1\"\n [style.width]=\"customWidth()\"\n [style.height]=\"customHeight()\"\n [style.--drawer-animation-duration]=\"animationDuration() + 'ms'\"\n [style.--drawer-animation-timing]=\"animationEasing()\">\n\n <!-- Header -->\n @if (showHeader() && (headerTemplate() || header() || showCloseButton())) {\n <div class=\"studio-drawer__header\">\n @if (headerTemplate(); as tmpl) {\n <!-- Custom template -->\n <ng-container *ngTemplateOutlet=\"tmpl\" />\n } @else if (header()) {\n <!-- Simple string header -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <h2 class=\"studio-drawer__title\">{{ header() }}</h2>\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n } @else {\n <!-- Named slot fallback -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <ng-content select=\"[drawerHeader]\" />\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Content -->\n <div class=\"studio-drawer__content\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n @if (showFooter() && footerTemplate()) {\n <div class=\"studio-drawer__footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()!\" />\n </div>\n } @else if (showFooter()) {\n <div class=\"studio-drawer__footer\">\n <ng-content select=\"[drawerFooter]\" />\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;pointer-events:none;font-family:var(--studio-font-family)}:host(.studio-drawer--visible){pointer-events:auto}.studio-drawer__backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:var(--studio-drawer-backdrop-bg, rgba(0, 0, 0, .5));-webkit-backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));z-index:var(--studio-drawer-z-index, 1000);opacity:0;transition:opacity var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}:host(.studio-drawer--visible) .studio-drawer__backdrop{opacity:1}.studio-drawer__panel{position:fixed;background:var(--studio-drawer-bg, var(--studio-bg-primary));color:var(--studio-drawer-text-color, var(--studio-text-primary));z-index:calc(var(--studio-drawer-z-index, 1000) + 1);overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;outline:none;transition:transform var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}.studio-drawer__panel::-webkit-scrollbar{width:var(--studio-drawer-scrollbar-width, 8px)}.studio-drawer__panel::-webkit-scrollbar-track{background:var(--studio-drawer-scrollbar-track-bg, transparent)}.studio-drawer__panel::-webkit-scrollbar-thumb{background:var(--studio-drawer-scrollbar-thumb-bg, rgba(0, 0, 0, .2));border-radius:var(--studio-drawer-scrollbar-thumb-radius, 4px)}.studio-drawer__panel::-webkit-scrollbar-thumb:hover{background:var(--studio-drawer-scrollbar-thumb-hover-bg, rgba(0, 0, 0, .3))}:host(.studio-drawer--left) .studio-drawer__panel{top:0;left:0;height:100%;border-right:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(-100%)}:host(.studio-drawer--left.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--right) .studio-drawer__panel{top:0;right:0;height:100%;border-left:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(100%)}:host(.studio-drawer--right.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--top) .studio-drawer__panel{top:0;left:0;width:100%;border-bottom:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(-100%)}:host(.studio-drawer--top.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--bottom) .studio-drawer__panel{bottom:0;left:0;width:100%;border-top:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(100%)}:host(.studio-drawer--bottom.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--left.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--sm) .studio-drawer__panel{width:var(--studio-drawer-width-sm, 20rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel{width:var(--studio-drawer-width-md, 28rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel{width:var(--studio-drawer-width-lg, 36rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:var(--studio-drawer-width-xl, 48rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--full) .studio-drawer__panel{width:100vw;max-width:none}:host(.studio-drawer--top.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--sm) .studio-drawer__panel{height:var(--studio-drawer-height-sm, 12rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--md) .studio-drawer__panel{height:var(--studio-drawer-height-md, 20rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--lg) .studio-drawer__panel{height:var(--studio-drawer-height-lg, 32rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--xl) .studio-drawer__panel{height:var(--studio-drawer-height-xl, 48rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--full) .studio-drawer__panel{height:100vh;max-height:none}:host(.studio-drawer--left.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:0 var(--studio-radius-sm) var(--studio-radius-sm) 0}:host(.studio-drawer--left.studio-drawer--radius-md) .studio-drawer__panel{border-radius:0 var(--studio-radius-md) var(--studio-radius-md) 0}:host(.studio-drawer--left.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:0 var(--studio-radius-lg) var(--studio-radius-lg) 0}:host(.studio-drawer--right.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:var(--studio-radius-sm) 0 0 var(--studio-radius-sm)}:host(.studio-drawer--right.studio-drawer--radius-md) .studio-drawer__panel{border-radius:var(--studio-radius-md) 0 0 var(--studio-radius-md)}:host(.studio-drawer--right.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:var(--studio-radius-lg) 0 0 var(--studio-radius-lg)}:host(.studio-drawer--shadow-sm) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-sm, var(--studio-shadow-sm))}:host(.studio-drawer--shadow-md) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-md, var(--studio-shadow-md))}:host(.studio-drawer--shadow-lg) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-lg, var(--studio-shadow-lg))}:host(.studio-drawer--shadow-xl) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-xl, 0 12px 32px rgba(0, 0, 0, .2))}.studio-drawer__header{flex-shrink:0;padding:var(--studio-drawer-header-padding-y, var(--studio-spacing-md)) var(--studio-drawer-header-padding-x, var(--studio-spacing-lg));border-bottom:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary))}.studio-drawer__header-content{display:flex;align-items:center;gap:var(--studio-drawer-header-gap, var(--studio-spacing-md))}.studio-drawer__title{flex:1;margin:0;font-size:var(--studio-drawer-title-font-size, 1.25rem);font-weight:var(--studio-drawer-title-font-weight, var(--studio-font-weight-semibold, 600));line-height:var(--studio-drawer-title-line-height, 1.5);color:var(--studio-drawer-title-color, var(--studio-text-primary))}.studio-drawer__close{display:flex;align-items:center;justify-content:center;width:var(--studio-drawer-close-button-size, 2.5rem);height:var(--studio-drawer-close-button-size, 2.5rem);padding:0;background:none;border:none;border-radius:var(--studio-drawer-close-button-radius, var(--studio-radius-md));color:var(--studio-drawer-close-button-color, var(--studio-text-secondary));cursor:pointer;transition:all var(--studio-transition-fast);flex-shrink:0}.studio-drawer__close:hover{background:var(--studio-drawer-close-button-hover-bg, var(--studio-bg-secondary));color:var(--studio-drawer-close-button-hover-color, var(--studio-text-primary))}.studio-drawer__close:active{transform:scale(.95)}.studio-drawer__close:focus-visible{outline:2px solid var(--studio-drawer-focus-ring-color, var(--studio-primary));outline-offset:var(--studio-drawer-focus-ring-offset, 2px)}.studio-drawer__content{flex:1;padding:var(--studio-drawer-content-padding-y, var(--studio-spacing-lg)) var(--studio-drawer-content-padding-x, var(--studio-spacing-lg));overflow-y:auto;overflow-x:hidden}.studio-drawer__footer{flex-shrink:0;padding:var(--studio-drawer-footer-padding-y, var(--studio-spacing-md)) var(--studio-drawer-footer-padding-x, var(--studio-spacing-lg));border-top:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary));display:flex;align-items:center;gap:var(--studio-drawer-footer-gap, var(--studio-spacing-sm))}:host(.studio-drawer--dragging) .studio-drawer__panel{transition:none!important}@media (max-width: 640px){:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:100vw;max-width:none}.studio-drawer__header,.studio-drawer__content,.studio-drawer__footer{padding-left:var(--studio-spacing-md);padding-right:var(--studio-spacing-md)}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2081
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: DrawerComponent, isStandalone: true, selector: "studio-drawer", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, positionInput: { classPropertyName: "positionInput", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, customWidth: { classPropertyName: "customWidth", publicName: "customWidth", isSignal: true, isRequired: false, transformFunction: null }, customHeight: { classPropertyName: "customHeight", publicName: "customHeight", isSignal: true, isRequired: false, transformFunction: null }, modalInput: { classPropertyName: "modalInput", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscapeInput: { classPropertyName: "closeOnEscapeInput", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClickInput: { classPropertyName: "closeOnBackdropClickInput", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, blockScrollInput: { classPropertyName: "blockScrollInput", publicName: "blockScroll", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, showHeaderInput: { classPropertyName: "showHeaderInput", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showCloseButtonInput: { classPropertyName: "showCloseButtonInput", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, closeButtonPositionInput: { classPropertyName: "closeButtonPositionInput", publicName: "closeButtonPosition", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, swipeToCloseInput: { classPropertyName: "swipeToCloseInput", publicName: "swipeToClose", isSignal: true, isRequired: false, transformFunction: null }, swipeThresholdInput: { classPropertyName: "swipeThresholdInput", publicName: "swipeThreshold", isSignal: true, isRequired: false, transformFunction: null }, animationDurationInput: { classPropertyName: "animationDurationInput", publicName: "animationDuration", isSignal: true, isRequired: false, transformFunction: null }, animationEasingInput: { classPropertyName: "animationEasingInput", publicName: "animationEasing", isSignal: true, isRequired: false, transformFunction: null }, disableAnimationInput: { classPropertyName: "disableAnimationInput", publicName: "disableAnimation", isSignal: true, isRequired: false, transformFunction: null }, radiusInput: { classPropertyName: "radiusInput", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, shadowInput: { classPropertyName: "shadowInput", publicName: "shadow", isSignal: true, isRequired: false, transformFunction: null }, shadowSizeInput: { classPropertyName: "shadowSizeInput", publicName: "shadowSize", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "ariaLabelledBy", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, autoFocusInput: { classPropertyName: "autoFocusInput", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, restoreFocusInput: { classPropertyName: "restoreFocusInput", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null }, roleInput: { classPropertyName: "roleInput", publicName: "role", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", visibleChange: "visibleChange", opened: "opened", closed: "closed", backdropClick: "backdropClick" }, host: { listeners: { "document:keydown.escape": "handleEscapeKey($event)", "touchstart": "onTouchStart($event)", "touchmove": "onTouchMove($event)", "touchend": "onTouchEnd($event)", "keydown": "handleKeydown($event)" }, properties: { "class": "hostClasses()", "attr.data-visible": "visible()" } }, queries: [{ propertyName: "headerTemplate", first: true, predicate: ["headerTemplate"], descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["footerTemplate"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "panelEl", first: true, predicate: ["drawerPanel"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (visible()) {\n <!-- Backdrop -->\n @if (modal()) {\n <div\n class=\"studio-drawer__backdrop\"\n (click)=\"handleBackdropClick()\">\n </div>\n }\n\n <!-- Drawer Panel -->\n <div\n #drawerPanel\n class=\"studio-drawer__panel\"\n [attr.role]=\"role()\"\n [attr.aria-modal]=\"modal()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.tabindex]=\"-1\"\n [style.width]=\"customWidth()\"\n [style.height]=\"customHeight()\"\n [style.--drawer-animation-duration]=\"animationDuration() + 'ms'\"\n [style.--drawer-animation-timing]=\"animationEasing()\">\n\n <!-- Header -->\n @if (showHeader() && (headerTemplate() || header() || showCloseButton())) {\n <div class=\"studio-drawer__header\">\n @if (headerTemplate(); as tmpl) {\n <!-- Custom template -->\n <ng-container *ngTemplateOutlet=\"tmpl\" />\n } @else if (header()) {\n <!-- Simple string header -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <h2 class=\"studio-drawer__title\">{{ header() }}</h2>\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n } @else {\n <!-- Named slot fallback -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <ng-content select=\"[drawerHeader]\" />\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Content -->\n <div class=\"studio-drawer__content\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n @if (showFooter() && footerTemplate()) {\n <div class=\"studio-drawer__footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()!\" />\n </div>\n } @else if (showFooter()) {\n <div class=\"studio-drawer__footer\">\n <ng-content select=\"[drawerFooter]\" />\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;pointer-events:none;font-family:var(--studio-font-family)}:host(.studio-drawer--visible){pointer-events:auto}.studio-drawer__backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:var(--studio-drawer-backdrop-bg, rgba(0, 0, 0, .5));-webkit-backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));z-index:var(--studio-drawer-z-index, 1000);opacity:0;transition:opacity var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}:host(.studio-drawer--visible) .studio-drawer__backdrop{opacity:1}.studio-drawer__panel{position:fixed;background:var(--studio-drawer-bg, var(--studio-bg-primary));color:var(--studio-drawer-text-color, var(--studio-text-primary));z-index:calc(var(--studio-drawer-z-index, 1000) + 1);overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;outline:none;transition:transform var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}.studio-drawer__panel::-webkit-scrollbar{width:var(--studio-drawer-scrollbar-width, 8px)}.studio-drawer__panel::-webkit-scrollbar-track{background:var(--studio-drawer-scrollbar-track-bg, transparent)}.studio-drawer__panel::-webkit-scrollbar-thumb{background:var(--studio-drawer-scrollbar-thumb-bg, rgba(0, 0, 0, .2));border-radius:var(--studio-drawer-scrollbar-thumb-radius, 4px)}.studio-drawer__panel::-webkit-scrollbar-thumb:hover{background:var(--studio-drawer-scrollbar-thumb-hover-bg, rgba(0, 0, 0, .3))}:host(.studio-drawer--left) .studio-drawer__panel{top:0;left:0;height:100%;border-right:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(-100%)}:host(.studio-drawer--left.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--right) .studio-drawer__panel{top:0;right:0;height:100%;border-left:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(100%)}:host(.studio-drawer--right.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--top) .studio-drawer__panel{top:0;left:0;width:100%;border-bottom:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(-100%)}:host(.studio-drawer--top.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--bottom) .studio-drawer__panel{bottom:0;left:0;width:100%;border-top:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(100%)}:host(.studio-drawer--bottom.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--left.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--sm) .studio-drawer__panel{width:var(--studio-drawer-width-sm, 20rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel{width:var(--studio-drawer-width-md, 28rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel{width:var(--studio-drawer-width-lg, 36rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:var(--studio-drawer-width-xl, 48rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--full) .studio-drawer__panel{width:100vw;max-width:none}:host(.studio-drawer--top.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--sm) .studio-drawer__panel{height:var(--studio-drawer-height-sm, 12rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--md) .studio-drawer__panel{height:var(--studio-drawer-height-md, 20rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--lg) .studio-drawer__panel{height:var(--studio-drawer-height-lg, 32rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--xl) .studio-drawer__panel{height:var(--studio-drawer-height-xl, 48rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--full) .studio-drawer__panel{height:100vh;max-height:none}:host(.studio-drawer--left.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:0 var(--studio-radius-sm) var(--studio-radius-sm) 0}:host(.studio-drawer--left.studio-drawer--radius-md) .studio-drawer__panel{border-radius:0 var(--studio-radius-md) var(--studio-radius-md) 0}:host(.studio-drawer--left.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:0 var(--studio-radius-lg) var(--studio-radius-lg) 0}:host(.studio-drawer--right.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:var(--studio-radius-sm) 0 0 var(--studio-radius-sm)}:host(.studio-drawer--right.studio-drawer--radius-md) .studio-drawer__panel{border-radius:var(--studio-radius-md) 0 0 var(--studio-radius-md)}:host(.studio-drawer--right.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:var(--studio-radius-lg) 0 0 var(--studio-radius-lg)}:host(.studio-drawer--shadow-sm) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-sm, var(--studio-shadow-sm))}:host(.studio-drawer--shadow-md) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-md, var(--studio-shadow-md))}:host(.studio-drawer--shadow-lg) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-lg, var(--studio-shadow-lg))}:host(.studio-drawer--shadow-xl) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-xl, 0 12px 32px rgba(0, 0, 0, .2))}.studio-drawer__header{flex-shrink:0;padding:var(--studio-drawer-header-padding-y, var(--studio-spacing-md)) var(--studio-drawer-header-padding-x, var(--studio-spacing-lg));border-bottom:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary))}.studio-drawer__header-content{display:flex;align-items:center;justify-content:space-between;gap:var(--studio-drawer-header-gap, var(--studio-spacing-md))}.studio-drawer__title{flex:1;margin:0;font-size:var(--studio-drawer-title-font-size, 1.25rem);font-weight:var(--studio-drawer-title-font-weight, var(--studio-font-weight-semibold, 600));line-height:var(--studio-drawer-title-line-height, 1.5);color:var(--studio-drawer-title-color, var(--studio-text-primary))}.studio-drawer__close{display:flex;align-items:center;justify-content:center;width:var(--studio-drawer-close-button-size, 2.5rem);height:var(--studio-drawer-close-button-size, 2.5rem);padding:0;background:none;border:none;border-radius:var(--studio-drawer-close-button-radius, var(--studio-radius-md));color:var(--studio-drawer-close-button-color, var(--studio-text-secondary));cursor:pointer;transition:all var(--studio-transition-fast);flex-shrink:0}.studio-drawer__close:hover{background:var(--studio-drawer-close-button-hover-bg, var(--studio-bg-secondary));color:var(--studio-drawer-close-button-hover-color, var(--studio-text-primary))}.studio-drawer__close:active{transform:scale(.95)}.studio-drawer__close:focus-visible{outline:2px solid var(--studio-drawer-focus-ring-color, var(--studio-primary));outline-offset:var(--studio-drawer-focus-ring-offset, 2px)}.studio-drawer__content{flex:1;padding:var(--studio-drawer-content-padding-y, var(--studio-spacing-lg)) var(--studio-drawer-content-padding-x, var(--studio-spacing-lg));overflow-y:auto;overflow-x:hidden}.studio-drawer__footer{flex-shrink:0;padding:var(--studio-drawer-footer-padding-y, var(--studio-spacing-md)) var(--studio-drawer-footer-padding-x, var(--studio-spacing-lg));border-top:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary));display:flex;align-items:center;gap:var(--studio-drawer-footer-gap, var(--studio-spacing-sm))}:host(.studio-drawer--dragging) .studio-drawer__panel{transition:none!important}@media (max-width: 640px){:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:100vw;max-width:none}.studio-drawer__header,.studio-drawer__content,.studio-drawer__footer{padding-left:var(--studio-spacing-md);padding-right:var(--studio-spacing-md)}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1613
2082
  }
1614
2083
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: DrawerComponent, decorators: [{
1615
2084
  type: Component,
1616
2085
  args: [{ selector: 'studio-drawer', standalone: true, imports: [NgTemplateOutlet, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1617
2086
  '[class]': 'hostClasses()',
1618
2087
  '[attr.data-visible]': 'visible()',
1619
- }, template: "@if (visible()) {\n <!-- Backdrop -->\n @if (modal()) {\n <div\n class=\"studio-drawer__backdrop\"\n (click)=\"handleBackdropClick()\">\n </div>\n }\n\n <!-- Drawer Panel -->\n <div\n #drawerPanel\n class=\"studio-drawer__panel\"\n [attr.role]=\"role()\"\n [attr.aria-modal]=\"modal()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.tabindex]=\"-1\"\n [style.width]=\"customWidth()\"\n [style.height]=\"customHeight()\"\n [style.--drawer-animation-duration]=\"animationDuration() + 'ms'\"\n [style.--drawer-animation-timing]=\"animationEasing()\">\n\n <!-- Header -->\n @if (showHeader() && (headerTemplate() || header() || showCloseButton())) {\n <div class=\"studio-drawer__header\">\n @if (headerTemplate(); as tmpl) {\n <!-- Custom template -->\n <ng-container *ngTemplateOutlet=\"tmpl\" />\n } @else if (header()) {\n <!-- Simple string header -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <h2 class=\"studio-drawer__title\">{{ header() }}</h2>\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n } @else {\n <!-- Named slot fallback -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <ng-content select=\"[drawerHeader]\" />\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Content -->\n <div class=\"studio-drawer__content\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n @if (showFooter() && footerTemplate()) {\n <div class=\"studio-drawer__footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()!\" />\n </div>\n } @else if (showFooter()) {\n <div class=\"studio-drawer__footer\">\n <ng-content select=\"[drawerFooter]\" />\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;pointer-events:none;font-family:var(--studio-font-family)}:host(.studio-drawer--visible){pointer-events:auto}.studio-drawer__backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:var(--studio-drawer-backdrop-bg, rgba(0, 0, 0, .5));-webkit-backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));z-index:var(--studio-drawer-z-index, 1000);opacity:0;transition:opacity var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}:host(.studio-drawer--visible) .studio-drawer__backdrop{opacity:1}.studio-drawer__panel{position:fixed;background:var(--studio-drawer-bg, var(--studio-bg-primary));color:var(--studio-drawer-text-color, var(--studio-text-primary));z-index:calc(var(--studio-drawer-z-index, 1000) + 1);overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;outline:none;transition:transform var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}.studio-drawer__panel::-webkit-scrollbar{width:var(--studio-drawer-scrollbar-width, 8px)}.studio-drawer__panel::-webkit-scrollbar-track{background:var(--studio-drawer-scrollbar-track-bg, transparent)}.studio-drawer__panel::-webkit-scrollbar-thumb{background:var(--studio-drawer-scrollbar-thumb-bg, rgba(0, 0, 0, .2));border-radius:var(--studio-drawer-scrollbar-thumb-radius, 4px)}.studio-drawer__panel::-webkit-scrollbar-thumb:hover{background:var(--studio-drawer-scrollbar-thumb-hover-bg, rgba(0, 0, 0, .3))}:host(.studio-drawer--left) .studio-drawer__panel{top:0;left:0;height:100%;border-right:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(-100%)}:host(.studio-drawer--left.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--right) .studio-drawer__panel{top:0;right:0;height:100%;border-left:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(100%)}:host(.studio-drawer--right.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--top) .studio-drawer__panel{top:0;left:0;width:100%;border-bottom:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(-100%)}:host(.studio-drawer--top.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--bottom) .studio-drawer__panel{bottom:0;left:0;width:100%;border-top:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(100%)}:host(.studio-drawer--bottom.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--left.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--sm) .studio-drawer__panel{width:var(--studio-drawer-width-sm, 20rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel{width:var(--studio-drawer-width-md, 28rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel{width:var(--studio-drawer-width-lg, 36rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:var(--studio-drawer-width-xl, 48rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--full) .studio-drawer__panel{width:100vw;max-width:none}:host(.studio-drawer--top.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--sm) .studio-drawer__panel{height:var(--studio-drawer-height-sm, 12rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--md) .studio-drawer__panel{height:var(--studio-drawer-height-md, 20rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--lg) .studio-drawer__panel{height:var(--studio-drawer-height-lg, 32rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--xl) .studio-drawer__panel{height:var(--studio-drawer-height-xl, 48rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--full) .studio-drawer__panel{height:100vh;max-height:none}:host(.studio-drawer--left.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:0 var(--studio-radius-sm) var(--studio-radius-sm) 0}:host(.studio-drawer--left.studio-drawer--radius-md) .studio-drawer__panel{border-radius:0 var(--studio-radius-md) var(--studio-radius-md) 0}:host(.studio-drawer--left.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:0 var(--studio-radius-lg) var(--studio-radius-lg) 0}:host(.studio-drawer--right.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:var(--studio-radius-sm) 0 0 var(--studio-radius-sm)}:host(.studio-drawer--right.studio-drawer--radius-md) .studio-drawer__panel{border-radius:var(--studio-radius-md) 0 0 var(--studio-radius-md)}:host(.studio-drawer--right.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:var(--studio-radius-lg) 0 0 var(--studio-radius-lg)}:host(.studio-drawer--shadow-sm) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-sm, var(--studio-shadow-sm))}:host(.studio-drawer--shadow-md) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-md, var(--studio-shadow-md))}:host(.studio-drawer--shadow-lg) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-lg, var(--studio-shadow-lg))}:host(.studio-drawer--shadow-xl) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-xl, 0 12px 32px rgba(0, 0, 0, .2))}.studio-drawer__header{flex-shrink:0;padding:var(--studio-drawer-header-padding-y, var(--studio-spacing-md)) var(--studio-drawer-header-padding-x, var(--studio-spacing-lg));border-bottom:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary))}.studio-drawer__header-content{display:flex;align-items:center;gap:var(--studio-drawer-header-gap, var(--studio-spacing-md))}.studio-drawer__title{flex:1;margin:0;font-size:var(--studio-drawer-title-font-size, 1.25rem);font-weight:var(--studio-drawer-title-font-weight, var(--studio-font-weight-semibold, 600));line-height:var(--studio-drawer-title-line-height, 1.5);color:var(--studio-drawer-title-color, var(--studio-text-primary))}.studio-drawer__close{display:flex;align-items:center;justify-content:center;width:var(--studio-drawer-close-button-size, 2.5rem);height:var(--studio-drawer-close-button-size, 2.5rem);padding:0;background:none;border:none;border-radius:var(--studio-drawer-close-button-radius, var(--studio-radius-md));color:var(--studio-drawer-close-button-color, var(--studio-text-secondary));cursor:pointer;transition:all var(--studio-transition-fast);flex-shrink:0}.studio-drawer__close:hover{background:var(--studio-drawer-close-button-hover-bg, var(--studio-bg-secondary));color:var(--studio-drawer-close-button-hover-color, var(--studio-text-primary))}.studio-drawer__close:active{transform:scale(.95)}.studio-drawer__close:focus-visible{outline:2px solid var(--studio-drawer-focus-ring-color, var(--studio-primary));outline-offset:var(--studio-drawer-focus-ring-offset, 2px)}.studio-drawer__content{flex:1;padding:var(--studio-drawer-content-padding-y, var(--studio-spacing-lg)) var(--studio-drawer-content-padding-x, var(--studio-spacing-lg));overflow-y:auto;overflow-x:hidden}.studio-drawer__footer{flex-shrink:0;padding:var(--studio-drawer-footer-padding-y, var(--studio-spacing-md)) var(--studio-drawer-footer-padding-x, var(--studio-spacing-lg));border-top:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary));display:flex;align-items:center;gap:var(--studio-drawer-footer-gap, var(--studio-spacing-sm))}:host(.studio-drawer--dragging) .studio-drawer__panel{transition:none!important}@media (max-width: 640px){:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:100vw;max-width:none}.studio-drawer__header,.studio-drawer__content,.studio-drawer__footer{padding-left:var(--studio-spacing-md);padding-right:var(--studio-spacing-md)}}\n"] }]
2088
+ }, template: "@if (visible()) {\n <!-- Backdrop -->\n @if (modal()) {\n <div\n class=\"studio-drawer__backdrop\"\n (click)=\"handleBackdropClick()\">\n </div>\n }\n\n <!-- Drawer Panel -->\n <div\n #drawerPanel\n class=\"studio-drawer__panel\"\n [attr.role]=\"role()\"\n [attr.aria-modal]=\"modal()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.tabindex]=\"-1\"\n [style.width]=\"customWidth()\"\n [style.height]=\"customHeight()\"\n [style.--drawer-animation-duration]=\"animationDuration() + 'ms'\"\n [style.--drawer-animation-timing]=\"animationEasing()\">\n\n <!-- Header -->\n @if (showHeader() && (headerTemplate() || header() || showCloseButton())) {\n <div class=\"studio-drawer__header\">\n @if (headerTemplate(); as tmpl) {\n <!-- Custom template -->\n <ng-container *ngTemplateOutlet=\"tmpl\" />\n } @else if (header()) {\n <!-- Simple string header -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <h2 class=\"studio-drawer__title\">{{ header() }}</h2>\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n } @else {\n <!-- Named slot fallback -->\n <div class=\"studio-drawer__header-content\">\n @if (showCloseButton() && closeButtonPosition() === 'left') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n\n <ng-content select=\"[drawerHeader]\" />\n\n @if (showCloseButton() && closeButtonPosition() === 'right') {\n <button\n type=\"button\"\n class=\"studio-drawer__close\"\n (click)=\"close()\"\n aria-label=\"Close drawer\">\n <studio-icon name=\"x\" [size]=\"20\" />\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Content -->\n <div class=\"studio-drawer__content\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n @if (showFooter() && footerTemplate()) {\n <div class=\"studio-drawer__footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()!\" />\n </div>\n } @else if (showFooter()) {\n <div class=\"studio-drawer__footer\">\n <ng-content select=\"[drawerFooter]\" />\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;pointer-events:none;font-family:var(--studio-font-family)}:host(.studio-drawer--visible){pointer-events:auto}.studio-drawer__backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:var(--studio-drawer-backdrop-bg, rgba(0, 0, 0, .5));-webkit-backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));backdrop-filter:blur(var(--studio-drawer-backdrop-blur, 2px));z-index:var(--studio-drawer-z-index, 1000);opacity:0;transition:opacity var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}:host(.studio-drawer--visible) .studio-drawer__backdrop{opacity:1}.studio-drawer__panel{position:fixed;background:var(--studio-drawer-bg, var(--studio-bg-primary));color:var(--studio-drawer-text-color, var(--studio-text-primary));z-index:calc(var(--studio-drawer-z-index, 1000) + 1);overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;outline:none;transition:transform var(--drawer-animation-duration, .3s) var(--drawer-animation-timing, ease-out)}.studio-drawer__panel::-webkit-scrollbar{width:var(--studio-drawer-scrollbar-width, 8px)}.studio-drawer__panel::-webkit-scrollbar-track{background:var(--studio-drawer-scrollbar-track-bg, transparent)}.studio-drawer__panel::-webkit-scrollbar-thumb{background:var(--studio-drawer-scrollbar-thumb-bg, rgba(0, 0, 0, .2));border-radius:var(--studio-drawer-scrollbar-thumb-radius, 4px)}.studio-drawer__panel::-webkit-scrollbar-thumb:hover{background:var(--studio-drawer-scrollbar-thumb-hover-bg, rgba(0, 0, 0, .3))}:host(.studio-drawer--left) .studio-drawer__panel{top:0;left:0;height:100%;border-right:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(-100%)}:host(.studio-drawer--left.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--right) .studio-drawer__panel{top:0;right:0;height:100%;border-left:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translate(100%)}:host(.studio-drawer--right.studio-drawer--visible) .studio-drawer__panel{transform:translate(0)}:host(.studio-drawer--top) .studio-drawer__panel{top:0;left:0;width:100%;border-bottom:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(-100%)}:host(.studio-drawer--top.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--bottom) .studio-drawer__panel{bottom:0;left:0;width:100%;border-top:var(--studio-drawer-border-width, 1px) solid var(--studio-drawer-border-color, var(--studio-border-primary));transform:translateY(100%)}:host(.studio-drawer--bottom.studio-drawer--visible) .studio-drawer__panel{transform:translateY(0)}:host(.studio-drawer--left.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--sm) .studio-drawer__panel{width:var(--studio-drawer-width-sm, 20rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel{width:var(--studio-drawer-width-md, 28rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel{width:var(--studio-drawer-width-lg, 36rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:var(--studio-drawer-width-xl, 48rem);max-width:var(--studio-drawer-max-width, 90vw)}:host(.studio-drawer--left.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--full) .studio-drawer__panel{width:100vw;max-width:none}:host(.studio-drawer--top.studio-drawer--sm) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--sm) .studio-drawer__panel{height:var(--studio-drawer-height-sm, 12rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--md) .studio-drawer__panel{height:var(--studio-drawer-height-md, 20rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--lg) .studio-drawer__panel{height:var(--studio-drawer-height-lg, 32rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--xl) .studio-drawer__panel{height:var(--studio-drawer-height-xl, 48rem);max-height:var(--studio-drawer-max-height, 90vh)}:host(.studio-drawer--top.studio-drawer--full) .studio-drawer__panel,:host(.studio-drawer--bottom.studio-drawer--full) .studio-drawer__panel{height:100vh;max-height:none}:host(.studio-drawer--left.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:0 var(--studio-radius-sm) var(--studio-radius-sm) 0}:host(.studio-drawer--left.studio-drawer--radius-md) .studio-drawer__panel{border-radius:0 var(--studio-radius-md) var(--studio-radius-md) 0}:host(.studio-drawer--left.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:0 var(--studio-radius-lg) var(--studio-radius-lg) 0}:host(.studio-drawer--right.studio-drawer--radius-sm) .studio-drawer__panel{border-radius:var(--studio-radius-sm) 0 0 var(--studio-radius-sm)}:host(.studio-drawer--right.studio-drawer--radius-md) .studio-drawer__panel{border-radius:var(--studio-radius-md) 0 0 var(--studio-radius-md)}:host(.studio-drawer--right.studio-drawer--radius-lg) .studio-drawer__panel{border-radius:var(--studio-radius-lg) 0 0 var(--studio-radius-lg)}:host(.studio-drawer--shadow-sm) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-sm, var(--studio-shadow-sm))}:host(.studio-drawer--shadow-md) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-md, var(--studio-shadow-md))}:host(.studio-drawer--shadow-lg) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-lg, var(--studio-shadow-lg))}:host(.studio-drawer--shadow-xl) .studio-drawer__panel{box-shadow:var(--studio-drawer-shadow-xl, 0 12px 32px rgba(0, 0, 0, .2))}.studio-drawer__header{flex-shrink:0;padding:var(--studio-drawer-header-padding-y, var(--studio-spacing-md)) var(--studio-drawer-header-padding-x, var(--studio-spacing-lg));border-bottom:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary))}.studio-drawer__header-content{display:flex;align-items:center;justify-content:space-between;gap:var(--studio-drawer-header-gap, var(--studio-spacing-md))}.studio-drawer__title{flex:1;margin:0;font-size:var(--studio-drawer-title-font-size, 1.25rem);font-weight:var(--studio-drawer-title-font-weight, var(--studio-font-weight-semibold, 600));line-height:var(--studio-drawer-title-line-height, 1.5);color:var(--studio-drawer-title-color, var(--studio-text-primary))}.studio-drawer__close{display:flex;align-items:center;justify-content:center;width:var(--studio-drawer-close-button-size, 2.5rem);height:var(--studio-drawer-close-button-size, 2.5rem);padding:0;background:none;border:none;border-radius:var(--studio-drawer-close-button-radius, var(--studio-radius-md));color:var(--studio-drawer-close-button-color, var(--studio-text-secondary));cursor:pointer;transition:all var(--studio-transition-fast);flex-shrink:0}.studio-drawer__close:hover{background:var(--studio-drawer-close-button-hover-bg, var(--studio-bg-secondary));color:var(--studio-drawer-close-button-hover-color, var(--studio-text-primary))}.studio-drawer__close:active{transform:scale(.95)}.studio-drawer__close:focus-visible{outline:2px solid var(--studio-drawer-focus-ring-color, var(--studio-primary));outline-offset:var(--studio-drawer-focus-ring-offset, 2px)}.studio-drawer__content{flex:1;padding:var(--studio-drawer-content-padding-y, var(--studio-spacing-lg)) var(--studio-drawer-content-padding-x, var(--studio-spacing-lg));overflow-y:auto;overflow-x:hidden}.studio-drawer__footer{flex-shrink:0;padding:var(--studio-drawer-footer-padding-y, var(--studio-spacing-md)) var(--studio-drawer-footer-padding-x, var(--studio-spacing-lg));border-top:1px solid var(--studio-drawer-divider-color, var(--studio-border-primary));display:flex;align-items:center;gap:var(--studio-drawer-footer-gap, var(--studio-spacing-sm))}:host(.studio-drawer--dragging) .studio-drawer__panel{transition:none!important}@media (max-width: 640px){:host(.studio-drawer--left.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--md) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--lg) .studio-drawer__panel,:host(.studio-drawer--left.studio-drawer--xl) .studio-drawer__panel,:host(.studio-drawer--right.studio-drawer--xl) .studio-drawer__panel{width:100vw;max-width:none}.studio-drawer__header,.studio-drawer__content,.studio-drawer__footer{padding-left:var(--studio-spacing-md);padding-right:var(--studio-spacing-md)}}\n"] }]
1620
2089
  }], ctorParameters: () => [], propDecorators: { headerTemplate: [{ type: i0.ContentChild, args: ['headerTemplate', { isSignal: true }] }], footerTemplate: [{ type: i0.ContentChild, args: ['footerTemplate', { isSignal: true }] }], panelEl: [{ type: i0.ViewChild, args: ['drawerPanel', { isSignal: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], positionInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], customWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "customWidth", required: false }] }], customHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "customHeight", required: false }] }], modalInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], closeOnEscapeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], closeOnBackdropClickInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdropClick", required: false }] }], blockScrollInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "blockScroll", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], showHeaderInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], showCloseButtonInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], closeButtonPositionInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeButtonPosition", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], swipeToCloseInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "swipeToClose", required: false }] }], swipeThresholdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "swipeThreshold", required: false }] }], animationDurationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationDuration", required: false }] }], animationEasingInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationEasing", required: false }] }], disableAnimationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableAnimation", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], shadowInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], shadowSizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadowSize", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledBy", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }], autoFocusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], restoreFocusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreFocus", required: false }] }], roleInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], visibleChange: [{ type: i0.Output, args: ["visibleChange"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], backdropClick: [{ type: i0.Output, args: ["backdropClick"] }], handleEscapeKey: [{
1621
2090
  type: HostListener,
1622
2091
  args: ['document:keydown.escape', ['$event']]
@@ -2188,6 +2657,177 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2188
2657
  args: ['keydown', ['$event']]
2189
2658
  }] } });
2190
2659
 
2660
+ /**
2661
+ * Navbar component - Primitive component for navigation headers
2662
+ *
2663
+ * @example
2664
+ * <studio-navbar variant="filled" [sticky]="true">
2665
+ * <div navbarLeft>Logo</div>
2666
+ * <div navbarCenter>Search</div>
2667
+ * <div navbarRight>User menu</div>
2668
+ * </studio-navbar>
2669
+ */
2670
+ class NavbarComponent {
2671
+ // ========== Visual variants ==========
2672
+ variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
2673
+ color = input('inherit', ...(ngDevMode ? [{ debugName: "color" }] : []));
2674
+ shadow = input('sm', ...(ngDevMode ? [{ debugName: "shadow" }] : []));
2675
+ // ========== Size ==========
2676
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
2677
+ customHeight = input(null, ...(ngDevMode ? [{ debugName: "customHeight" }] : []));
2678
+ // ========== Behavior ==========
2679
+ sticky = input(false, ...(ngDevMode ? [{ debugName: "sticky" }] : []));
2680
+ blurBg = input(false, ...(ngDevMode ? [{ debugName: "blurBg" }] : []));
2681
+ // ========== Borders ==========
2682
+ bordered = input(true, ...(ngDevMode ? [{ debugName: "bordered" }] : []));
2683
+ // ========== Customization ==========
2684
+ class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
2685
+ // ========== Outputs ==========
2686
+ navbarClick = output();
2687
+ // ========== Computed classes ==========
2688
+ hostClasses = computed(() => {
2689
+ const classes = ['studio-navbar'];
2690
+ classes.push(`studio-navbar--${this.variant()}`);
2691
+ classes.push(`studio-navbar--${this.size()}`);
2692
+ classes.push(`studio-navbar--shadow-${this.shadow()}`);
2693
+ if (this.color() !== 'inherit')
2694
+ classes.push(`studio-navbar--${this.color()}`);
2695
+ if (this.sticky())
2696
+ classes.push('studio-navbar--sticky');
2697
+ if (this.blurBg())
2698
+ classes.push('studio-navbar--blur');
2699
+ if (this.bordered())
2700
+ classes.push('studio-navbar--bordered');
2701
+ if (this.class())
2702
+ classes.push(this.class());
2703
+ return classes.join(' ');
2704
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
2705
+ handleClick(event) {
2706
+ this.navbarClick.emit(event);
2707
+ }
2708
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: NavbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2709
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: NavbarComponent, isStandalone: true, selector: "studio-navbar", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, shadow: { classPropertyName: "shadow", publicName: "shadow", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, customHeight: { classPropertyName: "customHeight", publicName: "customHeight", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null }, blurBg: { classPropertyName: "blurBg", publicName: "blurBg", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { navbarClick: "navbarClick" }, host: { properties: { "class": "hostClasses()", "attr.role": "\"banner\"", "style.height": "customHeight() ? customHeight() + \"px\" : null" } }, ngImport: i0, template: "<div class=\"studio-navbar__left\">\n <ng-content select=\"[navbarLeft]\" />\n</div>\n\n<div class=\"studio-navbar__center\">\n <ng-content select=\"[navbarCenter]\" />\n</div>\n\n<div class=\"studio-navbar__right\">\n <ng-content select=\"[navbarRight]\" />\n</div>\n\n<ng-content />\n", styles: [":host{display:flex;align-items:center;width:100%;min-height:var(--navbar-height, 4rem);padding:0 var(--navbar-padding-x, 1.5rem);gap:var(--navbar-gap, 1.5rem);background:var(--studio-bg-primary);transition:all .2s cubic-bezier(.4,0,.2,1);--navbar-height: 4rem;--navbar-padding-x: 1.5rem;--navbar-gap: 1.5rem;--navbar-z-index: 1000}:host(.studio-navbar--sm){--navbar-height: 3.5rem;--navbar-padding-x: 1rem;--navbar-gap: 1rem}:host(.studio-navbar--md){--navbar-height: 4rem;--navbar-padding-x: 1.5rem;--navbar-gap: 1.5rem}:host(.studio-navbar--lg){--navbar-height: 5rem;--navbar-padding-x: 2rem;--navbar-gap: 2rem}:host(.studio-navbar--sticky){position:sticky;top:0;z-index:var(--navbar-z-index)}:host(.studio-navbar--blur){-webkit-backdrop-filter:blur(12px) saturate(180%);backdrop-filter:blur(12px) saturate(180%);background:hsl(var(--studio-bg-primary-hsl)/.8)}:host(.studio-navbar--default){background:var(--studio-bg-primary);border-bottom:1px solid hsl(var(--studio-border-primary-hsl)/.1)}:host(.studio-navbar--filled){background:var(--studio-bg-secondary);border-bottom:1px solid var(--studio-border-secondary)}:host(.studio-navbar--outlined){background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-left:none;border-right:none}:host(.studio-navbar--ghost){background:transparent}:host(.studio-navbar--transparent){background:transparent}:host(.studio-navbar--primary){background:var(--studio-primary);color:var(--studio-primary-contrast);border-bottom:1px solid hsl(var(--studio-primary-hsl)/.2)}:host(.studio-navbar--secondary){background:var(--studio-secondary);color:var(--studio-secondary-contrast);border-bottom:1px solid hsl(var(--studio-secondary-hsl)/.2)}:host(.studio-navbar--bordered){border-bottom:1px solid var(--studio-border-secondary)}:host(.studio-navbar--shadow-none){box-shadow:none}:host(.studio-navbar--shadow-sm){box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a}:host(.studio-navbar--shadow-md){box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}:host(.studio-navbar--shadow-lg){box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.studio-navbar__left{display:flex;align-items:center;gap:var(--navbar-gap);flex-shrink:0}.studio-navbar__center{display:flex;align-items:center;justify-content:center;gap:calc(var(--navbar-gap) * .75);flex:1}.studio-navbar__right{display:flex;align-items:center;gap:calc(var(--navbar-gap) * .5);flex-shrink:0;margin-left:auto}@media (max-width: 768px){:host{--navbar-padding-x: 1rem;--navbar-gap: 1rem}.studio-navbar__center{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2710
+ }
2711
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: NavbarComponent, decorators: [{
2712
+ type: Component,
2713
+ args: [{ selector: 'studio-navbar', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, host: {
2714
+ '[class]': 'hostClasses()',
2715
+ '[attr.role]': '"banner"',
2716
+ '[style.height]': 'customHeight() ? customHeight() + "px" : null'
2717
+ }, template: "<div class=\"studio-navbar__left\">\n <ng-content select=\"[navbarLeft]\" />\n</div>\n\n<div class=\"studio-navbar__center\">\n <ng-content select=\"[navbarCenter]\" />\n</div>\n\n<div class=\"studio-navbar__right\">\n <ng-content select=\"[navbarRight]\" />\n</div>\n\n<ng-content />\n", styles: [":host{display:flex;align-items:center;width:100%;min-height:var(--navbar-height, 4rem);padding:0 var(--navbar-padding-x, 1.5rem);gap:var(--navbar-gap, 1.5rem);background:var(--studio-bg-primary);transition:all .2s cubic-bezier(.4,0,.2,1);--navbar-height: 4rem;--navbar-padding-x: 1.5rem;--navbar-gap: 1.5rem;--navbar-z-index: 1000}:host(.studio-navbar--sm){--navbar-height: 3.5rem;--navbar-padding-x: 1rem;--navbar-gap: 1rem}:host(.studio-navbar--md){--navbar-height: 4rem;--navbar-padding-x: 1.5rem;--navbar-gap: 1.5rem}:host(.studio-navbar--lg){--navbar-height: 5rem;--navbar-padding-x: 2rem;--navbar-gap: 2rem}:host(.studio-navbar--sticky){position:sticky;top:0;z-index:var(--navbar-z-index)}:host(.studio-navbar--blur){-webkit-backdrop-filter:blur(12px) saturate(180%);backdrop-filter:blur(12px) saturate(180%);background:hsl(var(--studio-bg-primary-hsl)/.8)}:host(.studio-navbar--default){background:var(--studio-bg-primary);border-bottom:1px solid hsl(var(--studio-border-primary-hsl)/.1)}:host(.studio-navbar--filled){background:var(--studio-bg-secondary);border-bottom:1px solid var(--studio-border-secondary)}:host(.studio-navbar--outlined){background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-left:none;border-right:none}:host(.studio-navbar--ghost){background:transparent}:host(.studio-navbar--transparent){background:transparent}:host(.studio-navbar--primary){background:var(--studio-primary);color:var(--studio-primary-contrast);border-bottom:1px solid hsl(var(--studio-primary-hsl)/.2)}:host(.studio-navbar--secondary){background:var(--studio-secondary);color:var(--studio-secondary-contrast);border-bottom:1px solid hsl(var(--studio-secondary-hsl)/.2)}:host(.studio-navbar--bordered){border-bottom:1px solid var(--studio-border-secondary)}:host(.studio-navbar--shadow-none){box-shadow:none}:host(.studio-navbar--shadow-sm){box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a}:host(.studio-navbar--shadow-md){box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}:host(.studio-navbar--shadow-lg){box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.studio-navbar__left{display:flex;align-items:center;gap:var(--navbar-gap);flex-shrink:0}.studio-navbar__center{display:flex;align-items:center;justify-content:center;gap:calc(var(--navbar-gap) * .75);flex:1}.studio-navbar__right{display:flex;align-items:center;gap:calc(var(--navbar-gap) * .5);flex-shrink:0;margin-left:auto}@media (max-width: 768px){:host{--navbar-padding-x: 1rem;--navbar-gap: 1rem}.studio-navbar__center{display:none}}\n"] }]
2718
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], shadow: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], customHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "customHeight", required: false }] }], sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "sticky", required: false }] }], blurBg: [{ type: i0.Input, args: [{ isSignal: true, alias: "blurBg", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], navbarClick: [{ type: i0.Output, args: ["navbarClick"] }] } });
2719
+
2720
+ /**
2721
+ * RadioButton component for selecting a single option from a group
2722
+ *
2723
+ * @example
2724
+ * <studio-radio-button
2725
+ * [(ngModel)]="selectedValue"
2726
+ * [value]="'option1'"
2727
+ * label="Option 1"
2728
+ * name="options"
2729
+ * />
2730
+ */
2731
+ class RadioButtonComponent {
2732
+ configService = inject(StudioConfigService);
2733
+ radioDefaults = computed(() => this.configService.config().components?.radioButton, ...(ngDevMode ? [{ debugName: "radioDefaults" }] : []));
2734
+ size = input(this.radioDefaults()?.size ?? 'md', ...(ngDevMode ? [{ debugName: "size" }] : []));
2735
+ color = input(this.radioDefaults()?.color ?? 'primary', ...(ngDevMode ? [{ debugName: "color" }] : []));
2736
+ variant = input(this.radioDefaults()?.variant ?? 'default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
2737
+ radius = input(this.radioDefaults()?.radius ?? 'full', ...(ngDevMode ? [{ debugName: "radius" }] : []));
2738
+ label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
2739
+ labelPosition = input(this.radioDefaults()?.labelPosition ?? 'right', ...(ngDevMode ? [{ debugName: "labelPosition" }] : []));
2740
+ description = input(...(ngDevMode ? [undefined, { debugName: "description" }] : []));
2741
+ hint = input(...(ngDevMode ? [undefined, { debugName: "hint" }] : []));
2742
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
2743
+ error = input(false, ...(ngDevMode ? [{ debugName: "error" }] : []));
2744
+ errorMessage = input(...(ngDevMode ? [undefined, { debugName: "errorMessage" }] : []));
2745
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
2746
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
2747
+ name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
2748
+ tabIndex = input(0, ...(ngDevMode ? [{ debugName: "tabIndex" }] : []));
2749
+ value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
2750
+ changed = output();
2751
+ internalValue = signal(null, ...(ngDevMode ? [{ debugName: "internalValue" }] : []));
2752
+ isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
2753
+ radioId = signal(`studio-radio-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "radioId" }] : []));
2754
+ hostClasses = computed(() => ({
2755
+ 'studio-radio-wrapper': true,
2756
+ [`studio-radio-wrapper--${this.size()}`]: true,
2757
+ 'studio-radio-wrapper--disabled': this.disabled(),
2758
+ 'studio-radio-wrapper--error': this.error(),
2759
+ 'studio-radio-wrapper--focused': this.isFocused(),
2760
+ 'studio-radio-wrapper--label-left': this.labelPosition() === 'left'
2761
+ }), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
2762
+ radioClasses = computed(() => ({
2763
+ 'studio-radio': true,
2764
+ [`studio-radio--${this.size()}`]: true,
2765
+ [`studio-radio--${this.color()}`]: true,
2766
+ [`studio-radio--${this.variant()}`]: true,
2767
+ [`studio-radio--radius-${this.radius()}`]: true,
2768
+ 'studio-radio--checked': this.isChecked(),
2769
+ 'studio-radio--disabled': this.disabled(),
2770
+ 'studio-radio--error': this.error()
2771
+ }), ...(ngDevMode ? [{ debugName: "radioClasses" }] : []));
2772
+ showError = computed(() => this.error() && this.errorMessage(), ...(ngDevMode ? [{ debugName: "showError" }] : []));
2773
+ showHint = computed(() => !this.error() && this.hint(), ...(ngDevMode ? [{ debugName: "showHint" }] : []));
2774
+ isChecked = computed(() => this.internalValue() === this.value(), ...(ngDevMode ? [{ debugName: "isChecked" }] : []));
2775
+ onChange = () => { };
2776
+ onTouched = () => { };
2777
+ writeValue(value) {
2778
+ this.internalValue.set(value);
2779
+ }
2780
+ registerOnChange(fn) {
2781
+ this.onChange = fn;
2782
+ }
2783
+ registerOnTouched(fn) {
2784
+ this.onTouched = fn;
2785
+ }
2786
+ setDisabledState(isDisabled) { }
2787
+ handleChange(event) {
2788
+ if (this.disabled() || this.readonly()) {
2789
+ event.preventDefault();
2790
+ return;
2791
+ }
2792
+ const inputValue = this.value();
2793
+ this.internalValue.set(inputValue);
2794
+ this.onChange(inputValue);
2795
+ this.changed.emit(inputValue);
2796
+ }
2797
+ handleFocus() {
2798
+ this.isFocused.set(true);
2799
+ }
2800
+ handleBlur() {
2801
+ this.isFocused.set(false);
2802
+ this.onTouched();
2803
+ }
2804
+ handleLabelClick(event) {
2805
+ if (this.disabled() || this.readonly()) {
2806
+ event.preventDefault();
2807
+ }
2808
+ }
2809
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: RadioButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2810
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: RadioButtonComponent, isStandalone: true, selector: "studio-radio-button", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed" }, host: { properties: { "class": "hostClasses()", "attr.data-size": "size()", "attr.data-color": "color()", "attr.data-disabled": "disabled()", "attr.data-error": "error()" } }, providers: [{
2811
+ provide: NG_VALUE_ACCESSOR,
2812
+ useExisting: forwardRef(() => RadioButtonComponent),
2813
+ multi: true
2814
+ }], ngImport: i0, template: "<label\n [for]=\"radioId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <input\n type=\"radio\"\n [id]=\"radioId()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [checked]=\"isChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"isChecked() ? 'true' : 'false'\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? radioId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-radio__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <span [ngClass]=\"radioClasses()\">\n @if (isChecked()) {\n <span class=\"studio-radio__dot\"></span>\n }\n </span>\n\n @if (label() || description()) {\n <span class=\"studio-radio__label-wrapper\">\n @if (label()) {\n <span class=\"studio-radio__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-radio__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-radio__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n@if (showHint() || showError()) {\n <div\n [id]=\"radioId() + '-description'\"\n class=\"studio-radio__info\"\n >\n @if (showError()) {\n <span class=\"studio-radio__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-radio__hint\">\n {{ hint() }}\n </span>\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-direction:column;font-family:var(--studio-font-family)!important}.studio-radio-wrapper{display:inline-flex;align-items:flex-start;gap:var(--studio-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.studio-radio-wrapper--label-left{flex-direction:row-reverse}.studio-radio-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-radio-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-radio-wrapper--md{font-size:var(--studio-font-size-base)}.studio-radio-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-radio__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-radio{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border:2px solid var(--studio-border-primary);background-color:var(--studio-bg-primary);transition:all var(--studio-transition-base);border-radius:var(--studio-radius-full)}.studio-radio--sm{width:1rem;height:1rem}.studio-radio--md{width:1.25rem;height:1.25rem}.studio-radio--lg{width:1.5rem;height:1.5rem}.studio-radio--radius-none{border-radius:0}.studio-radio--radius-sm{border-radius:var(--studio-radius-sm)}.studio-radio--radius-md{border-radius:var(--studio-radius-md)}.studio-radio--radius-lg{border-radius:var(--studio-radius-lg)}.studio-radio--radius-full{border-radius:var(--studio-radius-full)}.studio-radio--default.studio-radio--checked{border-color:transparent}.studio-radio--default.studio-radio--checked.studio-radio--primary{background-color:var(--studio-primary)}.studio-radio--default.studio-radio--checked.studio-radio--secondary{background-color:var(--studio-secondary)}.studio-radio--default.studio-radio--checked.studio-radio--success{background-color:var(--studio-success)}.studio-radio--default.studio-radio--checked.studio-radio--error{background-color:var(--studio-error)}.studio-radio--outlined.studio-radio--checked{background-color:transparent}.studio-radio--outlined.studio-radio--checked.studio-radio--primary{border-color:var(--studio-primary)}.studio-radio--outlined.studio-radio--checked.studio-radio--primary .studio-radio__dot{background-color:var(--studio-primary)}.studio-radio--outlined.studio-radio--checked.studio-radio--secondary{border-color:var(--studio-secondary)}.studio-radio--outlined.studio-radio--checked.studio-radio--secondary .studio-radio__dot{background-color:var(--studio-secondary)}.studio-radio--outlined.studio-radio--checked.studio-radio--success{border-color:var(--studio-success)}.studio-radio--outlined.studio-radio--checked.studio-radio--success .studio-radio__dot{background-color:var(--studio-success)}.studio-radio--outlined.studio-radio--checked.studio-radio--error{border-color:var(--studio-error)}.studio-radio--outlined.studio-radio--checked.studio-radio--error .studio-radio__dot{background-color:var(--studio-error)}.studio-radio--filled.studio-radio--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-radio--filled.studio-radio--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-radio--filled.studio-radio--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-radio--filled.studio-radio--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-radio--filled.studio-radio--checked.studio-radio--primary{background-color:var(--studio-primary);border-color:var(--studio-primary)}.studio-radio--filled.studio-radio--checked.studio-radio--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary)}.studio-radio--filled.studio-radio--checked.studio-radio--success{background-color:var(--studio-success);border-color:var(--studio-success)}.studio-radio--filled.studio-radio--checked.studio-radio--error{background-color:var(--studio-error);border-color:var(--studio-error)}.studio-radio--error:not(.studio-radio--checked){border-color:var(--studio-error)}.studio-radio:hover:not(.studio-radio--disabled){border-color:var(--studio-border-secondary)}.studio-radio__input:focus-visible+.studio-radio{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-radio__dot{border-radius:var(--studio-radius-full);background-color:var(--studio-text-inverse);opacity:0;transform:scale(.5);transition:all var(--studio-transition-fast)}.studio-radio--sm .studio-radio__dot{width:.375rem;height:.375rem}.studio-radio--md .studio-radio__dot{width:.5rem;height:.5rem}.studio-radio--lg .studio-radio__dot{width:.625rem;height:.625rem}.studio-radio--checked .studio-radio__dot{opacity:1;transform:scale(1)}.studio-radio__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-radio__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-radio__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-radio__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-radio__info{display:flex;flex-direction:column;gap:var(--studio-spacing-xs);margin-top:var(--studio-spacing-xs);padding-left:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-radio-wrapper--label-left+.studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-radio-wrapper--sm .studio-radio__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-radio-wrapper--sm.studio-radio-wrapper--label-left .studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-radio-wrapper--lg .studio-radio__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-radio-wrapper--lg.studio-radio-wrapper--label-left .studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-radio__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-radio__error{font-size:var(--studio-font-size-xs);color:var(--studio-error);line-height:var(--studio-line-height-normal)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
2815
+ }
2816
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: RadioButtonComponent, decorators: [{
2817
+ type: Component,
2818
+ args: [{ selector: 'studio-radio-button', standalone: true, imports: [CommonModule], providers: [{
2819
+ provide: NG_VALUE_ACCESSOR,
2820
+ useExisting: forwardRef(() => RadioButtonComponent),
2821
+ multi: true
2822
+ }], host: {
2823
+ '[class]': 'hostClasses()',
2824
+ '[attr.data-size]': 'size()',
2825
+ '[attr.data-color]': 'color()',
2826
+ '[attr.data-disabled]': 'disabled()',
2827
+ '[attr.data-error]': 'error()'
2828
+ }, 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"] }]
2829
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
2830
+
2191
2831
  class SelectComponent {
2192
2832
  configService = inject(StudioConfigService);
2193
2833
  selectDefaults = computed(() => this.configService.config().components?.select, ...(ngDevMode ? [{ debugName: "selectDefaults" }] : []));
@@ -2463,11 +3103,132 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2463
3103
  }, template: "@if (label() && !floatingLabel()) {\n <label [for]=\"generatedId\" class=\"studio-select__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-select__required\">*</span>\n }\n </label>\n}\n\n<div class=\"studio-select__control\">\n @if (prefixIcon()) {\n <span class=\"studio-select__prefix\">\n <studio-icon [name]=\"prefixIcon()!\" [size]=\"16\" />\n </span>\n }\n\n @if (label() && floatingLabel()) {\n <label [for]=\"generatedId\" class=\"studio-select__label--floating\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-select__required\">*</span>\n }\n </label>\n }\n\n <button\n #triggerButton\n type=\"button\"\n [id]=\"generatedId\"\n class=\"studio-select__trigger\"\n [disabled]=\"disabled() || loading()\"\n (click)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\"\n (focus)=\"isFocused.set(true)\"\n (blur)=\"isFocused.set(false)\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n >\n @if (hasValue()) {\n <span class=\"studio-select__value\">{{ displayValue() }}</span>\n } @else {\n <span class=\"studio-select__placeholder\">{{ placeholder() }}</span>\n }\n </button>\n\n @if (clearable() && hasValue() && !disabled() && !loading()) {\n <button\n type=\"button\"\n class=\"studio-select__clear\"\n (click)=\"clear($event)\"\n aria-label=\"Clear selection\"\n tabindex=\"-1\"\n >\n <studio-icon name=\"x\" [size]=\"14\" />\n </button>\n }\n\n @if (loading()) {\n <span class=\"studio-select__loading\">\n <studio-icon name=\"loader-2\" [size]=\"16\" class=\"studio-icon--spin\" />\n </span>\n } @else {\n <span class=\"studio-select__suffix\">\n <studio-icon\n [name]=\"suffixIcon()\"\n [size]=\"16\"\n />\n </span>\n }\n</div>\n\n@if (isOpen()) {\n <div\n #dropdownPanel\n class=\"studio-select__dropdown\"\n [attr.data-position]=\"position()\"\n [style.max-height]=\"maxHeight()\"\n >\n @if (searchable()) {\n <div class=\"studio-select__search\">\n <input\n type=\"text\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"searchQuery()\"\n (input)=\"handleSearch($event)\"\n />\n </div>\n }\n\n <div class=\"studio-select__options\" role=\"listbox\">\n @if (filteredOptions().length === 0) {\n <div class=\"studio-select__empty\">\n No options found\n </div>\n }\n\n @for (option of filteredOptions(); track option.value; let idx = $index) {\n <div\n class=\"studio-select__option\"\n [class.studio-select__option--selected]=\"isSelected(option)\"\n [class.studio-select__option--disabled]=\"option.disabled\"\n [class.studio-select__option--highlighted]=\"highlightedIndex() === idx\"\n (click)=\"selectOption(option)\"\n role=\"option\"\n [attr.aria-selected]=\"isSelected(option)\"\n >\n @if (multiple()) {\n <input\n type=\"checkbox\"\n class=\"studio-select__checkbox\"\n [checked]=\"isSelected(option)\"\n [disabled]=\"option.disabled\"\n tabindex=\"-1\"\n />\n }\n\n @if (option.icon) {\n <studio-icon [name]=\"option.icon\" [size]=\"18\" class=\"studio-select__option-icon\" />\n }\n\n <div class=\"studio-select__option-content\">\n <div class=\"studio-select__option-label\">\n {{ option.label }}\n </div>\n @if (option.description) {\n <div class=\"studio-select__option-description\">\n {{ option.description }}\n </div>\n }\n </div>\n\n @if (!multiple() && isSelected(option)) {\n <studio-icon name=\"check\" [size]=\"16\" class=\"studio-select__check-icon\" />\n }\n </div>\n }\n </div>\n </div>\n}\n\n@if (hint() && !error()) {\n <div class=\"studio-select__hint\">{{ hint() }}</div>\n}\n\n@if (error() && errorMessage()) {\n <div class=\"studio-select__error\">{{ errorMessage() }}</div>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:.375rem;font-family:var(--studio-font-family);position:relative}:host(.studio-select--full-width){width:100%}.studio-select__label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);margin-bottom:.25rem}.studio-select__label .studio-select__required{color:var(--studio-error);margin-left:.125rem}.studio-select__control{position:relative;display:flex;align-items:center;transition:all var(--studio-transition-fast)}.studio-select__prefix,.studio-select__suffix{display:flex;align-items:center;justify-content:center;color:var(--studio-text-secondary);flex-shrink:0}.studio-select__suffix{transition:var(--studio-transition-fast)}:host(.studio-select--open) .studio-select__suffix{transform:rotate(180deg)}.studio-select__trigger{flex:1;width:100%;display:flex;align-items:center;background:transparent;border:none;padding:0;font-family:inherit;text-align:left;color:var(--studio-text-primary);cursor:pointer;outline:none;transition:var(--studio-transition-fast)}.studio-select__trigger:disabled{cursor:not-allowed;opacity:.6}.studio-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--studio-text-primary)}.studio-select__placeholder{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--studio-text-tertiary)}.studio-select__clear,.studio-select__loading{display:flex;align-items:center;justify-content:center;flex-shrink:0}.studio-select__clear{background:none;border:none;padding:.25rem;color:var(--studio-text-secondary);cursor:pointer;border-radius:var(--studio-radius-sm);transition:all var(--studio-transition-fast)}.studio-select__clear:hover{color:var(--studio-text-primary);background:var(--studio-bg-secondary)}.studio-select__clear:active{transform:scale(.95)}.studio-select__loading{color:var(--studio-primary)}.studio-select__loading .studio-icon--spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-select__dropdown{position:absolute;top:100%;left:0;right:0;z-index:var(--studio-z-dropdown, 1000);background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);box-shadow:var(--studio-shadow-lg);margin-top:.25rem;overflow:hidden;display:flex;flex-direction:column}.studio-select__search{padding:.5rem;border-bottom:1px solid var(--studio-border-primary);flex-shrink:0}.studio-select__search input{width:100%;padding:.5rem;border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);font-family:inherit;font-size:.875rem;color:var(--studio-text-primary);background:var(--studio-bg-primary);outline:none;transition:var(--studio-transition-fast)}.studio-select__search input:focus{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}.studio-select__search input::placeholder{color:var(--studio-text-tertiary)}.studio-select__options{overflow-y:auto;flex:1}.studio-select__option{display:flex;align-items:center;gap:.75rem;padding:.625rem .75rem;cursor:pointer;transition:var(--studio-transition-fast);color:var(--studio-text-primary)}.studio-select__option:hover{background:var(--studio-bg-secondary)}.studio-select__option--selected{background:var(--studio-primary-bg);color:var(--studio-primary)}.studio-select__option--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.studio-select__option input[type=checkbox]{margin:0;cursor:pointer}.studio-select__option-icon{flex-shrink:0;color:var(--studio-text-secondary)}.studio-select__option-content{flex:1;min-width:0}.studio-select__option-label{font-size:.875rem;color:inherit}.studio-select__option-description{font-size:.75rem;color:var(--studio-text-secondary);margin-top:.125rem}.studio-select__empty{padding:1rem;text-align:center;color:var(--studio-text-tertiary);font-size:.875rem}.studio-select__hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-select__error{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--studio-error);line-height:1.4}.studio-select__label--floating{position:absolute;top:50%;left:1rem;transform:translateY(-50%);font-size:1rem;color:var(--studio-text-tertiary);pointer-events:none;transition:all var(--studio-transition-fast);background:var(--studio-bg-primary);padding:0 .25rem;z-index:1}:host(.studio-select--focused) .studio-select__label--floating,:host(.studio-select--has-value) .studio-select__label--floating{top:0;font-size:.75rem;color:var(--studio-primary)}:host(.studio-select--error) .studio-select__label--floating{color:var(--studio-error)}:host(.studio-select--outline) .studio-select__control{border:1px solid var(--studio-border-primary);background:var(--studio-bg-primary);border-radius:var(--studio-radius-md)}:host(.studio-select--outline) .studio-select__control:hover:not(:has(.studio-select__trigger:disabled)){border-color:var(--studio-primary)}:host(.studio-select--outline.studio-select--focused) .studio-select__control{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}:host(.studio-select--outline.studio-select--error) .studio-select__control{border-color:var(--studio-error)}:host(.studio-select--outline.studio-select--error) .studio-select__control:hover{border-color:var(--studio-error)}:host(.studio-select--outline.studio-select--error.studio-select--focused) .studio-select__control{box-shadow:0 0 0 3px #ef44441a}:host(.studio-select--outline.studio-select--disabled) .studio-select__control{background:var(--studio-bg-secondary);border-color:var(--studio-border-secondary)}:host(.studio-select--filled) .studio-select__control{background:var(--studio-bg-secondary);border:none;border-bottom:2px solid var(--studio-border-primary);border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-select--filled) .studio-select__control:hover:not(:has(.studio-select__trigger:disabled)){background:var(--studio-bg-tertiary)}:host(.studio-select--filled.studio-select--focused) .studio-select__control{border-bottom-color:var(--studio-primary);background:var(--studio-bg-tertiary)}:host(.studio-select--filled.studio-select--error) .studio-select__control{border-bottom-color:var(--studio-error)}:host(.studio-select--filled.studio-select--disabled) .studio-select__control{background:var(--studio-bg-secondary);opacity:.6}:host(.studio-select--underline) .studio-select__control{background:transparent;border:none;border-bottom:1px solid var(--studio-border-primary);border-radius:0}:host(.studio-select--underline) .studio-select__control:hover:not(:has(.studio-select__trigger:disabled)){border-bottom-color:var(--studio-primary)}:host(.studio-select--underline.studio-select--focused) .studio-select__control{border-bottom:2px solid var(--studio-primary)}:host(.studio-select--underline.studio-select--error) .studio-select__control{border-bottom-color:var(--studio-error)}:host(.studio-select--underline.studio-select--disabled) .studio-select__control{border-bottom-style:dashed;opacity:.6}:host(.studio-select--sm) .studio-select__trigger{height:2rem;font-size:.875rem;padding:0 .75rem}:host(.studio-select--sm) .studio-select__prefix{padding-left:.75rem}:host(.studio-select--sm) .studio-select__suffix,:host(.studio-select--sm) .studio-select__clear,:host(.studio-select--sm) .studio-select__loading{padding-right:.5rem}:host(.studio-select--md) .studio-select__trigger{height:2.5rem;font-size:1rem;padding:0 1rem}:host(.studio-select--md) .studio-select__prefix{padding-left:1rem}:host(.studio-select--md) .studio-select__suffix,:host(.studio-select--md) .studio-select__clear,:host(.studio-select--md) .studio-select__loading{padding-right:.75rem}:host(.studio-select--lg) .studio-select__trigger{height:3rem;font-size:1.125rem;padding:0 1.25rem}:host(.studio-select--lg) .studio-select__prefix{padding-left:1.25rem}:host(.studio-select--lg) .studio-select__suffix,:host(.studio-select--lg) .studio-select__clear,:host(.studio-select--lg) .studio-select__loading{padding-right:1rem}:host(.studio-select--radius-none) .studio-select__control{border-radius:0}:host(.studio-select--radius-sm) .studio-select__control{border-radius:var(--studio-radius-sm)}:host(.studio-select--radius-md) .studio-select__control{border-radius:var(--studio-radius-md)}:host(.studio-select--radius-lg) .studio-select__control{border-radius:var(--studio-radius-lg)}:host(.studio-select--radius-full) .studio-select__control{border-radius:9999px}:host(.studio-select--filled.studio-select--radius-none) .studio-select__control{border-radius:0}:host(.studio-select--filled.studio-select--radius-sm) .studio-select__control{border-radius:var(--studio-radius-sm) var(--studio-radius-sm) 0 0}:host(.studio-select--filled.studio-select--radius-md) .studio-select__control{border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-select--filled.studio-select--radius-lg) .studio-select__control{border-radius:var(--studio-radius-lg) var(--studio-radius-lg) 0 0}:host(.studio-select--filled.studio-select--radius-full) .studio-select__control{border-radius:9999px 9999px 0 0}\n"] }]
2464
3104
  }], ctorParameters: () => [], propDecorators: { triggerEl: [{ type: i0.ViewChild, args: ['triggerButton', { isSignal: true }] }], dropdownEl: [{ type: i0.ViewChild, args: ['dropdownPanel', { isSignal: true }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], floatingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatingLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], prefixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefixIcon", required: false }] }], suffixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixIcon", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], searchChange: [{ type: i0.Output, args: ["searchChange"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], optionSelected: [{ type: i0.Output, args: ["optionSelected"] }] } });
2465
3105
 
3106
+ /**
3107
+ * Sidebar component - Navigation sidebar built on top of Drawer
3108
+ *
3109
+ * @example
3110
+ * <studio-sidebar [(visible)]="sidebarOpen">
3111
+ * <nav sidebarHeader>
3112
+ * <h2>Navigation</h2>
3113
+ * </nav>
3114
+ *
3115
+ * <studio-menu>
3116
+ * <studio-menu-item>Home</studio-menu-item>
3117
+ * <studio-menu-item>About</studio-menu-item>
3118
+ * </studio-menu>
3119
+ *
3120
+ * <div sidebarFooter>
3121
+ * <studio-button>Logout</studio-button>
3122
+ * </div>
3123
+ * </studio-sidebar>
3124
+ */
3125
+ class SidebarComponent {
3126
+ router = inject(Router, { optional: true });
3127
+ configService = inject(StudioConfigService);
3128
+ sidebarDefaults = computed(() => this.configService.config().components?.sidebar, ...(ngDevMode ? [{ debugName: "sidebarDefaults" }] : []));
3129
+ // Core
3130
+ id = input(`studio-sidebar-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : []));
3131
+ visible = model(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
3132
+ // Position & Size
3133
+ positionInput = input(undefined, ...(ngDevMode ? [{ debugName: "positionInput", alias: 'position' }] : [{ alias: 'position' }]));
3134
+ sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
3135
+ variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
3136
+ customWidth = input(undefined, ...(ngDevMode ? [{ debugName: "customWidth" }] : []));
3137
+ position = withConfigDefault(this.positionInput, computed(() => this.sidebarDefaults()?.position), 'left');
3138
+ size = withConfigDefault(this.sizeInput, computed(() => this.sidebarDefaults()?.size), 'md');
3139
+ variant = withConfigDefault(this.variantInput, computed(() => this.sidebarDefaults()?.variant), 'default');
3140
+ // Behavior
3141
+ modalInput = input(undefined, ...(ngDevMode ? [{ debugName: "modalInput", alias: 'modal' }] : [{ alias: 'modal' }]));
3142
+ collapsibleInput = input(undefined, ...(ngDevMode ? [{ debugName: "collapsibleInput", alias: 'collapsible' }] : [{ alias: 'collapsible' }]));
3143
+ defaultCollapsedInput = input(undefined, ...(ngDevMode ? [{ debugName: "defaultCollapsedInput", alias: 'defaultCollapsed' }] : [{ alias: 'defaultCollapsed' }]));
3144
+ closeOnNavigateInput = input(undefined, ...(ngDevMode ? [{ debugName: "closeOnNavigateInput", alias: 'closeOnNavigate' }] : [{ alias: 'closeOnNavigate' }]));
3145
+ closeOnBackdropClickInput = input(undefined, ...(ngDevMode ? [{ debugName: "closeOnBackdropClickInput", alias: 'closeOnBackdropClick' }] : [{ alias: 'closeOnBackdropClick' }]));
3146
+ closeOnEscapeInput = input(undefined, ...(ngDevMode ? [{ debugName: "closeOnEscapeInput", alias: 'closeOnEscape' }] : [{ alias: 'closeOnEscape' }]));
3147
+ blockScrollInput = input(undefined, ...(ngDevMode ? [{ debugName: "blockScrollInput", alias: 'blockScroll' }] : [{ alias: 'blockScroll' }]));
3148
+ swipeToCloseInput = input(undefined, ...(ngDevMode ? [{ debugName: "swipeToCloseInput", alias: 'swipeToClose' }] : [{ alias: 'swipeToClose' }]));
3149
+ modal = withConfigDefault(this.modalInput, computed(() => this.sidebarDefaults()?.modal), true);
3150
+ collapsible = withConfigDefault(this.collapsibleInput, computed(() => this.sidebarDefaults()?.collapsible), false);
3151
+ defaultCollapsed = withConfigDefault(this.defaultCollapsedInput, computed(() => this.sidebarDefaults()?.defaultCollapsed), false);
3152
+ closeOnNavigate = withConfigDefault(this.closeOnNavigateInput, computed(() => this.sidebarDefaults()?.closeOnNavigate), true);
3153
+ closeOnBackdropClick = withConfigDefault(this.closeOnBackdropClickInput, computed(() => this.sidebarDefaults()?.closeOnBackdropClick), true);
3154
+ closeOnEscape = withConfigDefault(this.closeOnEscapeInput, computed(() => this.sidebarDefaults()?.closeOnEscape), true);
3155
+ blockScroll = withConfigDefault(this.blockScrollInput, computed(() => this.sidebarDefaults()?.blockScroll), true);
3156
+ swipeToClose = withConfigDefault(this.swipeToCloseInput, computed(() => this.sidebarDefaults()?.swipeToClose), true);
3157
+ // UI Elements
3158
+ header = input(undefined, ...(ngDevMode ? [{ debugName: "header" }] : []));
3159
+ showHeaderInput = input(undefined, ...(ngDevMode ? [{ debugName: "showHeaderInput", alias: 'showHeader' }] : [{ alias: 'showHeader' }]));
3160
+ showFooterInput = input(undefined, ...(ngDevMode ? [{ debugName: "showFooterInput", alias: 'showFooter' }] : [{ alias: 'showFooter' }]));
3161
+ showCloseButtonInput = input(undefined, ...(ngDevMode ? [{ debugName: "showCloseButtonInput", alias: 'showCloseButton' }] : [{ alias: 'showCloseButton' }]));
3162
+ showHeader = withConfigDefault(this.showHeaderInput, computed(() => this.sidebarDefaults()?.showHeader), true);
3163
+ showFooter = withConfigDefault(this.showFooterInput, computed(() => this.sidebarDefaults()?.showFooter), true);
3164
+ showCloseButton = withConfigDefault(this.showCloseButtonInput, computed(() => this.sidebarDefaults()?.showCloseButton), true);
3165
+ // Content Customization
3166
+ contentPadding = input(undefined, ...(ngDevMode ? [{ debugName: "contentPadding" }] : []));
3167
+ contentGap = input(undefined, ...(ngDevMode ? [{ debugName: "contentGap" }] : []));
3168
+ background = input(undefined, ...(ngDevMode ? [{ debugName: "background" }] : []));
3169
+ // Customization
3170
+ class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
3171
+ // ========== Computed values ==========
3172
+ hostClasses = computed(() => {
3173
+ const classes = ['studio-sidebar'];
3174
+ classes.push(`studio-sidebar--${this.position()}`);
3175
+ classes.push(`studio-sidebar--${this.size()}`);
3176
+ classes.push(`studio-sidebar--${this.variant()}`);
3177
+ if (this.collapsible())
3178
+ classes.push('studio-sidebar--collapsible');
3179
+ if (this.class())
3180
+ classes.push(this.class());
3181
+ return classes.join(' ');
3182
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
3183
+ drawerSize = computed(() => {
3184
+ const currentSize = this.size();
3185
+ const sizeMap = {
3186
+ 'sm': 'sm',
3187
+ 'md': 'md',
3188
+ 'lg': 'lg',
3189
+ 'full': 'full'
3190
+ };
3191
+ return sizeMap[currentSize];
3192
+ }, ...(ngDevMode ? [{ debugName: "drawerSize" }] : []));
3193
+ constructor() {
3194
+ // Close sidebar on navigation if enabled
3195
+ if (this.router && this.closeOnNavigate()) {
3196
+ effect(() => {
3197
+ const subscription = this.router.events
3198
+ .pipe(filter(event => event instanceof NavigationEnd))
3199
+ .subscribe(() => {
3200
+ if (this.closeOnNavigate() && this.visible()) {
3201
+ this.visible.set(false);
3202
+ }
3203
+ });
3204
+ return () => subscription.unsubscribe();
3205
+ });
3206
+ }
3207
+ }
3208
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3209
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: SidebarComponent, isStandalone: true, selector: "studio-sidebar", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, positionInput: { classPropertyName: "positionInput", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variantInput: { classPropertyName: "variantInput", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, customWidth: { classPropertyName: "customWidth", publicName: "customWidth", isSignal: true, isRequired: false, transformFunction: null }, modalInput: { classPropertyName: "modalInput", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, collapsibleInput: { classPropertyName: "collapsibleInput", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, defaultCollapsedInput: { classPropertyName: "defaultCollapsedInput", publicName: "defaultCollapsed", isSignal: true, isRequired: false, transformFunction: null }, closeOnNavigateInput: { classPropertyName: "closeOnNavigateInput", publicName: "closeOnNavigate", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClickInput: { classPropertyName: "closeOnBackdropClickInput", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscapeInput: { classPropertyName: "closeOnEscapeInput", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, blockScrollInput: { classPropertyName: "blockScrollInput", publicName: "blockScroll", isSignal: true, isRequired: false, transformFunction: null }, swipeToCloseInput: { classPropertyName: "swipeToCloseInput", publicName: "swipeToClose", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, showHeaderInput: { classPropertyName: "showHeaderInput", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showFooterInput: { classPropertyName: "showFooterInput", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showCloseButtonInput: { classPropertyName: "showCloseButtonInput", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, contentPadding: { classPropertyName: "contentPadding", publicName: "contentPadding", isSignal: true, isRequired: false, transformFunction: null }, contentGap: { classPropertyName: "contentGap", publicName: "contentGap", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange" }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: "<studio-drawer\n [visible]=\"visible()\"\n (visibleChange)=\"visible.set($event)\"\n [position]=\"position()\"\n [size]=\"drawerSize()\"\n [modal]=\"modal()\"\n [closeOnBackdropClick]=\"closeOnBackdropClick()\"\n [closeOnEscape]=\"closeOnEscape()\"\n [blockScroll]=\"blockScroll()\"\n [showHeader]=\"showHeader()\"\n [header]=\"header()\"\n [showCloseButton]=\"showCloseButton()\"\n [showFooter]=\"showFooter()\"\n [swipeToClose]=\"swipeToClose()\"\n [customWidth]=\"customWidth()\"\n>\n <ng-content select=\"[sidebarHeader]\" drawerHeader />\n\n <div\n class=\"studio-sidebar__content\"\n [class]=\"'studio-sidebar__content--' + variant()\"\n [style.padding]=\"contentPadding()\"\n [style.gap]=\"contentGap()\"\n [style.background]=\"background()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[sidebarFooter]\" drawerFooter />\n</studio-drawer>\n", styles: [":host{display:contents}.studio-sidebar__content{display:flex;flex-direction:column;height:100%;gap:var(--studio-spacing-md, 1rem);padding:var(--studio-spacing-md, 1rem)}.studio-sidebar__content--default{padding:var(--studio-spacing-lg, 1.5rem);gap:var(--studio-spacing-lg, 1.5rem)}.studio-sidebar__content--minimal{padding:var(--studio-spacing-sm, .5rem);gap:var(--studio-spacing-sm, .5rem)}.studio-sidebar__content--compact{padding:var(--studio-spacing-xs, .25rem);gap:var(--studio-spacing-xs, .25rem)}\n"], dependencies: [{ kind: "component", type: DrawerComponent, selector: "studio-drawer", inputs: ["id", "visible", "position", "size", "customWidth", "customHeight", "modal", "closeOnEscape", "closeOnBackdropClick", "blockScroll", "header", "showHeader", "showCloseButton", "closeButtonPosition", "showFooter", "swipeToClose", "swipeThreshold", "animationDuration", "animationEasing", "disableAnimation", "radius", "shadow", "shadowSize", "ariaLabel", "ariaLabelledBy", "ariaDescribedBy", "autoFocus", "restoreFocus", "role"], outputs: ["visibleChange", "opened", "closed", "backdropClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3210
+ }
3211
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SidebarComponent, decorators: [{
3212
+ type: Component,
3213
+ args: [{ selector: 'studio-sidebar', standalone: true, imports: [DrawerComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3214
+ '[class]': 'hostClasses()',
3215
+ }, template: "<studio-drawer\n [visible]=\"visible()\"\n (visibleChange)=\"visible.set($event)\"\n [position]=\"position()\"\n [size]=\"drawerSize()\"\n [modal]=\"modal()\"\n [closeOnBackdropClick]=\"closeOnBackdropClick()\"\n [closeOnEscape]=\"closeOnEscape()\"\n [blockScroll]=\"blockScroll()\"\n [showHeader]=\"showHeader()\"\n [header]=\"header()\"\n [showCloseButton]=\"showCloseButton()\"\n [showFooter]=\"showFooter()\"\n [swipeToClose]=\"swipeToClose()\"\n [customWidth]=\"customWidth()\"\n>\n <ng-content select=\"[sidebarHeader]\" drawerHeader />\n\n <div\n class=\"studio-sidebar__content\"\n [class]=\"'studio-sidebar__content--' + variant()\"\n [style.padding]=\"contentPadding()\"\n [style.gap]=\"contentGap()\"\n [style.background]=\"background()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[sidebarFooter]\" drawerFooter />\n</studio-drawer>\n", styles: [":host{display:contents}.studio-sidebar__content{display:flex;flex-direction:column;height:100%;gap:var(--studio-spacing-md, 1rem);padding:var(--studio-spacing-md, 1rem)}.studio-sidebar__content--default{padding:var(--studio-spacing-lg, 1.5rem);gap:var(--studio-spacing-lg, 1.5rem)}.studio-sidebar__content--minimal{padding:var(--studio-spacing-sm, .5rem);gap:var(--studio-spacing-sm, .5rem)}.studio-sidebar__content--compact{padding:var(--studio-spacing-xs, .25rem);gap:var(--studio-spacing-xs, .25rem)}\n"] }]
3216
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], positionInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], customWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "customWidth", required: false }] }], modalInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], collapsibleInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], defaultCollapsedInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultCollapsed", required: false }] }], closeOnNavigateInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnNavigate", required: false }] }], closeOnBackdropClickInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdropClick", required: false }] }], closeOnEscapeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], blockScrollInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "blockScroll", required: false }] }], swipeToCloseInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "swipeToClose", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], showHeaderInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], showFooterInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], showCloseButtonInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], contentPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentPadding", required: false }] }], contentGap: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentGap", required: false }] }], background: [{ type: i0.Input, args: [{ isSignal: true, alias: "background", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
3217
+
3218
+ /**
3219
+ * Sidebar component types
3220
+ */
3221
+
3222
+ /**
3223
+ * Sidebar component
3224
+ */
3225
+
2466
3226
  /**
2467
3227
  * Toggle switch component with customizable size and color
2468
3228
  *
2469
3229
  * @example
2470
3230
  * <studio-switch [(checked)]="isEnabled" label="Enable feature" />
3231
+ * <studio-switch [(ngModel)]="isEnabled" label="Enable feature" />
2471
3232
  */
2472
3233
  class SwitchComponent {
2473
3234
  configService = inject(StudioConfigService);
@@ -2483,11 +3244,25 @@ class SwitchComponent {
2483
3244
  size = withConfigDefault(this.sizeInput, computed(() => this.switchDefaults()?.size), 'md');
2484
3245
  color = withConfigDefault(this.colorInput, computed(() => this.switchDefaults()?.color), 'primary');
2485
3246
  checkedChange = output();
3247
+ internalChecked = signal(false, ...(ngDevMode ? [{ debugName: "internalChecked" }] : []));
3248
+ onChange = () => { };
3249
+ onTouched = () => { };
2486
3250
  iconSize = computed(() => {
2487
3251
  const sizeMap = { sm: 10, md: 12, lg: 14 };
2488
3252
  return sizeMap[this.size()];
2489
3253
  }, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
2490
- hostClasses = computed(() => classNames('studio-switch', `studio-switch--${this.size()}`, `studio-switch--${this.color()}`, this.checked() && 'studio-switch--checked', this.disabled() && 'studio-switch--disabled'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
3254
+ hostClasses = computed(() => classNames('studio-switch', `studio-switch--${this.size()}`, `studio-switch--${this.color()}`, this.internalChecked() && 'studio-switch--checked', this.disabled() && 'studio-switch--disabled'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
3255
+ writeValue(value) {
3256
+ this.internalChecked.set(value ?? false);
3257
+ this.checked.set(value ?? false);
3258
+ }
3259
+ registerOnChange(fn) {
3260
+ this.onChange = fn;
3261
+ }
3262
+ registerOnTouched(fn) {
3263
+ this.onTouched = fn;
3264
+ }
3265
+ setDisabledState(isDisabled) { }
2491
3266
  handleClick() {
2492
3267
  if (this.disabled())
2493
3268
  return;
@@ -2500,12 +3275,21 @@ class SwitchComponent {
2500
3275
  this.toggle();
2501
3276
  }
2502
3277
  toggle() {
2503
- const newValue = !this.checked();
3278
+ const newValue = !this.internalChecked();
3279
+ this.internalChecked.set(newValue);
2504
3280
  this.checked.set(newValue);
3281
+ this.onChange(newValue);
3282
+ this.onTouched();
2505
3283
  this.checkedChange.emit(newValue);
2506
3284
  }
2507
3285
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2508
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: SwitchComponent, isStandalone: true, selector: "studio-switch", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, colorInput: { classPropertyName: "colorInput", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", checkedChange: "checkedChange" }, host: { listeners: { "click": "handleClick()", "keydown.space": "handleKeydown($event)", "keydown.enter": "handleKeydown($event)" }, properties: { "class": "hostClasses()", "attr.role": "\"switch\"", "attr.aria-checked": "checked()", "attr.aria-disabled": "disabled() ? \"true\" : null", "attr.aria-label": "ariaLabel() || label()", "tabindex": "disabled() ? -1 : 0" } }, ngImport: i0, template: `
3286
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: SwitchComponent, isStandalone: true, selector: "studio-switch", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, colorInput: { classPropertyName: "colorInput", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", checkedChange: "checkedChange" }, host: { listeners: { "click": "handleClick()", "keydown.space": "handleKeydown($event)", "keydown.enter": "handleKeydown($event)" }, properties: { "class": "hostClasses()", "attr.role": "\"switch\"", "attr.aria-checked": "internalChecked()", "attr.aria-disabled": "disabled() ? \"true\" : null", "attr.aria-label": "ariaLabel() || label()", "tabindex": "disabled() ? -1 : 0" } }, providers: [
3287
+ {
3288
+ provide: NG_VALUE_ACCESSOR,
3289
+ useExisting: forwardRef(() => SwitchComponent),
3290
+ multi: true
3291
+ }
3292
+ ], ngImport: i0, template: `
2509
3293
  <span class="studio-switch__container">
2510
3294
  @if (label() && labelPosition() === 'left') {
2511
3295
  <span class="studio-switch__label studio-switch__label--left">
@@ -2516,7 +3300,7 @@ class SwitchComponent {
2516
3300
  <span class="studio-switch__track">
2517
3301
  <span class="studio-switch__thumb">
2518
3302
  @if (showIcons()) {
2519
- @if (checked()) {
3303
+ @if (internalChecked()) {
2520
3304
  <studio-icon name="check" [size]="iconSize()" color="inherit" />
2521
3305
  } @else {
2522
3306
  <studio-icon name="x" [size]="iconSize()" color="inherit" />
@@ -2535,10 +3319,16 @@ class SwitchComponent {
2535
3319
  }
2536
3320
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SwitchComponent, decorators: [{
2537
3321
  type: Component,
2538
- args: [{ selector: 'studio-switch', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3322
+ args: [{ selector: 'studio-switch', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
3323
+ {
3324
+ provide: NG_VALUE_ACCESSOR,
3325
+ useExisting: forwardRef(() => SwitchComponent),
3326
+ multi: true
3327
+ }
3328
+ ], host: {
2539
3329
  '[class]': 'hostClasses()',
2540
3330
  '[attr.role]': '"switch"',
2541
- '[attr.aria-checked]': 'checked()',
3331
+ '[attr.aria-checked]': 'internalChecked()',
2542
3332
  '[attr.aria-disabled]': 'disabled() ? "true" : null',
2543
3333
  '[attr.aria-label]': 'ariaLabel() || label()',
2544
3334
  '(click)': 'handleClick()',
@@ -2556,7 +3346,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2556
3346
  <span class="studio-switch__track">
2557
3347
  <span class="studio-switch__thumb">
2558
3348
  @if (showIcons()) {
2559
- @if (checked()) {
3349
+ @if (internalChecked()) {
2560
3350
  <studio-icon name="check" [size]="iconSize()" color="inherit" />
2561
3351
  } @else {
2562
3352
  <studio-icon name="x" [size]="iconSize()" color="inherit" />
@@ -3090,6 +3880,215 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
3090
3880
  `, styles: [":host{display:inline-block}:host(.studio-button-toggle-group--disabled){opacity:.6;pointer-events:none}\n"] }]
3091
3881
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], allowEmpty: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowEmpty", required: false }] }], 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 }] }], shadowInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", 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 }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
3092
3882
 
3883
+ class InspectorComponent {
3884
+ configService = inject(StudioConfigService);
3885
+ componentSize = input('sm', ...(ngDevMode ? [{ debugName: "componentSize" }] : []));
3886
+ componentVariant = input('outline', ...(ngDevMode ? [{ debugName: "componentVariant" }] : []));
3887
+ compact = input(false, ...(ngDevMode ? [{ debugName: "compact" }] : []));
3888
+ showIcons = input(true, ...(ngDevMode ? [{ debugName: "showIcons" }] : []));
3889
+ showDefaultIndicator = input(true, ...(ngDevMode ? [{ debugName: "showDefaultIndicator" }] : []));
3890
+ collapsible = input(true, ...(ngDevMode ? [{ debugName: "collapsible" }] : []));
3891
+ expandedByDefault = input(true, ...(ngDevMode ? [{ debugName: "expandedByDefault" }] : []));
3892
+ expandedSectionsInput = input([], ...(ngDevMode ? [{ debugName: "expandedSectionsInput", alias: 'expandedSections' }] : [{ alias: 'expandedSections' }]));
3893
+ showGroupLabels = input(true, ...(ngDevMode ? [{ debugName: "showGroupLabels" }] : []));
3894
+ groupDivider = input('line', ...(ngDevMode ? [{ debugName: "groupDivider" }] : []));
3895
+ groupDividerSpacing = input('md', ...(ngDevMode ? [{ debugName: "groupDividerSpacing" }] : []));
3896
+ labelWidth = input('auto', ...(ngDevMode ? [{ debugName: "labelWidth" }] : []));
3897
+ fullWidth = input(true, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
3898
+ spacing = input('md', ...(ngDevMode ? [{ debugName: "spacing" }] : []));
3899
+ sectionTemplate = input(undefined, ...(ngDevMode ? [{ debugName: "sectionTemplate" }] : []));
3900
+ parameterTemplates = input(undefined, ...(ngDevMode ? [{ debugName: "parameterTemplates" }] : []));
3901
+ ariaLabel = input('Inspector panel', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
3902
+ ariaDescribedBy = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
3903
+ sectionToggled = output();
3904
+ parameterFocused = output();
3905
+ parameterBlurred = output();
3906
+ values = signal(null, ...(ngDevMode ? [{ debugName: "values" }] : []));
3907
+ expandedSections = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedSections" }] : []));
3908
+ onChange = () => { };
3909
+ onTouched = () => { };
3910
+ constructor() {
3911
+ effect(() => {
3912
+ const inputSections = this.expandedSectionsInput();
3913
+ if (inputSections.length > 0) {
3914
+ this.expandedSections.set(new Set(inputSections));
3915
+ }
3916
+ });
3917
+ }
3918
+ hostClasses = computed(() => classNames('studio-inspector', this.compact() && 'studio-inspector--compact', `studio-inspector--spacing-${this.spacing()}`), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
3919
+ isSectionExpanded(componentId) {
3920
+ return this.expandedSections().has(componentId);
3921
+ }
3922
+ toggleSection(componentId) {
3923
+ if (!this.collapsible())
3924
+ return;
3925
+ const expanded = new Set(this.expandedSections());
3926
+ if (expanded.has(componentId)) {
3927
+ expanded.delete(componentId);
3928
+ }
3929
+ else {
3930
+ expanded.add(componentId);
3931
+ }
3932
+ this.expandedSections.set(expanded);
3933
+ this.sectionToggled.emit({
3934
+ id: componentId,
3935
+ expanded: expanded.has(componentId)
3936
+ });
3937
+ }
3938
+ onParameterChange(componentId, groupId, parameterId, newValue) {
3939
+ const updated = structuredClone(this.values());
3940
+ if (!updated)
3941
+ return;
3942
+ const section = updated.sections.find(c => c.id === componentId);
3943
+ if (!section)
3944
+ return;
3945
+ let parameter;
3946
+ if (groupId) {
3947
+ const group = section.groups?.find(g => g.id === groupId);
3948
+ parameter = group?.parameters.find(p => p.id === parameterId);
3949
+ }
3950
+ else {
3951
+ parameter = section.parameters?.find(p => p.id === parameterId);
3952
+ }
3953
+ if (parameter) {
3954
+ parameter.value = newValue;
3955
+ }
3956
+ this.values.set(updated);
3957
+ this.onChange(updated);
3958
+ this.onTouched();
3959
+ }
3960
+ onCheckboxChange(componentId, groupId, parameterId, optionValue, checked) {
3961
+ const updated = structuredClone(this.values());
3962
+ if (!updated)
3963
+ return;
3964
+ const section = updated.sections.find(c => c.id === componentId);
3965
+ if (!section)
3966
+ return;
3967
+ let parameter;
3968
+ if (groupId) {
3969
+ const group = section.groups?.find(g => g.id === groupId);
3970
+ parameter = group?.parameters.find(p => p.id === parameterId);
3971
+ }
3972
+ else {
3973
+ parameter = section.parameters?.find(p => p.id === parameterId);
3974
+ }
3975
+ if (parameter && parameter.type === 'checkbox') {
3976
+ const currentValues = Array.isArray(parameter.value) ? parameter.value : [];
3977
+ if (checked) {
3978
+ if (!currentValues.includes(optionValue)) {
3979
+ parameter.value = [...currentValues, optionValue];
3980
+ }
3981
+ }
3982
+ else {
3983
+ parameter.value = currentValues.filter(v => v !== optionValue);
3984
+ }
3985
+ }
3986
+ this.values.set(updated);
3987
+ this.onChange(updated);
3988
+ this.onTouched();
3989
+ }
3990
+ onRadioChange(componentId, groupId, parameterId, newValue) {
3991
+ this.onParameterChange(componentId, groupId, parameterId, newValue);
3992
+ }
3993
+ getRadioName(componentId, groupId, parameterId) {
3994
+ return `${componentId}-${groupId || 'root'}-${parameterId}`;
3995
+ }
3996
+ isChecked(parameter, optionValue) {
3997
+ if (parameter.type === 'checkbox') {
3998
+ return Array.isArray(parameter.value) && parameter.value.includes(optionValue);
3999
+ }
4000
+ else if (parameter.type === 'radio') {
4001
+ return parameter.value === optionValue;
4002
+ }
4003
+ return false;
4004
+ }
4005
+ isRadioChecked(parameter, optionValue) {
4006
+ return parameter.value === optionValue;
4007
+ }
4008
+ isDefault(parameter, optionValue) {
4009
+ return parameter.default !== undefined && parameter.default === optionValue;
4010
+ }
4011
+ trackBySectionId(_, section) {
4012
+ return section.id;
4013
+ }
4014
+ trackByGroupId(_, group) {
4015
+ return group.id;
4016
+ }
4017
+ trackByParameterId(_, param) {
4018
+ return param.id;
4019
+ }
4020
+ trackByOptionValue(_, option) {
4021
+ return option.value;
4022
+ }
4023
+ writeValue(value) {
4024
+ this.values.set(value);
4025
+ this.initializeExpandedSections();
4026
+ }
4027
+ registerOnChange(fn) {
4028
+ this.onChange = fn;
4029
+ }
4030
+ registerOnTouched(fn) {
4031
+ this.onTouched = fn;
4032
+ }
4033
+ setDisabledState(_) { }
4034
+ initializeExpandedSections() {
4035
+ const expanded = new Set();
4036
+ const inputSections = this.expandedSectionsInput();
4037
+ if (inputSections.length > 0) {
4038
+ inputSections.forEach(id => expanded.add(id));
4039
+ }
4040
+ else if (this.expandedByDefault()) {
4041
+ this.values()?.sections.forEach(c => {
4042
+ if (c.expanded !== false) {
4043
+ expanded.add(c.id);
4044
+ }
4045
+ });
4046
+ }
4047
+ else {
4048
+ this.values()?.sections.forEach(c => {
4049
+ if (c.expanded === true) {
4050
+ expanded.add(c.id);
4051
+ }
4052
+ });
4053
+ }
4054
+ this.expandedSections.set(expanded);
4055
+ }
4056
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: InspectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4057
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: InspectorComponent, isStandalone: true, selector: "studio-inspector", inputs: { componentSize: { classPropertyName: "componentSize", publicName: "componentSize", isSignal: true, isRequired: false, transformFunction: null }, componentVariant: { classPropertyName: "componentVariant", publicName: "componentVariant", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, showDefaultIndicator: { classPropertyName: "showDefaultIndicator", publicName: "showDefaultIndicator", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, expandedByDefault: { classPropertyName: "expandedByDefault", publicName: "expandedByDefault", isSignal: true, isRequired: false, transformFunction: null }, expandedSectionsInput: { classPropertyName: "expandedSectionsInput", publicName: "expandedSections", isSignal: true, isRequired: false, transformFunction: null }, showGroupLabels: { classPropertyName: "showGroupLabels", publicName: "showGroupLabels", isSignal: true, isRequired: false, transformFunction: null }, groupDivider: { classPropertyName: "groupDivider", publicName: "groupDivider", isSignal: true, isRequired: false, transformFunction: null }, groupDividerSpacing: { classPropertyName: "groupDividerSpacing", publicName: "groupDividerSpacing", isSignal: true, isRequired: false, transformFunction: null }, labelWidth: { classPropertyName: "labelWidth", publicName: "labelWidth", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, spacing: { classPropertyName: "spacing", publicName: "spacing", isSignal: true, isRequired: false, transformFunction: null }, sectionTemplate: { classPropertyName: "sectionTemplate", publicName: "sectionTemplate", isSignal: true, isRequired: false, transformFunction: null }, parameterTemplates: { classPropertyName: "parameterTemplates", publicName: "parameterTemplates", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sectionToggled: "sectionToggled", parameterFocused: "parameterFocused", parameterBlurred: "parameterBlurred" }, host: { properties: { "class": "hostClasses()", "attr.role": "\"region\"", "attr.aria-label": "ariaLabel()" } }, providers: [
4058
+ {
4059
+ provide: NG_VALUE_ACCESSOR,
4060
+ useExisting: forwardRef(() => InspectorComponent),
4061
+ multi: true
4062
+ }
4063
+ ], ngImport: i0, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ButtonComponent, selector: "studio-button", inputs: ["variant", "size", "color", "radius", "shadow", "compact", "disabled", "loading", "loadingText", "fullWidth", "type", "icon", "iconPosition", "href", "target", "badge", "badgeColor", "ariaLabel"], outputs: ["clicked"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }, { kind: "component", type: InputComponent, selector: "studio-input", inputs: ["variant", "size", "radius", "disabled", "readonly", "loading", "type", "inputmode", "autocomplete", "placeholder", "maxLength", "minLength", "min", "max", "step", "pattern", "label", "floatingLabel", "hint", "required", "error", "errorMessage", "prefixIcon", "suffixIcon", "clearable", "showPasswordToggle", "fullWidth", "autoFocus", "name", "id", "ariaLabel"], outputs: ["valueChange", "focused", "blurred", "cleared", "entered"] }, { kind: "component", type: CheckboxComponent, selector: "studio-checkbox", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "indeterminate", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: RadioButtonComponent, selector: "studio-radio-button", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: ColorPickerComponent, selector: "studio-color-picker", inputs: ["variant", "size", "format", "showAlpha", "showPresets", "showFormatToggle", "showCopyButton", "presets", "label", "hint", "required", "error", "errorMessage", "disabled", "readonly"], outputs: ["colorChange", "colorValueChange", "copied"] }, { kind: "component", type: SelectComponent, selector: "studio-select", inputs: ["variant", "size", "radius", "options", "placeholder", "multiple", "searchable", "clearable", "disabled", "loading", "label", "floatingLabel", "hint", "error", "errorMessage", "required", "prefixIcon", "suffixIcon", "fullWidth", "maxHeight", "position", "searchPlaceholder"], outputs: ["valueChange", "searchChange", "opened", "closed", "optionSelected"] }, { kind: "component", type: TextareaComponent, selector: "studio-textarea", inputs: ["variant", "size", "color", "radius", "label", "floatingLabel", "placeholder", "hint", "rows", "minRows", "maxRows", "autoResize", "resize", "maxLength", "showCharCount", "charCountPosition", "required", "minLength", "error", "errorMessage", "disabled", "readonly", "fullWidth", "name", "autocomplete", "spellcheck", "clearable", "loading"], outputs: ["changed", "focused", "blurred", "keyPressed"] }, { kind: "component", type: SwitchComponent, selector: "studio-switch", inputs: ["checked", "disabled", "label", "labelPosition", "showIcons", "ariaLabel", "size", "color"], outputs: ["checkedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4064
+ }
4065
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: InspectorComponent, decorators: [{
4066
+ type: Component,
4067
+ args: [{ selector: 'studio-inspector', standalone: true, imports: [
4068
+ CommonModule,
4069
+ FormsModule,
4070
+ ButtonComponent,
4071
+ IconComponent,
4072
+ InputComponent,
4073
+ CheckboxComponent,
4074
+ RadioButtonComponent,
4075
+ ColorPickerComponent,
4076
+ SelectComponent,
4077
+ TextareaComponent,
4078
+ SwitchComponent
4079
+ ], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
4080
+ {
4081
+ provide: NG_VALUE_ACCESSOR,
4082
+ useExisting: forwardRef(() => InspectorComponent),
4083
+ multi: true
4084
+ }
4085
+ ], host: {
4086
+ '[class]': 'hostClasses()',
4087
+ '[attr.role]': '"region"',
4088
+ '[attr.aria-label]': 'ariaLabel()'
4089
+ }, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"] }]
4090
+ }], ctorParameters: () => [], propDecorators: { componentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentSize", required: false }] }], componentVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentVariant", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], showDefaultIndicator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDefaultIndicator", required: false }] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], expandedByDefault: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedByDefault", required: false }] }], expandedSectionsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedSections", required: false }] }], showGroupLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGroupLabels", required: false }] }], groupDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupDivider", required: false }] }], groupDividerSpacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupDividerSpacing", required: false }] }], labelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelWidth", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], sectionTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "sectionTemplate", required: false }] }], parameterTemplates: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterTemplates", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }], sectionToggled: [{ type: i0.Output, args: ["sectionToggled"] }], parameterFocused: [{ type: i0.Output, args: ["parameterFocused"] }], parameterBlurred: [{ type: i0.Output, args: ["parameterBlurred"] }] } });
4091
+
3093
4092
  /**
3094
4093
  * Theme toggle switch with sun/moon icons
3095
4094
  *
@@ -3618,5 +4617,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
3618
4617
  * Generated bundle index. Do not edit.
3619
4618
  */
3620
4619
 
3621
- export { BadgeComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, CheckboxComponent, DrawerComponent, DrawerService, IconComponent, InputComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, STUDIO_CONFIG, SelectComponent, StudioConfigService, SwitchComponent, TextareaComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
4620
+ export { BadgeComponent, BadgeWrapperComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, CheckboxComponent, ColorPickerComponent, DEFAULT_COLOR_PRESETS, DrawerComponent, DrawerService, IconComponent, InputComponent, InspectorComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, NavbarComponent, RadioButtonComponent, STUDIO_CONFIG, SelectComponent, SidebarComponent, StudioConfigService, SwitchComponent, TextareaComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
3622
4621
  //# sourceMappingURL=eduboxpro-studio.mjs.map