@eduboxpro/studio 0.1.26 → 0.1.27

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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, PLATFORM_ID, ElementRef, contentChild, viewChild, forwardRef, DOCUMENT as DOCUMENT$1, DestroyRef, Injector, model, afterNextRender, HostListener, TemplateRef, ContentChild, Input, Directive, contentChildren, Renderer2 } from '@angular/core';
2
+ import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, PLATFORM_ID, ElementRef, contentChild, viewChild, forwardRef, DOCUMENT as DOCUMENT$1, DestroyRef, Injector, model, afterNextRender, HostListener, Renderer2, TemplateRef, ContentChild, Input, Directive, contentChildren } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { DOCUMENT, CommonModule, isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
5
5
  import * as LucideIcons from 'lucide-angular';
@@ -4835,6 +4835,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
4835
4835
  class SelectComponent {
4836
4836
  configService = inject(StudioConfigService);
4837
4837
  selectDefaults = computed(() => this.configService.config().components?.select, ...(ngDevMode ? [{ debugName: "selectDefaults" }] : []));
4838
+ document = inject(DOCUMENT);
4839
+ renderer = inject(Renderer2);
4840
+ hostEl = inject(ElementRef);
4838
4841
  triggerEl = viewChild('triggerButton', ...(ngDevMode ? [{ debugName: "triggerEl" }] : []));
4839
4842
  dropdownEl = viewChild('dropdownPanel', ...(ngDevMode ? [{ debugName: "dropdownEl" }] : []));
4840
4843
  variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
@@ -4861,6 +4864,7 @@ class SelectComponent {
4861
4864
  fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
4862
4865
  maxHeight = input('300px', ...(ngDevMode ? [{ debugName: "maxHeight" }] : []));
4863
4866
  position = input('bottom', ...(ngDevMode ? [{ debugName: "position" }] : []));
4867
+ appendToBody = input(false, ...(ngDevMode ? [{ debugName: "appendToBody" }] : []));
4864
4868
  searchPlaceholder = input('Search...', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
4865
4869
  valueChange = output();
4866
4870
  searchChange = output();
@@ -4876,16 +4880,27 @@ class SelectComponent {
4876
4880
  generatedId = `studio-select-${Math.random().toString(36).substr(2, 9)}`;
4877
4881
  onChange = () => { };
4878
4882
  onTouched = () => { };
4883
+ portalContainer = null;
4879
4884
  constructor() {
4880
4885
  effect(() => {
4881
4886
  if (this.isOpen()) {
4882
4887
  this.setupClickOutside();
4888
+ if (this.appendToBody()) {
4889
+ this.attachDropdownToBody();
4890
+ }
4883
4891
  }
4884
4892
  else {
4885
4893
  this.cleanupClickOutside();
4894
+ if (this.appendToBody()) {
4895
+ this.detachDropdownFromBody();
4896
+ }
4886
4897
  }
4887
4898
  });
4888
4899
  }
4900
+ ngOnDestroy() {
4901
+ this.cleanupClickOutside();
4902
+ this.detachDropdownFromBody();
4903
+ }
4889
4904
  flattenedOptions = computed(() => {
4890
4905
  const opts = this.options();
4891
4906
  if (!opts || opts.length === 0)
@@ -5084,14 +5099,46 @@ class SelectComponent {
5084
5099
  }
5085
5100
  setDisabledState(isDisabled) {
5086
5101
  }
5102
+ attachDropdownToBody() {
5103
+ setTimeout(() => {
5104
+ const dropdown = this.dropdownEl()?.nativeElement;
5105
+ const trigger = this.triggerEl()?.nativeElement;
5106
+ if (!dropdown || !trigger)
5107
+ return;
5108
+ // Create container if not exists
5109
+ if (!this.portalContainer) {
5110
+ this.portalContainer = this.renderer.createElement('div');
5111
+ this.renderer.addClass(this.portalContainer, 'studio-select-portal');
5112
+ this.renderer.appendChild(this.document.body, this.portalContainer);
5113
+ }
5114
+ // Get trigger position
5115
+ const rect = trigger.getBoundingClientRect();
5116
+ const controlEl = this.hostEl.nativeElement.querySelector('.studio-select__control');
5117
+ const controlRect = controlEl?.getBoundingClientRect() || rect;
5118
+ // Move dropdown to portal
5119
+ this.renderer.appendChild(this.portalContainer, dropdown);
5120
+ // Position dropdown
5121
+ this.renderer.setStyle(dropdown, 'position', 'fixed');
5122
+ this.renderer.setStyle(dropdown, 'top', `${controlRect.bottom + 4}px`);
5123
+ this.renderer.setStyle(dropdown, 'left', `${controlRect.left}px`);
5124
+ this.renderer.setStyle(dropdown, 'width', `${controlRect.width}px`);
5125
+ this.renderer.setStyle(dropdown, 'zIndex', '9999');
5126
+ }, 0);
5127
+ }
5128
+ detachDropdownFromBody() {
5129
+ if (this.portalContainer) {
5130
+ this.renderer.removeChild(this.document.body, this.portalContainer);
5131
+ this.portalContainer = null;
5132
+ }
5133
+ }
5087
5134
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5088
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: SelectComponent, isStandalone: true, selector: "studio-select", inputs: { variantInput: { classPropertyName: "variantInput", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, radiusInput: { classPropertyName: "radiusInput", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, floatingLabel: { classPropertyName: "floatingLabel", publicName: "floatingLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", 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 }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, prefixIcon: { classPropertyName: "prefixIcon", publicName: "prefixIcon", isSignal: true, isRequired: false, transformFunction: null }, suffixIcon: { classPropertyName: "suffixIcon", publicName: "suffixIcon", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", searchChange: "searchChange", opened: "opened", closed: "closed", optionSelected: "optionSelected" }, host: { properties: { "class": "hostClasses()", "attr.data-open": "isOpen()" } }, providers: [
5135
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: SelectComponent, isStandalone: true, selector: "studio-select", inputs: { variantInput: { classPropertyName: "variantInput", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, radiusInput: { classPropertyName: "radiusInput", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, floatingLabel: { classPropertyName: "floatingLabel", publicName: "floatingLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", 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 }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, prefixIcon: { classPropertyName: "prefixIcon", publicName: "prefixIcon", isSignal: true, isRequired: false, transformFunction: null }, suffixIcon: { classPropertyName: "suffixIcon", publicName: "suffixIcon", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, appendToBody: { classPropertyName: "appendToBody", publicName: "appendToBody", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", searchChange: "searchChange", opened: "opened", closed: "closed", optionSelected: "optionSelected" }, host: { properties: { "class": "hostClasses()", "attr.data-open": "isOpen()" } }, providers: [
5089
5136
  {
5090
5137
  provide: NG_VALUE_ACCESSOR,
5091
5138
  useExisting: forwardRef(() => SelectComponent),
5092
5139
  multi: true
5093
5140
  }
5094
- ], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerButton"], descendants: true, isSignal: true }, { propertyName: "dropdownEl", first: true, predicate: ["dropdownPanel"], descendants: true, isSignal: true }], ngImport: i0, 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"], dependencies: [{ kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5141
+ ], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerButton"], descendants: true, isSignal: true }, { propertyName: "dropdownEl", first: true, predicate: ["dropdownPanel"], descendants: true, isSignal: true }], ngImport: i0, 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, 1100);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"], dependencies: [{ kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5095
5142
  }
5096
5143
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SelectComponent, decorators: [{
5097
5144
  type: Component,
@@ -5104,8 +5151,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
5104
5151
  ], host: {
5105
5152
  '[class]': 'hostClasses()',
5106
5153
  '[attr.data-open]': 'isOpen()',
5107
- }, 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"] }]
5108
- }], 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"] }] } });
5154
+ }, 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, 1100);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"] }]
5155
+ }], 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 }] }], appendToBody: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendToBody", 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"] }] } });
5109
5156
 
5110
5157
  /**
5111
5158
  * Sidebar component - Navigation sidebar built on top of Drawer
@@ -6134,9 +6181,12 @@ class TableComponent {
6134
6181
  getRowKey(row) {
6135
6182
  const keyFn = this.rowKey();
6136
6183
  if (typeof keyFn === 'function') {
6137
- return keyFn(row);
6184
+ const result = keyFn(row);
6185
+ return result ?? this.processedData().indexOf(row);
6138
6186
  }
6139
- return row[keyFn];
6187
+ const value = row[keyFn];
6188
+ // Fallback to index if key is empty/undefined
6189
+ return value ?? this.processedData().indexOf(row);
6140
6190
  }
6141
6191
  getSelectedRows() {
6142
6192
  const selected = this.selectedRows();
@@ -7022,7 +7072,7 @@ class InspectorComponent {
7022
7072
  useExisting: forwardRef(() => InspectorComponent),
7023
7073
  multi: true
7024
7074
  }
7025
- ], ngImport: i0, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker-compact\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker-compact\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ButtonComponent, selector: "studio-button", inputs: ["variant", "size", "color", "radius", "shadow", "compact", "disabled", "loading", "loadingText", "fullWidth", "type", "icon", "iconPosition", "href", "target", "badge", "badgeColor", "ariaLabel"], outputs: ["clicked"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }, { kind: "component", type: InputComponent, selector: "studio-input", inputs: ["variant", "size", "radius", "disabled", "readonly", "loading", "type", "inputmode", "autocomplete", "placeholder", "maxLength", "minLength", "min", "max", "step", "pattern", "label", "floatingLabel", "hint", "required", "error", "errorMessage", "prefixIcon", "suffixIcon", "clearable", "showPasswordToggle", "fullWidth", "autoFocus", "name", "id", "ariaLabel"], outputs: ["valueChange", "focused", "blurred", "cleared", "entered"] }, { kind: "component", type: CheckboxComponent, selector: "studio-checkbox", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "indeterminate", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: RadioButtonComponent, selector: "studio-radio-button", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: ColorPickerCompactComponent, selector: "studio-color-picker-compact", inputs: ["trigger", "position", "popoverWidth", "showArrow", "closeOnClickOutside", "triggerSize", "triggerRadius", "showCurrentColor", "format", "showAlpha", "showPresets", "showFormatToggle", "showCopyButton", "presets", "showFooter", "applyLabel", "cancelLabel", "disabled", "ariaLabel"], outputs: ["colorChange"] }, { kind: "component", type: SelectComponent, selector: "studio-select", inputs: ["variant", "size", "radius", "options", "placeholder", "multiple", "searchable", "clearable", "disabled", "loading", "label", "floatingLabel", "hint", "error", "errorMessage", "required", "prefixIcon", "suffixIcon", "fullWidth", "maxHeight", "position", "searchPlaceholder"], outputs: ["valueChange", "searchChange", "opened", "closed", "optionSelected"] }, { kind: "component", type: TextareaComponent, selector: "studio-textarea", inputs: ["variant", "size", "color", "radius", "label", "floatingLabel", "placeholder", "hint", "rows", "minRows", "maxRows", "autoResize", "resize", "maxLength", "showCharCount", "charCountPosition", "required", "minLength", "error", "errorMessage", "disabled", "readonly", "fullWidth", "name", "autocomplete", "spellcheck", "clearable", "loading"], outputs: ["changed", "focused", "blurred", "keyPressed"] }, { kind: "component", type: SwitchComponent, selector: "studio-switch", inputs: ["checked", "disabled", "label", "labelPosition", "showIcons", "ariaLabel", "size", "color"], outputs: ["checkedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7075
+ ], ngImport: i0, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker-compact\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker-compact\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ButtonComponent, selector: "studio-button", inputs: ["variant", "size", "color", "radius", "shadow", "compact", "disabled", "loading", "loadingText", "fullWidth", "type", "icon", "iconPosition", "href", "target", "badge", "badgeColor", "ariaLabel"], outputs: ["clicked"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }, { kind: "component", type: InputComponent, selector: "studio-input", inputs: ["variant", "size", "radius", "disabled", "readonly", "loading", "type", "inputmode", "autocomplete", "placeholder", "maxLength", "minLength", "min", "max", "step", "pattern", "label", "floatingLabel", "hint", "required", "error", "errorMessage", "prefixIcon", "suffixIcon", "clearable", "showPasswordToggle", "fullWidth", "autoFocus", "name", "id", "ariaLabel"], outputs: ["valueChange", "focused", "blurred", "cleared", "entered"] }, { kind: "component", type: CheckboxComponent, selector: "studio-checkbox", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "indeterminate", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: RadioButtonComponent, selector: "studio-radio-button", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: ColorPickerCompactComponent, selector: "studio-color-picker-compact", inputs: ["trigger", "position", "popoverWidth", "showArrow", "closeOnClickOutside", "triggerSize", "triggerRadius", "showCurrentColor", "format", "showAlpha", "showPresets", "showFormatToggle", "showCopyButton", "presets", "showFooter", "applyLabel", "cancelLabel", "disabled", "ariaLabel"], outputs: ["colorChange"] }, { kind: "component", type: SelectComponent, selector: "studio-select", inputs: ["variant", "size", "radius", "options", "placeholder", "multiple", "searchable", "clearable", "disabled", "loading", "label", "floatingLabel", "hint", "error", "errorMessage", "required", "prefixIcon", "suffixIcon", "fullWidth", "maxHeight", "position", "appendToBody", "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 });
7026
7076
  }
7027
7077
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: InspectorComponent, decorators: [{
7028
7078
  type: Component,