@eduboxpro/studio 0.1.7 → 0.1.9
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.
- package/fesm2022/eduboxpro-studio.mjs +941 -5
- package/fesm2022/eduboxpro-studio.mjs.map +1 -1
- package/index.d.ts +286 -3
- package/package.json +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, forwardRef, viewChild, model } from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, ElementRef, forwardRef, viewChild, model, Renderer2, DestroyRef, HostListener, Directive } from '@angular/core';
|
|
3
3
|
import * as i1$1 from '@angular/common';
|
|
4
4
|
import { DOCUMENT, CommonModule } from '@angular/common';
|
|
5
5
|
import * as i1 from 'lucide-angular';
|
|
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';
|
|
7
|
-
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
6
|
+
import { icons, LucideAngularModule, LucideIconProvider, LUCIDE_ICONS, Circle, Apple, Globe, Laptop, MessageSquare, List, Grid3x3, Strikethrough, Underline, Italic, Bold, AlignJustify, AlignRight, AlignCenter, AlignLeft, 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';
|
|
7
|
+
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Injection token for Studio configuration
|
|
@@ -443,7 +443,22 @@ function provideStudioIcons() {
|
|
|
443
443
|
Loader2,
|
|
444
444
|
ShoppingCart,
|
|
445
445
|
Sun,
|
|
446
|
-
Moon
|
|
446
|
+
Moon,
|
|
447
|
+
AlignLeft,
|
|
448
|
+
AlignCenter,
|
|
449
|
+
AlignRight,
|
|
450
|
+
AlignJustify,
|
|
451
|
+
Bold,
|
|
452
|
+
Italic,
|
|
453
|
+
Underline,
|
|
454
|
+
Strikethrough,
|
|
455
|
+
Grid3x3,
|
|
456
|
+
List,
|
|
457
|
+
MessageSquare,
|
|
458
|
+
Laptop,
|
|
459
|
+
Globe,
|
|
460
|
+
Apple,
|
|
461
|
+
Circle
|
|
447
462
|
})
|
|
448
463
|
}
|
|
449
464
|
]);
|
|
@@ -869,6 +884,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
869
884
|
* Button component
|
|
870
885
|
*/
|
|
871
886
|
|
|
887
|
+
class ButtonGroupComponent {
|
|
888
|
+
elementRef = inject(ElementRef);
|
|
889
|
+
configService = inject(StudioConfigService);
|
|
890
|
+
groupDefaults = computed(() => this.configService.config().components?.buttonGroup, ...(ngDevMode ? [{ debugName: "groupDefaults" }] : []));
|
|
891
|
+
orientationInput = input(undefined, ...(ngDevMode ? [{ debugName: "orientationInput", alias: 'orientation' }] : [{ alias: 'orientation' }]));
|
|
892
|
+
sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
|
|
893
|
+
variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
|
|
894
|
+
colorInput = input(undefined, ...(ngDevMode ? [{ debugName: "colorInput", alias: 'color' }] : [{ alias: 'color' }]));
|
|
895
|
+
radiusInput = input(undefined, ...(ngDevMode ? [{ debugName: "radiusInput", alias: 'radius' }] : [{ alias: 'radius' }]));
|
|
896
|
+
orientation = withConfigDefault(this.orientationInput, computed(() => this.groupDefaults()?.orientation), 'horizontal');
|
|
897
|
+
size = withConfigDefault(this.sizeInput, computed(() => this.groupDefaults()?.size), undefined);
|
|
898
|
+
variant = withConfigDefault(this.variantInput, computed(() => this.groupDefaults()?.variant), undefined);
|
|
899
|
+
color = withConfigDefault(this.colorInput, computed(() => this.groupDefaults()?.color), undefined);
|
|
900
|
+
radius = withConfigDefault(this.radiusInput, computed(() => this.groupDefaults()?.radius), undefined);
|
|
901
|
+
attached = input(false, ...(ngDevMode ? [{ debugName: "attached" }] : []));
|
|
902
|
+
fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
|
|
903
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
904
|
+
spacing = input('sm', ...(ngDevMode ? [{ debugName: "spacing" }] : []));
|
|
905
|
+
align = input('start', ...(ngDevMode ? [{ debugName: "align" }] : []));
|
|
906
|
+
ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : []));
|
|
907
|
+
role = input('group', ...(ngDevMode ? [{ debugName: "role" }] : []));
|
|
908
|
+
hostClasses = computed(() => classNames('studio-button-group', `studio-button-group--${this.orientation()}`, `studio-button-group--spacing-${this.spacing()}`, `studio-button-group--align-${this.align()}`, this.attached() && 'studio-button-group--attached', this.fullWidth() && 'studio-button-group--full', this.disabled() && 'studio-button-group--disabled'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
|
|
909
|
+
constructor() {
|
|
910
|
+
effect(() => {
|
|
911
|
+
const isAttached = this.attached();
|
|
912
|
+
const hostElement = this.elementRef.nativeElement;
|
|
913
|
+
const buttonElements = hostElement.querySelectorAll('studio-button');
|
|
914
|
+
buttonElements.forEach((buttonEl, index) => {
|
|
915
|
+
const isFirst = index === 0;
|
|
916
|
+
const isLast = index === buttonElements.length - 1;
|
|
917
|
+
const isMiddle = !isFirst && !isLast;
|
|
918
|
+
if (isAttached) {
|
|
919
|
+
buttonEl.classList.add('studio-button-group__item--attached');
|
|
920
|
+
if (isFirst)
|
|
921
|
+
buttonEl.classList.add('studio-button-group__item--first');
|
|
922
|
+
if (isLast)
|
|
923
|
+
buttonEl.classList.add('studio-button-group__item--last');
|
|
924
|
+
if (isMiddle)
|
|
925
|
+
buttonEl.classList.add('studio-button-group__item--middle');
|
|
926
|
+
}
|
|
927
|
+
else {
|
|
928
|
+
buttonEl.classList.remove('studio-button-group__item--attached');
|
|
929
|
+
buttonEl.classList.remove('studio-button-group__item--first');
|
|
930
|
+
buttonEl.classList.remove('studio-button-group__item--last');
|
|
931
|
+
buttonEl.classList.remove('studio-button-group__item--middle');
|
|
932
|
+
}
|
|
933
|
+
});
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ButtonGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
937
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: ButtonGroupComponent, isStandalone: true, selector: "studio-button-group", inputs: { orientationInput: { classPropertyName: "orientationInput", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variantInput: { classPropertyName: "variantInput", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, colorInput: { classPropertyName: "colorInput", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, radiusInput: { classPropertyName: "radiusInput", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, attached: { classPropertyName: "attached", publicName: "attached", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, spacing: { classPropertyName: "spacing", publicName: "spacing", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.role": "role()", "attr.aria-label": "ariaLabel()" } }, ngImport: i0, template: `<ng-content select="studio-button" />`, isInline: true, styles: [":host{display:inline-flex;align-items:center;position:relative}:host(.studio-button-group--horizontal){flex-direction:row}:host(.studio-button-group--vertical){flex-direction:column}:host(.studio-button-group--spacing-none){gap:0}:host(.studio-button-group--spacing-xs){gap:var(--studio-spacing-xs)}:host(.studio-button-group--spacing-sm){gap:var(--studio-spacing-sm)}:host(.studio-button-group--spacing-md){gap:var(--studio-spacing-md)}:host(.studio-button-group--spacing-lg){gap:var(--studio-spacing-lg)}:host(.studio-button-group--align-start){justify-content:flex-start}:host(.studio-button-group--align-center){justify-content:center}:host(.studio-button-group--align-end){justify-content:flex-end}:host(.studio-button-group--align-stretch){align-items:stretch}:host(.studio-button-group--align-stretch) ::ng-deep studio-button{flex:1}:host(.studio-button-group--full){width:100%}:host(.studio-button-group--full) ::ng-deep studio-button{flex:1}:host(.studio-button-group--attached){gap:0}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--attached{margin:0;position:relative}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--middle{border-radius:0}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--first:not(.studio-button-group__item--last){border-top-right-radius:0;border-bottom-right-radius:0}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--last:not(.studio-button-group__item--first){border-top-left-radius:0;border-bottom-left-radius:0}:host(.studio-button-group--attached).studio-button-group--horizontal ::ng-deep studio-button.studio-button-group__item--attached:not(:last-child){border-right:1px solid rgba(0,0,0,.1)}:host(.studio-button-group--attached).studio-button-group--horizontal ::ng-deep studio-button.studio-button-group__item--attached.studio-button--outline:not(:last-child){margin-right:-1px}:host(.studio-button-group--vertical){align-items:stretch}:host(.studio-button-group--vertical) ::ng-deep studio-button{width:100%;justify-content:flex-start}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--first:not(.studio-button-group__item--last){border-top-right-radius:var(--studio-radius-sm);border-bottom-right-radius:0;border-top-left-radius:var(--studio-radius-sm);border-bottom-left-radius:0}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--last:not(.studio-button-group__item--first){border-top-left-radius:0;border-bottom-left-radius:var(--studio-radius-sm);border-top-right-radius:0;border-bottom-right-radius:var(--studio-radius-sm)}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--attached:not(:last-child){border-right:none;border-bottom:1px solid rgba(255,255,255,.2)}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--middle{border-radius:0}:host(.studio-button-group--vertical.studio-button-group--full) ::ng-deep studio-button{width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
938
|
+
}
|
|
939
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ButtonGroupComponent, decorators: [{
|
|
940
|
+
type: Component,
|
|
941
|
+
args: [{ selector: 'studio-button-group', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
942
|
+
'[class]': 'hostClasses()',
|
|
943
|
+
'[attr.role]': 'role()',
|
|
944
|
+
'[attr.aria-label]': 'ariaLabel()'
|
|
945
|
+
}, template: `<ng-content select="studio-button" />`, styles: [":host{display:inline-flex;align-items:center;position:relative}:host(.studio-button-group--horizontal){flex-direction:row}:host(.studio-button-group--vertical){flex-direction:column}:host(.studio-button-group--spacing-none){gap:0}:host(.studio-button-group--spacing-xs){gap:var(--studio-spacing-xs)}:host(.studio-button-group--spacing-sm){gap:var(--studio-spacing-sm)}:host(.studio-button-group--spacing-md){gap:var(--studio-spacing-md)}:host(.studio-button-group--spacing-lg){gap:var(--studio-spacing-lg)}:host(.studio-button-group--align-start){justify-content:flex-start}:host(.studio-button-group--align-center){justify-content:center}:host(.studio-button-group--align-end){justify-content:flex-end}:host(.studio-button-group--align-stretch){align-items:stretch}:host(.studio-button-group--align-stretch) ::ng-deep studio-button{flex:1}:host(.studio-button-group--full){width:100%}:host(.studio-button-group--full) ::ng-deep studio-button{flex:1}:host(.studio-button-group--attached){gap:0}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--attached{margin:0;position:relative}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--middle{border-radius:0}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--first:not(.studio-button-group__item--last){border-top-right-radius:0;border-bottom-right-radius:0}:host(.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--last:not(.studio-button-group__item--first){border-top-left-radius:0;border-bottom-left-radius:0}:host(.studio-button-group--attached).studio-button-group--horizontal ::ng-deep studio-button.studio-button-group__item--attached:not(:last-child){border-right:1px solid rgba(0,0,0,.1)}:host(.studio-button-group--attached).studio-button-group--horizontal ::ng-deep studio-button.studio-button-group__item--attached.studio-button--outline:not(:last-child){margin-right:-1px}:host(.studio-button-group--vertical){align-items:stretch}:host(.studio-button-group--vertical) ::ng-deep studio-button{width:100%;justify-content:flex-start}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--first:not(.studio-button-group__item--last){border-top-right-radius:var(--studio-radius-sm);border-bottom-right-radius:0;border-top-left-radius:var(--studio-radius-sm);border-bottom-left-radius:0}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--last:not(.studio-button-group__item--first){border-top-left-radius:0;border-bottom-left-radius:var(--studio-radius-sm);border-top-right-radius:0;border-bottom-right-radius:var(--studio-radius-sm)}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--attached:not(:last-child){border-right:none;border-bottom:1px solid rgba(255,255,255,.2)}:host(.studio-button-group--vertical.studio-button-group--attached) ::ng-deep studio-button.studio-button-group__item--middle{border-radius:0}:host(.studio-button-group--vertical.studio-button-group--full) ::ng-deep studio-button{width:100%}\n"] }]
|
|
946
|
+
}], ctorParameters: () => [], propDecorators: { orientationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], colorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], attached: [{ type: i0.Input, args: [{ isSignal: true, alias: "attached", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }] } });
|
|
947
|
+
|
|
872
948
|
/**
|
|
873
949
|
* Checkbox component for selecting boolean values
|
|
874
950
|
*
|
|
@@ -1259,6 +1335,281 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
1259
1335
|
}, template: "@if (label() && !floatingLabel()) {\n <label [for]=\"id() || generatedId\" class=\"studio-input__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-input__required\">*</span>\n }\n </label>\n}\n\n<div class=\"studio-input__container\">\n @if (prefixIcon()) {\n <span class=\"studio-input__prefix\">\n <studio-icon [name]=\"prefixIcon()!\" [size]=\"16\" />\n </span>\n }\n\n @if (label() && floatingLabel()) {\n <label [for]=\"id() || generatedId\" class=\"studio-input__label--floating\">\n {{ label() }}\n @if (required()) {\n <span>*</span>\n }\n </label>\n }\n\n <input\n #inputElement\n class=\"studio-input__field\"\n [type]=\"computedType()\"\n [value]=\"value()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [placeholder]=\"computedPlaceholder()\"\n [required]=\"required()\"\n [attr.maxlength]=\"maxLength()\"\n [attr.minlength]=\"minLength()\"\n [min]=\"min()\"\n [max]=\"max()\"\n [step]=\"step()\"\n [pattern]=\"pattern()\"\n [attr.inputmode]=\"inputmode()\"\n [attr.autocomplete]=\"autocomplete()\"\n [name]=\"name()\"\n [id]=\"id() || generatedId\"\n [attr.aria-label]=\"ariaLabel() || (!label() ? placeholder() : null)\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n [attr.aria-describedby]=\"ariaDescribedByValue()\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\"\n (keydown.enter)=\"handleEnter($event)\"\n />\n\n @if (loading()) {\n <span class=\"studio-input__loading\">\n <studio-icon name=\"loader-2\" [size]=\"16\" class=\"studio-icon--spin\" />\n </span>\n }\n\n @if (clearable() && value() && !disabled() && !loading()) {\n <button\n type=\"button\"\n class=\"studio-input__clear\"\n (click)=\"handleClear()\"\n [attr.aria-label]=\"'Clear input'\"\n tabindex=\"-1\"\n >\n <studio-icon name=\"x\" [size]=\"14\" />\n </button>\n }\n\n @if (type() === 'password' && showPasswordToggle() && !loading()) {\n <button\n type=\"button\"\n class=\"studio-input__toggle-password\"\n (click)=\"togglePasswordVisibility()\"\n [attr.aria-label]=\"isPasswordVisible() ? 'Hide password' : 'Show password'\"\n tabindex=\"-1\"\n >\n <studio-icon [name]=\"isPasswordVisible() ? 'eye-off' : 'eye'\" [size]=\"16\" />\n </button>\n }\n\n @if (suffixIcon() && !loading() && !clearable() && !(type() === 'password' && showPasswordToggle())) {\n <span class=\"studio-input__suffix\">\n <studio-icon [name]=\"suffixIcon()!\" [size]=\"16\" />\n </span>\n }\n </div>\n\n@if (hint() && !error()) {\n <span class=\"studio-input__hint\" [id]=\"hintId\">\n {{ hint() }}\n </span>\n}\n\n@if (error() && errorMessage()) {\n <span class=\"studio-input__error\" [id]=\"errorId\" role=\"alert\">\n <studio-icon name=\"alert-circle\" [size]=\"14\" />\n {{ errorMessage() }}\n </span>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:.375rem;font-family:var(--studio-font-family)}:host(.studio-input--full-width){width:100%}.studio-input__label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);margin-bottom:.25rem}.studio-input__label .studio-input__required{color:var(--studio-error);margin-left:.125rem}.studio-input__container{position:relative;display:flex;align-items:center;transition:all var(--studio-transition-fast)}.studio-input__field{flex:1;width:100%;font-family:inherit;font-size:1rem;color:var(--studio-text-primary);background:transparent;border:none;outline:none;transition:all var(--studio-transition-fast)}.studio-input__field::placeholder{color:var(--studio-text-tertiary)}.studio-input__field:disabled{cursor:not-allowed;opacity:.6}.studio-input__field:read-only{cursor:default}.studio-input__prefix,.studio-input__suffix{display:flex;align-items:center;justify-content:center;color:var(--studio-text-secondary);flex-shrink:0}.studio-input__clear,.studio-input__toggle-password{display:flex;align-items:center;justify-content:center;background:none;border:none;padding:.25rem;color:var(--studio-text-secondary);cursor:pointer;border-radius:var(--studio-radius-sm);transition:all var(--studio-transition-fast);flex-shrink:0}.studio-input__clear:hover,.studio-input__toggle-password:hover{color:var(--studio-text-primary);background:var(--studio-bg-secondary)}.studio-input__clear:active,.studio-input__toggle-password:active{transform:scale(.95)}.studio-input__loading{display:flex;align-items:center;color:var(--studio-primary);flex-shrink:0}.studio-input__loading .studio-icon--spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-input__hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-input__error{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--studio-error);line-height:1.4}:host(.studio-input--outline) .studio-input__container{border:1px solid var(--studio-border-primary);background:var(--studio-bg-primary);border-radius:var(--studio-radius-md)}:host(.studio-input--outline) .studio-input__container:hover:not(:has(.studio-input__field:disabled)){border-color:var(--studio-primary)}:host(.studio-input--outline.studio-input--focused) .studio-input__container{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}:host(.studio-input--outline.studio-input--error) .studio-input__container{border-color:var(--studio-error)}:host(.studio-input--outline.studio-input--error) .studio-input__container:hover{border-color:var(--studio-error)}:host(.studio-input--outline.studio-input--error.studio-input--focused) .studio-input__container{box-shadow:0 0 0 3px #ef44441a}:host(.studio-input--outline.studio-input--disabled) .studio-input__container{background:var(--studio-bg-secondary);border-color:var(--studio-border-secondary)}:host(.studio-input--filled) .studio-input__container{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-input--filled) .studio-input__container:hover:not(:has(.studio-input__field:disabled)){background:var(--studio-bg-tertiary)}:host(.studio-input--filled.studio-input--focused) .studio-input__container{border-bottom-color:var(--studio-primary);background:var(--studio-bg-tertiary)}:host(.studio-input--filled.studio-input--error) .studio-input__container{border-bottom-color:var(--studio-error)}:host(.studio-input--filled.studio-input--disabled) .studio-input__container{background:var(--studio-bg-secondary);opacity:.6}:host(.studio-input--underline) .studio-input__container{background:transparent;border:none;border-bottom:1px solid var(--studio-border-primary);border-radius:0}:host(.studio-input--underline) .studio-input__container:hover:not(:has(.studio-input__field:disabled)){border-bottom-color:var(--studio-primary)}:host(.studio-input--underline.studio-input--focused) .studio-input__container{border-bottom:2px solid var(--studio-primary)}:host(.studio-input--underline.studio-input--error) .studio-input__container{border-bottom-color:var(--studio-error)}:host(.studio-input--underline.studio-input--disabled) .studio-input__container{border-bottom-style:dashed;opacity:.6}:host(.studio-input--sm) .studio-input__field{height:2rem;font-size:.875rem;padding:0 .75rem}:host(.studio-input--sm) .studio-input__prefix{padding-left:.75rem}:host(.studio-input--sm) .studio-input__suffix,:host(.studio-input--sm) .studio-input__clear,:host(.studio-input--sm) .studio-input__toggle-password,:host(.studio-input--sm) .studio-input__loading{padding-right:.5rem}:host(.studio-input--md) .studio-input__field{height:2.5rem;font-size:1rem;padding:0 1rem}:host(.studio-input--md) .studio-input__prefix{padding-left:1rem}:host(.studio-input--md) .studio-input__suffix,:host(.studio-input--md) .studio-input__clear,:host(.studio-input--md) .studio-input__toggle-password,:host(.studio-input--md) .studio-input__loading{padding-right:.75rem}:host(.studio-input--lg) .studio-input__field{height:3rem;font-size:1.125rem;padding:0 1.25rem}:host(.studio-input--lg) .studio-input__prefix{padding-left:1.25rem}:host(.studio-input--lg) .studio-input__suffix,:host(.studio-input--lg) .studio-input__clear,:host(.studio-input--lg) .studio-input__toggle-password,:host(.studio-input--lg) .studio-input__loading{padding-right:1rem}.studio-input__label--floating{position:absolute;top:50%;left:1rem;transform:translateY(-50%);font-size:1rem;color:var(--studio-text-tertiary);pointer-events:none;transition:all var(--studio-transition-fast);background:var(--studio-bg-primary);padding:0 .25rem}:host(.studio-input--filled) .studio-input__label--floating{background:transparent}:host(.studio-input--focused) .studio-input__label--floating,:host(.studio-input--has-value) .studio-input__label--floating{top:0;font-size:.75rem;color:var(--studio-primary)}:host(.studio-input--error) .studio-input__label--floating{color:var(--studio-error)}:host(.studio-input--radius-none) .studio-input__container{border-radius:0}:host(.studio-input--radius-sm) .studio-input__container{border-radius:var(--studio-radius-sm)}:host(.studio-input--radius-md) .studio-input__container{border-radius:var(--studio-radius-md)}:host(.studio-input--radius-lg) .studio-input__container{border-radius:var(--studio-radius-lg)}:host(.studio-input--radius-full) .studio-input__container{border-radius:9999px}:host(.studio-input--filled.studio-input--radius-none) .studio-input__container{border-radius:0}:host(.studio-input--filled.studio-input--radius-sm) .studio-input__container{border-radius:var(--studio-radius-sm) var(--studio-radius-sm) 0 0}:host(.studio-input--filled.studio-input--radius-md) .studio-input__container{border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-input--filled.studio-input--radius-lg) .studio-input__container{border-radius:var(--studio-radius-lg) var(--studio-radius-lg) 0 0}:host(.studio-input--filled.studio-input--radius-full) .studio-input__container{border-radius:9999px 9999px 0 0}\n"] }]
|
|
1260
1336
|
}], ctorParameters: () => [], propDecorators: { inputEl: [{ type: i0.ViewChild, args: ['inputElement', { isSignal: true }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], inputmode: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputmode", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], floatingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatingLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], 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 }] }], prefixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefixIcon", required: false }] }], suffixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixIcon", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], showPasswordToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPasswordToggle", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], focused: [{ type: i0.Output, args: ["focused"] }], blurred: [{ type: i0.Output, args: ["blurred"] }], cleared: [{ type: i0.Output, args: ["cleared"] }], entered: [{ type: i0.Output, args: ["entered"] }] } });
|
|
1261
1337
|
|
|
1338
|
+
class SelectComponent {
|
|
1339
|
+
configService = inject(StudioConfigService);
|
|
1340
|
+
selectDefaults = computed(() => this.configService.config().components?.select, ...(ngDevMode ? [{ debugName: "selectDefaults" }] : []));
|
|
1341
|
+
triggerEl = viewChild('triggerButton', ...(ngDevMode ? [{ debugName: "triggerEl" }] : []));
|
|
1342
|
+
dropdownEl = viewChild('dropdownPanel', ...(ngDevMode ? [{ debugName: "dropdownEl" }] : []));
|
|
1343
|
+
variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
|
|
1344
|
+
sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
|
|
1345
|
+
radiusInput = input(undefined, ...(ngDevMode ? [{ debugName: "radiusInput", alias: 'radius' }] : [{ alias: 'radius' }]));
|
|
1346
|
+
variant = withConfigDefault(this.variantInput, computed(() => this.selectDefaults()?.variant), 'outline');
|
|
1347
|
+
size = withConfigDefault(this.sizeInput, computed(() => this.selectDefaults()?.size), 'md');
|
|
1348
|
+
radius = withConfigDefault(this.radiusInput, computed(() => this.selectDefaults()?.radius), 'md');
|
|
1349
|
+
options = input.required(...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
1350
|
+
placeholder = input('Select option...', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
1351
|
+
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : []));
|
|
1352
|
+
searchable = input(false, ...(ngDevMode ? [{ debugName: "searchable" }] : []));
|
|
1353
|
+
clearable = input(true, ...(ngDevMode ? [{ debugName: "clearable" }] : []));
|
|
1354
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
1355
|
+
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
1356
|
+
label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
1357
|
+
floatingLabel = input(false, ...(ngDevMode ? [{ debugName: "floatingLabel" }] : []));
|
|
1358
|
+
hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : []));
|
|
1359
|
+
error = input(false, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
1360
|
+
errorMessage = input(undefined, ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
|
|
1361
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
|
|
1362
|
+
prefixIcon = input(undefined, ...(ngDevMode ? [{ debugName: "prefixIcon" }] : []));
|
|
1363
|
+
suffixIcon = input('chevron-down', ...(ngDevMode ? [{ debugName: "suffixIcon" }] : []));
|
|
1364
|
+
fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
|
|
1365
|
+
maxHeight = input('300px', ...(ngDevMode ? [{ debugName: "maxHeight" }] : []));
|
|
1366
|
+
position = input('bottom', ...(ngDevMode ? [{ debugName: "position" }] : []));
|
|
1367
|
+
searchPlaceholder = input('Search...', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
|
|
1368
|
+
valueChange = output();
|
|
1369
|
+
searchChange = output();
|
|
1370
|
+
opened = output();
|
|
1371
|
+
closed = output();
|
|
1372
|
+
optionSelected = output();
|
|
1373
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
1374
|
+
searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : []));
|
|
1375
|
+
selectedValue = signal(null, ...(ngDevMode ? [{ debugName: "selectedValue" }] : []));
|
|
1376
|
+
highlightedIndex = signal(0, ...(ngDevMode ? [{ debugName: "highlightedIndex" }] : []));
|
|
1377
|
+
isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
|
|
1378
|
+
isTouched = signal(false, ...(ngDevMode ? [{ debugName: "isTouched" }] : []));
|
|
1379
|
+
generatedId = `studio-select-${Math.random().toString(36).substr(2, 9)}`;
|
|
1380
|
+
onChange = () => { };
|
|
1381
|
+
onTouched = () => { };
|
|
1382
|
+
constructor() {
|
|
1383
|
+
effect(() => {
|
|
1384
|
+
if (this.isOpen()) {
|
|
1385
|
+
this.setupClickOutside();
|
|
1386
|
+
}
|
|
1387
|
+
else {
|
|
1388
|
+
this.cleanupClickOutside();
|
|
1389
|
+
}
|
|
1390
|
+
});
|
|
1391
|
+
}
|
|
1392
|
+
flattenedOptions = computed(() => {
|
|
1393
|
+
const opts = this.options();
|
|
1394
|
+
if (!opts || opts.length === 0)
|
|
1395
|
+
return [];
|
|
1396
|
+
if (this.isOptionGroup(opts[0])) {
|
|
1397
|
+
return opts.flatMap(g => g.options);
|
|
1398
|
+
}
|
|
1399
|
+
return opts;
|
|
1400
|
+
}, ...(ngDevMode ? [{ debugName: "flattenedOptions" }] : []));
|
|
1401
|
+
filteredOptions = computed(() => {
|
|
1402
|
+
const query = this.searchQuery().toLowerCase().trim();
|
|
1403
|
+
const opts = this.flattenedOptions();
|
|
1404
|
+
if (!query)
|
|
1405
|
+
return opts;
|
|
1406
|
+
return opts.filter(opt => opt.label.toLowerCase().includes(query) ||
|
|
1407
|
+
opt.description?.toLowerCase().includes(query));
|
|
1408
|
+
}, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : []));
|
|
1409
|
+
selectedOptions = computed(() => {
|
|
1410
|
+
const value = this.selectedValue();
|
|
1411
|
+
const opts = this.flattenedOptions();
|
|
1412
|
+
if (this.multiple()) {
|
|
1413
|
+
const values = value || [];
|
|
1414
|
+
return opts.filter(opt => values.includes(opt.value));
|
|
1415
|
+
}
|
|
1416
|
+
return opts.find(opt => this.compareValues(opt.value, value)) || null;
|
|
1417
|
+
}, ...(ngDevMode ? [{ debugName: "selectedOptions" }] : []));
|
|
1418
|
+
displayValue = computed(() => {
|
|
1419
|
+
const selected = this.selectedOptions();
|
|
1420
|
+
if (this.multiple() && Array.isArray(selected)) {
|
|
1421
|
+
return selected.map(opt => opt.label).join(', ');
|
|
1422
|
+
}
|
|
1423
|
+
if (selected && !Array.isArray(selected)) {
|
|
1424
|
+
return selected.label;
|
|
1425
|
+
}
|
|
1426
|
+
return '';
|
|
1427
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
|
|
1428
|
+
hasValue = computed(() => {
|
|
1429
|
+
const val = this.selectedValue();
|
|
1430
|
+
return this.multiple()
|
|
1431
|
+
? Array.isArray(val) && val.length > 0
|
|
1432
|
+
: val !== null && val !== undefined;
|
|
1433
|
+
}, ...(ngDevMode ? [{ debugName: "hasValue" }] : []));
|
|
1434
|
+
hostClasses = computed(() => classNames('studio-select', `studio-select--${this.variant()}`, `studio-select--${this.size()}`, `studio-select--radius-${this.radius()}`, this.isOpen() && 'studio-select--open', this.disabled() && 'studio-select--disabled', this.loading() && 'studio-select--loading', this.error() && 'studio-select--error', this.isFocused() && 'studio-select--focused', this.hasValue() && 'studio-select--has-value', this.fullWidth() && 'studio-select--full-width'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
|
|
1435
|
+
toggle() {
|
|
1436
|
+
if (!this.disabled() && !this.loading()) {
|
|
1437
|
+
this.isOpen.update(v => !v);
|
|
1438
|
+
if (this.isOpen()) {
|
|
1439
|
+
this.opened.emit();
|
|
1440
|
+
setTimeout(() => this.focusSearchInput(), 0);
|
|
1441
|
+
}
|
|
1442
|
+
else {
|
|
1443
|
+
this.closed.emit();
|
|
1444
|
+
this.searchQuery.set('');
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
close() {
|
|
1449
|
+
if (this.isOpen()) {
|
|
1450
|
+
this.isOpen.set(false);
|
|
1451
|
+
this.closed.emit();
|
|
1452
|
+
this.searchQuery.set('');
|
|
1453
|
+
this.isTouched.set(true);
|
|
1454
|
+
this.onTouched();
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
selectOption(option) {
|
|
1458
|
+
if (option.disabled)
|
|
1459
|
+
return;
|
|
1460
|
+
if (this.multiple()) {
|
|
1461
|
+
const current = (this.selectedValue() || []);
|
|
1462
|
+
const isSelected = current.includes(option.value);
|
|
1463
|
+
if (isSelected) {
|
|
1464
|
+
this.selectedValue.set(current.filter(v => v !== option.value));
|
|
1465
|
+
}
|
|
1466
|
+
else {
|
|
1467
|
+
this.selectedValue.set([...current, option.value]);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
else {
|
|
1471
|
+
this.selectedValue.set(option.value);
|
|
1472
|
+
this.close();
|
|
1473
|
+
}
|
|
1474
|
+
this.onChange(this.selectedValue());
|
|
1475
|
+
this.valueChange.emit(this.selectedValue());
|
|
1476
|
+
this.optionSelected.emit(option);
|
|
1477
|
+
}
|
|
1478
|
+
clear(event) {
|
|
1479
|
+
event.stopPropagation();
|
|
1480
|
+
this.selectedValue.set(this.multiple() ? [] : null);
|
|
1481
|
+
this.onChange(this.selectedValue());
|
|
1482
|
+
this.valueChange.emit(this.selectedValue());
|
|
1483
|
+
}
|
|
1484
|
+
isSelected(option) {
|
|
1485
|
+
if (this.multiple()) {
|
|
1486
|
+
const values = this.selectedValue() || [];
|
|
1487
|
+
return values.includes(option.value);
|
|
1488
|
+
}
|
|
1489
|
+
return this.compareValues(option.value, this.selectedValue());
|
|
1490
|
+
}
|
|
1491
|
+
handleSearch(event) {
|
|
1492
|
+
const query = event.target.value;
|
|
1493
|
+
this.searchQuery.set(query);
|
|
1494
|
+
this.searchChange.emit(query);
|
|
1495
|
+
}
|
|
1496
|
+
handleKeydown(event) {
|
|
1497
|
+
switch (event.key) {
|
|
1498
|
+
case 'ArrowDown':
|
|
1499
|
+
event.preventDefault();
|
|
1500
|
+
if (!this.isOpen()) {
|
|
1501
|
+
this.toggle();
|
|
1502
|
+
}
|
|
1503
|
+
else {
|
|
1504
|
+
this.highlightNext();
|
|
1505
|
+
}
|
|
1506
|
+
break;
|
|
1507
|
+
case 'ArrowUp':
|
|
1508
|
+
event.preventDefault();
|
|
1509
|
+
if (this.isOpen()) {
|
|
1510
|
+
this.highlightPrevious();
|
|
1511
|
+
}
|
|
1512
|
+
break;
|
|
1513
|
+
case 'Enter':
|
|
1514
|
+
case ' ':
|
|
1515
|
+
event.preventDefault();
|
|
1516
|
+
if (this.isOpen()) {
|
|
1517
|
+
this.selectHighlighted();
|
|
1518
|
+
}
|
|
1519
|
+
else {
|
|
1520
|
+
this.toggle();
|
|
1521
|
+
}
|
|
1522
|
+
break;
|
|
1523
|
+
case 'Escape':
|
|
1524
|
+
if (this.isOpen()) {
|
|
1525
|
+
event.preventDefault();
|
|
1526
|
+
this.close();
|
|
1527
|
+
}
|
|
1528
|
+
break;
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
highlightNext() {
|
|
1532
|
+
const opts = this.filteredOptions();
|
|
1533
|
+
const current = this.highlightedIndex();
|
|
1534
|
+
this.highlightedIndex.set(Math.min(current + 1, opts.length - 1));
|
|
1535
|
+
}
|
|
1536
|
+
highlightPrevious() {
|
|
1537
|
+
const current = this.highlightedIndex();
|
|
1538
|
+
this.highlightedIndex.set(Math.max(current - 1, 0));
|
|
1539
|
+
}
|
|
1540
|
+
selectHighlighted() {
|
|
1541
|
+
const opts = this.filteredOptions();
|
|
1542
|
+
const index = this.highlightedIndex();
|
|
1543
|
+
if (opts[index]) {
|
|
1544
|
+
this.selectOption(opts[index]);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
compareValues(a, b) {
|
|
1548
|
+
return a === b;
|
|
1549
|
+
}
|
|
1550
|
+
isOptionGroup(item) {
|
|
1551
|
+
return item && 'options' in item && Array.isArray(item.options);
|
|
1552
|
+
}
|
|
1553
|
+
focusSearchInput() {
|
|
1554
|
+
if (this.searchable()) {
|
|
1555
|
+
const searchInput = this.dropdownEl()?.nativeElement.querySelector('input');
|
|
1556
|
+
searchInput?.focus();
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
clickOutsideListener;
|
|
1560
|
+
setupClickOutside() {
|
|
1561
|
+
this.clickOutsideListener = (event) => {
|
|
1562
|
+
const target = event.target;
|
|
1563
|
+
const trigger = this.triggerEl()?.nativeElement;
|
|
1564
|
+
const dropdown = this.dropdownEl()?.nativeElement;
|
|
1565
|
+
if (trigger && !trigger.contains(target) && dropdown && !dropdown.contains(target)) {
|
|
1566
|
+
this.close();
|
|
1567
|
+
}
|
|
1568
|
+
};
|
|
1569
|
+
setTimeout(() => {
|
|
1570
|
+
document.addEventListener('click', this.clickOutsideListener);
|
|
1571
|
+
}, 0);
|
|
1572
|
+
}
|
|
1573
|
+
cleanupClickOutside() {
|
|
1574
|
+
if (this.clickOutsideListener) {
|
|
1575
|
+
document.removeEventListener('click', this.clickOutsideListener);
|
|
1576
|
+
this.clickOutsideListener = undefined;
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
writeValue(value) {
|
|
1580
|
+
this.selectedValue.set(value);
|
|
1581
|
+
}
|
|
1582
|
+
registerOnChange(fn) {
|
|
1583
|
+
this.onChange = fn;
|
|
1584
|
+
}
|
|
1585
|
+
registerOnTouched(fn) {
|
|
1586
|
+
this.onTouched = fn;
|
|
1587
|
+
}
|
|
1588
|
+
setDisabledState(isDisabled) {
|
|
1589
|
+
}
|
|
1590
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1591
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: SelectComponent, isStandalone: true, selector: "studio-select", inputs: { variantInput: { classPropertyName: "variantInput", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, radiusInput: { classPropertyName: "radiusInput", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, floatingLabel: { classPropertyName: "floatingLabel", publicName: "floatingLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, prefixIcon: { classPropertyName: "prefixIcon", publicName: "prefixIcon", isSignal: true, isRequired: false, transformFunction: null }, suffixIcon: { classPropertyName: "suffixIcon", publicName: "suffixIcon", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", searchChange: "searchChange", opened: "opened", closed: "closed", optionSelected: "optionSelected" }, host: { properties: { "class": "hostClasses()", "attr.data-open": "isOpen()" } }, providers: [
|
|
1592
|
+
{
|
|
1593
|
+
provide: NG_VALUE_ACCESSOR,
|
|
1594
|
+
useExisting: forwardRef(() => SelectComponent),
|
|
1595
|
+
multi: true
|
|
1596
|
+
}
|
|
1597
|
+
], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerButton"], descendants: true, isSignal: true }, { propertyName: "dropdownEl", first: true, predicate: ["dropdownPanel"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label() && !floatingLabel()) {\n <label [for]=\"generatedId\" class=\"studio-select__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-select__required\">*</span>\n }\n </label>\n}\n\n<div class=\"studio-select__control\">\n @if (prefixIcon()) {\n <span class=\"studio-select__prefix\">\n <studio-icon [name]=\"prefixIcon()!\" [size]=\"16\" />\n </span>\n }\n\n @if (label() && floatingLabel()) {\n <label [for]=\"generatedId\" class=\"studio-select__label--floating\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-select__required\">*</span>\n }\n </label>\n }\n\n <button\n #triggerButton\n type=\"button\"\n [id]=\"generatedId\"\n class=\"studio-select__trigger\"\n [disabled]=\"disabled() || loading()\"\n (click)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\"\n (focus)=\"isFocused.set(true)\"\n (blur)=\"isFocused.set(false)\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n >\n @if (hasValue()) {\n <span class=\"studio-select__value\">{{ displayValue() }}</span>\n } @else {\n <span class=\"studio-select__placeholder\">{{ placeholder() }}</span>\n }\n </button>\n\n @if (clearable() && hasValue() && !disabled() && !loading()) {\n <button\n type=\"button\"\n class=\"studio-select__clear\"\n (click)=\"clear($event)\"\n aria-label=\"Clear selection\"\n tabindex=\"-1\"\n >\n <studio-icon name=\"x\" [size]=\"14\" />\n </button>\n }\n\n @if (loading()) {\n <span class=\"studio-select__loading\">\n <studio-icon name=\"loader-2\" [size]=\"16\" class=\"studio-icon--spin\" />\n </span>\n } @else {\n <span class=\"studio-select__suffix\">\n <studio-icon\n [name]=\"suffixIcon()\"\n [size]=\"16\"\n />\n </span>\n }\n</div>\n\n@if (isOpen()) {\n <div\n #dropdownPanel\n class=\"studio-select__dropdown\"\n [attr.data-position]=\"position()\"\n [style.max-height]=\"maxHeight()\"\n >\n @if (searchable()) {\n <div class=\"studio-select__search\">\n <input\n type=\"text\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"searchQuery()\"\n (input)=\"handleSearch($event)\"\n />\n </div>\n }\n\n <div class=\"studio-select__options\" role=\"listbox\">\n @if (filteredOptions().length === 0) {\n <div class=\"studio-select__empty\">\n No options found\n </div>\n }\n\n @for (option of filteredOptions(); track option.value; let idx = $index) {\n <div\n class=\"studio-select__option\"\n [class.studio-select__option--selected]=\"isSelected(option)\"\n [class.studio-select__option--disabled]=\"option.disabled\"\n [class.studio-select__option--highlighted]=\"highlightedIndex() === idx\"\n (click)=\"selectOption(option)\"\n role=\"option\"\n [attr.aria-selected]=\"isSelected(option)\"\n >\n @if (multiple()) {\n <input\n type=\"checkbox\"\n class=\"studio-select__checkbox\"\n [checked]=\"isSelected(option)\"\n [disabled]=\"option.disabled\"\n tabindex=\"-1\"\n />\n }\n\n @if (option.icon) {\n <studio-icon [name]=\"option.icon\" [size]=\"18\" class=\"studio-select__option-icon\" />\n }\n\n <div class=\"studio-select__option-content\">\n <div class=\"studio-select__option-label\">\n {{ option.label }}\n </div>\n @if (option.description) {\n <div class=\"studio-select__option-description\">\n {{ option.description }}\n </div>\n }\n </div>\n\n @if (!multiple() && isSelected(option)) {\n <studio-icon name=\"check\" [size]=\"16\" class=\"studio-select__check-icon\" />\n }\n </div>\n }\n </div>\n </div>\n}\n\n@if (hint() && !error()) {\n <div class=\"studio-select__hint\">{{ hint() }}</div>\n}\n\n@if (error() && errorMessage()) {\n <div class=\"studio-select__error\">{{ errorMessage() }}</div>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:.375rem;font-family:var(--studio-font-family);position:relative}:host(.studio-select--full-width){width:100%}.studio-select__label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);margin-bottom:.25rem}.studio-select__label .studio-select__required{color:var(--studio-error);margin-left:.125rem}.studio-select__control{position:relative;display:flex;align-items:center;transition:all var(--studio-transition-fast)}.studio-select__prefix,.studio-select__suffix{display:flex;align-items:center;justify-content:center;color:var(--studio-text-secondary);flex-shrink:0}.studio-select__suffix{transition:var(--studio-transition-fast)}:host(.studio-select--open) .studio-select__suffix{transform:rotate(180deg)}.studio-select__trigger{flex:1;width:100%;display:flex;align-items:center;background:transparent;border:none;padding:0;font-family:inherit;text-align:left;color:var(--studio-text-primary);cursor:pointer;outline:none;transition:var(--studio-transition-fast)}.studio-select__trigger:disabled{cursor:not-allowed;opacity:.6}.studio-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--studio-text-primary)}.studio-select__placeholder{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--studio-text-tertiary)}.studio-select__clear,.studio-select__loading{display:flex;align-items:center;justify-content:center;flex-shrink:0}.studio-select__clear{background:none;border:none;padding:.25rem;color:var(--studio-text-secondary);cursor:pointer;border-radius:var(--studio-radius-sm);transition:all var(--studio-transition-fast)}.studio-select__clear:hover{color:var(--studio-text-primary);background:var(--studio-bg-secondary)}.studio-select__clear:active{transform:scale(.95)}.studio-select__loading{color:var(--studio-primary)}.studio-select__loading .studio-icon--spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-select__dropdown{position:absolute;top:100%;left:0;right:0;z-index:var(--studio-z-dropdown, 1000);background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);box-shadow:var(--studio-shadow-lg);margin-top:.25rem;overflow:hidden;display:flex;flex-direction:column}.studio-select__search{padding:.5rem;border-bottom:1px solid var(--studio-border-primary);flex-shrink:0}.studio-select__search input{width:100%;padding:.5rem;border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);font-family:inherit;font-size:.875rem;color:var(--studio-text-primary);background:var(--studio-bg-primary);outline:none;transition:var(--studio-transition-fast)}.studio-select__search input:focus{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}.studio-select__search input::placeholder{color:var(--studio-text-tertiary)}.studio-select__options{overflow-y:auto;flex:1}.studio-select__option{display:flex;align-items:center;gap:.75rem;padding:.625rem .75rem;cursor:pointer;transition:var(--studio-transition-fast);color:var(--studio-text-primary)}.studio-select__option:hover{background:var(--studio-bg-secondary)}.studio-select__option--selected{background:var(--studio-primary-bg);color:var(--studio-primary)}.studio-select__option--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.studio-select__option input[type=checkbox]{margin:0;cursor:pointer}.studio-select__option-icon{flex-shrink:0;color:var(--studio-text-secondary)}.studio-select__option-content{flex:1;min-width:0}.studio-select__option-label{font-size:.875rem;color:inherit}.studio-select__option-description{font-size:.75rem;color:var(--studio-text-secondary);margin-top:.125rem}.studio-select__empty{padding:1rem;text-align:center;color:var(--studio-text-tertiary);font-size:.875rem}.studio-select__hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-select__error{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--studio-error);line-height:1.4}.studio-select__label--floating{position:absolute;top:50%;left:1rem;transform:translateY(-50%);font-size:1rem;color:var(--studio-text-tertiary);pointer-events:none;transition:all var(--studio-transition-fast);background:var(--studio-bg-primary);padding:0 .25rem;z-index:1}:host(.studio-select--focused) .studio-select__label--floating,:host(.studio-select--has-value) .studio-select__label--floating{top:0;font-size:.75rem;color:var(--studio-primary)}:host(.studio-select--error) .studio-select__label--floating{color:var(--studio-error)}:host(.studio-select--outline) .studio-select__control{border:1px solid var(--studio-border-primary);background:var(--studio-bg-primary);border-radius:var(--studio-radius-md)}:host(.studio-select--outline) .studio-select__control:hover:not(:has(.studio-select__trigger:disabled)){border-color:var(--studio-primary)}:host(.studio-select--outline.studio-select--focused) .studio-select__control{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}:host(.studio-select--outline.studio-select--error) .studio-select__control{border-color:var(--studio-error)}:host(.studio-select--outline.studio-select--error) .studio-select__control:hover{border-color:var(--studio-error)}:host(.studio-select--outline.studio-select--error.studio-select--focused) .studio-select__control{box-shadow:0 0 0 3px #ef44441a}:host(.studio-select--outline.studio-select--disabled) .studio-select__control{background:var(--studio-bg-secondary);border-color:var(--studio-border-secondary)}:host(.studio-select--filled) .studio-select__control{background:var(--studio-bg-secondary);border:none;border-bottom:2px solid var(--studio-border-primary);border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-select--filled) .studio-select__control:hover:not(:has(.studio-select__trigger:disabled)){background:var(--studio-bg-tertiary)}:host(.studio-select--filled.studio-select--focused) .studio-select__control{border-bottom-color:var(--studio-primary);background:var(--studio-bg-tertiary)}:host(.studio-select--filled.studio-select--error) .studio-select__control{border-bottom-color:var(--studio-error)}:host(.studio-select--filled.studio-select--disabled) .studio-select__control{background:var(--studio-bg-secondary);opacity:.6}:host(.studio-select--underline) .studio-select__control{background:transparent;border:none;border-bottom:1px solid var(--studio-border-primary);border-radius:0}:host(.studio-select--underline) .studio-select__control:hover:not(:has(.studio-select__trigger:disabled)){border-bottom-color:var(--studio-primary)}:host(.studio-select--underline.studio-select--focused) .studio-select__control{border-bottom:2px solid var(--studio-primary)}:host(.studio-select--underline.studio-select--error) .studio-select__control{border-bottom-color:var(--studio-error)}:host(.studio-select--underline.studio-select--disabled) .studio-select__control{border-bottom-style:dashed;opacity:.6}:host(.studio-select--sm) .studio-select__trigger{height:2rem;font-size:.875rem;padding:0 .75rem}:host(.studio-select--sm) .studio-select__prefix{padding-left:.75rem}:host(.studio-select--sm) .studio-select__suffix,:host(.studio-select--sm) .studio-select__clear,:host(.studio-select--sm) .studio-select__loading{padding-right:.5rem}:host(.studio-select--md) .studio-select__trigger{height:2.5rem;font-size:1rem;padding:0 1rem}:host(.studio-select--md) .studio-select__prefix{padding-left:1rem}:host(.studio-select--md) .studio-select__suffix,:host(.studio-select--md) .studio-select__clear,:host(.studio-select--md) .studio-select__loading{padding-right:.75rem}:host(.studio-select--lg) .studio-select__trigger{height:3rem;font-size:1.125rem;padding:0 1.25rem}:host(.studio-select--lg) .studio-select__prefix{padding-left:1.25rem}:host(.studio-select--lg) .studio-select__suffix,:host(.studio-select--lg) .studio-select__clear,:host(.studio-select--lg) .studio-select__loading{padding-right:1rem}:host(.studio-select--radius-none) .studio-select__control{border-radius:0}:host(.studio-select--radius-sm) .studio-select__control{border-radius:var(--studio-radius-sm)}:host(.studio-select--radius-md) .studio-select__control{border-radius:var(--studio-radius-md)}:host(.studio-select--radius-lg) .studio-select__control{border-radius:var(--studio-radius-lg)}:host(.studio-select--radius-full) .studio-select__control{border-radius:9999px}:host(.studio-select--filled.studio-select--radius-none) .studio-select__control{border-radius:0}:host(.studio-select--filled.studio-select--radius-sm) .studio-select__control{border-radius:var(--studio-radius-sm) var(--studio-radius-sm) 0 0}:host(.studio-select--filled.studio-select--radius-md) .studio-select__control{border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-select--filled.studio-select--radius-lg) .studio-select__control{border-radius:var(--studio-radius-lg) var(--studio-radius-lg) 0 0}:host(.studio-select--filled.studio-select--radius-full) .studio-select__control{border-radius:9999px 9999px 0 0}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1598
|
+
}
|
|
1599
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SelectComponent, decorators: [{
|
|
1600
|
+
type: Component,
|
|
1601
|
+
args: [{ selector: 'studio-select', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1602
|
+
{
|
|
1603
|
+
provide: NG_VALUE_ACCESSOR,
|
|
1604
|
+
useExisting: forwardRef(() => SelectComponent),
|
|
1605
|
+
multi: true
|
|
1606
|
+
}
|
|
1607
|
+
], host: {
|
|
1608
|
+
'[class]': 'hostClasses()',
|
|
1609
|
+
'[attr.data-open]': 'isOpen()',
|
|
1610
|
+
}, template: "@if (label() && !floatingLabel()) {\n <label [for]=\"generatedId\" class=\"studio-select__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-select__required\">*</span>\n }\n </label>\n}\n\n<div class=\"studio-select__control\">\n @if (prefixIcon()) {\n <span class=\"studio-select__prefix\">\n <studio-icon [name]=\"prefixIcon()!\" [size]=\"16\" />\n </span>\n }\n\n @if (label() && floatingLabel()) {\n <label [for]=\"generatedId\" class=\"studio-select__label--floating\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-select__required\">*</span>\n }\n </label>\n }\n\n <button\n #triggerButton\n type=\"button\"\n [id]=\"generatedId\"\n class=\"studio-select__trigger\"\n [disabled]=\"disabled() || loading()\"\n (click)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\"\n (focus)=\"isFocused.set(true)\"\n (blur)=\"isFocused.set(false)\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n >\n @if (hasValue()) {\n <span class=\"studio-select__value\">{{ displayValue() }}</span>\n } @else {\n <span class=\"studio-select__placeholder\">{{ placeholder() }}</span>\n }\n </button>\n\n @if (clearable() && hasValue() && !disabled() && !loading()) {\n <button\n type=\"button\"\n class=\"studio-select__clear\"\n (click)=\"clear($event)\"\n aria-label=\"Clear selection\"\n tabindex=\"-1\"\n >\n <studio-icon name=\"x\" [size]=\"14\" />\n </button>\n }\n\n @if (loading()) {\n <span class=\"studio-select__loading\">\n <studio-icon name=\"loader-2\" [size]=\"16\" class=\"studio-icon--spin\" />\n </span>\n } @else {\n <span class=\"studio-select__suffix\">\n <studio-icon\n [name]=\"suffixIcon()\"\n [size]=\"16\"\n />\n </span>\n }\n</div>\n\n@if (isOpen()) {\n <div\n #dropdownPanel\n class=\"studio-select__dropdown\"\n [attr.data-position]=\"position()\"\n [style.max-height]=\"maxHeight()\"\n >\n @if (searchable()) {\n <div class=\"studio-select__search\">\n <input\n type=\"text\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"searchQuery()\"\n (input)=\"handleSearch($event)\"\n />\n </div>\n }\n\n <div class=\"studio-select__options\" role=\"listbox\">\n @if (filteredOptions().length === 0) {\n <div class=\"studio-select__empty\">\n No options found\n </div>\n }\n\n @for (option of filteredOptions(); track option.value; let idx = $index) {\n <div\n class=\"studio-select__option\"\n [class.studio-select__option--selected]=\"isSelected(option)\"\n [class.studio-select__option--disabled]=\"option.disabled\"\n [class.studio-select__option--highlighted]=\"highlightedIndex() === idx\"\n (click)=\"selectOption(option)\"\n role=\"option\"\n [attr.aria-selected]=\"isSelected(option)\"\n >\n @if (multiple()) {\n <input\n type=\"checkbox\"\n class=\"studio-select__checkbox\"\n [checked]=\"isSelected(option)\"\n [disabled]=\"option.disabled\"\n tabindex=\"-1\"\n />\n }\n\n @if (option.icon) {\n <studio-icon [name]=\"option.icon\" [size]=\"18\" class=\"studio-select__option-icon\" />\n }\n\n <div class=\"studio-select__option-content\">\n <div class=\"studio-select__option-label\">\n {{ option.label }}\n </div>\n @if (option.description) {\n <div class=\"studio-select__option-description\">\n {{ option.description }}\n </div>\n }\n </div>\n\n @if (!multiple() && isSelected(option)) {\n <studio-icon name=\"check\" [size]=\"16\" class=\"studio-select__check-icon\" />\n }\n </div>\n }\n </div>\n </div>\n}\n\n@if (hint() && !error()) {\n <div class=\"studio-select__hint\">{{ hint() }}</div>\n}\n\n@if (error() && errorMessage()) {\n <div class=\"studio-select__error\">{{ errorMessage() }}</div>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:.375rem;font-family:var(--studio-font-family);position:relative}:host(.studio-select--full-width){width:100%}.studio-select__label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);margin-bottom:.25rem}.studio-select__label .studio-select__required{color:var(--studio-error);margin-left:.125rem}.studio-select__control{position:relative;display:flex;align-items:center;transition:all var(--studio-transition-fast)}.studio-select__prefix,.studio-select__suffix{display:flex;align-items:center;justify-content:center;color:var(--studio-text-secondary);flex-shrink:0}.studio-select__suffix{transition:var(--studio-transition-fast)}:host(.studio-select--open) .studio-select__suffix{transform:rotate(180deg)}.studio-select__trigger{flex:1;width:100%;display:flex;align-items:center;background:transparent;border:none;padding:0;font-family:inherit;text-align:left;color:var(--studio-text-primary);cursor:pointer;outline:none;transition:var(--studio-transition-fast)}.studio-select__trigger:disabled{cursor:not-allowed;opacity:.6}.studio-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--studio-text-primary)}.studio-select__placeholder{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--studio-text-tertiary)}.studio-select__clear,.studio-select__loading{display:flex;align-items:center;justify-content:center;flex-shrink:0}.studio-select__clear{background:none;border:none;padding:.25rem;color:var(--studio-text-secondary);cursor:pointer;border-radius:var(--studio-radius-sm);transition:all var(--studio-transition-fast)}.studio-select__clear:hover{color:var(--studio-text-primary);background:var(--studio-bg-secondary)}.studio-select__clear:active{transform:scale(.95)}.studio-select__loading{color:var(--studio-primary)}.studio-select__loading .studio-icon--spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-select__dropdown{position:absolute;top:100%;left:0;right:0;z-index:var(--studio-z-dropdown, 1000);background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);box-shadow:var(--studio-shadow-lg);margin-top:.25rem;overflow:hidden;display:flex;flex-direction:column}.studio-select__search{padding:.5rem;border-bottom:1px solid var(--studio-border-primary);flex-shrink:0}.studio-select__search input{width:100%;padding:.5rem;border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);font-family:inherit;font-size:.875rem;color:var(--studio-text-primary);background:var(--studio-bg-primary);outline:none;transition:var(--studio-transition-fast)}.studio-select__search input:focus{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}.studio-select__search input::placeholder{color:var(--studio-text-tertiary)}.studio-select__options{overflow-y:auto;flex:1}.studio-select__option{display:flex;align-items:center;gap:.75rem;padding:.625rem .75rem;cursor:pointer;transition:var(--studio-transition-fast);color:var(--studio-text-primary)}.studio-select__option:hover{background:var(--studio-bg-secondary)}.studio-select__option--selected{background:var(--studio-primary-bg);color:var(--studio-primary)}.studio-select__option--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.studio-select__option input[type=checkbox]{margin:0;cursor:pointer}.studio-select__option-icon{flex-shrink:0;color:var(--studio-text-secondary)}.studio-select__option-content{flex:1;min-width:0}.studio-select__option-label{font-size:.875rem;color:inherit}.studio-select__option-description{font-size:.75rem;color:var(--studio-text-secondary);margin-top:.125rem}.studio-select__empty{padding:1rem;text-align:center;color:var(--studio-text-tertiary);font-size:.875rem}.studio-select__hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-select__error{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--studio-error);line-height:1.4}.studio-select__label--floating{position:absolute;top:50%;left:1rem;transform:translateY(-50%);font-size:1rem;color:var(--studio-text-tertiary);pointer-events:none;transition:all var(--studio-transition-fast);background:var(--studio-bg-primary);padding:0 .25rem;z-index:1}:host(.studio-select--focused) .studio-select__label--floating,:host(.studio-select--has-value) .studio-select__label--floating{top:0;font-size:.75rem;color:var(--studio-primary)}:host(.studio-select--error) .studio-select__label--floating{color:var(--studio-error)}:host(.studio-select--outline) .studio-select__control{border:1px solid var(--studio-border-primary);background:var(--studio-bg-primary);border-radius:var(--studio-radius-md)}:host(.studio-select--outline) .studio-select__control:hover:not(:has(.studio-select__trigger:disabled)){border-color:var(--studio-primary)}:host(.studio-select--outline.studio-select--focused) .studio-select__control{border-color:var(--studio-primary);box-shadow:0 0 0 3px var(--studio-primary-bg)}:host(.studio-select--outline.studio-select--error) .studio-select__control{border-color:var(--studio-error)}:host(.studio-select--outline.studio-select--error) .studio-select__control:hover{border-color:var(--studio-error)}:host(.studio-select--outline.studio-select--error.studio-select--focused) .studio-select__control{box-shadow:0 0 0 3px #ef44441a}:host(.studio-select--outline.studio-select--disabled) .studio-select__control{background:var(--studio-bg-secondary);border-color:var(--studio-border-secondary)}:host(.studio-select--filled) .studio-select__control{background:var(--studio-bg-secondary);border:none;border-bottom:2px solid var(--studio-border-primary);border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-select--filled) .studio-select__control:hover:not(:has(.studio-select__trigger:disabled)){background:var(--studio-bg-tertiary)}:host(.studio-select--filled.studio-select--focused) .studio-select__control{border-bottom-color:var(--studio-primary);background:var(--studio-bg-tertiary)}:host(.studio-select--filled.studio-select--error) .studio-select__control{border-bottom-color:var(--studio-error)}:host(.studio-select--filled.studio-select--disabled) .studio-select__control{background:var(--studio-bg-secondary);opacity:.6}:host(.studio-select--underline) .studio-select__control{background:transparent;border:none;border-bottom:1px solid var(--studio-border-primary);border-radius:0}:host(.studio-select--underline) .studio-select__control:hover:not(:has(.studio-select__trigger:disabled)){border-bottom-color:var(--studio-primary)}:host(.studio-select--underline.studio-select--focused) .studio-select__control{border-bottom:2px solid var(--studio-primary)}:host(.studio-select--underline.studio-select--error) .studio-select__control{border-bottom-color:var(--studio-error)}:host(.studio-select--underline.studio-select--disabled) .studio-select__control{border-bottom-style:dashed;opacity:.6}:host(.studio-select--sm) .studio-select__trigger{height:2rem;font-size:.875rem;padding:0 .75rem}:host(.studio-select--sm) .studio-select__prefix{padding-left:.75rem}:host(.studio-select--sm) .studio-select__suffix,:host(.studio-select--sm) .studio-select__clear,:host(.studio-select--sm) .studio-select__loading{padding-right:.5rem}:host(.studio-select--md) .studio-select__trigger{height:2.5rem;font-size:1rem;padding:0 1rem}:host(.studio-select--md) .studio-select__prefix{padding-left:1rem}:host(.studio-select--md) .studio-select__suffix,:host(.studio-select--md) .studio-select__clear,:host(.studio-select--md) .studio-select__loading{padding-right:.75rem}:host(.studio-select--lg) .studio-select__trigger{height:3rem;font-size:1.125rem;padding:0 1.25rem}:host(.studio-select--lg) .studio-select__prefix{padding-left:1.25rem}:host(.studio-select--lg) .studio-select__suffix,:host(.studio-select--lg) .studio-select__clear,:host(.studio-select--lg) .studio-select__loading{padding-right:1rem}:host(.studio-select--radius-none) .studio-select__control{border-radius:0}:host(.studio-select--radius-sm) .studio-select__control{border-radius:var(--studio-radius-sm)}:host(.studio-select--radius-md) .studio-select__control{border-radius:var(--studio-radius-md)}:host(.studio-select--radius-lg) .studio-select__control{border-radius:var(--studio-radius-lg)}:host(.studio-select--radius-full) .studio-select__control{border-radius:9999px}:host(.studio-select--filled.studio-select--radius-none) .studio-select__control{border-radius:0}:host(.studio-select--filled.studio-select--radius-sm) .studio-select__control{border-radius:var(--studio-radius-sm) var(--studio-radius-sm) 0 0}:host(.studio-select--filled.studio-select--radius-md) .studio-select__control{border-radius:var(--studio-radius-md) var(--studio-radius-md) 0 0}:host(.studio-select--filled.studio-select--radius-lg) .studio-select__control{border-radius:var(--studio-radius-lg) var(--studio-radius-lg) 0 0}:host(.studio-select--filled.studio-select--radius-full) .studio-select__control{border-radius:9999px 9999px 0 0}\n"] }]
|
|
1611
|
+
}], ctorParameters: () => [], propDecorators: { triggerEl: [{ type: i0.ViewChild, args: ['triggerButton', { isSignal: true }] }], dropdownEl: [{ type: i0.ViewChild, args: ['dropdownPanel', { isSignal: true }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], floatingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatingLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], prefixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefixIcon", required: false }] }], suffixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixIcon", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], searchChange: [{ type: i0.Output, args: ["searchChange"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], optionSelected: [{ type: i0.Output, args: ["optionSelected"] }] } });
|
|
1612
|
+
|
|
1262
1613
|
/**
|
|
1263
1614
|
* Toggle switch component with customizable size and color
|
|
1264
1615
|
*
|
|
@@ -1728,6 +2079,164 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
1728
2079
|
* Basic building blocks
|
|
1729
2080
|
*/
|
|
1730
2081
|
|
|
2082
|
+
class ButtonToggleGroupComponent {
|
|
2083
|
+
configService = inject(StudioConfigService);
|
|
2084
|
+
toggleGroupDefaults = computed(() => this.configService.config().components?.buttonToggleGroup, ...(ngDevMode ? [{ debugName: "toggleGroupDefaults" }] : []));
|
|
2085
|
+
onChange = () => { };
|
|
2086
|
+
onTouched = () => { };
|
|
2087
|
+
value = model('', ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
2088
|
+
options = input.required(...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
2089
|
+
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : []));
|
|
2090
|
+
allowEmpty = input(true, ...(ngDevMode ? [{ debugName: "allowEmpty" }] : []));
|
|
2091
|
+
orientationInput = input(undefined, ...(ngDevMode ? [{ debugName: "orientationInput", alias: 'orientation' }] : [{ alias: 'orientation' }]));
|
|
2092
|
+
sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
|
|
2093
|
+
variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
|
|
2094
|
+
colorInput = input(undefined, ...(ngDevMode ? [{ debugName: "colorInput", alias: 'color' }] : [{ alias: 'color' }]));
|
|
2095
|
+
radiusInput = input(undefined, ...(ngDevMode ? [{ debugName: "radiusInput", alias: 'radius' }] : [{ alias: 'radius' }]));
|
|
2096
|
+
shadowInput = input(undefined, ...(ngDevMode ? [{ debugName: "shadowInput", alias: 'shadow' }] : [{ alias: 'shadow' }]));
|
|
2097
|
+
orientation = withConfigDefault(this.orientationInput, computed(() => this.toggleGroupDefaults()?.orientation), 'horizontal');
|
|
2098
|
+
size = withConfigDefault(this.sizeInput, computed(() => this.toggleGroupDefaults()?.size), 'md');
|
|
2099
|
+
variant = withConfigDefault(this.variantInput, computed(() => this.toggleGroupDefaults()?.variant), 'outline');
|
|
2100
|
+
color = withConfigDefault(this.colorInput, computed(() => this.toggleGroupDefaults()?.color), 'primary');
|
|
2101
|
+
radius = withConfigDefault(this.radiusInput, computed(() => this.toggleGroupDefaults()?.radius), 'sm');
|
|
2102
|
+
shadow = withConfigDefault(this.shadowInput, computed(() => this.toggleGroupDefaults()?.shadow), 'none');
|
|
2103
|
+
attached = input(true, ...(ngDevMode ? [{ debugName: "attached" }] : []));
|
|
2104
|
+
fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
|
|
2105
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
2106
|
+
spacing = input('sm', ...(ngDevMode ? [{ debugName: "spacing" }] : []));
|
|
2107
|
+
align = input('start', ...(ngDevMode ? [{ debugName: "align" }] : []));
|
|
2108
|
+
showIcons = input(true, ...(ngDevMode ? [{ debugName: "showIcons" }] : []));
|
|
2109
|
+
iconPosition = input('left', ...(ngDevMode ? [{ debugName: "iconPosition" }] : []));
|
|
2110
|
+
ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : []));
|
|
2111
|
+
valueChange = output();
|
|
2112
|
+
hostClasses = computed(() => classNames('studio-button-toggle-group', this.disabled() && 'studio-button-toggle-group--disabled'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
|
|
2113
|
+
isSelected(optionValue) {
|
|
2114
|
+
const currentValue = this.value();
|
|
2115
|
+
if (this.multiple()) {
|
|
2116
|
+
return Array.isArray(currentValue) && currentValue.includes(optionValue);
|
|
2117
|
+
}
|
|
2118
|
+
return currentValue === optionValue;
|
|
2119
|
+
}
|
|
2120
|
+
handleToggle(optionValue) {
|
|
2121
|
+
if (this.disabled())
|
|
2122
|
+
return;
|
|
2123
|
+
let newValue;
|
|
2124
|
+
if (this.multiple()) {
|
|
2125
|
+
const currentArray = Array.isArray(this.value()) ? this.value() : [];
|
|
2126
|
+
const index = currentArray.indexOf(optionValue);
|
|
2127
|
+
if (index > -1) {
|
|
2128
|
+
if (!this.allowEmpty() && currentArray.length === 1) {
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
newValue = currentArray.filter(v => v !== optionValue);
|
|
2132
|
+
}
|
|
2133
|
+
else {
|
|
2134
|
+
newValue = [...currentArray, optionValue];
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
else {
|
|
2138
|
+
const currentValue = this.value();
|
|
2139
|
+
if (currentValue === optionValue && !this.allowEmpty()) {
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2142
|
+
newValue = currentValue === optionValue ? (this.allowEmpty() ? '' : optionValue) : optionValue;
|
|
2143
|
+
}
|
|
2144
|
+
this.value.set(newValue);
|
|
2145
|
+
this.onChange(newValue);
|
|
2146
|
+
this.onTouched();
|
|
2147
|
+
this.valueChange.emit(newValue);
|
|
2148
|
+
}
|
|
2149
|
+
writeValue(val) {
|
|
2150
|
+
if (val !== undefined && val !== null) {
|
|
2151
|
+
this.value.set(val);
|
|
2152
|
+
}
|
|
2153
|
+
else {
|
|
2154
|
+
this.value.set(this.multiple() ? [] : '');
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
registerOnChange(fn) {
|
|
2158
|
+
this.onChange = fn;
|
|
2159
|
+
}
|
|
2160
|
+
registerOnTouched(fn) {
|
|
2161
|
+
this.onTouched = fn;
|
|
2162
|
+
}
|
|
2163
|
+
setDisabledState(isDisabled) {
|
|
2164
|
+
// disabled handled via input signal
|
|
2165
|
+
}
|
|
2166
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ButtonToggleGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2167
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: ButtonToggleGroupComponent, isStandalone: true, selector: "studio-button-toggle-group", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, allowEmpty: { classPropertyName: "allowEmpty", publicName: "allowEmpty", isSignal: true, isRequired: false, transformFunction: null }, orientationInput: { classPropertyName: "orientationInput", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variantInput: { classPropertyName: "variantInput", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, colorInput: { classPropertyName: "colorInput", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, radiusInput: { classPropertyName: "radiusInput", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, shadowInput: { classPropertyName: "shadowInput", publicName: "shadow", isSignal: true, isRequired: false, transformFunction: null }, attached: { classPropertyName: "attached", publicName: "attached", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, spacing: { classPropertyName: "spacing", publicName: "spacing", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "iconPosition", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", valueChange: "valueChange" }, host: { properties: { "class": "hostClasses()" } }, providers: [
|
|
2168
|
+
{
|
|
2169
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2170
|
+
useExisting: forwardRef(() => ButtonToggleGroupComponent),
|
|
2171
|
+
multi: true
|
|
2172
|
+
}
|
|
2173
|
+
], ngImport: i0, template: `
|
|
2174
|
+
<studio-button-group
|
|
2175
|
+
[orientation]="orientation()"
|
|
2176
|
+
[attached]="attached()"
|
|
2177
|
+
[fullWidth]="fullWidth()"
|
|
2178
|
+
[spacing]="spacing()"
|
|
2179
|
+
[align]="align()"
|
|
2180
|
+
[ariaLabel]="ariaLabel()">
|
|
2181
|
+
@for (option of options(); track option.value) {
|
|
2182
|
+
<studio-button
|
|
2183
|
+
[variant]="isSelected(option.value) ? 'solid' : variant()"
|
|
2184
|
+
[size]="size()"
|
|
2185
|
+
[color]="isSelected(option.value) ? color() : 'secondary'"
|
|
2186
|
+
[radius]="radius()"
|
|
2187
|
+
[shadow]="shadow()"
|
|
2188
|
+
[disabled]="disabled() || option.disabled || false"
|
|
2189
|
+
[icon]="showIcons() ? option.icon : undefined"
|
|
2190
|
+
[iconPosition]="iconPosition()"
|
|
2191
|
+
[ariaLabel]="option.ariaLabel"
|
|
2192
|
+
(clicked)="handleToggle(option.value)">
|
|
2193
|
+
@if (iconPosition() !== 'only') {
|
|
2194
|
+
{{ option.label }}
|
|
2195
|
+
}
|
|
2196
|
+
</studio-button>
|
|
2197
|
+
}
|
|
2198
|
+
</studio-button-group>
|
|
2199
|
+
`, isInline: true, styles: [":host{display:inline-block}:host(.studio-button-toggle-group--disabled){opacity:.6;pointer-events:none}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "studio-button", inputs: ["variant", "size", "color", "radius", "shadow", "compact", "disabled", "loading", "loadingText", "fullWidth", "type", "icon", "iconPosition", "href", "target", "badge", "badgeColor", "ariaLabel"], outputs: ["clicked"] }, { kind: "component", type: ButtonGroupComponent, selector: "studio-button-group", inputs: ["orientation", "size", "variant", "color", "radius", "attached", "fullWidth", "disabled", "spacing", "align", "ariaLabel", "role"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2200
|
+
}
|
|
2201
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ButtonToggleGroupComponent, decorators: [{
|
|
2202
|
+
type: Component,
|
|
2203
|
+
args: [{ selector: 'studio-button-toggle-group', standalone: true, imports: [ButtonComponent, ButtonGroupComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
2204
|
+
{
|
|
2205
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2206
|
+
useExisting: forwardRef(() => ButtonToggleGroupComponent),
|
|
2207
|
+
multi: true
|
|
2208
|
+
}
|
|
2209
|
+
], host: {
|
|
2210
|
+
'[class]': 'hostClasses()'
|
|
2211
|
+
}, template: `
|
|
2212
|
+
<studio-button-group
|
|
2213
|
+
[orientation]="orientation()"
|
|
2214
|
+
[attached]="attached()"
|
|
2215
|
+
[fullWidth]="fullWidth()"
|
|
2216
|
+
[spacing]="spacing()"
|
|
2217
|
+
[align]="align()"
|
|
2218
|
+
[ariaLabel]="ariaLabel()">
|
|
2219
|
+
@for (option of options(); track option.value) {
|
|
2220
|
+
<studio-button
|
|
2221
|
+
[variant]="isSelected(option.value) ? 'solid' : variant()"
|
|
2222
|
+
[size]="size()"
|
|
2223
|
+
[color]="isSelected(option.value) ? color() : 'secondary'"
|
|
2224
|
+
[radius]="radius()"
|
|
2225
|
+
[shadow]="shadow()"
|
|
2226
|
+
[disabled]="disabled() || option.disabled || false"
|
|
2227
|
+
[icon]="showIcons() ? option.icon : undefined"
|
|
2228
|
+
[iconPosition]="iconPosition()"
|
|
2229
|
+
[ariaLabel]="option.ariaLabel"
|
|
2230
|
+
(clicked)="handleToggle(option.value)">
|
|
2231
|
+
@if (iconPosition() !== 'only') {
|
|
2232
|
+
{{ option.label }}
|
|
2233
|
+
}
|
|
2234
|
+
</studio-button>
|
|
2235
|
+
}
|
|
2236
|
+
</studio-button-group>
|
|
2237
|
+
`, styles: [":host{display:inline-block}:host(.studio-button-toggle-group--disabled){opacity:.6;pointer-events:none}\n"] }]
|
|
2238
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], allowEmpty: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowEmpty", required: false }] }], orientationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], colorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], shadowInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], attached: [{ type: i0.Input, args: [{ isSignal: true, alias: "attached", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
2239
|
+
|
|
1731
2240
|
/**
|
|
1732
2241
|
* Theme toggle switch with sun/moon icons
|
|
1733
2242
|
*
|
|
@@ -1818,6 +2327,433 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
1818
2327
|
* Domain-specific components for educational platforms
|
|
1819
2328
|
*/
|
|
1820
2329
|
|
|
2330
|
+
class MaskEngine {
|
|
2331
|
+
config;
|
|
2332
|
+
tokens;
|
|
2333
|
+
patterns = {
|
|
2334
|
+
'9': /\d/,
|
|
2335
|
+
'A': /[a-zA-Zа-яА-Я]/,
|
|
2336
|
+
'*': /[a-zA-Z0-9]/,
|
|
2337
|
+
'#': /./,
|
|
2338
|
+
'X': /[a-zA-Z0-9а-яА-Я]/,
|
|
2339
|
+
};
|
|
2340
|
+
constructor(config) {
|
|
2341
|
+
this.config = config;
|
|
2342
|
+
this.tokens = this.parsePattern(config.pattern);
|
|
2343
|
+
}
|
|
2344
|
+
process(value, cursorPos) {
|
|
2345
|
+
if (!value) {
|
|
2346
|
+
return {
|
|
2347
|
+
value: '',
|
|
2348
|
+
raw: '',
|
|
2349
|
+
cursor: 0,
|
|
2350
|
+
isComplete: false
|
|
2351
|
+
};
|
|
2352
|
+
}
|
|
2353
|
+
const cleaned = this.extractRaw(value);
|
|
2354
|
+
const formatted = this.applyMask(cleaned);
|
|
2355
|
+
const newCursor = cursorPos !== undefined
|
|
2356
|
+
? this.calculateCursor(cursorPos, value, formatted)
|
|
2357
|
+
: formatted.length;
|
|
2358
|
+
const displayValue = this.config.guide && this.config.showOnFocus
|
|
2359
|
+
? this.applyGuide(formatted)
|
|
2360
|
+
: formatted;
|
|
2361
|
+
return {
|
|
2362
|
+
value: displayValue,
|
|
2363
|
+
raw: cleaned,
|
|
2364
|
+
cursor: newCursor,
|
|
2365
|
+
isComplete: this.checkComplete(cleaned)
|
|
2366
|
+
};
|
|
2367
|
+
}
|
|
2368
|
+
getPlaceholder() {
|
|
2369
|
+
if (!this.tokens || this.tokens.length === 0)
|
|
2370
|
+
return '';
|
|
2371
|
+
return this.tokens
|
|
2372
|
+
.map(token => {
|
|
2373
|
+
if (token.type === 'static' && token.char)
|
|
2374
|
+
return token.char;
|
|
2375
|
+
return this.config.placeholder || '_';
|
|
2376
|
+
})
|
|
2377
|
+
.join('');
|
|
2378
|
+
}
|
|
2379
|
+
parsePattern(pattern) {
|
|
2380
|
+
const tokens = [];
|
|
2381
|
+
let i = 0;
|
|
2382
|
+
while (i < pattern.length) {
|
|
2383
|
+
const char = pattern[i];
|
|
2384
|
+
if (char === '\\' && i + 1 < pattern.length) {
|
|
2385
|
+
tokens.push({
|
|
2386
|
+
type: 'static',
|
|
2387
|
+
char: pattern[i + 1]
|
|
2388
|
+
});
|
|
2389
|
+
i += 2;
|
|
2390
|
+
continue;
|
|
2391
|
+
}
|
|
2392
|
+
if (char === '?' && tokens.length > 0) {
|
|
2393
|
+
tokens[tokens.length - 1].optional = true;
|
|
2394
|
+
i++;
|
|
2395
|
+
continue;
|
|
2396
|
+
}
|
|
2397
|
+
if (char in this.patterns) {
|
|
2398
|
+
tokens.push({
|
|
2399
|
+
type: this.getTokenType(char),
|
|
2400
|
+
pattern: this.patterns[char]
|
|
2401
|
+
});
|
|
2402
|
+
i++;
|
|
2403
|
+
}
|
|
2404
|
+
else {
|
|
2405
|
+
tokens.push({
|
|
2406
|
+
type: 'static',
|
|
2407
|
+
char
|
|
2408
|
+
});
|
|
2409
|
+
i++;
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
return tokens;
|
|
2413
|
+
}
|
|
2414
|
+
getTokenType(char) {
|
|
2415
|
+
const typeMap = {
|
|
2416
|
+
'9': 'digit',
|
|
2417
|
+
'A': 'letter',
|
|
2418
|
+
'*': 'alphanumeric',
|
|
2419
|
+
'#': 'any',
|
|
2420
|
+
'X': 'mixed'
|
|
2421
|
+
};
|
|
2422
|
+
return typeMap[char] || 'any';
|
|
2423
|
+
}
|
|
2424
|
+
applyMask(raw) {
|
|
2425
|
+
if (!raw || !this.tokens)
|
|
2426
|
+
return '';
|
|
2427
|
+
let result = '';
|
|
2428
|
+
let rawIndex = 0;
|
|
2429
|
+
for (const token of this.tokens) {
|
|
2430
|
+
if (rawIndex >= raw.length) {
|
|
2431
|
+
break;
|
|
2432
|
+
}
|
|
2433
|
+
if (token.type === 'static' && token.char) {
|
|
2434
|
+
result += token.char;
|
|
2435
|
+
if (raw[rawIndex] === token.char) {
|
|
2436
|
+
rawIndex++;
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
else {
|
|
2440
|
+
const char = raw[rawIndex];
|
|
2441
|
+
if (token.pattern?.test(char)) {
|
|
2442
|
+
result += char;
|
|
2443
|
+
rawIndex++;
|
|
2444
|
+
}
|
|
2445
|
+
else if (!token.optional) {
|
|
2446
|
+
break;
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
return result;
|
|
2451
|
+
}
|
|
2452
|
+
extractRaw(value) {
|
|
2453
|
+
if (!value || !this.tokens)
|
|
2454
|
+
return '';
|
|
2455
|
+
const staticChars = this.tokens
|
|
2456
|
+
.filter(t => t.type === 'static' && t.char)
|
|
2457
|
+
.map(t => t.char)
|
|
2458
|
+
.filter(Boolean);
|
|
2459
|
+
return value
|
|
2460
|
+
.split('')
|
|
2461
|
+
.filter(char => !staticChars.includes(char))
|
|
2462
|
+
.join('');
|
|
2463
|
+
}
|
|
2464
|
+
applyGuide(value) {
|
|
2465
|
+
if (!this.tokens || this.tokens.length === 0)
|
|
2466
|
+
return value;
|
|
2467
|
+
const placeholder = this.config.placeholder || '_';
|
|
2468
|
+
let result = value;
|
|
2469
|
+
const currentLength = value.replace(/[^a-zA-Z0-9а-яА-Я]/g, '').length;
|
|
2470
|
+
let addedCount = 0;
|
|
2471
|
+
for (let i = 0; i < this.tokens.length; i++) {
|
|
2472
|
+
const token = this.tokens[i];
|
|
2473
|
+
if (addedCount >= currentLength) {
|
|
2474
|
+
if (token.type === 'static' && token.char) {
|
|
2475
|
+
result += token.char;
|
|
2476
|
+
}
|
|
2477
|
+
else {
|
|
2478
|
+
result += placeholder;
|
|
2479
|
+
addedCount++;
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
return result;
|
|
2484
|
+
}
|
|
2485
|
+
calculateCursor(oldCursor, oldValue, newValue) {
|
|
2486
|
+
const diff = newValue.length - oldValue.length;
|
|
2487
|
+
let newCursor = oldCursor + diff;
|
|
2488
|
+
while (newCursor < newValue.length) {
|
|
2489
|
+
const charAtCursor = newValue[newCursor];
|
|
2490
|
+
const isStatic = this.tokens.some((t, i) => t.type === 'static' && t.char === charAtCursor && i === newCursor);
|
|
2491
|
+
if (!isStatic)
|
|
2492
|
+
break;
|
|
2493
|
+
newCursor++;
|
|
2494
|
+
}
|
|
2495
|
+
return Math.max(0, Math.min(newValue.length, newCursor));
|
|
2496
|
+
}
|
|
2497
|
+
checkComplete(raw) {
|
|
2498
|
+
const requiredTokens = this.tokens.filter(t => t.type !== 'static' && !t.optional);
|
|
2499
|
+
return raw.length >= requiredTokens.length;
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
const MASK_PRESETS = {
|
|
2504
|
+
'phone': {
|
|
2505
|
+
pattern: '+7 (999) 999-99-99',
|
|
2506
|
+
placeholder: '_',
|
|
2507
|
+
guide: true
|
|
2508
|
+
},
|
|
2509
|
+
'phone-ru': {
|
|
2510
|
+
pattern: '+7 (999) 999-99-99',
|
|
2511
|
+
placeholder: '_',
|
|
2512
|
+
guide: true
|
|
2513
|
+
},
|
|
2514
|
+
'phone-kz': {
|
|
2515
|
+
pattern: '+7 (999) 999-99-99',
|
|
2516
|
+
placeholder: '_',
|
|
2517
|
+
guide: true
|
|
2518
|
+
},
|
|
2519
|
+
'date': {
|
|
2520
|
+
pattern: '99.99.9999',
|
|
2521
|
+
placeholder: '_',
|
|
2522
|
+
guide: true
|
|
2523
|
+
},
|
|
2524
|
+
'datetime': {
|
|
2525
|
+
pattern: '99.99.9999 99:99',
|
|
2526
|
+
placeholder: '_',
|
|
2527
|
+
guide: true
|
|
2528
|
+
},
|
|
2529
|
+
'time': {
|
|
2530
|
+
pattern: '99:99',
|
|
2531
|
+
placeholder: '_',
|
|
2532
|
+
guide: true
|
|
2533
|
+
},
|
|
2534
|
+
'card': {
|
|
2535
|
+
pattern: '9999 9999 9999 9999',
|
|
2536
|
+
placeholder: 'X',
|
|
2537
|
+
guide: true
|
|
2538
|
+
},
|
|
2539
|
+
'inn': {
|
|
2540
|
+
pattern: '999999999999',
|
|
2541
|
+
placeholder: '_',
|
|
2542
|
+
guide: false
|
|
2543
|
+
},
|
|
2544
|
+
'snils': {
|
|
2545
|
+
pattern: '999-999-999 99',
|
|
2546
|
+
placeholder: '_',
|
|
2547
|
+
guide: true
|
|
2548
|
+
},
|
|
2549
|
+
'passport-ru': {
|
|
2550
|
+
pattern: '99 99 999999',
|
|
2551
|
+
placeholder: '_',
|
|
2552
|
+
guide: true
|
|
2553
|
+
}
|
|
2554
|
+
};
|
|
2555
|
+
|
|
2556
|
+
class MaskDirective {
|
|
2557
|
+
el = inject((ElementRef));
|
|
2558
|
+
renderer = inject(Renderer2);
|
|
2559
|
+
destroyRef = inject(DestroyRef);
|
|
2560
|
+
mask = input('', ...(ngDevMode ? [{ debugName: "mask", alias: 'studioMask',
|
|
2561
|
+
transform: (value) => {
|
|
2562
|
+
if (!value)
|
|
2563
|
+
return '';
|
|
2564
|
+
if (value in MASK_PRESETS) {
|
|
2565
|
+
return MASK_PRESETS[value].pattern;
|
|
2566
|
+
}
|
|
2567
|
+
return value;
|
|
2568
|
+
} }] : [{
|
|
2569
|
+
alias: 'studioMask',
|
|
2570
|
+
transform: (value) => {
|
|
2571
|
+
if (!value)
|
|
2572
|
+
return '';
|
|
2573
|
+
if (value in MASK_PRESETS) {
|
|
2574
|
+
return MASK_PRESETS[value].pattern;
|
|
2575
|
+
}
|
|
2576
|
+
return value;
|
|
2577
|
+
}
|
|
2578
|
+
}]));
|
|
2579
|
+
maskPlaceholder = input('_', ...(ngDevMode ? [{ debugName: "maskPlaceholder" }] : []));
|
|
2580
|
+
maskGuide = input(true, ...(ngDevMode ? [{ debugName: "maskGuide" }] : []));
|
|
2581
|
+
maskShowOnHover = input(false, ...(ngDevMode ? [{ debugName: "maskShowOnHover" }] : []));
|
|
2582
|
+
maskShowOnFocus = input(true, ...(ngDevMode ? [{ debugName: "maskShowOnFocus" }] : []));
|
|
2583
|
+
maskClearIncomplete = input(false, ...(ngDevMode ? [{ debugName: "maskClearIncomplete" }] : []));
|
|
2584
|
+
maskAutoUnmask = input(false, ...(ngDevMode ? [{ debugName: "maskAutoUnmask" }] : []));
|
|
2585
|
+
config = computed(() => ({
|
|
2586
|
+
pattern: this.mask(),
|
|
2587
|
+
placeholder: this.maskPlaceholder(),
|
|
2588
|
+
guide: this.maskGuide(),
|
|
2589
|
+
showOnHover: this.maskShowOnHover(),
|
|
2590
|
+
showOnFocus: this.maskShowOnFocus(),
|
|
2591
|
+
clearIncomplete: this.maskClearIncomplete(),
|
|
2592
|
+
autoUnmask: this.maskAutoUnmask()
|
|
2593
|
+
}), ...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
2594
|
+
engine = signal(null, ...(ngDevMode ? [{ debugName: "engine" }] : []));
|
|
2595
|
+
isComplete = signal(false, ...(ngDevMode ? [{ debugName: "isComplete" }] : []));
|
|
2596
|
+
isActive = signal(false, ...(ngDevMode ? [{ debugName: "isActive" }] : []));
|
|
2597
|
+
onChange = () => { };
|
|
2598
|
+
onTouched = () => { };
|
|
2599
|
+
constructor() {
|
|
2600
|
+
effect(() => {
|
|
2601
|
+
const maskPattern = this.mask();
|
|
2602
|
+
if (!maskPattern)
|
|
2603
|
+
return;
|
|
2604
|
+
const cfg = this.config();
|
|
2605
|
+
const newEngine = new MaskEngine(cfg);
|
|
2606
|
+
this.engine.set(newEngine);
|
|
2607
|
+
this.updatePlaceholder();
|
|
2608
|
+
});
|
|
2609
|
+
}
|
|
2610
|
+
onInput(event) {
|
|
2611
|
+
const eng = this.engine();
|
|
2612
|
+
if (!eng)
|
|
2613
|
+
return;
|
|
2614
|
+
const element = this.el.nativeElement;
|
|
2615
|
+
const cursorPos = element.selectionStart ?? 0;
|
|
2616
|
+
const result = eng.process(element.value, cursorPos);
|
|
2617
|
+
if (element.value !== result.value) {
|
|
2618
|
+
this.renderer.setProperty(element, 'value', result.value);
|
|
2619
|
+
element.setSelectionRange(result.cursor, result.cursor);
|
|
2620
|
+
}
|
|
2621
|
+
this.isComplete.set(result.isComplete);
|
|
2622
|
+
const outputValue = this.config().autoUnmask ? result.raw : result.value;
|
|
2623
|
+
this.onChange(outputValue);
|
|
2624
|
+
}
|
|
2625
|
+
onFocus() {
|
|
2626
|
+
this.isActive.set(true);
|
|
2627
|
+
if (this.maskShowOnFocus() && this.maskGuide()) {
|
|
2628
|
+
const eng = this.engine();
|
|
2629
|
+
if (!eng)
|
|
2630
|
+
return;
|
|
2631
|
+
const element = this.el.nativeElement;
|
|
2632
|
+
if (!element.value) {
|
|
2633
|
+
const result = eng.process('', 0);
|
|
2634
|
+
this.renderer.setProperty(element, 'value', result.value);
|
|
2635
|
+
element.setSelectionRange(0, 0);
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
onBlur() {
|
|
2640
|
+
this.isActive.set(false);
|
|
2641
|
+
this.onTouched();
|
|
2642
|
+
if (this.maskClearIncomplete() && !this.isComplete()) {
|
|
2643
|
+
this.renderer.setProperty(this.el.nativeElement, 'value', '');
|
|
2644
|
+
this.onChange('');
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
onPaste(event) {
|
|
2648
|
+
event.preventDefault();
|
|
2649
|
+
const eng = this.engine();
|
|
2650
|
+
if (!eng)
|
|
2651
|
+
return;
|
|
2652
|
+
const pastedText = event.clipboardData?.getData('text') || '';
|
|
2653
|
+
const element = this.el.nativeElement;
|
|
2654
|
+
const cursorPos = element.selectionStart ?? 0;
|
|
2655
|
+
const currentValue = element.value;
|
|
2656
|
+
const before = currentValue.slice(0, cursorPos);
|
|
2657
|
+
const after = currentValue.slice(element.selectionEnd ?? cursorPos);
|
|
2658
|
+
const newValue = before + pastedText + after;
|
|
2659
|
+
const result = eng.process(newValue, cursorPos + pastedText.length);
|
|
2660
|
+
this.renderer.setProperty(element, 'value', result.value);
|
|
2661
|
+
element.setSelectionRange(result.cursor, result.cursor);
|
|
2662
|
+
const outputValue = this.config().autoUnmask ? result.raw : result.value;
|
|
2663
|
+
this.onChange(outputValue);
|
|
2664
|
+
}
|
|
2665
|
+
writeValue(value) {
|
|
2666
|
+
const eng = this.engine();
|
|
2667
|
+
if (!eng)
|
|
2668
|
+
return;
|
|
2669
|
+
if (value) {
|
|
2670
|
+
const result = eng.process(value);
|
|
2671
|
+
this.renderer.setProperty(this.el.nativeElement, 'value', result.value);
|
|
2672
|
+
this.isComplete.set(result.isComplete);
|
|
2673
|
+
}
|
|
2674
|
+
else {
|
|
2675
|
+
this.renderer.setProperty(this.el.nativeElement, 'value', '');
|
|
2676
|
+
this.isComplete.set(false);
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
registerOnChange(fn) {
|
|
2680
|
+
this.onChange = fn;
|
|
2681
|
+
}
|
|
2682
|
+
registerOnTouched(fn) {
|
|
2683
|
+
this.onTouched = fn;
|
|
2684
|
+
}
|
|
2685
|
+
validate(control) {
|
|
2686
|
+
if (!control.value)
|
|
2687
|
+
return null;
|
|
2688
|
+
const complete = this.isComplete();
|
|
2689
|
+
return complete ? null : { maskIncomplete: { value: control.value } };
|
|
2690
|
+
}
|
|
2691
|
+
updatePlaceholder() {
|
|
2692
|
+
if (!this.maskShowOnFocus())
|
|
2693
|
+
return;
|
|
2694
|
+
const eng = this.engine();
|
|
2695
|
+
if (!eng)
|
|
2696
|
+
return;
|
|
2697
|
+
try {
|
|
2698
|
+
const placeholderText = eng.getPlaceholder();
|
|
2699
|
+
if (placeholderText) {
|
|
2700
|
+
this.renderer.setAttribute(this.el.nativeElement, 'placeholder', placeholderText);
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
catch (e) {
|
|
2704
|
+
console.warn('Failed to update placeholder:', e);
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2707
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: MaskDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2708
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.12", type: MaskDirective, isStandalone: true, selector: "input[studioMask]", inputs: { mask: { classPropertyName: "mask", publicName: "studioMask", isSignal: true, isRequired: false, transformFunction: null }, maskPlaceholder: { classPropertyName: "maskPlaceholder", publicName: "maskPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, maskGuide: { classPropertyName: "maskGuide", publicName: "maskGuide", isSignal: true, isRequired: false, transformFunction: null }, maskShowOnHover: { classPropertyName: "maskShowOnHover", publicName: "maskShowOnHover", isSignal: true, isRequired: false, transformFunction: null }, maskShowOnFocus: { classPropertyName: "maskShowOnFocus", publicName: "maskShowOnFocus", isSignal: true, isRequired: false, transformFunction: null }, maskClearIncomplete: { classPropertyName: "maskClearIncomplete", publicName: "maskClearIncomplete", isSignal: true, isRequired: false, transformFunction: null }, maskAutoUnmask: { classPropertyName: "maskAutoUnmask", publicName: "maskAutoUnmask", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "input": "onInput($event)", "focus": "onFocus()", "blur": "onBlur()", "paste": "onPaste($event)" }, properties: { "attr.data-mask-complete": "isComplete()", "attr.data-mask-active": "isActive()" } }, providers: [
|
|
2709
|
+
{
|
|
2710
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2711
|
+
useExisting: forwardRef(() => MaskDirective),
|
|
2712
|
+
multi: true
|
|
2713
|
+
},
|
|
2714
|
+
{
|
|
2715
|
+
provide: NG_VALIDATORS,
|
|
2716
|
+
useExisting: forwardRef(() => MaskDirective),
|
|
2717
|
+
multi: true
|
|
2718
|
+
}
|
|
2719
|
+
], ngImport: i0 });
|
|
2720
|
+
}
|
|
2721
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: MaskDirective, decorators: [{
|
|
2722
|
+
type: Directive,
|
|
2723
|
+
args: [{
|
|
2724
|
+
selector: 'input[studioMask]',
|
|
2725
|
+
standalone: true,
|
|
2726
|
+
providers: [
|
|
2727
|
+
{
|
|
2728
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2729
|
+
useExisting: forwardRef(() => MaskDirective),
|
|
2730
|
+
multi: true
|
|
2731
|
+
},
|
|
2732
|
+
{
|
|
2733
|
+
provide: NG_VALIDATORS,
|
|
2734
|
+
useExisting: forwardRef(() => MaskDirective),
|
|
2735
|
+
multi: true
|
|
2736
|
+
}
|
|
2737
|
+
],
|
|
2738
|
+
host: {
|
|
2739
|
+
'[attr.data-mask-complete]': 'isComplete()',
|
|
2740
|
+
'[attr.data-mask-active]': 'isActive()'
|
|
2741
|
+
}
|
|
2742
|
+
}]
|
|
2743
|
+
}], ctorParameters: () => [], propDecorators: { mask: [{ type: i0.Input, args: [{ isSignal: true, alias: "studioMask", required: false }] }], maskPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "maskPlaceholder", required: false }] }], maskGuide: [{ type: i0.Input, args: [{ isSignal: true, alias: "maskGuide", required: false }] }], maskShowOnHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "maskShowOnHover", required: false }] }], maskShowOnFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "maskShowOnFocus", required: false }] }], maskClearIncomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "maskClearIncomplete", required: false }] }], maskAutoUnmask: [{ type: i0.Input, args: [{ isSignal: true, alias: "maskAutoUnmask", required: false }] }], onInput: [{
|
|
2744
|
+
type: HostListener,
|
|
2745
|
+
args: ['input', ['$event']]
|
|
2746
|
+
}], onFocus: [{
|
|
2747
|
+
type: HostListener,
|
|
2748
|
+
args: ['focus']
|
|
2749
|
+
}], onBlur: [{
|
|
2750
|
+
type: HostListener,
|
|
2751
|
+
args: ['blur']
|
|
2752
|
+
}], onPaste: [{
|
|
2753
|
+
type: HostListener,
|
|
2754
|
+
args: ['paste', ['$event']]
|
|
2755
|
+
}] } });
|
|
2756
|
+
|
|
1821
2757
|
/**
|
|
1822
2758
|
* Public API Surface of @eduboxpro/studio
|
|
1823
2759
|
*/
|
|
@@ -1829,5 +2765,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
1829
2765
|
* Generated bundle index. Do not edit.
|
|
1830
2766
|
*/
|
|
1831
2767
|
|
|
1832
|
-
export { BadgeComponent, ButtonComponent, CheckboxComponent, IconComponent, InputComponent, STUDIO_CONFIG, StudioConfigService, SwitchComponent, TextareaComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
|
|
2768
|
+
export { BadgeComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, CheckboxComponent, IconComponent, InputComponent, MASK_PRESETS, MaskDirective, MaskEngine, STUDIO_CONFIG, SelectComponent, StudioConfigService, SwitchComponent, TextareaComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
|
|
1833
2769
|
//# sourceMappingURL=eduboxpro-studio.mjs.map
|