@eduboxpro/studio 0.1.6 → 0.1.7

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,6 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, viewChild, forwardRef, model } from '@angular/core';
3
- import { DOCUMENT } from '@angular/common';
2
+ import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, forwardRef, viewChild, model } from '@angular/core';
3
+ import * as i1$1 from '@angular/common';
4
+ import { DOCUMENT, CommonModule } from '@angular/common';
4
5
  import * as i1 from 'lucide-angular';
5
6
  import { icons, LucideAngularModule, LucideIconProvider, LUCIDE_ICONS, Moon, Sun, ShoppingCart, Loader2, Loader, RotateCw, RefreshCw, Printer, Save, Image, Folder, FileText, File, HelpCircle, XCircle, CheckCircle, Info, AlertTriangle, AlertCircle, LogOut, LogIn, Unlock, Lock, EyeOff, Eye, Clock, Calendar, Bell, MoreHorizontal, MoreVertical, Menu, Home, Share2, Copy, Link, ExternalLink, Filter, Search, X, Check, Minus, Plus, Edit, Trash2, User, Settings, Star, Heart, Phone, Mail, Upload, Download, ChevronRight, ChevronLeft, ChevronUp, ChevronDown, ArrowLeft, ArrowRight } from 'lucide-angular';
6
7
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
@@ -868,6 +869,241 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
868
869
  * Button component
869
870
  */
870
871
 
872
+ /**
873
+ * Checkbox component for selecting boolean values
874
+ *
875
+ * @example
876
+ * <studio-checkbox
877
+ * [(ngModel)]="accepted"
878
+ * label="I accept terms and conditions"
879
+ * (changed)="onAccept($event)"
880
+ * />
881
+ */
882
+ class CheckboxComponent {
883
+ configService = inject(StudioConfigService);
884
+ checkboxDefaults = computed(() => this.configService.config().components?.checkbox, ...(ngDevMode ? [{ debugName: "checkboxDefaults" }] : []));
885
+ // ==========================================
886
+ // INPUTS - Appearance
887
+ // ==========================================
888
+ /**
889
+ * Size of the checkbox
890
+ */
891
+ size = input(this.checkboxDefaults()?.size ?? 'md', ...(ngDevMode ? [{ debugName: "size" }] : []));
892
+ /**
893
+ * Color scheme
894
+ */
895
+ color = input(this.checkboxDefaults()?.color ?? 'primary', ...(ngDevMode ? [{ debugName: "color" }] : []));
896
+ /**
897
+ * Visual variant
898
+ */
899
+ variant = input(this.checkboxDefaults()?.variant ?? 'default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
900
+ /**
901
+ * Border radius
902
+ */
903
+ radius = input(this.checkboxDefaults()?.radius ?? 'sm', ...(ngDevMode ? [{ debugName: "radius" }] : []));
904
+ // ==========================================
905
+ // INPUTS - Labels & Description
906
+ // ==========================================
907
+ /**
908
+ * Label text
909
+ */
910
+ label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
911
+ /**
912
+ * Label position relative to checkbox
913
+ */
914
+ labelPosition = input(this.checkboxDefaults()?.labelPosition ?? 'right', ...(ngDevMode ? [{ debugName: "labelPosition" }] : []));
915
+ /**
916
+ * Additional description text
917
+ */
918
+ description = input(...(ngDevMode ? [undefined, { debugName: "description" }] : []));
919
+ /**
920
+ * Helper text
921
+ */
922
+ hint = input(...(ngDevMode ? [undefined, { debugName: "hint" }] : []));
923
+ // ==========================================
924
+ // INPUTS - Validation
925
+ // ==========================================
926
+ /**
927
+ * Required field
928
+ */
929
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
930
+ /**
931
+ * Error state
932
+ */
933
+ error = input(false, ...(ngDevMode ? [{ debugName: "error" }] : []));
934
+ /**
935
+ * Error message
936
+ */
937
+ errorMessage = input(...(ngDevMode ? [undefined, { debugName: "errorMessage" }] : []));
938
+ // ==========================================
939
+ // INPUTS - Behavior
940
+ // ==========================================
941
+ /**
942
+ * Disabled state
943
+ */
944
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
945
+ /**
946
+ * Readonly state
947
+ */
948
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
949
+ /**
950
+ * Indeterminate state (for "select all" checkboxes)
951
+ */
952
+ indeterminate = input(false, ...(ngDevMode ? [{ debugName: "indeterminate" }] : []));
953
+ /**
954
+ * Name attribute for form control
955
+ */
956
+ name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
957
+ /**
958
+ * Tab index
959
+ */
960
+ tabIndex = input(0, ...(ngDevMode ? [{ debugName: "tabIndex" }] : []));
961
+ /**
962
+ * Value for checkbox groups
963
+ */
964
+ value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
965
+ // ==========================================
966
+ // OUTPUTS
967
+ // ==========================================
968
+ /**
969
+ * Emitted when checkbox state changes
970
+ */
971
+ changed = output();
972
+ // ==========================================
973
+ // STATE
974
+ // ==========================================
975
+ /**
976
+ * Internal checked state
977
+ */
978
+ internalChecked = signal(false, ...(ngDevMode ? [{ debugName: "internalChecked" }] : []));
979
+ /**
980
+ * Internal focus state
981
+ */
982
+ isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
983
+ /**
984
+ * Unique ID for accessibility
985
+ */
986
+ checkboxId = signal(`studio-checkbox-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "checkboxId" }] : []));
987
+ // ==========================================
988
+ // COMPUTED
989
+ // ==========================================
990
+ /**
991
+ * Host CSS classes
992
+ */
993
+ hostClasses = computed(() => ({
994
+ 'studio-checkbox-wrapper': true,
995
+ [`studio-checkbox-wrapper--${this.size()}`]: true,
996
+ 'studio-checkbox-wrapper--disabled': this.disabled(),
997
+ 'studio-checkbox-wrapper--error': this.error(),
998
+ 'studio-checkbox-wrapper--focused': this.isFocused(),
999
+ 'studio-checkbox-wrapper--label-left': this.labelPosition() === 'left'
1000
+ }), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
1001
+ /**
1002
+ * Checkbox element CSS classes
1003
+ */
1004
+ checkboxClasses = computed(() => ({
1005
+ 'studio-checkbox': true,
1006
+ [`studio-checkbox--${this.size()}`]: true,
1007
+ [`studio-checkbox--${this.color()}`]: true,
1008
+ [`studio-checkbox--${this.variant()}`]: true,
1009
+ [`studio-checkbox--radius-${this.radius()}`]: true,
1010
+ 'studio-checkbox--checked': this.internalChecked(),
1011
+ 'studio-checkbox--indeterminate': this.indeterminate(),
1012
+ 'studio-checkbox--disabled': this.disabled(),
1013
+ 'studio-checkbox--error': this.error()
1014
+ }), ...(ngDevMode ? [{ debugName: "checkboxClasses" }] : []));
1015
+ /**
1016
+ * Show error message
1017
+ */
1018
+ showError = computed(() => this.error() && this.errorMessage(), ...(ngDevMode ? [{ debugName: "showError" }] : []));
1019
+ /**
1020
+ * Show hint
1021
+ */
1022
+ showHint = computed(() => !this.error() && this.hint(), ...(ngDevMode ? [{ debugName: "showHint" }] : []));
1023
+ /**
1024
+ * ARIA checked state
1025
+ */
1026
+ ariaChecked = computed(() => {
1027
+ if (this.indeterminate())
1028
+ return 'mixed';
1029
+ return this.internalChecked() ? 'true' : 'false';
1030
+ }, ...(ngDevMode ? [{ debugName: "ariaChecked" }] : []));
1031
+ // ==========================================
1032
+ // CONTROL VALUE ACCESSOR
1033
+ // ==========================================
1034
+ onChange = () => { };
1035
+ onTouched = () => { };
1036
+ writeValue(value) {
1037
+ this.internalChecked.set(value ?? false);
1038
+ }
1039
+ registerOnChange(fn) {
1040
+ this.onChange = fn;
1041
+ }
1042
+ registerOnTouched(fn) {
1043
+ this.onTouched = fn;
1044
+ }
1045
+ setDisabledState(isDisabled) {
1046
+ // Disabled state is controlled via input
1047
+ }
1048
+ // ==========================================
1049
+ // METHODS
1050
+ // ==========================================
1051
+ /**
1052
+ * Handle checkbox toggle
1053
+ */
1054
+ handleChange(event) {
1055
+ if (this.disabled() || this.readonly()) {
1056
+ event.preventDefault();
1057
+ return;
1058
+ }
1059
+ const newValue = event.target.checked;
1060
+ this.internalChecked.set(newValue);
1061
+ this.onChange(newValue);
1062
+ this.changed.emit(newValue);
1063
+ }
1064
+ /**
1065
+ * Handle focus
1066
+ */
1067
+ handleFocus() {
1068
+ this.isFocused.set(true);
1069
+ }
1070
+ /**
1071
+ * Handle blur
1072
+ */
1073
+ handleBlur() {
1074
+ this.isFocused.set(false);
1075
+ this.onTouched();
1076
+ }
1077
+ /**
1078
+ * Handle label click
1079
+ */
1080
+ handleLabelClick(event) {
1081
+ if (this.disabled() || this.readonly()) {
1082
+ event.preventDefault();
1083
+ }
1084
+ }
1085
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: CheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1086
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: CheckboxComponent, isStandalone: true, selector: "studio-checkbox", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed" }, host: { properties: { "class": "hostClasses()", "attr.data-size": "size()", "attr.data-color": "color()", "attr.data-disabled": "disabled()", "attr.data-error": "error()" } }, providers: [{
1087
+ provide: NG_VALUE_ACCESSOR,
1088
+ useExisting: forwardRef(() => CheckboxComponent),
1089
+ multi: true
1090
+ }], ngImport: i0, template: "<label\n [for]=\"checkboxId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <!-- Checkbox input -->\n <input\n type=\"checkbox\"\n [id]=\"checkboxId()\"\n [name]=\"name()\"\n [checked]=\"internalChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? checkboxId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-checkbox__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <!-- Custom checkbox -->\n <span [ngClass]=\"checkboxClasses()\">\n <!-- Checkmark icon -->\n @if (internalChecked() && !indeterminate()) {\n <svg\n class=\"studio-checkbox__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M13.3333 4L6 11.3333L2.66666 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n\n <!-- Indeterminate icon -->\n @if (indeterminate()) {\n <svg\n class=\"studio-checkbox__icon studio-checkbox__icon--indeterminate\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 8H12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n </span>\n\n <!-- Label content -->\n @if (label() || description()) {\n <span class=\"studio-checkbox__label-wrapper\">\n @if (label()) {\n <span class=\"studio-checkbox__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-checkbox__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-checkbox__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n<!-- Helper text / Error message -->\n@if (showHint() || showError()) {\n <div\n [id]=\"checkboxId() + '-description'\"\n class=\"studio-checkbox__info\"\n >\n @if (showError()) {\n <span class=\"studio-checkbox__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-checkbox__hint\">\n {{ hint() }}\n </span>\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-direction:column;font-family:var(--studio-font-family)!important}.studio-checkbox-wrapper{display:inline-flex;align-items:flex-start;gap:var(--studio-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.studio-checkbox-wrapper--label-left{flex-direction:row-reverse}.studio-checkbox-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-checkbox-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-checkbox-wrapper--md{font-size:var(--studio-font-size-base)}.studio-checkbox-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-checkbox__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-checkbox{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border:2px solid var(--studio-border-primary);background-color:var(--studio-bg-primary);transition:all var(--studio-transition-base)}.studio-checkbox--sm{width:1rem;height:1rem}.studio-checkbox--md{width:1.25rem;height:1.25rem}.studio-checkbox--lg{width:1.5rem;height:1.5rem}.studio-checkbox--radius-none{border-radius:0}.studio-checkbox--radius-sm{border-radius:var(--studio-radius-sm)}.studio-checkbox--radius-md{border-radius:var(--studio-radius-md)}.studio-checkbox--radius-lg{border-radius:var(--studio-radius-lg)}.studio-checkbox--radius-full{border-radius:var(--studio-radius-full)}.studio-checkbox--default.studio-checkbox--checked,.studio-checkbox--default.studio-checkbox--indeterminate{border-color:transparent}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--outlined.studio-checkbox--checked,.studio-checkbox--outlined.studio-checkbox--indeterminate{background-color:transparent}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--primary{border-color:var(--studio-primary);color:var(--studio-primary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--secondary{border-color:var(--studio-secondary);color:var(--studio-secondary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--success{border-color:var(--studio-success);color:var(--studio-success)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--error{border-color:var(--studio-error);color:var(--studio-error)}.studio-checkbox--filled.studio-checkbox--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-checkbox--filled.studio-checkbox--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-checkbox--filled.studio-checkbox--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-checkbox--filled.studio-checkbox--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);border-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);border-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);border-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--error:not(.studio-checkbox--checked):not(.studio-checkbox--indeterminate){border-color:var(--studio-error)}.studio-checkbox:hover:not(.studio-checkbox--disabled){border-color:var(--studio-border-secondary)}.studio-checkbox__input:focus-visible+.studio-checkbox{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-checkbox__icon{width:100%;height:100%;opacity:0;transform:scale(.8);transition:all var(--studio-transition-fast)}.studio-checkbox--checked .studio-checkbox__icon,.studio-checkbox--indeterminate .studio-checkbox__icon{opacity:1;transform:scale(1)}.studio-checkbox__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-checkbox__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-checkbox__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-checkbox__info{display:flex;flex-direction:column;gap:var(--studio-spacing-xs);margin-top:var(--studio-spacing-xs);padding-left:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--label-left+.studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--sm .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--sm.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--lg .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox-wrapper--lg.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__error{font-size:var(--studio-font-size-xs);color:var(--studio-error);line-height:var(--studio-line-height-normal)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1091
+ }
1092
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: CheckboxComponent, decorators: [{
1093
+ type: Component,
1094
+ args: [{ selector: 'studio-checkbox', standalone: true, imports: [CommonModule], providers: [{
1095
+ provide: NG_VALUE_ACCESSOR,
1096
+ useExisting: forwardRef(() => CheckboxComponent),
1097
+ multi: true
1098
+ }], host: {
1099
+ '[class]': 'hostClasses()',
1100
+ '[attr.data-size]': 'size()',
1101
+ '[attr.data-color]': 'color()',
1102
+ '[attr.data-disabled]': 'disabled()',
1103
+ '[attr.data-error]': 'error()'
1104
+ }, template: "<label\n [for]=\"checkboxId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <!-- Checkbox input -->\n <input\n type=\"checkbox\"\n [id]=\"checkboxId()\"\n [name]=\"name()\"\n [checked]=\"internalChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? checkboxId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-checkbox__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <!-- Custom checkbox -->\n <span [ngClass]=\"checkboxClasses()\">\n <!-- Checkmark icon -->\n @if (internalChecked() && !indeterminate()) {\n <svg\n class=\"studio-checkbox__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M13.3333 4L6 11.3333L2.66666 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n\n <!-- Indeterminate icon -->\n @if (indeterminate()) {\n <svg\n class=\"studio-checkbox__icon studio-checkbox__icon--indeterminate\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 8H12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n </span>\n\n <!-- Label content -->\n @if (label() || description()) {\n <span class=\"studio-checkbox__label-wrapper\">\n @if (label()) {\n <span class=\"studio-checkbox__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-checkbox__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-checkbox__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n<!-- Helper text / Error message -->\n@if (showHint() || showError()) {\n <div\n [id]=\"checkboxId() + '-description'\"\n class=\"studio-checkbox__info\"\n >\n @if (showError()) {\n <span class=\"studio-checkbox__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-checkbox__hint\">\n {{ hint() }}\n </span>\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-direction:column;font-family:var(--studio-font-family)!important}.studio-checkbox-wrapper{display:inline-flex;align-items:flex-start;gap:var(--studio-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.studio-checkbox-wrapper--label-left{flex-direction:row-reverse}.studio-checkbox-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-checkbox-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-checkbox-wrapper--md{font-size:var(--studio-font-size-base)}.studio-checkbox-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-checkbox__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-checkbox{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border:2px solid var(--studio-border-primary);background-color:var(--studio-bg-primary);transition:all var(--studio-transition-base)}.studio-checkbox--sm{width:1rem;height:1rem}.studio-checkbox--md{width:1.25rem;height:1.25rem}.studio-checkbox--lg{width:1.5rem;height:1.5rem}.studio-checkbox--radius-none{border-radius:0}.studio-checkbox--radius-sm{border-radius:var(--studio-radius-sm)}.studio-checkbox--radius-md{border-radius:var(--studio-radius-md)}.studio-checkbox--radius-lg{border-radius:var(--studio-radius-lg)}.studio-checkbox--radius-full{border-radius:var(--studio-radius-full)}.studio-checkbox--default.studio-checkbox--checked,.studio-checkbox--default.studio-checkbox--indeterminate{border-color:transparent}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--outlined.studio-checkbox--checked,.studio-checkbox--outlined.studio-checkbox--indeterminate{background-color:transparent}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--primary{border-color:var(--studio-primary);color:var(--studio-primary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--secondary{border-color:var(--studio-secondary);color:var(--studio-secondary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--success{border-color:var(--studio-success);color:var(--studio-success)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--error{border-color:var(--studio-error);color:var(--studio-error)}.studio-checkbox--filled.studio-checkbox--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-checkbox--filled.studio-checkbox--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-checkbox--filled.studio-checkbox--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-checkbox--filled.studio-checkbox--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);border-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);border-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);border-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--error:not(.studio-checkbox--checked):not(.studio-checkbox--indeterminate){border-color:var(--studio-error)}.studio-checkbox:hover:not(.studio-checkbox--disabled){border-color:var(--studio-border-secondary)}.studio-checkbox__input:focus-visible+.studio-checkbox{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-checkbox__icon{width:100%;height:100%;opacity:0;transform:scale(.8);transition:all var(--studio-transition-fast)}.studio-checkbox--checked .studio-checkbox__icon,.studio-checkbox--indeterminate .studio-checkbox__icon{opacity:1;transform:scale(1)}.studio-checkbox__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-checkbox__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-checkbox__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-checkbox__info{display:flex;flex-direction:column;gap:var(--studio-spacing-xs);margin-top:var(--studio-spacing-xs);padding-left:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--label-left+.studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--sm .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--sm.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--lg .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox-wrapper--lg.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__error{font-size:var(--studio-font-size-xs);color:var(--studio-error);line-height:var(--studio-line-height-normal)}\n"] }]
1105
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
1106
+
871
1107
  /**
872
1108
  * Input component with form control support, variants, and accessibility
873
1109
  *
@@ -1138,6 +1374,355 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1138
1374
  * Switch component
1139
1375
  */
1140
1376
 
1377
+ /**
1378
+ * Textarea component for multi-line text input
1379
+ *
1380
+ * @example
1381
+ * <studio-textarea
1382
+ * [(ngModel)]="message"
1383
+ * label="Your message"
1384
+ * placeholder="Enter your message..."
1385
+ * [rows]="4"
1386
+ * />
1387
+ */
1388
+ class TextareaComponent {
1389
+ configService = inject(StudioConfigService);
1390
+ textareaDefaults = computed(() => this.configService.config().components?.textarea, ...(ngDevMode ? [{ debugName: "textareaDefaults" }] : []));
1391
+ variant = input(this.textareaDefaults()?.variant ?? 'outline', ...(ngDevMode ? [{ debugName: "variant" }] : []));
1392
+ size = input(this.textareaDefaults()?.size ?? 'md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1393
+ color = input(this.textareaDefaults()?.color ?? 'primary', ...(ngDevMode ? [{ debugName: "color" }] : []));
1394
+ radius = input(this.textareaDefaults()?.radius ?? 'md', ...(ngDevMode ? [{ debugName: "radius" }] : []));
1395
+ // ==========================================
1396
+ // INPUTS - Labels & Description
1397
+ // ==========================================
1398
+ /**
1399
+ * Label text
1400
+ */
1401
+ label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
1402
+ /**
1403
+ * Floating label (moves up when focused/filled)
1404
+ */
1405
+ floatingLabel = input(false, ...(ngDevMode ? [{ debugName: "floatingLabel" }] : []));
1406
+ /**
1407
+ * Placeholder text
1408
+ */
1409
+ placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : []));
1410
+ /**
1411
+ * Helper text
1412
+ */
1413
+ hint = input(...(ngDevMode ? [undefined, { debugName: "hint" }] : []));
1414
+ // ==========================================
1415
+ // INPUTS - Textarea Specific
1416
+ // ==========================================
1417
+ /**
1418
+ * Number of visible text rows
1419
+ */
1420
+ rows = input(this.textareaDefaults()?.rows ?? 3, ...(ngDevMode ? [{ debugName: "rows" }] : []));
1421
+ /**
1422
+ * Minimum rows for auto-resize
1423
+ */
1424
+ minRows = input(...(ngDevMode ? [undefined, { debugName: "minRows" }] : []));
1425
+ /**
1426
+ * Maximum rows for auto-resize
1427
+ */
1428
+ maxRows = input(...(ngDevMode ? [undefined, { debugName: "maxRows" }] : []));
1429
+ /**
1430
+ * Enable auto-resize based on content
1431
+ */
1432
+ autoResize = input(this.textareaDefaults()?.autoResize ?? false, ...(ngDevMode ? [{ debugName: "autoResize" }] : []));
1433
+ /**
1434
+ * Resize behavior
1435
+ */
1436
+ resize = input(this.textareaDefaults()?.resize ?? 'vertical', ...(ngDevMode ? [{ debugName: "resize" }] : []));
1437
+ // ==========================================
1438
+ // INPUTS - Character Count
1439
+ // ==========================================
1440
+ /**
1441
+ * Maximum character length
1442
+ */
1443
+ maxLength = input(...(ngDevMode ? [undefined, { debugName: "maxLength" }] : []));
1444
+ /**
1445
+ * Show character counter
1446
+ */
1447
+ showCharCount = input(this.textareaDefaults()?.showCharCount ?? false, ...(ngDevMode ? [{ debugName: "showCharCount" }] : []));
1448
+ /**
1449
+ * Character counter position
1450
+ */
1451
+ charCountPosition = input('bottom-right', ...(ngDevMode ? [{ debugName: "charCountPosition" }] : []));
1452
+ // ==========================================
1453
+ // INPUTS - Validation
1454
+ // ==========================================
1455
+ /**
1456
+ * Required field
1457
+ */
1458
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
1459
+ /**
1460
+ * Minimum character length
1461
+ */
1462
+ minLength = input(...(ngDevMode ? [undefined, { debugName: "minLength" }] : []));
1463
+ /**
1464
+ * Error state
1465
+ */
1466
+ error = input(false, ...(ngDevMode ? [{ debugName: "error" }] : []));
1467
+ /**
1468
+ * Error message
1469
+ */
1470
+ errorMessage = input(...(ngDevMode ? [undefined, { debugName: "errorMessage" }] : []));
1471
+ // ==========================================
1472
+ // INPUTS - Behavior
1473
+ // ==========================================
1474
+ /**
1475
+ * Disabled state
1476
+ */
1477
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1478
+ /**
1479
+ * Readonly state
1480
+ */
1481
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
1482
+ /**
1483
+ * Full width (100% of parent)
1484
+ */
1485
+ fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
1486
+ /**
1487
+ * Name attribute for form control
1488
+ */
1489
+ name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
1490
+ /**
1491
+ * Autocomplete attribute
1492
+ */
1493
+ autocomplete = input(...(ngDevMode ? [undefined, { debugName: "autocomplete" }] : []));
1494
+ /**
1495
+ * Spellcheck attribute
1496
+ */
1497
+ spellcheck = input(true, ...(ngDevMode ? [{ debugName: "spellcheck" }] : []));
1498
+ /**
1499
+ * Show clear button
1500
+ */
1501
+ clearable = input(this.textareaDefaults()?.clearable ?? false, ...(ngDevMode ? [{ debugName: "clearable" }] : []));
1502
+ /**
1503
+ * Loading state
1504
+ */
1505
+ loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1506
+ // ==========================================
1507
+ // OUTPUTS
1508
+ // ==========================================
1509
+ /**
1510
+ * Emitted when value changes
1511
+ */
1512
+ changed = output();
1513
+ /**
1514
+ * Emitted on focus
1515
+ */
1516
+ focused = output();
1517
+ /**
1518
+ * Emitted on blur
1519
+ */
1520
+ blurred = output();
1521
+ /**
1522
+ * Emitted on key press
1523
+ */
1524
+ keyPressed = output();
1525
+ // ==========================================
1526
+ // STATE
1527
+ // ==========================================
1528
+ /**
1529
+ * Internal value
1530
+ */
1531
+ internalValue = signal('', ...(ngDevMode ? [{ debugName: "internalValue" }] : []));
1532
+ /**
1533
+ * Internal focus state
1534
+ */
1535
+ isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
1536
+ /**
1537
+ * Unique ID for accessibility
1538
+ */
1539
+ textareaId = signal(`studio-textarea-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "textareaId" }] : []));
1540
+ /**
1541
+ * Textarea element reference
1542
+ */
1543
+ textareaEl = viewChild('textarea', ...(ngDevMode ? [{ debugName: "textareaEl" }] : []));
1544
+ // ==========================================
1545
+ // COMPUTED
1546
+ // ==========================================
1547
+ hostClasses = computed(() => classNames('studio-textarea-wrapper', `studio-textarea-wrapper--${this.size()}`, `studio-textarea-wrapper--${this.variant()}`, this.disabled() && 'studio-textarea-wrapper--disabled', this.error() && 'studio-textarea-wrapper--error', this.isFocused() && 'studio-textarea-wrapper--focused', this.fullWidth() && 'studio-textarea-wrapper--full-width', this.floatingLabel() && 'studio-textarea-wrapper--floating-label'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
1548
+ /**
1549
+ * Textarea element CSS classes
1550
+ */
1551
+ textareaClasses = computed(() => classNames('studio-textarea', `studio-textarea--${this.size()}`, `studio-textarea--${this.variant()}`, `studio-textarea--${this.color()}`, `studio-textarea--radius-${this.radius()}`, `studio-textarea--resize-${this.resize()}`, this.disabled() && 'studio-textarea--disabled', this.readonly() && 'studio-textarea--readonly', this.error() && 'studio-textarea--error', this.internalValue().length > 0 && 'studio-textarea--has-value', this.autoResize() && 'studio-textarea--auto-resize'), ...(ngDevMode ? [{ debugName: "textareaClasses" }] : []));
1552
+ /**
1553
+ * Show error message
1554
+ */
1555
+ showError = computed(() => this.error() && this.errorMessage(), ...(ngDevMode ? [{ debugName: "showError" }] : []));
1556
+ /**
1557
+ * Show hint
1558
+ */
1559
+ showHint = computed(() => !this.error() && this.hint(), ...(ngDevMode ? [{ debugName: "showHint" }] : []));
1560
+ /**
1561
+ * Character count text
1562
+ */
1563
+ charCountText = computed(() => {
1564
+ const length = this.internalValue().length;
1565
+ const max = this.maxLength();
1566
+ return max ? `${length}/${max}` : `${length}`;
1567
+ }, ...(ngDevMode ? [{ debugName: "charCountText" }] : []));
1568
+ /**
1569
+ * Is character limit exceeded
1570
+ */
1571
+ isCharLimitExceeded = computed(() => {
1572
+ const max = this.maxLength();
1573
+ return max ? this.internalValue().length > max : false;
1574
+ }, ...(ngDevMode ? [{ debugName: "isCharLimitExceeded" }] : []));
1575
+ /**
1576
+ * Computed placeholder (empty if floating label)
1577
+ */
1578
+ computedPlaceholder = computed(() => {
1579
+ if (this.floatingLabel()) {
1580
+ return '';
1581
+ }
1582
+ return this.placeholder();
1583
+ }, ...(ngDevMode ? [{ debugName: "computedPlaceholder" }] : []));
1584
+ /**
1585
+ * Show floating label in "up" position
1586
+ */
1587
+ showFloatingLabelUp = computed(() => {
1588
+ return this.floatingLabel() && (this.isFocused() || this.internalValue().length > 0);
1589
+ }, ...(ngDevMode ? [{ debugName: "showFloatingLabelUp" }] : []));
1590
+ // ==========================================
1591
+ // CONTROL VALUE ACCESSOR
1592
+ // ==========================================
1593
+ onChange = () => { };
1594
+ onTouched = () => { };
1595
+ writeValue(value) {
1596
+ this.internalValue.set(value ?? '');
1597
+ this.adjustHeightIfNeeded();
1598
+ }
1599
+ registerOnChange(fn) {
1600
+ this.onChange = fn;
1601
+ }
1602
+ registerOnTouched(fn) {
1603
+ this.onTouched = fn;
1604
+ }
1605
+ setDisabledState(isDisabled) {
1606
+ // Disabled state is controlled via input
1607
+ }
1608
+ // ==========================================
1609
+ // CONSTRUCTOR & EFFECTS
1610
+ // ==========================================
1611
+ constructor() {
1612
+ // Auto-resize effect
1613
+ effect(() => {
1614
+ if (this.autoResize()) {
1615
+ this.adjustHeightIfNeeded();
1616
+ }
1617
+ });
1618
+ }
1619
+ // ==========================================
1620
+ // METHODS
1621
+ // ==========================================
1622
+ /**
1623
+ * Handle textarea input
1624
+ */
1625
+ handleInput(event) {
1626
+ if (this.disabled() || this.readonly()) {
1627
+ return;
1628
+ }
1629
+ const newValue = event.target.value;
1630
+ this.internalValue.set(newValue);
1631
+ this.onChange(newValue);
1632
+ this.changed.emit(newValue);
1633
+ if (this.autoResize()) {
1634
+ this.adjustHeight(event.target);
1635
+ }
1636
+ }
1637
+ /**
1638
+ * Handle focus
1639
+ */
1640
+ handleFocus(event) {
1641
+ this.isFocused.set(true);
1642
+ this.focused.emit(event);
1643
+ }
1644
+ /**
1645
+ * Handle blur
1646
+ */
1647
+ handleBlur(event) {
1648
+ this.isFocused.set(false);
1649
+ this.onTouched();
1650
+ this.blurred.emit(event);
1651
+ }
1652
+ /**
1653
+ * Handle key press
1654
+ */
1655
+ handleKeyPress(event) {
1656
+ this.keyPressed.emit(event);
1657
+ }
1658
+ /**
1659
+ * Clear textarea value
1660
+ */
1661
+ handleClear() {
1662
+ if (this.disabled() || this.readonly()) {
1663
+ return;
1664
+ }
1665
+ this.internalValue.set('');
1666
+ this.onChange('');
1667
+ this.changed.emit('');
1668
+ // Focus textarea after clearing
1669
+ this.textareaEl()?.nativeElement.focus();
1670
+ }
1671
+ /**
1672
+ * Adjust textarea height for auto-resize
1673
+ */
1674
+ adjustHeightIfNeeded() {
1675
+ if (this.autoResize()) {
1676
+ setTimeout(() => {
1677
+ const textarea = this.textareaEl()?.nativeElement;
1678
+ if (textarea) {
1679
+ this.adjustHeight(textarea);
1680
+ }
1681
+ });
1682
+ }
1683
+ }
1684
+ /**
1685
+ * Adjust textarea height based on content
1686
+ */
1687
+ adjustHeight(textarea) {
1688
+ // Reset height to auto to get proper scrollHeight
1689
+ textarea.style.height = 'auto';
1690
+ const minRows = this.minRows() ?? this.rows();
1691
+ const maxRows = this.maxRows();
1692
+ // Calculate line height
1693
+ const lineHeight = parseInt(getComputedStyle(textarea).lineHeight);
1694
+ const padding = parseInt(getComputedStyle(textarea).paddingTop) +
1695
+ parseInt(getComputedStyle(textarea).paddingBottom);
1696
+ // Calculate min and max heights
1697
+ const minHeight = minRows * lineHeight + padding;
1698
+ const maxHeight = maxRows ? maxRows * lineHeight + padding : Infinity;
1699
+ // Set new height within bounds
1700
+ const newHeight = Math.max(minHeight, Math.min(textarea.scrollHeight, maxHeight));
1701
+ textarea.style.height = `${newHeight}px`;
1702
+ }
1703
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: TextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1704
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: TextareaComponent, isStandalone: true, selector: "studio-textarea", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, floatingLabel: { classPropertyName: "floatingLabel", publicName: "floatingLabel", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, minRows: { classPropertyName: "minRows", publicName: "minRows", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, autoResize: { classPropertyName: "autoResize", publicName: "autoResize", isSignal: true, isRequired: false, transformFunction: null }, resize: { classPropertyName: "resize", publicName: "resize", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, showCharCount: { classPropertyName: "showCharCount", publicName: "showCharCount", isSignal: true, isRequired: false, transformFunction: null }, charCountPosition: { classPropertyName: "charCountPosition", publicName: "charCountPosition", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, spellcheck: { classPropertyName: "spellcheck", publicName: "spellcheck", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed", focused: "focused", blurred: "blurred", keyPressed: "keyPressed" }, host: { properties: { "class": "hostClasses()", "attr.data-size": "size()", "attr.data-variant": "variant()", "attr.data-disabled": "disabled()", "attr.data-error": "error()", "attr.data-full-width": "fullWidth()" } }, providers: [{
1705
+ provide: NG_VALUE_ACCESSOR,
1706
+ useExisting: forwardRef(() => TextareaComponent),
1707
+ multi: true
1708
+ }], viewQueries: [{ propertyName: "textareaEl", first: true, predicate: ["textarea"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"studio-textarea-container\">\n <!-- Label (static or floating) -->\n @if (label() && !floatingLabel()) {\n <label\n [for]=\"textareaId()\"\n class=\"studio-textarea-label\"\n [class.studio-textarea-label--required]=\"required()\"\n >\n {{ label() }}\n @if (required()) {\n <span class=\"studio-textarea-label__required\">*</span>\n }\n </label>\n }\n\n <!-- Textarea wrapper -->\n <div class=\"studio-textarea-input-wrapper\">\n <!-- Floating label -->\n @if (floatingLabel() && label()) {\n <label\n [for]=\"textareaId()\"\n class=\"studio-textarea-label studio-textarea-label--floating\"\n [class.studio-textarea-label--floating-up]=\"showFloatingLabelUp()\"\n [class.studio-textarea-label--required]=\"required()\"\n >\n {{ label() }}\n @if (required()) {\n <span class=\"studio-textarea-label__required\">*</span>\n }\n </label>\n }\n\n <!-- Textarea element -->\n <textarea\n #textarea\n [id]=\"textareaId()\"\n [class]=\"textareaClasses()\"\n [value]=\"internalValue()\"\n [placeholder]=\"computedPlaceholder()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [rows]=\"rows()\"\n [attr.maxlength]=\"maxLength()\"\n [attr.minlength]=\"minLength()\"\n [required]=\"required()\"\n [name]=\"name()\"\n [autocomplete]=\"autocomplete()\"\n [spellcheck]=\"spellcheck()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-describedby]=\"showHint() || showError() ? textareaId() + '-description' : undefined\"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\"\n (keypress)=\"handleKeyPress($event)\"\n ></textarea>\n\n <!-- Clear button -->\n @if (clearable() && internalValue().length > 0 && !disabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"studio-textarea-clear\"\n [attr.aria-label]=\"'Clear textarea'\"\n (click)=\"handleClear()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n\n <!-- Loading indicator -->\n @if (loading()) {\n <div class=\"studio-textarea-loading\">\n <svg\n class=\"studio-textarea-spinner\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n class=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n ></circle>\n <path\n class=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n </div>\n }\n\n <!-- Character counter -->\n @if (showCharCount()) {\n <div\n class=\"studio-textarea-char-count\"\n [class.studio-textarea-char-count--exceeded]=\"isCharLimitExceeded()\"\n [attr.data-position]=\"charCountPosition()\"\n >\n {{ charCountText() }}\n </div>\n }\n </div>\n\n <!-- Helper text / Error message -->\n @if (showError()) {\n <div\n class=\"studio-textarea-message studio-textarea-message--error\"\n [id]=\"textareaId() + '-description'\"\n role=\"alert\"\n >\n {{ errorMessage() }}\n </div>\n } @else if (showHint()) {\n <div\n class=\"studio-textarea-message studio-textarea-message--hint\"\n [id]=\"textareaId() + '-description'\"\n >\n {{ hint() }}\n </div>\n }\n</div>\n", styles: [":host{display:flex;flex-direction:column;gap:.375rem;font-family:var(--studio-font-family)}:host(.studio-textarea-wrapper--full-width){width:100%}.studio-textarea-label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);margin-bottom:.25rem}.studio-textarea-label__required{color:var(--studio-error);margin-left:.125rem}.studio-textarea-label--floating{position:absolute;top:.75rem;left:.75rem;pointer-events:none;background:transparent;padding:0 .25rem;z-index:1;transition:all .2s ease}.studio-textarea-label--floating-up{top:-.5rem;font-size:.75rem;background:var(--studio-background);color:var(--studio-primary)}.studio-textarea-input-wrapper{position:relative;display:flex;flex-direction:column;transition:all var(--studio-transition-fast)}.studio-textarea{width:100%;padding:.75rem;font-size:1rem;font-family:inherit;color:var(--studio-text-primary);background:transparent;border:none;outline:none;resize:vertical;transition:all var(--studio-transition-fast)}.studio-textarea::placeholder{color:var(--studio-text-tertiary)}.studio-textarea:disabled{cursor:not-allowed;opacity:.6}.studio-textarea:read-only{cursor:default}.studio-textarea-clear,.studio-textarea-loading{position:absolute;top:.5rem;right:.5rem;display:flex;align-items:center;justify-content:center}.studio-textarea-clear{padding:.25rem;background:none;border:none;color:var(--studio-text-secondary);cursor:pointer;border-radius:var(--studio-radius-sm);transition:all var(--studio-transition-fast)}.studio-textarea-clear:hover{background:var(--studio-background-hover);color:var(--studio-text-primary)}.studio-textarea-clear svg{width:1rem;height:1rem}.studio-textarea-spinner{width:1rem;height:1rem;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-textarea-char-count{position:absolute;bottom:.5rem;font-size:.75rem;color:var(--studio-text-muted);pointer-events:none}.studio-textarea-char-count[data-position=bottom-right]{right:.75rem}.studio-textarea-char-count[data-position=bottom-left]{left:.75rem}.studio-textarea-char-count--exceeded{color:var(--studio-error);font-weight:500}.studio-textarea-message{font-size:.75rem;line-height:1.4}.studio-textarea-message--hint{color:var(--studio-text-secondary)}.studio-textarea-message--error{color:var(--studio-error)}:host(.studio-textarea-wrapper--outline) .studio-textarea-input-wrapper{border:1px solid var(--studio-border-primary);background:var(--studio-bg-primary);border-radius:var(--studio-radius-md)}:host(.studio-textarea-wrapper--outline) .studio-textarea-input-wrapper:hover:not(:has(.studio-textarea:disabled)){border-color:var(--studio-primary)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--focused) .studio-textarea-input-wrapper{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--error) .studio-textarea-input-wrapper{border-color:var(--studio-error)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--error) .studio-textarea-input-wrapper:hover{border-color:var(--studio-error)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--disabled) .studio-textarea-input-wrapper{background:var(--studio-bg-secondary);border-color:var(--studio-border-secondary)}:host(.studio-textarea-wrapper--filled) .studio-textarea-input-wrapper{background:var(--studio-bg-secondary);border:none;border-bottom:2px solid var(--studio-border-primary);border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-textarea-wrapper--filled) .studio-textarea-input-wrapper:hover:not(:has(.studio-textarea:disabled)){background:var(--studio-bg-tertiary)}:host(.studio-textarea-wrapper--filled.studio-textarea-wrapper--focused) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-primary);background:var(--studio-bg-tertiary)}:host(.studio-textarea-wrapper--filled.studio-textarea-wrapper--error) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-error)}:host(.studio-textarea-wrapper--filled.studio-textarea-wrapper--disabled) .studio-textarea-input-wrapper{background:var(--studio-bg-secondary);opacity:.6}:host(.studio-textarea-wrapper--underline) .studio-textarea-input-wrapper{background:transparent;border:none;border-bottom:2px solid var(--studio-border-primary);border-radius:0}:host(.studio-textarea-wrapper--underline) .studio-textarea-input-wrapper .studio-textarea{padding-left:0;padding-right:0}:host(.studio-textarea-wrapper--underline) .studio-textarea-input-wrapper:hover:not(:has(.studio-textarea:disabled)){border-bottom-color:var(--studio-primary)}:host(.studio-textarea-wrapper--underline.studio-textarea-wrapper--focused) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-primary)}:host(.studio-textarea-wrapper--underline.studio-textarea-wrapper--error) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-error)}:host(.studio-textarea-wrapper--sm) .studio-textarea{padding:.5rem .75rem;font-size:.875rem}:host(.studio-textarea-wrapper--md) .studio-textarea{padding:.75rem;font-size:1rem}:host(.studio-textarea-wrapper--lg) .studio-textarea{padding:1rem;font-size:1.125rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
1709
+ }
1710
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: TextareaComponent, decorators: [{
1711
+ type: Component,
1712
+ args: [{ selector: 'studio-textarea', standalone: true, imports: [CommonModule], providers: [{
1713
+ provide: NG_VALUE_ACCESSOR,
1714
+ useExisting: forwardRef(() => TextareaComponent),
1715
+ multi: true
1716
+ }], host: {
1717
+ '[class]': 'hostClasses()',
1718
+ '[attr.data-size]': 'size()',
1719
+ '[attr.data-variant]': 'variant()',
1720
+ '[attr.data-disabled]': 'disabled()',
1721
+ '[attr.data-error]': 'error()',
1722
+ '[attr.data-full-width]': 'fullWidth()'
1723
+ }, template: "<div class=\"studio-textarea-container\">\n <!-- Label (static or floating) -->\n @if (label() && !floatingLabel()) {\n <label\n [for]=\"textareaId()\"\n class=\"studio-textarea-label\"\n [class.studio-textarea-label--required]=\"required()\"\n >\n {{ label() }}\n @if (required()) {\n <span class=\"studio-textarea-label__required\">*</span>\n }\n </label>\n }\n\n <!-- Textarea wrapper -->\n <div class=\"studio-textarea-input-wrapper\">\n <!-- Floating label -->\n @if (floatingLabel() && label()) {\n <label\n [for]=\"textareaId()\"\n class=\"studio-textarea-label studio-textarea-label--floating\"\n [class.studio-textarea-label--floating-up]=\"showFloatingLabelUp()\"\n [class.studio-textarea-label--required]=\"required()\"\n >\n {{ label() }}\n @if (required()) {\n <span class=\"studio-textarea-label__required\">*</span>\n }\n </label>\n }\n\n <!-- Textarea element -->\n <textarea\n #textarea\n [id]=\"textareaId()\"\n [class]=\"textareaClasses()\"\n [value]=\"internalValue()\"\n [placeholder]=\"computedPlaceholder()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [rows]=\"rows()\"\n [attr.maxlength]=\"maxLength()\"\n [attr.minlength]=\"minLength()\"\n [required]=\"required()\"\n [name]=\"name()\"\n [autocomplete]=\"autocomplete()\"\n [spellcheck]=\"spellcheck()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-describedby]=\"showHint() || showError() ? textareaId() + '-description' : undefined\"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\"\n (keypress)=\"handleKeyPress($event)\"\n ></textarea>\n\n <!-- Clear button -->\n @if (clearable() && internalValue().length > 0 && !disabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"studio-textarea-clear\"\n [attr.aria-label]=\"'Clear textarea'\"\n (click)=\"handleClear()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n\n <!-- Loading indicator -->\n @if (loading()) {\n <div class=\"studio-textarea-loading\">\n <svg\n class=\"studio-textarea-spinner\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n class=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n ></circle>\n <path\n class=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n </div>\n }\n\n <!-- Character counter -->\n @if (showCharCount()) {\n <div\n class=\"studio-textarea-char-count\"\n [class.studio-textarea-char-count--exceeded]=\"isCharLimitExceeded()\"\n [attr.data-position]=\"charCountPosition()\"\n >\n {{ charCountText() }}\n </div>\n }\n </div>\n\n <!-- Helper text / Error message -->\n @if (showError()) {\n <div\n class=\"studio-textarea-message studio-textarea-message--error\"\n [id]=\"textareaId() + '-description'\"\n role=\"alert\"\n >\n {{ errorMessage() }}\n </div>\n } @else if (showHint()) {\n <div\n class=\"studio-textarea-message studio-textarea-message--hint\"\n [id]=\"textareaId() + '-description'\"\n >\n {{ hint() }}\n </div>\n }\n</div>\n", styles: [":host{display:flex;flex-direction:column;gap:.375rem;font-family:var(--studio-font-family)}:host(.studio-textarea-wrapper--full-width){width:100%}.studio-textarea-label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);margin-bottom:.25rem}.studio-textarea-label__required{color:var(--studio-error);margin-left:.125rem}.studio-textarea-label--floating{position:absolute;top:.75rem;left:.75rem;pointer-events:none;background:transparent;padding:0 .25rem;z-index:1;transition:all .2s ease}.studio-textarea-label--floating-up{top:-.5rem;font-size:.75rem;background:var(--studio-background);color:var(--studio-primary)}.studio-textarea-input-wrapper{position:relative;display:flex;flex-direction:column;transition:all var(--studio-transition-fast)}.studio-textarea{width:100%;padding:.75rem;font-size:1rem;font-family:inherit;color:var(--studio-text-primary);background:transparent;border:none;outline:none;resize:vertical;transition:all var(--studio-transition-fast)}.studio-textarea::placeholder{color:var(--studio-text-tertiary)}.studio-textarea:disabled{cursor:not-allowed;opacity:.6}.studio-textarea:read-only{cursor:default}.studio-textarea-clear,.studio-textarea-loading{position:absolute;top:.5rem;right:.5rem;display:flex;align-items:center;justify-content:center}.studio-textarea-clear{padding:.25rem;background:none;border:none;color:var(--studio-text-secondary);cursor:pointer;border-radius:var(--studio-radius-sm);transition:all var(--studio-transition-fast)}.studio-textarea-clear:hover{background:var(--studio-background-hover);color:var(--studio-text-primary)}.studio-textarea-clear svg{width:1rem;height:1rem}.studio-textarea-spinner{width:1rem;height:1rem;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-textarea-char-count{position:absolute;bottom:.5rem;font-size:.75rem;color:var(--studio-text-muted);pointer-events:none}.studio-textarea-char-count[data-position=bottom-right]{right:.75rem}.studio-textarea-char-count[data-position=bottom-left]{left:.75rem}.studio-textarea-char-count--exceeded{color:var(--studio-error);font-weight:500}.studio-textarea-message{font-size:.75rem;line-height:1.4}.studio-textarea-message--hint{color:var(--studio-text-secondary)}.studio-textarea-message--error{color:var(--studio-error)}:host(.studio-textarea-wrapper--outline) .studio-textarea-input-wrapper{border:1px solid var(--studio-border-primary);background:var(--studio-bg-primary);border-radius:var(--studio-radius-md)}:host(.studio-textarea-wrapper--outline) .studio-textarea-input-wrapper:hover:not(:has(.studio-textarea:disabled)){border-color:var(--studio-primary)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--focused) .studio-textarea-input-wrapper{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--error) .studio-textarea-input-wrapper{border-color:var(--studio-error)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--error) .studio-textarea-input-wrapper:hover{border-color:var(--studio-error)}:host(.studio-textarea-wrapper--outline.studio-textarea-wrapper--disabled) .studio-textarea-input-wrapper{background:var(--studio-bg-secondary);border-color:var(--studio-border-secondary)}:host(.studio-textarea-wrapper--filled) .studio-textarea-input-wrapper{background:var(--studio-bg-secondary);border:none;border-bottom:2px solid var(--studio-border-primary);border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-textarea-wrapper--filled) .studio-textarea-input-wrapper:hover:not(:has(.studio-textarea:disabled)){background:var(--studio-bg-tertiary)}:host(.studio-textarea-wrapper--filled.studio-textarea-wrapper--focused) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-primary);background:var(--studio-bg-tertiary)}:host(.studio-textarea-wrapper--filled.studio-textarea-wrapper--error) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-error)}:host(.studio-textarea-wrapper--filled.studio-textarea-wrapper--disabled) .studio-textarea-input-wrapper{background:var(--studio-bg-secondary);opacity:.6}:host(.studio-textarea-wrapper--underline) .studio-textarea-input-wrapper{background:transparent;border:none;border-bottom:2px solid var(--studio-border-primary);border-radius:0}:host(.studio-textarea-wrapper--underline) .studio-textarea-input-wrapper .studio-textarea{padding-left:0;padding-right:0}:host(.studio-textarea-wrapper--underline) .studio-textarea-input-wrapper:hover:not(:has(.studio-textarea:disabled)){border-bottom-color:var(--studio-primary)}:host(.studio-textarea-wrapper--underline.studio-textarea-wrapper--focused) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-primary)}:host(.studio-textarea-wrapper--underline.studio-textarea-wrapper--error) .studio-textarea-input-wrapper{border-bottom-color:var(--studio-error)}:host(.studio-textarea-wrapper--sm) .studio-textarea{padding:.5rem .75rem;font-size:.875rem}:host(.studio-textarea-wrapper--md) .studio-textarea{padding:.75rem;font-size:1rem}:host(.studio-textarea-wrapper--lg) .studio-textarea{padding:1rem;font-size:1.125rem}\n"] }]
1724
+ }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], floatingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatingLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], minRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "minRows", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], autoResize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoResize", required: false }] }], resize: [{ type: i0.Input, args: [{ isSignal: true, alias: "resize", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], showCharCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCharCount", required: false }] }], charCountPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "charCountPosition", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], spellcheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellcheck", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }], focused: [{ type: i0.Output, args: ["focused"] }], blurred: [{ type: i0.Output, args: ["blurred"] }], keyPressed: [{ type: i0.Output, args: ["keyPressed"] }], textareaEl: [{ type: i0.ViewChild, args: ['textarea', { isSignal: true }] }] } });
1725
+
1141
1726
  /**
1142
1727
  * Primitives (Atoms)
1143
1728
  * Basic building blocks
@@ -1244,5 +1829,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1244
1829
  * Generated bundle index. Do not edit.
1245
1830
  */
1246
1831
 
1247
- export { BadgeComponent, ButtonComponent, IconComponent, InputComponent, STUDIO_CONFIG, StudioConfigService, SwitchComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
1832
+ export { BadgeComponent, ButtonComponent, CheckboxComponent, IconComponent, InputComponent, STUDIO_CONFIG, StudioConfigService, SwitchComponent, TextareaComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
1248
1833
  //# sourceMappingURL=eduboxpro-studio.mjs.map