@eduboxpro/studio 0.1.27 → 0.1.28

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.
@@ -6662,6 +6662,148 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
6662
6662
  }, 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"] }]
6663
6663
  }], 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 }] }] } });
6664
6664
 
6665
+ class ToastService {
6666
+ _messages = signal([], ...(ngDevMode ? [{ debugName: "_messages" }] : []));
6667
+ messages = this._messages.asReadonly();
6668
+ defaultLife = 5000;
6669
+ counter = 0;
6670
+ generateId() {
6671
+ return `toast-${++this.counter}-${Date.now()}`;
6672
+ }
6673
+ show(severity, summary, detail, config) {
6674
+ const message = {
6675
+ id: this.generateId(),
6676
+ severity,
6677
+ summary,
6678
+ detail,
6679
+ life: config?.life ?? this.defaultLife,
6680
+ sticky: false,
6681
+ closable: config?.closable ?? true
6682
+ };
6683
+ this._messages.update(msgs => [...msgs, message]);
6684
+ if (!message.sticky && message.life) {
6685
+ setTimeout(() => {
6686
+ this.remove(message.id);
6687
+ }, message.life);
6688
+ }
6689
+ }
6690
+ success(summary, detail, config) {
6691
+ this.show('success', summary, detail, config);
6692
+ }
6693
+ info(summary, detail, config) {
6694
+ this.show('info', summary, detail, config);
6695
+ }
6696
+ warning(summary, detail, config) {
6697
+ this.show('warning', summary, detail, config);
6698
+ }
6699
+ error(summary, detail, config) {
6700
+ this.show('error', summary, detail, config);
6701
+ }
6702
+ remove(id) {
6703
+ this._messages.update(msgs => msgs.filter(m => m.id !== id));
6704
+ }
6705
+ clear() {
6706
+ this._messages.set([]);
6707
+ }
6708
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6709
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ToastService, providedIn: 'root' });
6710
+ }
6711
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ToastService, decorators: [{
6712
+ type: Injectable,
6713
+ args: [{
6714
+ providedIn: 'root'
6715
+ }]
6716
+ }] });
6717
+
6718
+ class ToastComponent {
6719
+ toastService = inject(ToastService);
6720
+ position = input('top-right', ...(ngDevMode ? [{ debugName: "position" }] : []));
6721
+ hostClasses = computed(() => classNames('studio-toast', 'toast--' + this.position()), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
6722
+ getIcon(severity) {
6723
+ const icons = {
6724
+ success: 'check-circle',
6725
+ info: 'info',
6726
+ warning: 'alert-triangle',
6727
+ error: 'alert-circle'
6728
+ };
6729
+ return icons[severity];
6730
+ }
6731
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6732
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: ToastComponent, isStandalone: true, selector: "studio-toast", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
6733
+ <div class="studio-toast__container">
6734
+ @for (message of toastService.messages(); track message.id) {
6735
+ <div
6736
+ class="studio-toast__item"
6737
+ [class.studio-toast__item--success]="message.severity === 'success'"
6738
+ [class.studio-toast__item--info]="message.severity === 'info'"
6739
+ [class.studio-toast__item--warning]="message.severity === 'warning'"
6740
+ [class.studio-toast__item--error]="message.severity === 'error'"
6741
+ role="alert"
6742
+ >
6743
+ <div class="studio-toast__icon">
6744
+ <studio-icon [name]="getIcon(message.severity)" [size]="20" />
6745
+ </div>
6746
+ <div class="studio-toast__content">
6747
+ <div class="studio-toast__summary">{{ message.summary }}</div>
6748
+ @if (message.detail) {
6749
+ <div class="studio-toast__detail">{{ message.detail }}</div>
6750
+ }
6751
+ </div>
6752
+ @if (message.closable) {
6753
+ <button
6754
+ type="button"
6755
+ class="studio-toast__close"
6756
+ (click)="toastService.remove(message.id)"
6757
+ aria-label="Close"
6758
+ >
6759
+ <studio-icon name="x" [size]="16" />
6760
+ </button>
6761
+ }
6762
+ </div>
6763
+ }
6764
+ </div>
6765
+ `, isInline: true, styles: [":host{position:fixed;z-index:var(--studio-z-toast, 9999);pointer-events:none}:host(.toast--top-right){top:1rem;right:1rem}:host(.toast--top-left){top:1rem;left:1rem}:host(.toast--bottom-right){bottom:1rem;right:1rem}:host(.toast--bottom-left){bottom:1rem;left:1rem}:host(.toast--top-center){top:1rem;left:50%;transform:translate(-50%)}:host(.toast--bottom-center){bottom:1rem;left:50%;transform:translate(-50%)}.studio-toast__container{display:flex;flex-direction:column;gap:.75rem;min-width:320px;max-width:420px}.studio-toast__item{display:flex;align-items:flex-start;gap:.75rem;padding:1rem;border-radius:var(--studio-radius-lg, .75rem);background:var(--studio-bg-primary, #ffffff);box-shadow:var(--studio-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, .1));border:1px solid var(--studio-border-primary, #e5e7eb);pointer-events:auto;animation:slideIn .2s ease-out}@keyframes slideIn{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}.studio-toast__icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:var(--studio-radius-full, 9999px)}.studio-toast__item--success .studio-toast__icon{background:#dcfce7;color:#16a34a}.studio-toast__item--info .studio-toast__icon{background:#dbeafe;color:#2563eb}.studio-toast__item--warning .studio-toast__icon{background:#fef3c7;color:#d97706}.studio-toast__item--error .studio-toast__icon{background:#fee2e2;color:#dc2626}.studio-toast__content{flex:1;min-width:0}.studio-toast__summary{font-weight:var(--studio-font-weight-semibold, 600);font-size:.875rem;color:var(--studio-text-primary, #111827)}.studio-toast__detail{margin-top:.25rem;font-size:.875rem;color:var(--studio-text-secondary, #6b7280)}.studio-toast__close{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;padding:0;background:none;border:none;border-radius:var(--studio-radius-sm, .25rem);color:var(--studio-text-tertiary, #9ca3af);cursor:pointer;transition:all var(--studio-transition-fast, .15s)}.studio-toast__close:hover{background:var(--studio-bg-secondary, #f3f4f6);color:var(--studio-text-secondary, #6b7280)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6766
+ }
6767
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ToastComponent, decorators: [{
6768
+ type: Component,
6769
+ args: [{ selector: 'studio-toast', standalone: true, imports: [CommonModule, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
6770
+ '[class]': 'hostClasses()'
6771
+ }, template: `
6772
+ <div class="studio-toast__container">
6773
+ @for (message of toastService.messages(); track message.id) {
6774
+ <div
6775
+ class="studio-toast__item"
6776
+ [class.studio-toast__item--success]="message.severity === 'success'"
6777
+ [class.studio-toast__item--info]="message.severity === 'info'"
6778
+ [class.studio-toast__item--warning]="message.severity === 'warning'"
6779
+ [class.studio-toast__item--error]="message.severity === 'error'"
6780
+ role="alert"
6781
+ >
6782
+ <div class="studio-toast__icon">
6783
+ <studio-icon [name]="getIcon(message.severity)" [size]="20" />
6784
+ </div>
6785
+ <div class="studio-toast__content">
6786
+ <div class="studio-toast__summary">{{ message.summary }}</div>
6787
+ @if (message.detail) {
6788
+ <div class="studio-toast__detail">{{ message.detail }}</div>
6789
+ }
6790
+ </div>
6791
+ @if (message.closable) {
6792
+ <button
6793
+ type="button"
6794
+ class="studio-toast__close"
6795
+ (click)="toastService.remove(message.id)"
6796
+ aria-label="Close"
6797
+ >
6798
+ <studio-icon name="x" [size]="16" />
6799
+ </button>
6800
+ }
6801
+ </div>
6802
+ }
6803
+ </div>
6804
+ `, styles: [":host{position:fixed;z-index:var(--studio-z-toast, 9999);pointer-events:none}:host(.toast--top-right){top:1rem;right:1rem}:host(.toast--top-left){top:1rem;left:1rem}:host(.toast--bottom-right){bottom:1rem;right:1rem}:host(.toast--bottom-left){bottom:1rem;left:1rem}:host(.toast--top-center){top:1rem;left:50%;transform:translate(-50%)}:host(.toast--bottom-center){bottom:1rem;left:50%;transform:translate(-50%)}.studio-toast__container{display:flex;flex-direction:column;gap:.75rem;min-width:320px;max-width:420px}.studio-toast__item{display:flex;align-items:flex-start;gap:.75rem;padding:1rem;border-radius:var(--studio-radius-lg, .75rem);background:var(--studio-bg-primary, #ffffff);box-shadow:var(--studio-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, .1));border:1px solid var(--studio-border-primary, #e5e7eb);pointer-events:auto;animation:slideIn .2s ease-out}@keyframes slideIn{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}.studio-toast__icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:var(--studio-radius-full, 9999px)}.studio-toast__item--success .studio-toast__icon{background:#dcfce7;color:#16a34a}.studio-toast__item--info .studio-toast__icon{background:#dbeafe;color:#2563eb}.studio-toast__item--warning .studio-toast__icon{background:#fef3c7;color:#d97706}.studio-toast__item--error .studio-toast__icon{background:#fee2e2;color:#dc2626}.studio-toast__content{flex:1;min-width:0}.studio-toast__summary{font-weight:var(--studio-font-weight-semibold, 600);font-size:.875rem;color:var(--studio-text-primary, #111827)}.studio-toast__detail{margin-top:.25rem;font-size:.875rem;color:var(--studio-text-secondary, #6b7280)}.studio-toast__close{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;padding:0;background:none;border:none;border-radius:var(--studio-radius-sm, .25rem);color:var(--studio-text-tertiary, #9ca3af);cursor:pointer;transition:all var(--studio-transition-fast, .15s)}.studio-toast__close:hover{background:var(--studio-bg-secondary, #f3f4f6);color:var(--studio-text-secondary, #6b7280)}\n"] }]
6805
+ }], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }] } });
6806
+
6665
6807
  class TooltipComponent {
6666
6808
  content = input.required(...(ngDevMode ? [{ debugName: "content" }] : []));
6667
6809
  trigger = input('hover', ...(ngDevMode ? [{ debugName: "trigger" }] : []));
@@ -6729,6 +6871,168 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
6729
6871
  `, styles: [":host{display:inline-block}\n"] }]
6730
6872
  }], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: true }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], openDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "openDelay", required: false }] }], closeDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDelay", required: false }] }], arrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrow", required: false }] }], arrowSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrowSize", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
6731
6873
 
6874
+ class ConfirmDialogService {
6875
+ _config = signal(null, ...(ngDevMode ? [{ debugName: "_config" }] : []));
6876
+ _visible = signal(false, ...(ngDevMode ? [{ debugName: "_visible" }] : []));
6877
+ config = this._config.asReadonly();
6878
+ visible = this._visible.asReadonly();
6879
+ confirm(config) {
6880
+ this._config.set({
6881
+ confirmText: 'Подтвердить',
6882
+ cancelText: 'Отмена',
6883
+ variant: 'default',
6884
+ ...config
6885
+ });
6886
+ this._visible.set(true);
6887
+ }
6888
+ accept() {
6889
+ const config = this._config();
6890
+ if (config?.onConfirm) {
6891
+ config.onConfirm();
6892
+ }
6893
+ this.close();
6894
+ }
6895
+ reject() {
6896
+ const config = this._config();
6897
+ if (config?.onCancel) {
6898
+ config.onCancel();
6899
+ }
6900
+ this.close();
6901
+ }
6902
+ close() {
6903
+ this._visible.set(false);
6904
+ this._config.set(null);
6905
+ }
6906
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ConfirmDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6907
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ConfirmDialogService, providedIn: 'root' });
6908
+ }
6909
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ConfirmDialogService, decorators: [{
6910
+ type: Injectable,
6911
+ args: [{
6912
+ providedIn: 'root'
6913
+ }]
6914
+ }] });
6915
+
6916
+ class ConfirmDialogComponent {
6917
+ confirmService = inject(ConfirmDialogService);
6918
+ config = this.confirmService.config;
6919
+ handleEscape() {
6920
+ if (this.confirmService.visible()) {
6921
+ this.confirmService.reject();
6922
+ }
6923
+ }
6924
+ getIcon() {
6925
+ const config = this.config();
6926
+ if (config?.icon)
6927
+ return config.icon;
6928
+ switch (config?.variant) {
6929
+ case 'danger':
6930
+ return 'alert-triangle';
6931
+ case 'warning':
6932
+ return 'alert-circle';
6933
+ default:
6934
+ return 'help-circle';
6935
+ }
6936
+ }
6937
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ConfirmDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6938
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: ConfirmDialogComponent, isStandalone: true, selector: "studio-confirm-dialog", host: { listeners: { "document:keydown.escape": "handleEscape()" } }, ngImport: i0, template: `
6939
+ @if (confirmService.visible()) {
6940
+ <!-- Overlay -->
6941
+ <div
6942
+ class="studio-confirm__overlay"
6943
+ (click)="confirmService.reject()"
6944
+ ></div>
6945
+
6946
+ <!-- Dialog -->
6947
+ <div
6948
+ class="studio-confirm__dialog"
6949
+ [class.studio-confirm__dialog--danger]="config()?.variant === 'danger'"
6950
+ [class.studio-confirm__dialog--warning]="config()?.variant === 'warning'"
6951
+ role="alertdialog"
6952
+ aria-modal="true"
6953
+ >
6954
+ <!-- Icon -->
6955
+ <div class="studio-confirm__icon">
6956
+ <studio-icon [name]="getIcon()" [size]="24" />
6957
+ </div>
6958
+
6959
+ <!-- Content -->
6960
+ <div class="studio-confirm__content">
6961
+ <h3 class="studio-confirm__title">{{ config()?.title }}</h3>
6962
+ <p class="studio-confirm__message">{{ config()?.message }}</p>
6963
+ </div>
6964
+
6965
+ <!-- Actions -->
6966
+ <div class="studio-confirm__actions">
6967
+ <studio-button
6968
+ variant="outline"
6969
+ (clicked)="confirmService.reject()"
6970
+ >
6971
+ {{ config()?.cancelText }}
6972
+ </studio-button>
6973
+ <studio-button
6974
+ [color]="config()?.variant === 'danger' ? 'error' : 'primary'"
6975
+ (clicked)="confirmService.accept()"
6976
+ >
6977
+ {{ config()?.confirmText }}
6978
+ </studio-button>
6979
+ </div>
6980
+ </div>
6981
+ }
6982
+ `, isInline: true, styles: [":host{display:contents}.studio-confirm__overlay{position:fixed;inset:0;background:#00000080;z-index:var(--studio-z-modal-backdrop, 1040);animation:fadeIn .2s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.studio-confirm__dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:var(--studio-z-modal, 1050);width:90%;max-width:400px;padding:1.5rem;background:var(--studio-bg-primary, #ffffff);border-radius:var(--studio-radius-xl, 1rem);box-shadow:var(--studio-shadow-xl, 0 20px 25px -5px rgba(0, 0, 0, .1));animation:scaleIn .2s ease}@keyframes scaleIn{0%{opacity:0;transform:translate(-50%,-50%) scale(.95)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}.studio-confirm__icon{display:flex;align-items:center;justify-content:center;width:3rem;height:3rem;margin:0 auto 1rem;border-radius:var(--studio-radius-full, 9999px);background:#dbeafe;color:#2563eb}.studio-confirm__dialog--danger .studio-confirm__icon{background:#fee2e2;color:#dc2626}.studio-confirm__dialog--warning .studio-confirm__icon{background:#fef3c7;color:#d97706}.studio-confirm__content{text-align:center;margin-bottom:1.5rem}.studio-confirm__title{margin:0 0 .5rem;font-size:1.125rem;font-weight:var(--studio-font-weight-semibold, 600);color:var(--studio-text-primary, #111827)}.studio-confirm__message{margin:0;font-size:.875rem;color:var(--studio-text-secondary, #6b7280);line-height:1.5}.studio-confirm__actions{display:flex;gap:.75rem;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }, { kind: "component", type: ButtonComponent, selector: "studio-button", inputs: ["variant", "size", "color", "radius", "shadow", "compact", "disabled", "loading", "loadingText", "fullWidth", "type", "icon", "iconPosition", "href", "target", "badge", "badgeColor", "ariaLabel"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6983
+ }
6984
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
6985
+ type: Component,
6986
+ args: [{ selector: 'studio-confirm-dialog', standalone: true, imports: [CommonModule, IconComponent, ButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
6987
+ @if (confirmService.visible()) {
6988
+ <!-- Overlay -->
6989
+ <div
6990
+ class="studio-confirm__overlay"
6991
+ (click)="confirmService.reject()"
6992
+ ></div>
6993
+
6994
+ <!-- Dialog -->
6995
+ <div
6996
+ class="studio-confirm__dialog"
6997
+ [class.studio-confirm__dialog--danger]="config()?.variant === 'danger'"
6998
+ [class.studio-confirm__dialog--warning]="config()?.variant === 'warning'"
6999
+ role="alertdialog"
7000
+ aria-modal="true"
7001
+ >
7002
+ <!-- Icon -->
7003
+ <div class="studio-confirm__icon">
7004
+ <studio-icon [name]="getIcon()" [size]="24" />
7005
+ </div>
7006
+
7007
+ <!-- Content -->
7008
+ <div class="studio-confirm__content">
7009
+ <h3 class="studio-confirm__title">{{ config()?.title }}</h3>
7010
+ <p class="studio-confirm__message">{{ config()?.message }}</p>
7011
+ </div>
7012
+
7013
+ <!-- Actions -->
7014
+ <div class="studio-confirm__actions">
7015
+ <studio-button
7016
+ variant="outline"
7017
+ (clicked)="confirmService.reject()"
7018
+ >
7019
+ {{ config()?.cancelText }}
7020
+ </studio-button>
7021
+ <studio-button
7022
+ [color]="config()?.variant === 'danger' ? 'error' : 'primary'"
7023
+ (clicked)="confirmService.accept()"
7024
+ >
7025
+ {{ config()?.confirmText }}
7026
+ </studio-button>
7027
+ </div>
7028
+ </div>
7029
+ }
7030
+ `, styles: [":host{display:contents}.studio-confirm__overlay{position:fixed;inset:0;background:#00000080;z-index:var(--studio-z-modal-backdrop, 1040);animation:fadeIn .2s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.studio-confirm__dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:var(--studio-z-modal, 1050);width:90%;max-width:400px;padding:1.5rem;background:var(--studio-bg-primary, #ffffff);border-radius:var(--studio-radius-xl, 1rem);box-shadow:var(--studio-shadow-xl, 0 20px 25px -5px rgba(0, 0, 0, .1));animation:scaleIn .2s ease}@keyframes scaleIn{0%{opacity:0;transform:translate(-50%,-50%) scale(.95)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}.studio-confirm__icon{display:flex;align-items:center;justify-content:center;width:3rem;height:3rem;margin:0 auto 1rem;border-radius:var(--studio-radius-full, 9999px);background:#dbeafe;color:#2563eb}.studio-confirm__dialog--danger .studio-confirm__icon{background:#fee2e2;color:#dc2626}.studio-confirm__dialog--warning .studio-confirm__icon{background:#fef3c7;color:#d97706}.studio-confirm__content{text-align:center;margin-bottom:1.5rem}.studio-confirm__title{margin:0 0 .5rem;font-size:1.125rem;font-weight:var(--studio-font-weight-semibold, 600);color:var(--studio-text-primary, #111827)}.studio-confirm__message{margin:0;font-size:.875rem;color:var(--studio-text-secondary, #6b7280);line-height:1.5}.studio-confirm__actions{display:flex;gap:.75rem;justify-content:center}\n"] }]
7031
+ }], propDecorators: { handleEscape: [{
7032
+ type: HostListener,
7033
+ args: ['document:keydown.escape']
7034
+ }] } });
7035
+
6732
7036
  /**
6733
7037
  * Primitives (Atoms)
6734
7038
  * Basic building blocks
@@ -7629,5 +7933,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
7629
7933
  * Generated bundle index. Do not edit.
7630
7934
  */
7631
7935
 
7632
- export { BadgeComponent, BadgeWrapperComponent, BottomNavigationComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, COUNTRY_OPTIONS, CardComponent, ChatComponent, ChatInputComponent, ChatMessageComponent, CheckboxComponent, ColorPickerCompactComponent, ColorPickerComponent, DEFAULT_COLOR_PRESETS, DrawerComponent, DrawerService, DropdownComponent, IconComponent, InputComponent, InspectorComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, ModalComponent, NavbarComponent, PaginationComponent, PhoneInputComponent, PopoverComponent, RadioButtonComponent, STUDIO_CONFIG, SelectComponent, SidebarComponent, StudioConfigService, SwitchComponent, TableColumnDirective, TableComponent, TabsComponent, TextareaComponent, ThemeSwitchComponent, TooltipComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
7936
+ export { BadgeComponent, BadgeWrapperComponent, BottomNavigationComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, COUNTRY_OPTIONS, CardComponent, ChatComponent, ChatInputComponent, ChatMessageComponent, CheckboxComponent, ColorPickerCompactComponent, ColorPickerComponent, ConfirmDialogComponent, ConfirmDialogService, DEFAULT_COLOR_PRESETS, DrawerComponent, DrawerService, DropdownComponent, IconComponent, InputComponent, InspectorComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, ModalComponent, NavbarComponent, PaginationComponent, PhoneInputComponent, PopoverComponent, RadioButtonComponent, STUDIO_CONFIG, SelectComponent, SidebarComponent, StudioConfigService, SwitchComponent, TableColumnDirective, TableComponent, TabsComponent, TextareaComponent, ThemeSwitchComponent, ToastComponent, ToastService, TooltipComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
7633
7937
  //# sourceMappingURL=eduboxpro-studio.mjs.map