@haloduck/ui 2.0.38 → 2.0.40
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/README.md +10 -1
- package/fesm2022/haloduck-ui.mjs +481 -169
- package/fesm2022/haloduck-ui.mjs.map +1 -1
- package/index.d.ts +14 -1
- package/package.json +1 -1
- package/public/i18n/haloduck/ko.json +1 -1
- package/src/tailwind.css +189 -1
package/fesm2022/haloduck-ui.mjs
CHANGED
|
@@ -37,8 +37,7 @@ class NotificationService {
|
|
|
37
37
|
timeout: timeout,
|
|
38
38
|
}));
|
|
39
39
|
}
|
|
40
|
-
else if ('Notification' in window &&
|
|
41
|
-
Notification.permission === 'granted') {
|
|
40
|
+
else if ('Notification' in window && Notification.permission === 'granted') {
|
|
42
41
|
// 웹브라우저에서 실행될 때는 기본 브라우저 알림 사용
|
|
43
42
|
new Notification(title, { body: body });
|
|
44
43
|
}
|
|
@@ -86,11 +85,11 @@ class ButtonComponent {
|
|
|
86
85
|
disabled = false;
|
|
87
86
|
variant = 'primary';
|
|
88
87
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
89
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: ButtonComponent, isStandalone: true, selector: "haloduck-button", inputs: { disabled: "disabled", variant: "variant" }, ngImport: i0, template: "<button
|
|
88
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: ButtonComponent, isStandalone: true, selector: "haloduck-button", inputs: { disabled: "disabled", variant: "variant" }, ngImport: i0, template: "<button\n type=\"button\"\n [disabled]=\"disabled\"\n [ngClass]=\"{\n 'bg-light-primary text-light-on-primary dark:bg-dark-primary dark:text-dark-on-primary':\n variant === 'primary' && !disabled,\n 'bg-light-primary-light text-light-on-primary-light dark:bg-dark-primary-light dark:text-dark-on-primary-light':\n variant === 'secondary' && !disabled,\n 'bg-light-danger text-light-on-danger dark:bg-dark-danger dark:text-dark-on-danger':\n variant === 'danger' && !disabled,\n 'bg-light-background text-light-on-background dark:bg-dark-background dark:text-dark-on-background border border-light-on-background dark:border-dark-on-background':\n variant === 'none' && !disabled,\n 'bg-light-inactive text-light-on-inactive dark:bg-dark-inactive dark:text-dark-on-inactive active:animate-bounce hover:cursor-not-allowed':\n disabled,\n 'active:scale-95 transition-transform': !disabled,\n 'hover:cursor-pointer': !disabled,\n }\"\n class=\"px-4 py-1.5 rounded-lg text-sm/6 w-full text-nowrap\"\n>\n <ng-content></ng-content>\n</button>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
90
89
|
}
|
|
91
90
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
92
91
|
type: Component,
|
|
93
|
-
args: [{ selector: 'haloduck-button', imports: [CommonModule], template: "<button
|
|
92
|
+
args: [{ selector: 'haloduck-button', imports: [CommonModule], template: "<button\n type=\"button\"\n [disabled]=\"disabled\"\n [ngClass]=\"{\n 'bg-light-primary text-light-on-primary dark:bg-dark-primary dark:text-dark-on-primary':\n variant === 'primary' && !disabled,\n 'bg-light-primary-light text-light-on-primary-light dark:bg-dark-primary-light dark:text-dark-on-primary-light':\n variant === 'secondary' && !disabled,\n 'bg-light-danger text-light-on-danger dark:bg-dark-danger dark:text-dark-on-danger':\n variant === 'danger' && !disabled,\n 'bg-light-background text-light-on-background dark:bg-dark-background dark:text-dark-on-background border border-light-on-background dark:border-dark-on-background':\n variant === 'none' && !disabled,\n 'bg-light-inactive text-light-on-inactive dark:bg-dark-inactive dark:text-dark-on-inactive active:animate-bounce hover:cursor-not-allowed':\n disabled,\n 'active:scale-95 transition-transform': !disabled,\n 'hover:cursor-pointer': !disabled,\n }\"\n class=\"px-4 py-1.5 rounded-lg text-sm/6 w-full text-nowrap\"\n>\n <ng-content></ng-content>\n</button>\n" }]
|
|
94
93
|
}], propDecorators: { disabled: [{
|
|
95
94
|
type: Input
|
|
96
95
|
}], variant: [{
|
|
@@ -163,7 +162,7 @@ class InputComponent {
|
|
|
163
162
|
multi: true,
|
|
164
163
|
},
|
|
165
164
|
provideTranslocoScope('haloduck'),
|
|
166
|
-
], viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }, { propertyName: "inputElement", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\n <label
|
|
165
|
+
], viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }, { propertyName: "inputElement", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\"\n >\n <ng-content></ng-content>\n </label>\n @if (rows > 1) {\n <textarea\n #input\n [value]=\"value\"\n (input)=\"onInput($event)\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [rows]=\"rows\"\n (keydown)=\"onKeydown($event)\"\n class=\"block w-full rounded-md bg-light-control dark:bg-dark-control disabled:bg-light-control/60 dark:disabled:bg-dark-control/80 px-3 py-1.5 text-base text-light-on-control dark:text-dark-on-control disabled:cursor-not-allowed disabled:text-light-on-control/60 dark:disabled:text-dark-on-control/80 outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary sm:text-sm/6\"\n ></textarea>\n } @else {\n <input\n #input\n [type]=\"type\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n (keydown)=\"onKeydown($event)\"\n class=\"block w-full rounded-md bg-light-control dark:bg-dark-control disabled:bg-light-control/60 dark:disabled:bg-dark-control/80 px-3 py-1.5 text-base text-light-on-control dark:text-dark-on-control disabled:cursor-not-allowed disabled:text-light-on-control/60 dark:disabled:text-dark-on-control/80 outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary sm:text-sm/6\"\n />\n }\n</div>\n", styles: [""] });
|
|
167
166
|
}
|
|
168
167
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: InputComponent, decorators: [{
|
|
169
168
|
type: Component,
|
|
@@ -174,7 +173,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
174
173
|
multi: true,
|
|
175
174
|
},
|
|
176
175
|
provideTranslocoScope('haloduck'),
|
|
177
|
-
], template: "<div class=\"flex flex-col gap-2\">\n <label
|
|
176
|
+
], template: "<div class=\"flex flex-col gap-2\">\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\"\n >\n <ng-content></ng-content>\n </label>\n @if (rows > 1) {\n <textarea\n #input\n [value]=\"value\"\n (input)=\"onInput($event)\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [rows]=\"rows\"\n (keydown)=\"onKeydown($event)\"\n class=\"block w-full rounded-md bg-light-control dark:bg-dark-control disabled:bg-light-control/60 dark:disabled:bg-dark-control/80 px-3 py-1.5 text-base text-light-on-control dark:text-dark-on-control disabled:cursor-not-allowed disabled:text-light-on-control/60 dark:disabled:text-dark-on-control/80 outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary sm:text-sm/6\"\n ></textarea>\n } @else {\n <input\n #input\n [type]=\"type\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n (keydown)=\"onKeydown($event)\"\n class=\"block w-full rounded-md bg-light-control dark:bg-dark-control disabled:bg-light-control/60 dark:disabled:bg-dark-control/80 px-3 py-1.5 text-base text-light-on-control dark:text-dark-on-control disabled:cursor-not-allowed disabled:text-light-on-control/60 dark:disabled:text-dark-on-control/80 outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary sm:text-sm/6\"\n />\n }\n</div>\n" }]
|
|
178
177
|
}], propDecorators: { label: [{
|
|
179
178
|
type: ViewChild,
|
|
180
179
|
args: ['label']
|
|
@@ -323,7 +322,11 @@ class AuthenticateComponent {
|
|
|
323
322
|
return /[^A-Za-z0-9]/.test(this.passwordValue);
|
|
324
323
|
}
|
|
325
324
|
get isPasswordValid() {
|
|
326
|
-
return this.isMinLength &&
|
|
325
|
+
return (this.isMinLength &&
|
|
326
|
+
this.hasUppercase &&
|
|
327
|
+
this.hasLowercase &&
|
|
328
|
+
this.hasNumber &&
|
|
329
|
+
this.hasSpecialChar);
|
|
327
330
|
}
|
|
328
331
|
get passwordRules() {
|
|
329
332
|
return [
|
|
@@ -335,11 +338,11 @@ class AuthenticateComponent {
|
|
|
335
338
|
];
|
|
336
339
|
}
|
|
337
340
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AuthenticateComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
|
|
338
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: AuthenticateComponent, isStandalone: true, selector: "haloduck-authenticate", ngImport: i0, template: "<div class=\"flex flex-col items-center justify-center h-full\">\n <!-- auth.component.html -->\n <div
|
|
341
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: AuthenticateComponent, isStandalone: true, selector: "haloduck-authenticate", ngImport: i0, template: "<div class=\"flex flex-col items-center justify-center h-full\">\n <!-- auth.component.html -->\n <div\n class=\"w-full max-w-md mx-auto mt-20 p-8 shadow-lg rounded-2xl bg-light-background dark:bg-dark-background\"\n >\n @switch (stage) {\n @case ('login') {\n <!-- \uB85C\uADF8\uC778 -->\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"login()\" class=\"flex flex-col gap-4\">\n <haloduck-input\n data-testid=\"authenticate-login-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\"\n />\n <haloduck-input\n data-testid=\"authenticate-login-password\"\n type=\"password\"\n formControlName=\"password\"\n placeholder=\"Password\"\n />\n <haloduck-button\n data-testid=\"authenticate-login-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"login()\"\n >Sign In</haloduck-button\n >\n </form>\n }\n @case ('signup') {\n <!-- \uD68C\uC6D0\uAC00\uC785 -->\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"signup()\" class=\"flex flex-col gap-4\">\n <haloduck-input\n data-testid=\"authenticate-signup-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\"\n />\n <haloduck-input\n data-testid=\"authenticate-signup-password\"\n type=\"password\"\n formControlName=\"password\"\n placeholder=\"Password\"\n />\n <haloduck-button data-testid=\"authenticate-signup-submit\" type=\"submit\" variant=\"primary\"\n >Sign Up</haloduck-button\n >\n </form>\n }\n @case ('reset') {\n <!-- \uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815 \uC694\uCCAD -->\n <form [formGroup]=\"resetForm\" (ngSubmit)=\"reset()\" class=\"flex flex-col gap-4\">\n <haloduck-input\n data-testid=\"authenticate-reset-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\"\n />\n <haloduck-button\n data-testid=\"authenticate-reset-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"reset()\"\n >Send Verification Code</haloduck-button\n >\n </form>\n }\n @case ('otpVerify') {\n <!-- OTP \uC778\uC99D \uD6C4 \uC0C8 \uBE44\uBC00\uBC88\uD638 \uC785\uB825 -->\n <form [formGroup]=\"otpForm\" (ngSubmit)=\"verifyOtp()\" class=\"flex flex-col gap-4\">\n <haloduck-input\n data-testid=\"authenticate-otp-code\"\n type=\"text\"\n formControlName=\"code\"\n placeholder=\"Verification Code\"\n />\n <haloduck-input\n data-testid=\"authenticate-otp-password\"\n type=\"password\"\n formControlName=\"newPassword\"\n placeholder=\"New password\"\n />\n <haloduck-button\n data-testid=\"authenticate-otp-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"verifyOtp()\"\n >Reset Password</haloduck-button\n >\n </form>\n }\n @case ('newPassword') {\n <!-- \uC784\uC2DC \uBE44\uBC00\uBC88\uD638 \u2192 \uC0C8 \uBE44\uBC00\uBC88\uD638 \uBCC0\uACBD -->\n <form\n [formGroup]=\"newPasswordForm\"\n (ngSubmit)=\"confirmNewPassword()\"\n class=\"flex flex-col gap-4\"\n >\n <haloduck-input\n data-testid=\"authenticate-new-password-password\"\n type=\"password\"\n formControlName=\"newPassword\"\n placeholder=\"New password\"\n >\n </haloduck-input>\n <div class=\"text-sm flex flex-col\">\n @for (rule of passwordRules; track rule.label) {\n <span\n [class.text-light-secondary]=\"rule.valid && passwordValue !== ''\"\n [class.line-through]=\"rule.valid && passwordValue !== ''\"\n [class.text-light-danger]=\"!rule.valid && passwordValue !== ''\"\n [class.text-light-inactive]=\"passwordValue === ''\"\n >\n {{ rule.valid ? '\u2714' : '\u2717' }} {{ rule.label }}\n </span>\n }\n </div>\n <haloduck-button\n data-testid=\"authenticate-new-password-submit\"\n type=\"submit\"\n (click)=\"confirmNewPassword()\"\n variant=\"primary\"\n [disabled]=\"!isPasswordValid\"\n >Change Password</haloduck-button\n >\n </form>\n }\n }\n\n <!-- \uB2E8\uACC4 \uC804\uD658 \uD0ED -->\n <div class=\"flex justify-center mt-6 gap-4\">\n @if (stage !== 'login') {\n <haloduck-button\n data-testid=\"authenticate-to-signin\"\n variant=\"none\"\n (click)=\"switchStage('login')\"\n >to Sign In</haloduck-button\n >\n }\n <!-- <haloduck-button class=\"text-sm text-blue-600 hover:underline\"\n (click)=\"switchStage('signup')\">\uD68C\uC6D0\uAC00\uC785</haloduck-button> -->\n @if (stage !== 'reset' && stage !== 'otpVerify' && stage !== 'newPassword') {\n <haloduck-button\n data-testid=\"authenticate-to-reset-password\"\n variant=\"secondary\"\n (click)=\"switchStage('reset')\"\n >Reset Password</haloduck-button\n >\n }\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: InputComponent, selector: "haloduck-input", inputs: ["placeholder", "type", "disabled", "rows", "autofocus", "value"] }, { kind: "component", type: ButtonComponent, selector: "haloduck-button", inputs: ["disabled", "variant"] }] });
|
|
339
342
|
}
|
|
340
343
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AuthenticateComponent, decorators: [{
|
|
341
344
|
type: Component,
|
|
342
|
-
args: [{ selector: 'haloduck-authenticate', imports: [FormsModule, ReactiveFormsModule, InputComponent, ButtonComponent], template: "<div class=\"flex flex-col items-center justify-center h-full\">\n <!-- auth.component.html -->\n <div
|
|
345
|
+
args: [{ selector: 'haloduck-authenticate', imports: [FormsModule, ReactiveFormsModule, InputComponent, ButtonComponent], template: "<div class=\"flex flex-col items-center justify-center h-full\">\n <!-- auth.component.html -->\n <div\n class=\"w-full max-w-md mx-auto mt-20 p-8 shadow-lg rounded-2xl bg-light-background dark:bg-dark-background\"\n >\n @switch (stage) {\n @case ('login') {\n <!-- \uB85C\uADF8\uC778 -->\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"login()\" class=\"flex flex-col gap-4\">\n <haloduck-input\n data-testid=\"authenticate-login-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\"\n />\n <haloduck-input\n data-testid=\"authenticate-login-password\"\n type=\"password\"\n formControlName=\"password\"\n placeholder=\"Password\"\n />\n <haloduck-button\n data-testid=\"authenticate-login-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"login()\"\n >Sign In</haloduck-button\n >\n </form>\n }\n @case ('signup') {\n <!-- \uD68C\uC6D0\uAC00\uC785 -->\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"signup()\" class=\"flex flex-col gap-4\">\n <haloduck-input\n data-testid=\"authenticate-signup-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\"\n />\n <haloduck-input\n data-testid=\"authenticate-signup-password\"\n type=\"password\"\n formControlName=\"password\"\n placeholder=\"Password\"\n />\n <haloduck-button data-testid=\"authenticate-signup-submit\" type=\"submit\" variant=\"primary\"\n >Sign Up</haloduck-button\n >\n </form>\n }\n @case ('reset') {\n <!-- \uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815 \uC694\uCCAD -->\n <form [formGroup]=\"resetForm\" (ngSubmit)=\"reset()\" class=\"flex flex-col gap-4\">\n <haloduck-input\n data-testid=\"authenticate-reset-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\"\n />\n <haloduck-button\n data-testid=\"authenticate-reset-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"reset()\"\n >Send Verification Code</haloduck-button\n >\n </form>\n }\n @case ('otpVerify') {\n <!-- OTP \uC778\uC99D \uD6C4 \uC0C8 \uBE44\uBC00\uBC88\uD638 \uC785\uB825 -->\n <form [formGroup]=\"otpForm\" (ngSubmit)=\"verifyOtp()\" class=\"flex flex-col gap-4\">\n <haloduck-input\n data-testid=\"authenticate-otp-code\"\n type=\"text\"\n formControlName=\"code\"\n placeholder=\"Verification Code\"\n />\n <haloduck-input\n data-testid=\"authenticate-otp-password\"\n type=\"password\"\n formControlName=\"newPassword\"\n placeholder=\"New password\"\n />\n <haloduck-button\n data-testid=\"authenticate-otp-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"verifyOtp()\"\n >Reset Password</haloduck-button\n >\n </form>\n }\n @case ('newPassword') {\n <!-- \uC784\uC2DC \uBE44\uBC00\uBC88\uD638 \u2192 \uC0C8 \uBE44\uBC00\uBC88\uD638 \uBCC0\uACBD -->\n <form\n [formGroup]=\"newPasswordForm\"\n (ngSubmit)=\"confirmNewPassword()\"\n class=\"flex flex-col gap-4\"\n >\n <haloduck-input\n data-testid=\"authenticate-new-password-password\"\n type=\"password\"\n formControlName=\"newPassword\"\n placeholder=\"New password\"\n >\n </haloduck-input>\n <div class=\"text-sm flex flex-col\">\n @for (rule of passwordRules; track rule.label) {\n <span\n [class.text-light-secondary]=\"rule.valid && passwordValue !== ''\"\n [class.line-through]=\"rule.valid && passwordValue !== ''\"\n [class.text-light-danger]=\"!rule.valid && passwordValue !== ''\"\n [class.text-light-inactive]=\"passwordValue === ''\"\n >\n {{ rule.valid ? '\u2714' : '\u2717' }} {{ rule.label }}\n </span>\n }\n </div>\n <haloduck-button\n data-testid=\"authenticate-new-password-submit\"\n type=\"submit\"\n (click)=\"confirmNewPassword()\"\n variant=\"primary\"\n [disabled]=\"!isPasswordValid\"\n >Change Password</haloduck-button\n >\n </form>\n }\n }\n\n <!-- \uB2E8\uACC4 \uC804\uD658 \uD0ED -->\n <div class=\"flex justify-center mt-6 gap-4\">\n @if (stage !== 'login') {\n <haloduck-button\n data-testid=\"authenticate-to-signin\"\n variant=\"none\"\n (click)=\"switchStage('login')\"\n >to Sign In</haloduck-button\n >\n }\n <!-- <haloduck-button class=\"text-sm text-blue-600 hover:underline\"\n (click)=\"switchStage('signup')\">\uD68C\uC6D0\uAC00\uC785</haloduck-button> -->\n @if (stage !== 'reset' && stage !== 'otpVerify' && stage !== 'newPassword') {\n <haloduck-button\n data-testid=\"authenticate-to-reset-password\"\n variant=\"secondary\"\n (click)=\"switchStage('reset')\"\n >Reset Password</haloduck-button\n >\n }\n </div>\n </div>\n</div>\n" }]
|
|
343
346
|
}], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i2.HttpClient }] });
|
|
344
347
|
|
|
345
348
|
class SelectDropdownComponent {
|
|
@@ -473,7 +476,9 @@ class SelectDropdownComponent {
|
|
|
473
476
|
const isActive = this.activeManualKey === key;
|
|
474
477
|
if (prefix) {
|
|
475
478
|
// selected if there exists a value with more than prefix, OR if it's currently active
|
|
476
|
-
const hasValueWithPrefix = this._selectedOptionIds.some((selectedId) => typeof selectedId === 'string' &&
|
|
479
|
+
const hasValueWithPrefix = this._selectedOptionIds.some((selectedId) => typeof selectedId === 'string' &&
|
|
480
|
+
selectedId.startsWith(prefix) &&
|
|
481
|
+
selectedId.length > prefix.length);
|
|
477
482
|
return hasValueWithPrefix || isActive;
|
|
478
483
|
}
|
|
479
484
|
// no prefix: consider selected if any selected id equals current typed value (non-empty) OR if it's active
|
|
@@ -497,7 +502,7 @@ class SelectDropdownComponent {
|
|
|
497
502
|
return false;
|
|
498
503
|
}
|
|
499
504
|
getManualKey(option) {
|
|
500
|
-
return option.manualPrefix ||
|
|
505
|
+
return option.manualPrefix || option.id || option.value;
|
|
501
506
|
}
|
|
502
507
|
seedManualInputs() {
|
|
503
508
|
const manualOptions = this._options.filter((o) => o.shouldManualInput);
|
|
@@ -505,9 +510,7 @@ class SelectDropdownComponent {
|
|
|
505
510
|
const prefix = opt.manualPrefix || '';
|
|
506
511
|
const key = this.getManualKey(opt);
|
|
507
512
|
const existingWithPrefix = this._selectedOptionIds.find((id) => prefix ? id?.startsWith(prefix) : false);
|
|
508
|
-
const value = existingWithPrefix
|
|
509
|
-
? existingWithPrefix.substring(prefix.length)
|
|
510
|
-
: '';
|
|
513
|
+
const value = existingWithPrefix ? existingWithPrefix.substring(prefix.length) : '';
|
|
511
514
|
this.manualInputValues[key] = value;
|
|
512
515
|
}
|
|
513
516
|
}
|
|
@@ -607,11 +610,11 @@ class SelectDropdownComponent {
|
|
|
607
610
|
});
|
|
608
611
|
}
|
|
609
612
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SelectDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
610
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: SelectDropdownComponent, isStandalone: true, selector: "haloduck-select-dropdown", inputs: { useFilter: "useFilter", multiselect: "multiselect", atLeastOne: "atLeastOne", asButton: "asButton", options: "options", selectedOptionIds: "selectedOptionIds" }, outputs: { selectedChange: "selectedChange", closeDropdown: "closeDropdown" }, providers: [provideTranslocoScope('haloduck')], ngImport: i0, template: "<div
|
|
613
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: SelectDropdownComponent, isStandalone: true, selector: "haloduck-select-dropdown", inputs: { useFilter: "useFilter", multiselect: "multiselect", atLeastOne: "atLeastOne", asButton: "asButton", options: "options", selectedOptionIds: "selectedOptionIds" }, outputs: { selectedChange: "selectedChange", closeDropdown: "closeDropdown" }, providers: [provideTranslocoScope('haloduck')], ngImport: i0, template: "<div\n id=\"dropdown\"\n class=\"max-w-full mt-2 absolute z-40 bg-light-background dark:bg-dark-background text-light-on-background dark:text-dark-on-background border border-light-inactive dark:border-dark-inactive rounded max-h-60 flex flex-col gap-2\"\n>\n @if (useFilter && _options.length >= 5) {\n <input\n #inputFilter\n id=\"inputFilter\"\n type=\"text\"\n [placeholder]=\"'haloduck.ui.select.Keyword...' | transloco\"\n (input)=\"onFilterInput($event)\"\n class=\"text-light-inactive dark:text-dark-inactive rounded-md outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary px-3 py-1.5 text-sm/6 bg-light-control dark:bg-dark-control m-2\"\n />\n }\n <div class=\"overflow-y-auto\">\n @for (option of _filteredOptions(); track option.id ? option.id : option.value) {\n <div\n class=\"px-3 py-2 text-sm/6 hover:bg-light-secondary/60 dark:hover:bg-dark-secondary/60 flex items-center justify-start whitespace-nowrap\"\n [class.cursor-pointer]=\"!option.shouldManualInput\"\n (click)=\"onToggleOption(option)\"\n >\n @if (!asButton) {\n @if (isOptionSelected(option)) {\n <svg\n class=\"w-4 h-4 text-light-primary dark:text-dark-primary inline-block mr-2\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 00-1.414 0L8 12.586 4.707 9.293a1 1 0 00-1.414 1.414l4 4a1 1 0 001.414 0l8-8a1 1 0 000-1.414z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n } @else {\n <div class=\"w-4 h-4 inline-block mr-2\"></div>\n }\n }\n @if (\n option.shouldManualInput &&\n (isOptionSelected(option) ||\n activeManualKey ===\n (option.manualPrefix ? option.manualPrefix : option.id || option.value))\n ) {\n <input\n type=\"text\"\n [(ngModel)]=\"\n manualInputValues[\n option.manualPrefix ? option.manualPrefix : option.id || option.value\n ]\n \"\n [attr.data-manual-key]=\"\n option.manualPrefix ? option.manualPrefix : option.id || option.value\n \"\n (ngModelChange)=\"onManualInputChange(option, $event)\"\n (click)=\"$event.stopPropagation()\"\n (blur)=\"onManualInputBlur(option)\"\n (keydown.enter)=\"onManualInputConfirm(option)\"\n class=\"text-light-on-control dark:text-dark-on-control rounded-md outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary px-2 py-1 text-sm/6 bg-light-control dark:bg-dark-control w-full\"\n />\n } @else {\n {{ option.value }}\n }\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: TranslocoModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }] });
|
|
611
614
|
}
|
|
612
615
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SelectDropdownComponent, decorators: [{
|
|
613
616
|
type: Component,
|
|
614
|
-
args: [{ selector: 'haloduck-select-dropdown', imports: [TranslocoModule, FormsModule], providers: [provideTranslocoScope('haloduck')], template: "<div
|
|
617
|
+
args: [{ selector: 'haloduck-select-dropdown', imports: [TranslocoModule, FormsModule], providers: [provideTranslocoScope('haloduck')], template: "<div\n id=\"dropdown\"\n class=\"max-w-full mt-2 absolute z-40 bg-light-background dark:bg-dark-background text-light-on-background dark:text-dark-on-background border border-light-inactive dark:border-dark-inactive rounded max-h-60 flex flex-col gap-2\"\n>\n @if (useFilter && _options.length >= 5) {\n <input\n #inputFilter\n id=\"inputFilter\"\n type=\"text\"\n [placeholder]=\"'haloduck.ui.select.Keyword...' | transloco\"\n (input)=\"onFilterInput($event)\"\n class=\"text-light-inactive dark:text-dark-inactive rounded-md outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary px-3 py-1.5 text-sm/6 bg-light-control dark:bg-dark-control m-2\"\n />\n }\n <div class=\"overflow-y-auto\">\n @for (option of _filteredOptions(); track option.id ? option.id : option.value) {\n <div\n class=\"px-3 py-2 text-sm/6 hover:bg-light-secondary/60 dark:hover:bg-dark-secondary/60 flex items-center justify-start whitespace-nowrap\"\n [class.cursor-pointer]=\"!option.shouldManualInput\"\n (click)=\"onToggleOption(option)\"\n >\n @if (!asButton) {\n @if (isOptionSelected(option)) {\n <svg\n class=\"w-4 h-4 text-light-primary dark:text-dark-primary inline-block mr-2\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 00-1.414 0L8 12.586 4.707 9.293a1 1 0 00-1.414 1.414l4 4a1 1 0 001.414 0l8-8a1 1 0 000-1.414z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n } @else {\n <div class=\"w-4 h-4 inline-block mr-2\"></div>\n }\n }\n @if (\n option.shouldManualInput &&\n (isOptionSelected(option) ||\n activeManualKey ===\n (option.manualPrefix ? option.manualPrefix : option.id || option.value))\n ) {\n <input\n type=\"text\"\n [(ngModel)]=\"\n manualInputValues[\n option.manualPrefix ? option.manualPrefix : option.id || option.value\n ]\n \"\n [attr.data-manual-key]=\"\n option.manualPrefix ? option.manualPrefix : option.id || option.value\n \"\n (ngModelChange)=\"onManualInputChange(option, $event)\"\n (click)=\"$event.stopPropagation()\"\n (blur)=\"onManualInputBlur(option)\"\n (keydown.enter)=\"onManualInputConfirm(option)\"\n class=\"text-light-on-control dark:text-dark-on-control rounded-md outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary px-2 py-1 text-sm/6 bg-light-control dark:bg-dark-control w-full\"\n />\n } @else {\n {{ option.value }}\n }\n </div>\n }\n </div>\n</div>\n" }]
|
|
615
618
|
}], propDecorators: { selectedChange: [{
|
|
616
619
|
type: Output
|
|
617
620
|
}], closeDropdown: [{
|
|
@@ -647,6 +650,7 @@ class SelectComponent {
|
|
|
647
650
|
placeholder = '';
|
|
648
651
|
atLeastOne = false;
|
|
649
652
|
showAll = false;
|
|
653
|
+
showAllItems = false;
|
|
650
654
|
options = null;
|
|
651
655
|
layout = 'vertical';
|
|
652
656
|
labelWidth = '';
|
|
@@ -671,8 +675,12 @@ class SelectComponent {
|
|
|
671
675
|
selectedOptionIds = [];
|
|
672
676
|
displayedSelectedOptions = [];
|
|
673
677
|
selectedIdToDisplayOption = {};
|
|
678
|
+
// Manual input support for inline mode
|
|
679
|
+
manualInputValues = {};
|
|
680
|
+
activeManualKey = null;
|
|
681
|
+
isComposing = false; // IME 조합 중 여부
|
|
674
682
|
onClick(event) {
|
|
675
|
-
if (this.disabled) {
|
|
683
|
+
if (this.disabled || this.showAllItems) {
|
|
676
684
|
return;
|
|
677
685
|
}
|
|
678
686
|
const originWidth = this.origin?.nativeElement?.offsetWidth || 0;
|
|
@@ -720,6 +728,23 @@ class SelectComponent {
|
|
|
720
728
|
: selectedOptionIds;
|
|
721
729
|
setTimeout(() => {
|
|
722
730
|
this.selectedOptionIds = payload;
|
|
731
|
+
// Clear manual input values when selecting different options in dropdown mode
|
|
732
|
+
if (!this.showAllItems) {
|
|
733
|
+
const manualOptions = (this.options || []).filter((o) => o.shouldManualInput);
|
|
734
|
+
for (const manualOpt of manualOptions) {
|
|
735
|
+
const key = this.getManualKey(manualOpt);
|
|
736
|
+
const prefix = manualOpt.manualPrefix || '';
|
|
737
|
+
const sentinel = manualOpt.id || manualOpt.value;
|
|
738
|
+
// Check if this manual option is still selected
|
|
739
|
+
const isStillSelected = prefix
|
|
740
|
+
? this.selectedOptionIds.some((id) => typeof id === 'string' && id.startsWith(prefix))
|
|
741
|
+
: this.selectedOptionIds.includes(sentinel);
|
|
742
|
+
// If not selected, clear the manual input value
|
|
743
|
+
if (!isStillSelected) {
|
|
744
|
+
this.manualInputValues[key] = '';
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
}
|
|
723
748
|
this.recomputeSelectedOptions();
|
|
724
749
|
this.onChange(this.getSelectedValue());
|
|
725
750
|
this.selectedChange.emit(payload);
|
|
@@ -762,6 +787,186 @@ class SelectComponent {
|
|
|
762
787
|
this.selectedChange.emit(this.selectedOptionIds);
|
|
763
788
|
this.isDropdownOpen.set(false);
|
|
764
789
|
}
|
|
790
|
+
onToggleOption(option) {
|
|
791
|
+
if (this.disabled) {
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
// Handle manual input option
|
|
795
|
+
if (option.shouldManualInput && this.showAllItems) {
|
|
796
|
+
const key = this.getManualKey(option);
|
|
797
|
+
const prefix = option.manualPrefix || '';
|
|
798
|
+
const sentinel = option.id || option.value;
|
|
799
|
+
const typed = (this.manualInputValues[key] || '').trim();
|
|
800
|
+
const isSelected = this.isOptionSelected(option);
|
|
801
|
+
if (isSelected) {
|
|
802
|
+
// Already selected - handle toggle based on mode
|
|
803
|
+
if (this.multiselect) {
|
|
804
|
+
// Checkbox: always deselect when clicked again
|
|
805
|
+
let next;
|
|
806
|
+
if (prefix) {
|
|
807
|
+
// Remove all IDs that start with prefix AND the sentinel
|
|
808
|
+
next = this.selectedOptionIds.filter((id) => !id.startsWith(prefix) && id !== sentinel);
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
// Remove typed value AND the sentinel
|
|
812
|
+
next = this.selectedOptionIds.filter((id) => id !== typed && id !== sentinel);
|
|
813
|
+
}
|
|
814
|
+
this.selectedOptionIds = next;
|
|
815
|
+
// Clear input text when deselected
|
|
816
|
+
this.manualInputValues[key] = '';
|
|
817
|
+
// Hide input
|
|
818
|
+
this.activeManualKey = null;
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
// Radio: deselect only if there's no typed content
|
|
822
|
+
if (typed === '') {
|
|
823
|
+
this.selectedOptionIds = [];
|
|
824
|
+
this.manualInputValues[key] = '';
|
|
825
|
+
this.activeManualKey = null;
|
|
826
|
+
}
|
|
827
|
+
else {
|
|
828
|
+
// Has typed content - keep selected, do nothing
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
else {
|
|
834
|
+
// Open manual input
|
|
835
|
+
this.activeManualKey = key;
|
|
836
|
+
// In single select mode, clear existing selections first
|
|
837
|
+
if (!this.multiselect) {
|
|
838
|
+
this.selectedOptionIds = [sentinel];
|
|
839
|
+
}
|
|
840
|
+
else {
|
|
841
|
+
// In multiselect mode, add sentinel if not already present
|
|
842
|
+
if (!this.selectedOptionIds.includes(sentinel)) {
|
|
843
|
+
this.selectedOptionIds = [sentinel, ...this.selectedOptionIds];
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
// Ensure there is an entry in manualInputValues
|
|
847
|
+
if (this.manualInputValues[key] === undefined) {
|
|
848
|
+
this.manualInputValues[key] = '';
|
|
849
|
+
}
|
|
850
|
+
// Focus input on next tick
|
|
851
|
+
setTimeout(() => {
|
|
852
|
+
const selector = `input[data-manual-key="${key}"]`;
|
|
853
|
+
const el = document.querySelector(selector);
|
|
854
|
+
el?.focus();
|
|
855
|
+
el?.select();
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
this.recomputeSelectedOptions();
|
|
859
|
+
this.onChange(this.getSelectedValue());
|
|
860
|
+
const selectedValue = this.getSelectedValue();
|
|
861
|
+
if (selectedValue !== null) {
|
|
862
|
+
this.selectedChange.emit(selectedValue);
|
|
863
|
+
}
|
|
864
|
+
this.cdr.markForCheck();
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
const id = option.id || option.value;
|
|
868
|
+
if (this.multiselect) {
|
|
869
|
+
if (option.isExclusive) {
|
|
870
|
+
// Exclusive option: toggle between only this option or none
|
|
871
|
+
if (this.selectedOptionIds.includes(id)) {
|
|
872
|
+
this.selectedOptionIds = [];
|
|
873
|
+
}
|
|
874
|
+
else {
|
|
875
|
+
this.selectedOptionIds = [id];
|
|
876
|
+
// Clear all manual input values when selecting exclusive option
|
|
877
|
+
const manualOptions = (this.options || []).filter((o) => o.shouldManualInput);
|
|
878
|
+
for (const manualOpt of manualOptions) {
|
|
879
|
+
const key = this.getManualKey(manualOpt);
|
|
880
|
+
this.manualInputValues[key] = '';
|
|
881
|
+
}
|
|
882
|
+
this.activeManualKey = null;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
else {
|
|
886
|
+
// Non-exclusive option: remove any exclusive selections first
|
|
887
|
+
let next = this.selectedOptionIds.filter((selectedId) => !this.isIdExclusive(selectedId));
|
|
888
|
+
if (next.includes(id)) {
|
|
889
|
+
// Deselect
|
|
890
|
+
next = next.filter((selected) => selected !== id);
|
|
891
|
+
}
|
|
892
|
+
else {
|
|
893
|
+
// Select
|
|
894
|
+
next = [id, ...next];
|
|
895
|
+
}
|
|
896
|
+
this.selectedOptionIds = next;
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
else {
|
|
900
|
+
// Single select mode
|
|
901
|
+
// Clear manual input values when selecting different option
|
|
902
|
+
const manualOptions = (this.options || []).filter((o) => o.shouldManualInput);
|
|
903
|
+
for (const manualOpt of manualOptions) {
|
|
904
|
+
const manualKey = this.getManualKey(manualOpt);
|
|
905
|
+
const manualSentinel = manualOpt.id || manualOpt.value;
|
|
906
|
+
const manualPrefix = manualOpt.manualPrefix || '';
|
|
907
|
+
// Check if selecting a different option (not the manual input option itself)
|
|
908
|
+
const isSelectingDifferent = id !== manualSentinel && !(manualPrefix && id.startsWith(manualPrefix));
|
|
909
|
+
if (isSelectingDifferent) {
|
|
910
|
+
this.manualInputValues[manualKey] = '';
|
|
911
|
+
this.activeManualKey = null;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
if (this.atLeastOne) {
|
|
915
|
+
this.selectedOptionIds = [id];
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
if (this.selectedOptionIds.includes(id)) {
|
|
919
|
+
this.selectedOptionIds = [];
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
this.selectedOptionIds = [id];
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
this.recomputeSelectedOptions();
|
|
927
|
+
this.onChange(this.getSelectedValue());
|
|
928
|
+
const selectedValue = this.getSelectedValue();
|
|
929
|
+
if (selectedValue !== null) {
|
|
930
|
+
this.selectedChange.emit(selectedValue);
|
|
931
|
+
}
|
|
932
|
+
this.cdr.markForCheck();
|
|
933
|
+
}
|
|
934
|
+
isOptionSelected(option) {
|
|
935
|
+
const id = option.id || option.value;
|
|
936
|
+
if (option.shouldManualInput && this.showAllItems) {
|
|
937
|
+
const key = this.getManualKey(option);
|
|
938
|
+
const prefix = option.manualPrefix;
|
|
939
|
+
const sentinel = option.id || option.value;
|
|
940
|
+
if (prefix) {
|
|
941
|
+
const hasValueWithPrefix = this.selectedOptionIds.some((selectedId) => typeof selectedId === 'string' &&
|
|
942
|
+
selectedId.startsWith(prefix) &&
|
|
943
|
+
selectedId.length > prefix.length);
|
|
944
|
+
return hasValueWithPrefix;
|
|
945
|
+
}
|
|
946
|
+
const typed = (this.manualInputValues[key] || '').trim();
|
|
947
|
+
// Only consider selected if there's actual typed value, not just sentinel
|
|
948
|
+
if (typed !== '') {
|
|
949
|
+
return this.selectedOptionIds.includes(typed);
|
|
950
|
+
}
|
|
951
|
+
// If no typed value, check if there's only sentinel (which means just activated but not typed yet)
|
|
952
|
+
const hasSentinel = this.selectedOptionIds.includes(sentinel);
|
|
953
|
+
const hasOnlySentinel = hasSentinel &&
|
|
954
|
+
!this.selectedOptionIds.some((id) => id !== sentinel && (prefix ? id.startsWith(prefix) : false));
|
|
955
|
+
return hasOnlySentinel;
|
|
956
|
+
}
|
|
957
|
+
return this.selectedOptionIds.includes(id);
|
|
958
|
+
}
|
|
959
|
+
isIdExclusive(id) {
|
|
960
|
+
const options = this.options || [];
|
|
961
|
+
for (const o of options) {
|
|
962
|
+
if (!o.isExclusive)
|
|
963
|
+
continue;
|
|
964
|
+
const refId = o.id || o.value;
|
|
965
|
+
if (refId === id)
|
|
966
|
+
return true;
|
|
967
|
+
}
|
|
968
|
+
return false;
|
|
969
|
+
}
|
|
765
970
|
getSelectedValue() {
|
|
766
971
|
if (!this.multiselect) {
|
|
767
972
|
if (this.selectedOptionIds.length > 0) {
|
|
@@ -779,10 +984,10 @@ class SelectComponent {
|
|
|
779
984
|
onTouched = () => { };
|
|
780
985
|
writeValue(value) {
|
|
781
986
|
if (Array.isArray(value)) {
|
|
782
|
-
this.selectedOptionIds = value.filter(id => id !== null && id !== undefined && id !== '');
|
|
987
|
+
this.selectedOptionIds = value.filter((id) => id !== null && id !== undefined && id !== '');
|
|
783
988
|
}
|
|
784
989
|
else {
|
|
785
|
-
this.selectedOptionIds =
|
|
990
|
+
this.selectedOptionIds = value !== null && value !== undefined && value !== '' ? [value] : [];
|
|
786
991
|
}
|
|
787
992
|
this.recomputeSelectedOptions();
|
|
788
993
|
}
|
|
@@ -816,6 +1021,9 @@ class SelectComponent {
|
|
|
816
1021
|
ngOnChanges(changes) {
|
|
817
1022
|
if (changes['options']) {
|
|
818
1023
|
this.recomputeSelectedOptions();
|
|
1024
|
+
if (this.showAllItems) {
|
|
1025
|
+
this.seedManualInputs();
|
|
1026
|
+
}
|
|
819
1027
|
}
|
|
820
1028
|
}
|
|
821
1029
|
recomputeSelectedOptions() {
|
|
@@ -912,26 +1120,134 @@ class SelectComponent {
|
|
|
912
1120
|
}
|
|
913
1121
|
return false;
|
|
914
1122
|
}
|
|
1123
|
+
getManualKey(option) {
|
|
1124
|
+
// Use option.id or option.value as the unique key
|
|
1125
|
+
// This ensures each manual input option has a unique key
|
|
1126
|
+
// even if they have the same manualPrefix
|
|
1127
|
+
return option.id || option.value;
|
|
1128
|
+
}
|
|
1129
|
+
seedManualInputs() {
|
|
1130
|
+
const options = this.options || [];
|
|
1131
|
+
const manualOptions = options.filter((o) => o.shouldManualInput);
|
|
1132
|
+
for (const opt of manualOptions) {
|
|
1133
|
+
const prefix = opt.manualPrefix || '';
|
|
1134
|
+
const key = this.getManualKey(opt);
|
|
1135
|
+
const existingWithPrefix = this.selectedOptionIds.find((id) => prefix ? id?.startsWith(prefix) : false);
|
|
1136
|
+
const value = existingWithPrefix ? existingWithPrefix.substring(prefix.length) : '';
|
|
1137
|
+
this.manualInputValues[key] = value;
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
onManualInputChange(option, value) {
|
|
1141
|
+
// IME 조합 중이면 업데이트하지 않음
|
|
1142
|
+
if (this.isComposing) {
|
|
1143
|
+
return;
|
|
1144
|
+
}
|
|
1145
|
+
const key = this.getManualKey(option);
|
|
1146
|
+
this.manualInputValues[key] = value;
|
|
1147
|
+
const prefix = option.manualPrefix || '';
|
|
1148
|
+
const sentinel = option.id || option.value;
|
|
1149
|
+
const trimmed = (value || '').trim();
|
|
1150
|
+
if (this.multiselect) {
|
|
1151
|
+
if (option.isExclusive) {
|
|
1152
|
+
if (trimmed === '') {
|
|
1153
|
+
this.selectedOptionIds = [sentinel];
|
|
1154
|
+
}
|
|
1155
|
+
else {
|
|
1156
|
+
this.selectedOptionIds = [`${prefix}${trimmed}`];
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
else {
|
|
1160
|
+
let next = this.selectedOptionIds.filter((id) => !this.isIdExclusive(id));
|
|
1161
|
+
next = next.filter((id) => (prefix ? !id.startsWith(prefix) : id !== sentinel));
|
|
1162
|
+
if (trimmed !== '') {
|
|
1163
|
+
const toAdd = `${prefix}${trimmed}`;
|
|
1164
|
+
if (!next.includes(toAdd)) {
|
|
1165
|
+
next = [toAdd, ...next];
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
else {
|
|
1169
|
+
if (!next.includes(sentinel)) {
|
|
1170
|
+
next = [sentinel, ...next];
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
this.selectedOptionIds = next;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
else {
|
|
1177
|
+
if (trimmed === '') {
|
|
1178
|
+
this.selectedOptionIds = [sentinel];
|
|
1179
|
+
}
|
|
1180
|
+
else {
|
|
1181
|
+
this.selectedOptionIds = [`${prefix}${trimmed}`];
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
this.recomputeSelectedOptions();
|
|
1185
|
+
this.onChange(this.getSelectedValue());
|
|
1186
|
+
const selectedValue = this.getSelectedValue();
|
|
1187
|
+
if (selectedValue !== null) {
|
|
1188
|
+
this.selectedChange.emit(selectedValue);
|
|
1189
|
+
}
|
|
1190
|
+
this.cdr.markForCheck();
|
|
1191
|
+
}
|
|
1192
|
+
onCompositionStart() {
|
|
1193
|
+
this.isComposing = true;
|
|
1194
|
+
}
|
|
1195
|
+
onCompositionEnd(option, event) {
|
|
1196
|
+
this.isComposing = false;
|
|
1197
|
+
// 조합이 끝나면 최종 값으로 업데이트
|
|
1198
|
+
const target = event.target;
|
|
1199
|
+
this.onManualInputChange(option, target.value);
|
|
1200
|
+
}
|
|
1201
|
+
onManualInputBlur(option) {
|
|
1202
|
+
const key = this.getManualKey(option);
|
|
1203
|
+
const raw = (this.manualInputValues[key] || '').trim();
|
|
1204
|
+
if (raw === '') {
|
|
1205
|
+
this.activeManualKey = null;
|
|
1206
|
+
const prefix = option.manualPrefix || '';
|
|
1207
|
+
const sentinel = option.id || option.value;
|
|
1208
|
+
if (this.multiselect) {
|
|
1209
|
+
let next = [...this.selectedOptionIds];
|
|
1210
|
+
next = next.filter((id) => {
|
|
1211
|
+
if (id === sentinel)
|
|
1212
|
+
return false;
|
|
1213
|
+
if (prefix && id.startsWith(prefix))
|
|
1214
|
+
return false;
|
|
1215
|
+
return true;
|
|
1216
|
+
});
|
|
1217
|
+
this.selectedOptionIds = next;
|
|
1218
|
+
}
|
|
1219
|
+
else {
|
|
1220
|
+
this.selectedOptionIds = [];
|
|
1221
|
+
}
|
|
1222
|
+
this.recomputeSelectedOptions();
|
|
1223
|
+
this.onChange(this.getSelectedValue());
|
|
1224
|
+
const selectedValue = this.getSelectedValue();
|
|
1225
|
+
if (selectedValue !== null) {
|
|
1226
|
+
this.selectedChange.emit(selectedValue);
|
|
1227
|
+
}
|
|
1228
|
+
this.cdr.markForCheck();
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
915
1231
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
916
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: SelectComponent, isStandalone: true, selector: "haloduck-select", inputs: { disabled: "disabled", loading: "loading", variant: "variant", asButton: "asButton", useIcon: "useIcon", useFilter: "useFilter", multiselect: "multiselect", placeholder: "placeholder", atLeastOne: "atLeastOne", showAll: "showAll", options: "options", layout: "layout", labelWidth: "labelWidth", value: "value" }, outputs: { selectedChange: "selectedChange" }, providers: [
|
|
1232
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: SelectComponent, isStandalone: true, selector: "haloduck-select", inputs: { disabled: "disabled", loading: "loading", variant: "variant", asButton: "asButton", useIcon: "useIcon", useFilter: "useFilter", multiselect: "multiselect", placeholder: "placeholder", atLeastOne: "atLeastOne", showAll: "showAll", showAllItems: "showAllItems", options: "options", layout: "layout", labelWidth: "labelWidth", value: "value" }, outputs: { selectedChange: "selectedChange" }, providers: [
|
|
917
1233
|
{
|
|
918
1234
|
provide: NG_VALUE_ACCESSOR,
|
|
919
1235
|
useExisting: forwardRef(() => SelectComponent),
|
|
920
1236
|
multi: true,
|
|
921
1237
|
},
|
|
922
1238
|
provideTranslocoScope('haloduck'),
|
|
923
|
-
], viewQueries: [{ propertyName: "origin", first: true, predicate: ["origin"], descendants: true }, { propertyName: "label", first: true, predicate: ["label"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"flex gap-2 items-center w-full\"\n [ngClass]=\"{'flex-col items-start': layout === 'vertical'}\">\n <label #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control {{ labelWidth }}\"\n [ngClass]=\"{'w-full': layout === 'vertical'}\">\n <!-- <ng-content select=\"[slot=label]\"></ng-content> -->\n <ng-content></ng-content>\n </label>\n <div #origin\n class=\"w-full flex-1 relative overflow-visible rounded-md outline outline-light-inactive dark:outline-dark-inactive text-sm/6\"\n [ngClass]=\"{\n 'bg-light-control dark:bg-dark-control focus:outline-2 focus:outline-offset-2 focus:outline-light-primary focus:dark:outline-dark-primary': !disabled,\n 'bg-light-primary dark:bg-dark-primary text-light-on-primary dark:text-dark-on-primary' : variant === 'primary' && !disabled,\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary' : variant === 'secondary' && !disabled,\n 'bg-light-danger dark:bg-dark-danger text-light-on-danger dark:text-dark-on-danger' : variant === 'danger' && !disabled,\n 'bg-light-control/60 dark:bg-dark-control/60 text-light-on-control/60 dark:text-dark-on-control/60' : disabled,\n }\"\n [tabindex]=\"(disabled) ? -1 : 0\"\n (click)=\"onClick($event)\"\n (keydown)=\"onKeyDown($event)\">\n <div class=\"px-3 py-1.5 text-sm/6 cursor-pointer flex flex-nowrap items-center justify-between overflow-hidden\">\n @if(loading){\n <div class=\"flex-1 flex items-center gap-2 w-full h-3\">\n <div class=\"animate-pulse bg-light-inactive dark:bg-dark-inactive rounded-md h-5 w-full\"> </div>\n </div>\n }\n @else{\n <div class=\"flex-1\">\n @if (!asButton && displayedSelectedOptions && displayedSelectedOptions.length > 0) {\n @if (multiselect) {\n <div class=\"flex flex-wrap gap-x-2 gap-y-1 items-start\">\n @for (option of displayedSelectedOptions; track option; let i = $index) {\n @if (showAll || i === 0) {\n <span class=\"bg-light-secondary dark:bg-dark-secondary rounded-md flex items-center text-xs/6 text-light-on-secondary dark:text-dark-on-secondary\"\n [ngClass]=\"{'w-full h-full px-4': !multiselect, 'px-1': multiselect}\">\n {{ option.value }}\n @if (showAll || i === 0) {\n <div (click)=\"onDeselectOption($event, option)\"\n class=\"ml-2 text-light-danger dark:text-dark-danger hover:cursor-pointer\">\n <svg class=\"w-3 h-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 8.586l-2.293-2.293a1 1 0 00-1.414 1.414L8.586 10l-2.293 2.293a1 1 0 001.414 1.414L10 11.414l2.293 2.293a1 1 0 001.414-1.414L11.414 10l2.293-2.293a1 1 0 00-1.414-1.414L10 8.586z\"\n clip-rule=\"evenodd\" />\n </svg>\n </div>\n }\n </span>\n @if (!showAll && displayedSelectedOptions.length > 1) {\n <span class=\"text-light-on-control/80 dark:text-dark-on-control/80 text-xs/6\">\n +{{ displayedSelectedOptions.length - 1 }}\n </span>\n }\n }\n }\n </div>\n } @else {\n <span class=\"text-light-on-control dark:text-dark-on-control overflow-hidden overflow-ellipsis\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary dark:text-dark-on-primary': variant === 'primary' && !disabled,\n 'text-light-on-secondary dark:text-dark-on-secondary': variant === 'secondary' && !disabled,\n 'text-light-on-danger dark:text-dark-on-danger': variant === 'danger' && !disabled,\n }\">{{ displayedSelectedOptions[0].value }}</span>\n }\n } @else {\n <span class=\"text-light-inactive dark:text-dark-inactive overflow-hidden overflow-ellipsis\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary/80 dark:text-dark-on-primary/80': variant === 'primary' && !disabled,\n 'text-light-on-secondary/80 dark:text-dark-on-secondary/80': variant === 'secondary' && !disabled,\n 'text-light-on-danger/80 dark:text-dark-on-danger/80': variant === 'danger' && !disabled,\n }\">\n @if (useIcon) {\n <ng-content select=\"buttonIcon\"></ng-content>\n } @else {\n {{ placeholder }}\n }\n </span>\n }\n </div>\n }\n <div class=\"text-light-on-control dark:text-dark-on-control\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary/80 dark:text-dark-on-primary/80': variant === 'primary' && !disabled,\n 'text-light-on-secondary/80 dark:text-dark-on-secondary/80': variant === 'secondary' && !disabled,\n 'text-light-on-danger/80 dark:text-dark-on-danger/80': variant === 'danger' && !disabled,\n }\">\n @if (isDropdownOpen()) {\n <svg class=\"w-4 h-4 ml-2 inline-block\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z\"\n clip-rule=\"evenodd\" />\n </svg>\n } @else {\n <svg class=\"w-4 h-4 ml-2 inline-block\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 011.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
1239
|
+
], viewQueries: [{ propertyName: "origin", first: true, predicate: ["origin"], descendants: true }, { propertyName: "label", first: true, predicate: ["label"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"flex gap-2 items-center w-full\"\n [ngClass]=\"{ 'flex-col items-start': layout === 'vertical' }\"\n>\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control {{\n labelWidth\n }}\"\n [ngClass]=\"{ 'w-full': layout === 'vertical' }\"\n >\n <!-- <ng-content select=\"[slot=label]\"></ng-content> -->\n <ng-content></ng-content>\n </label>\n\n @if (showAllItems) {\n <!-- Inline options display -->\n <div class=\"w-full flex-1\">\n @if (loading) {\n <div class=\"flex-1 flex items-center gap-2 w-full h-3\">\n <div class=\"animate-pulse bg-light-inactive dark:bg-dark-inactive rounded-md h-5 w-full\">\n \n </div>\n </div>\n } @else {\n <div class=\"flex flex-col gap-2\">\n @for (option of options; track option.id || option.value) {\n <label\n class=\"flex items-center gap-2 text-sm/6 text-light-on-control dark:text-dark-on-control cursor-pointer\"\n [ngClass]=\"{\n 'opacity-60 cursor-not-allowed': disabled,\n }\"\n >\n @if (multiselect) {\n <!-- Checkbox for multiselect -->\n <input\n type=\"checkbox\"\n [checked]=\"isOptionSelected(option)\"\n [disabled]=\"disabled\"\n (click)=\"!disabled && onToggleOption(option)\"\n class=\"appearance-none w-5 h-5 rounded bg-light-control dark:bg-dark-control border-2 border-light-inactive dark:border-dark-inactive cursor-pointer disabled:cursor-not-allowed checked:bg-light-primary checked:dark:bg-dark-primary checked:border-light-primary checked:dark:border-dark-primary relative before:content-[''] before:absolute before:inset-0 before:bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iOSIgdmlld0JveD0iMCAwIDEyIDkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEgNEw0LjUgNy41TDExIDEiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PC9zdmc+')] before:bg-center before:bg-no-repeat before:opacity-0 checked:before:opacity-100\"\n />\n } @else {\n <!-- Radio button for single select -->\n <input\n type=\"radio\"\n [checked]=\"isOptionSelected(option)\"\n [disabled]=\"disabled\"\n (click)=\"!disabled && onToggleOption(option)\"\n name=\"radio-group\"\n class=\"appearance-none w-5 h-5 rounded-full bg-light-control dark:bg-dark-control border-2 border-light-inactive dark:border-dark-inactive cursor-pointer disabled:cursor-not-allowed checked:bg-light-primary checked:dark:bg-dark-primary checked:border-light-primary checked:dark:border-dark-primary relative before:content-[''] before:absolute before:inset-[4px] before:rounded-full before:bg-light-on-primary before:dark:bg-dark-on-primary before:opacity-0 checked:before:opacity-100\"\n />\n }\n @if (\n option.shouldManualInput &&\n (isOptionSelected(option) || activeManualKey === (option.id || option.value))\n ) {\n <input\n type=\"text\"\n [(ngModel)]=\"manualInputValues[option.id || option.value]\"\n [attr.data-manual-key]=\"option.id || option.value\"\n (ngModelChange)=\"onManualInputChange(option, $event)\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd(option, $event)\"\n (click)=\"$event.stopPropagation()\"\n (blur)=\"onManualInputBlur(option)\"\n (keydown.enter)=\"$event.preventDefault(); onManualInputBlur(option)\"\n [disabled]=\"!!disabled\"\n class=\"flex-1 text-light-on-control dark:text-dark-on-control rounded-md outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary px-2 py-1 text-sm/6 bg-light-control dark:bg-dark-control\"\n />\n } @else {\n <span (click)=\"!disabled && onToggleOption(option)\">{{ option.value }}</span>\n }\n </label>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Original dropdown display -->\n <div\n #origin\n class=\"w-full flex-1 relative overflow-visible rounded-md outline outline-light-inactive dark:outline-dark-inactive text-sm/6\"\n [ngClass]=\"{\n 'bg-light-control dark:bg-dark-control focus:outline-2 focus:outline-offset-2 focus:outline-light-primary focus:dark:outline-dark-primary':\n !disabled,\n 'bg-light-primary dark:bg-dark-primary text-light-on-primary dark:text-dark-on-primary':\n variant === 'primary' && !disabled,\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary':\n variant === 'secondary' && !disabled,\n 'bg-light-danger dark:bg-dark-danger text-light-on-danger dark:text-dark-on-danger':\n variant === 'danger' && !disabled,\n 'bg-light-control/60 dark:bg-dark-control/60 text-light-on-control/60 dark:text-dark-on-control/60':\n disabled,\n }\"\n [tabindex]=\"disabled ? -1 : 0\"\n (click)=\"onClick($event)\"\n (keydown)=\"onKeyDown($event)\"\n >\n <div\n class=\"px-3 py-1.5 text-sm/6 cursor-pointer flex flex-nowrap items-center justify-between overflow-hidden\"\n >\n @if (loading) {\n <div class=\"flex-1 flex items-center gap-2 w-full h-3\">\n <div\n class=\"animate-pulse bg-light-inactive dark:bg-dark-inactive rounded-md h-5 w-full\"\n >\n \n </div>\n </div>\n } @else {\n <div class=\"flex-1\">\n @if (!asButton && displayedSelectedOptions && displayedSelectedOptions.length > 0) {\n @if (multiselect) {\n <div class=\"flex flex-wrap gap-x-2 gap-y-1 items-start\">\n @for (option of displayedSelectedOptions; track option; let i = $index) {\n @if (showAll || i === 0) {\n <span\n class=\"bg-light-secondary dark:bg-dark-secondary rounded-md flex items-center text-xs/6 text-light-on-secondary dark:text-dark-on-secondary\"\n [ngClass]=\"{ 'w-full h-full px-4': !multiselect, 'px-1': multiselect }\"\n >\n {{ option.value }}\n @if (showAll || i === 0) {\n <div\n (click)=\"onDeselectOption($event, option)\"\n class=\"ml-2 text-light-danger dark:text-dark-danger hover:cursor-pointer\"\n >\n <svg\n class=\"w-3 h-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M10 8.586l-2.293-2.293a1 1 0 00-1.414 1.414L8.586 10l-2.293 2.293a1 1 0 001.414 1.414L10 11.414l2.293 2.293a1 1 0 001.414-1.414L11.414 10l2.293-2.293a1 1 0 00-1.414-1.414L10 8.586z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n }\n </span>\n @if (!showAll && displayedSelectedOptions.length > 1) {\n <span\n class=\"text-light-on-control/80 dark:text-dark-on-control/80 text-xs/6\"\n >\n +{{ displayedSelectedOptions.length - 1 }}\n </span>\n }\n }\n }\n </div>\n } @else {\n <span\n class=\"text-light-on-control dark:text-dark-on-control overflow-hidden overflow-ellipsis\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary dark:text-dark-on-primary':\n variant === 'primary' && !disabled,\n 'text-light-on-secondary dark:text-dark-on-secondary':\n variant === 'secondary' && !disabled,\n 'text-light-on-danger dark:text-dark-on-danger':\n variant === 'danger' && !disabled,\n }\"\n >{{ displayedSelectedOptions[0].value }}</span\n >\n }\n } @else {\n <span\n class=\"text-light-inactive dark:text-dark-inactive overflow-hidden overflow-ellipsis\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary/80 dark:text-dark-on-primary/80':\n variant === 'primary' && !disabled,\n 'text-light-on-secondary/80 dark:text-dark-on-secondary/80':\n variant === 'secondary' && !disabled,\n 'text-light-on-danger/80 dark:text-dark-on-danger/80':\n variant === 'danger' && !disabled,\n }\"\n >\n @if (useIcon) {\n <ng-content select=\"buttonIcon\"></ng-content>\n } @else {\n {{ placeholder }}\n }\n </span>\n }\n </div>\n }\n <div\n class=\"text-light-on-control dark:text-dark-on-control\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary/80 dark:text-dark-on-primary/80':\n variant === 'primary' && !disabled,\n 'text-light-on-secondary/80 dark:text-dark-on-secondary/80':\n variant === 'secondary' && !disabled,\n 'text-light-on-danger/80 dark:text-dark-on-danger/80':\n variant === 'danger' && !disabled,\n }\"\n >\n @if (isDropdownOpen()) {\n <svg\n class=\"w-4 h-4 ml-2 inline-block\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n } @else {\n <svg\n class=\"w-4 h-4 ml-2 inline-block\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 011.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
924
1240
|
}
|
|
925
1241
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SelectComponent, decorators: [{
|
|
926
1242
|
type: Component,
|
|
927
|
-
args: [{ selector: 'haloduck-select', imports: [CommonModule], providers: [
|
|
1243
|
+
args: [{ selector: 'haloduck-select', imports: [CommonModule, FormsModule], providers: [
|
|
928
1244
|
{
|
|
929
1245
|
provide: NG_VALUE_ACCESSOR,
|
|
930
1246
|
useExisting: forwardRef(() => SelectComponent),
|
|
931
1247
|
multi: true,
|
|
932
1248
|
},
|
|
933
1249
|
provideTranslocoScope('haloduck'),
|
|
934
|
-
], template: "<div class=\"flex gap-2 items-center w-full\"\n [ngClass]=\"{'flex-col items-start': layout === 'vertical'}\">\n <label #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control {{ labelWidth }}\"\n [ngClass]=\"{'w-full': layout === 'vertical'}\">\n <!-- <ng-content select=\"[slot=label]\"></ng-content> -->\n <ng-content></ng-content>\n </label>\n <div #origin\n class=\"w-full flex-1 relative overflow-visible rounded-md outline outline-light-inactive dark:outline-dark-inactive text-sm/6\"\n [ngClass]=\"{\n 'bg-light-control dark:bg-dark-control focus:outline-2 focus:outline-offset-2 focus:outline-light-primary focus:dark:outline-dark-primary': !disabled,\n 'bg-light-primary dark:bg-dark-primary text-light-on-primary dark:text-dark-on-primary' : variant === 'primary' && !disabled,\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary' : variant === 'secondary' && !disabled,\n 'bg-light-danger dark:bg-dark-danger text-light-on-danger dark:text-dark-on-danger' : variant === 'danger' && !disabled,\n 'bg-light-control/60 dark:bg-dark-control/60 text-light-on-control/60 dark:text-dark-on-control/60' : disabled,\n }\"\n [tabindex]=\"(disabled) ? -1 : 0\"\n (click)=\"onClick($event)\"\n (keydown)=\"onKeyDown($event)\">\n <div class=\"px-3 py-1.5 text-sm/6 cursor-pointer flex flex-nowrap items-center justify-between overflow-hidden\">\n @if(loading){\n <div class=\"flex-1 flex items-center gap-2 w-full h-3\">\n <div class=\"animate-pulse bg-light-inactive dark:bg-dark-inactive rounded-md h-5 w-full\"> </div>\n </div>\n }\n @else{\n <div class=\"flex-1\">\n @if (!asButton && displayedSelectedOptions && displayedSelectedOptions.length > 0) {\n @if (multiselect) {\n <div class=\"flex flex-wrap gap-x-2 gap-y-1 items-start\">\n @for (option of displayedSelectedOptions; track option; let i = $index) {\n @if (showAll || i === 0) {\n <span class=\"bg-light-secondary dark:bg-dark-secondary rounded-md flex items-center text-xs/6 text-light-on-secondary dark:text-dark-on-secondary\"\n [ngClass]=\"{'w-full h-full px-4': !multiselect, 'px-1': multiselect}\">\n {{ option.value }}\n @if (showAll || i === 0) {\n <div (click)=\"onDeselectOption($event, option)\"\n class=\"ml-2 text-light-danger dark:text-dark-danger hover:cursor-pointer\">\n <svg class=\"w-3 h-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 8.586l-2.293-2.293a1 1 0 00-1.414 1.414L8.586 10l-2.293 2.293a1 1 0 001.414 1.414L10 11.414l2.293 2.293a1 1 0 001.414-1.414L11.414 10l2.293-2.293a1 1 0 00-1.414-1.414L10 8.586z\"\n clip-rule=\"evenodd\" />\n </svg>\n </div>\n }\n </span>\n @if (!showAll && displayedSelectedOptions.length > 1) {\n <span class=\"text-light-on-control/80 dark:text-dark-on-control/80 text-xs/6\">\n +{{ displayedSelectedOptions.length - 1 }}\n </span>\n }\n }\n }\n </div>\n } @else {\n <span class=\"text-light-on-control dark:text-dark-on-control overflow-hidden overflow-ellipsis\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary dark:text-dark-on-primary': variant === 'primary' && !disabled,\n 'text-light-on-secondary dark:text-dark-on-secondary': variant === 'secondary' && !disabled,\n 'text-light-on-danger dark:text-dark-on-danger': variant === 'danger' && !disabled,\n }\">{{ displayedSelectedOptions[0].value }}</span>\n }\n } @else {\n <span class=\"text-light-inactive dark:text-dark-inactive overflow-hidden overflow-ellipsis\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary/80 dark:text-dark-on-primary/80': variant === 'primary' && !disabled,\n 'text-light-on-secondary/80 dark:text-dark-on-secondary/80': variant === 'secondary' && !disabled,\n 'text-light-on-danger/80 dark:text-dark-on-danger/80': variant === 'danger' && !disabled,\n }\">\n @if (useIcon) {\n <ng-content select=\"buttonIcon\"></ng-content>\n } @else {\n {{ placeholder }}\n }\n </span>\n }\n </div>\n }\n <div class=\"text-light-on-control dark:text-dark-on-control\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary/80 dark:text-dark-on-primary/80': variant === 'primary' && !disabled,\n 'text-light-on-secondary/80 dark:text-dark-on-secondary/80': variant === 'secondary' && !disabled,\n 'text-light-on-danger/80 dark:text-dark-on-danger/80': variant === 'danger' && !disabled,\n }\">\n @if (isDropdownOpen()) {\n <svg class=\"w-4 h-4 ml-2 inline-block\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z\"\n clip-rule=\"evenodd\" />\n </svg>\n } @else {\n <svg class=\"w-4 h-4 ml-2 inline-block\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 011.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n </div>\n </div>\n </div>\n</div>\n" }]
|
|
1250
|
+
], template: "<div\n class=\"flex gap-2 items-center w-full\"\n [ngClass]=\"{ 'flex-col items-start': layout === 'vertical' }\"\n>\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control {{\n labelWidth\n }}\"\n [ngClass]=\"{ 'w-full': layout === 'vertical' }\"\n >\n <!-- <ng-content select=\"[slot=label]\"></ng-content> -->\n <ng-content></ng-content>\n </label>\n\n @if (showAllItems) {\n <!-- Inline options display -->\n <div class=\"w-full flex-1\">\n @if (loading) {\n <div class=\"flex-1 flex items-center gap-2 w-full h-3\">\n <div class=\"animate-pulse bg-light-inactive dark:bg-dark-inactive rounded-md h-5 w-full\">\n \n </div>\n </div>\n } @else {\n <div class=\"flex flex-col gap-2\">\n @for (option of options; track option.id || option.value) {\n <label\n class=\"flex items-center gap-2 text-sm/6 text-light-on-control dark:text-dark-on-control cursor-pointer\"\n [ngClass]=\"{\n 'opacity-60 cursor-not-allowed': disabled,\n }\"\n >\n @if (multiselect) {\n <!-- Checkbox for multiselect -->\n <input\n type=\"checkbox\"\n [checked]=\"isOptionSelected(option)\"\n [disabled]=\"disabled\"\n (click)=\"!disabled && onToggleOption(option)\"\n class=\"appearance-none w-5 h-5 rounded bg-light-control dark:bg-dark-control border-2 border-light-inactive dark:border-dark-inactive cursor-pointer disabled:cursor-not-allowed checked:bg-light-primary checked:dark:bg-dark-primary checked:border-light-primary checked:dark:border-dark-primary relative before:content-[''] before:absolute before:inset-0 before:bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iOSIgdmlld0JveD0iMCAwIDEyIDkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEgNEw0LjUgNy41TDExIDEiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PC9zdmc+')] before:bg-center before:bg-no-repeat before:opacity-0 checked:before:opacity-100\"\n />\n } @else {\n <!-- Radio button for single select -->\n <input\n type=\"radio\"\n [checked]=\"isOptionSelected(option)\"\n [disabled]=\"disabled\"\n (click)=\"!disabled && onToggleOption(option)\"\n name=\"radio-group\"\n class=\"appearance-none w-5 h-5 rounded-full bg-light-control dark:bg-dark-control border-2 border-light-inactive dark:border-dark-inactive cursor-pointer disabled:cursor-not-allowed checked:bg-light-primary checked:dark:bg-dark-primary checked:border-light-primary checked:dark:border-dark-primary relative before:content-[''] before:absolute before:inset-[4px] before:rounded-full before:bg-light-on-primary before:dark:bg-dark-on-primary before:opacity-0 checked:before:opacity-100\"\n />\n }\n @if (\n option.shouldManualInput &&\n (isOptionSelected(option) || activeManualKey === (option.id || option.value))\n ) {\n <input\n type=\"text\"\n [(ngModel)]=\"manualInputValues[option.id || option.value]\"\n [attr.data-manual-key]=\"option.id || option.value\"\n (ngModelChange)=\"onManualInputChange(option, $event)\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd(option, $event)\"\n (click)=\"$event.stopPropagation()\"\n (blur)=\"onManualInputBlur(option)\"\n (keydown.enter)=\"$event.preventDefault(); onManualInputBlur(option)\"\n [disabled]=\"!!disabled\"\n class=\"flex-1 text-light-on-control dark:text-dark-on-control rounded-md outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary px-2 py-1 text-sm/6 bg-light-control dark:bg-dark-control\"\n />\n } @else {\n <span (click)=\"!disabled && onToggleOption(option)\">{{ option.value }}</span>\n }\n </label>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Original dropdown display -->\n <div\n #origin\n class=\"w-full flex-1 relative overflow-visible rounded-md outline outline-light-inactive dark:outline-dark-inactive text-sm/6\"\n [ngClass]=\"{\n 'bg-light-control dark:bg-dark-control focus:outline-2 focus:outline-offset-2 focus:outline-light-primary focus:dark:outline-dark-primary':\n !disabled,\n 'bg-light-primary dark:bg-dark-primary text-light-on-primary dark:text-dark-on-primary':\n variant === 'primary' && !disabled,\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary':\n variant === 'secondary' && !disabled,\n 'bg-light-danger dark:bg-dark-danger text-light-on-danger dark:text-dark-on-danger':\n variant === 'danger' && !disabled,\n 'bg-light-control/60 dark:bg-dark-control/60 text-light-on-control/60 dark:text-dark-on-control/60':\n disabled,\n }\"\n [tabindex]=\"disabled ? -1 : 0\"\n (click)=\"onClick($event)\"\n (keydown)=\"onKeyDown($event)\"\n >\n <div\n class=\"px-3 py-1.5 text-sm/6 cursor-pointer flex flex-nowrap items-center justify-between overflow-hidden\"\n >\n @if (loading) {\n <div class=\"flex-1 flex items-center gap-2 w-full h-3\">\n <div\n class=\"animate-pulse bg-light-inactive dark:bg-dark-inactive rounded-md h-5 w-full\"\n >\n \n </div>\n </div>\n } @else {\n <div class=\"flex-1\">\n @if (!asButton && displayedSelectedOptions && displayedSelectedOptions.length > 0) {\n @if (multiselect) {\n <div class=\"flex flex-wrap gap-x-2 gap-y-1 items-start\">\n @for (option of displayedSelectedOptions; track option; let i = $index) {\n @if (showAll || i === 0) {\n <span\n class=\"bg-light-secondary dark:bg-dark-secondary rounded-md flex items-center text-xs/6 text-light-on-secondary dark:text-dark-on-secondary\"\n [ngClass]=\"{ 'w-full h-full px-4': !multiselect, 'px-1': multiselect }\"\n >\n {{ option.value }}\n @if (showAll || i === 0) {\n <div\n (click)=\"onDeselectOption($event, option)\"\n class=\"ml-2 text-light-danger dark:text-dark-danger hover:cursor-pointer\"\n >\n <svg\n class=\"w-3 h-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M10 8.586l-2.293-2.293a1 1 0 00-1.414 1.414L8.586 10l-2.293 2.293a1 1 0 001.414 1.414L10 11.414l2.293 2.293a1 1 0 001.414-1.414L11.414 10l2.293-2.293a1 1 0 00-1.414-1.414L10 8.586z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n }\n </span>\n @if (!showAll && displayedSelectedOptions.length > 1) {\n <span\n class=\"text-light-on-control/80 dark:text-dark-on-control/80 text-xs/6\"\n >\n +{{ displayedSelectedOptions.length - 1 }}\n </span>\n }\n }\n }\n </div>\n } @else {\n <span\n class=\"text-light-on-control dark:text-dark-on-control overflow-hidden overflow-ellipsis\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary dark:text-dark-on-primary':\n variant === 'primary' && !disabled,\n 'text-light-on-secondary dark:text-dark-on-secondary':\n variant === 'secondary' && !disabled,\n 'text-light-on-danger dark:text-dark-on-danger':\n variant === 'danger' && !disabled,\n }\"\n >{{ displayedSelectedOptions[0].value }}</span\n >\n }\n } @else {\n <span\n class=\"text-light-inactive dark:text-dark-inactive overflow-hidden overflow-ellipsis\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary/80 dark:text-dark-on-primary/80':\n variant === 'primary' && !disabled,\n 'text-light-on-secondary/80 dark:text-dark-on-secondary/80':\n variant === 'secondary' && !disabled,\n 'text-light-on-danger/80 dark:text-dark-on-danger/80':\n variant === 'danger' && !disabled,\n }\"\n >\n @if (useIcon) {\n <ng-content select=\"buttonIcon\"></ng-content>\n } @else {\n {{ placeholder }}\n }\n </span>\n }\n </div>\n }\n <div\n class=\"text-light-on-control dark:text-dark-on-control\"\n [ngClass]=\"{\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n 'text-light-on-primary/80 dark:text-dark-on-primary/80':\n variant === 'primary' && !disabled,\n 'text-light-on-secondary/80 dark:text-dark-on-secondary/80':\n variant === 'secondary' && !disabled,\n 'text-light-on-danger/80 dark:text-dark-on-danger/80':\n variant === 'danger' && !disabled,\n }\"\n >\n @if (isDropdownOpen()) {\n <svg\n class=\"w-4 h-4 ml-2 inline-block\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n } @else {\n <svg\n class=\"w-4 h-4 ml-2 inline-block\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 011.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </div>\n </div>\n </div>\n }\n</div>\n" }]
|
|
935
1251
|
}], ctorParameters: () => [], propDecorators: { selectedChange: [{
|
|
936
1252
|
type: Output
|
|
937
1253
|
}], disabled: [{
|
|
@@ -954,6 +1270,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
954
1270
|
type: Input
|
|
955
1271
|
}], showAll: [{
|
|
956
1272
|
type: Input
|
|
1273
|
+
}], showAllItems: [{
|
|
1274
|
+
type: Input
|
|
957
1275
|
}], options: [{
|
|
958
1276
|
type: Input
|
|
959
1277
|
}], layout: [{
|
|
@@ -1040,9 +1358,7 @@ class CalendarComponent {
|
|
|
1040
1358
|
else {
|
|
1041
1359
|
const dateRange = value;
|
|
1042
1360
|
currentDate =
|
|
1043
|
-
dateRange && dateRange.from && dateRange.to
|
|
1044
|
-
? dateRange.from
|
|
1045
|
-
: dateToString(new Date());
|
|
1361
|
+
dateRange && dateRange.from && dateRange.to ? dateRange.from : dateToString(new Date());
|
|
1046
1362
|
}
|
|
1047
1363
|
this.currentYear = parseInt(currentDate.slice(0, 4), 10);
|
|
1048
1364
|
this.currentMonth = parseInt(currentDate.slice(5, 7), 10) - 1;
|
|
@@ -1059,8 +1375,7 @@ class CalendarComponent {
|
|
|
1059
1375
|
if (lastOfCalendar.getDate() > 6) {
|
|
1060
1376
|
lastOfCalendar.setDate(lastOfCalendar.getDate() - 7);
|
|
1061
1377
|
}
|
|
1062
|
-
const dateDiff = Math.ceil((lastOfCalendar.getTime() - firstOfCalendar.getTime()) /
|
|
1063
|
-
(1000 * 60 * 60 * 24)) + 1;
|
|
1378
|
+
const dateDiff = Math.ceil((lastOfCalendar.getTime() - firstOfCalendar.getTime()) / (1000 * 60 * 60 * 24)) + 1;
|
|
1064
1379
|
this.listCalendarDate = [];
|
|
1065
1380
|
for (let i = 0; i < dateDiff; i++) {
|
|
1066
1381
|
const datetime = dateToString(firstOfCalendar);
|
|
@@ -1175,11 +1490,11 @@ class CalendarComponent {
|
|
|
1175
1490
|
});
|
|
1176
1491
|
}
|
|
1177
1492
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: CalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1178
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: CalendarComponent, isStandalone: true, selector: "haloduck-calendar", inputs: { singleDate: "singleDate", firstDayOfWeek: "firstDayOfWeek", selectedDate: "selectedDate", selectedDateRange: "selectedDateRange" }, outputs: { dateChange: "dateChange", dateRangeChange: "dateRangeChange" }, providers: [provideTranslocoScope('haloduck')], viewQueries: [{ propertyName: "monthSelect", first: true, predicate: ["monthSelect"], descendants: true }], ngImport: i0, template: "<div
|
|
1493
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: CalendarComponent, isStandalone: true, selector: "haloduck-calendar", inputs: { singleDate: "singleDate", firstDayOfWeek: "firstDayOfWeek", selectedDate: "selectedDate", selectedDateRange: "selectedDateRange" }, outputs: { dateChange: "dateChange", dateRangeChange: "dateRangeChange" }, providers: [provideTranslocoScope('haloduck')], viewQueries: [{ propertyName: "monthSelect", first: true, predicate: ["monthSelect"], descendants: true }], ngImport: i0, template: "<div\n id=\"dateRangeCalendar\"\n class=\"min-w-96 brightness-125 bg-light-background dark:bg-dark-background border border-light-inactive dark:border-dark-inactive rounded text-center p-4 flex flex-col gap-4\"\n tabindex=\"1\"\n>\n <div class=\"flex items-center\">\n <button\n type=\"button\"\n class=\"-m-1.5 flex flex-none items-center justify-center p-1.5 text-light-on-background dark:text-dark-on-background hover:scale-105 hover:cursor-pointer active:scale-95\"\n (click)=\"onAdjustYear(-1)\"\n >\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n <div class=\"flex-auto text-sm font-semibold flex justify-center\">\n <div class=\"w-32\">\n <haloduck-select\n [multiselect]=\"false\"\n [atLeastOne]=\"true\"\n [options]=\"yearList\"\n [value]=\"currentYear + ''\"\n (selectedChange)=\"onSelectYear($event)\"\n >\n </haloduck-select>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"-m-1.5 flex flex-none items-center justify-center p-1.5 text-light-on-background dark:text-dark-on-background hover:scale-105 hover:cursor-pointer active:scale-95\"\n (click)=\"onAdjustYear(1)\"\n >\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n\n <div class=\"flex items-center\">\n <button\n type=\"button\"\n class=\"-m-1.5 flex flex-none items-center justify-center p-1.5 text-light-on-background dark:text-dark-on-background hover:scale-105 hover:cursor-pointer active:scale-95\"\n (click)=\"onAdjustMonth(-1)\"\n >\n <span class=\"sr-only\">\uC774\uC804 \uB2EC</span>\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n <div class=\"flex-auto text-sm font-semibold flex justify-center\">\n <div class=\"w-32\">\n <haloduck-select\n [multiselect]=\"false\"\n [atLeastOne]=\"true\"\n [options]=\"monthList\"\n [value]=\"currentMonth + ''\"\n (selectedChange)=\"onSelectMonth($event)\"\n >\n </haloduck-select>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"-m-1.5 flex flex-none items-center justify-center p-1.5 text-light-on-background dark:text-dark-on-background hover:scale-105 hover:cursor-pointer active:scale-95\"\n (click)=\"onAdjustMonth(1)\"\n >\n <span class=\"sr-only\">\uB2E4\uC74C \uB2EC</span>\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n\n <div>\n <div\n class=\"grid grid-cols-7 gap-[1px] text-xs/6 font-semibold text-light-on-background dark:text-dark-on-background\"\n >\n <div>{{ 'haloduck.ui.calendar.Mon' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Tue' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Wed' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Thu' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Fri' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Sat' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Sun' | transloco }}</div>\n </div>\n\n <div class=\"isolate mt-2 grid grid-cols-7 gap-[1px] rounded-lg text-sm shadow overflow-hidden\">\n @for (date of listCalendarDate; track date.datetime) {\n <button\n type=\"button\"\n (click)=\"onSelectCalendarDate(date)\"\n class=\"py-1.5 hover:cursor-pointer bg-light-alternative dark:bg-dark-alternative text-light-on-alternative dark:text-dark-on-alternative\"\n [ngClass]=\"{\n 'bg-light-control dark:bg-dark-control text-light-on-control dark:text-dark-on-control':\n date.isCurrentMonth,\n }\"\n >\n <time\n [ngClass]=\"{\n 'font-semibold bg-light-primary-light dark:bg-dark-primary-light text-on-light-primary-light dark:text-dark-on-primary-light':\n date.isToday && date.datetime !== selectedDateRange?.from,\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary':\n date.datetime === selectedDateRange?.from,\n 'bg-gray-500 font-semibold text-white': date.isTheDate,\n }\"\n class=\"mx-auto flex size-7 items-center justify-center rounded-full hover:font-bold\"\n >{{ date.date }}</time\n >\n </button>\n }\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: SelectComponent, selector: "haloduck-select", inputs: ["disabled", "loading", "variant", "asButton", "useIcon", "useFilter", "multiselect", "placeholder", "atLeastOne", "showAll", "showAllItems", "options", "layout", "labelWidth", "value"], outputs: ["selectedChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }] });
|
|
1179
1494
|
}
|
|
1180
1495
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: CalendarComponent, decorators: [{
|
|
1181
1496
|
type: Component,
|
|
1182
|
-
args: [{ selector: 'haloduck-calendar', imports: [CommonModule, SelectComponent, FormsModule, TranslocoModule], providers: [provideTranslocoScope('haloduck')], template: "<div
|
|
1497
|
+
args: [{ selector: 'haloduck-calendar', imports: [CommonModule, SelectComponent, FormsModule, TranslocoModule], providers: [provideTranslocoScope('haloduck')], template: "<div\n id=\"dateRangeCalendar\"\n class=\"min-w-96 brightness-125 bg-light-background dark:bg-dark-background border border-light-inactive dark:border-dark-inactive rounded text-center p-4 flex flex-col gap-4\"\n tabindex=\"1\"\n>\n <div class=\"flex items-center\">\n <button\n type=\"button\"\n class=\"-m-1.5 flex flex-none items-center justify-center p-1.5 text-light-on-background dark:text-dark-on-background hover:scale-105 hover:cursor-pointer active:scale-95\"\n (click)=\"onAdjustYear(-1)\"\n >\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n <div class=\"flex-auto text-sm font-semibold flex justify-center\">\n <div class=\"w-32\">\n <haloduck-select\n [multiselect]=\"false\"\n [atLeastOne]=\"true\"\n [options]=\"yearList\"\n [value]=\"currentYear + ''\"\n (selectedChange)=\"onSelectYear($event)\"\n >\n </haloduck-select>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"-m-1.5 flex flex-none items-center justify-center p-1.5 text-light-on-background dark:text-dark-on-background hover:scale-105 hover:cursor-pointer active:scale-95\"\n (click)=\"onAdjustYear(1)\"\n >\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n\n <div class=\"flex items-center\">\n <button\n type=\"button\"\n class=\"-m-1.5 flex flex-none items-center justify-center p-1.5 text-light-on-background dark:text-dark-on-background hover:scale-105 hover:cursor-pointer active:scale-95\"\n (click)=\"onAdjustMonth(-1)\"\n >\n <span class=\"sr-only\">\uC774\uC804 \uB2EC</span>\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n <div class=\"flex-auto text-sm font-semibold flex justify-center\">\n <div class=\"w-32\">\n <haloduck-select\n [multiselect]=\"false\"\n [atLeastOne]=\"true\"\n [options]=\"monthList\"\n [value]=\"currentMonth + ''\"\n (selectedChange)=\"onSelectMonth($event)\"\n >\n </haloduck-select>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"-m-1.5 flex flex-none items-center justify-center p-1.5 text-light-on-background dark:text-dark-on-background hover:scale-105 hover:cursor-pointer active:scale-95\"\n (click)=\"onAdjustMonth(1)\"\n >\n <span class=\"sr-only\">\uB2E4\uC74C \uB2EC</span>\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n\n <div>\n <div\n class=\"grid grid-cols-7 gap-[1px] text-xs/6 font-semibold text-light-on-background dark:text-dark-on-background\"\n >\n <div>{{ 'haloduck.ui.calendar.Mon' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Tue' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Wed' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Thu' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Fri' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Sat' | transloco }}</div>\n <div>{{ 'haloduck.ui.calendar.Sun' | transloco }}</div>\n </div>\n\n <div class=\"isolate mt-2 grid grid-cols-7 gap-[1px] rounded-lg text-sm shadow overflow-hidden\">\n @for (date of listCalendarDate; track date.datetime) {\n <button\n type=\"button\"\n (click)=\"onSelectCalendarDate(date)\"\n class=\"py-1.5 hover:cursor-pointer bg-light-alternative dark:bg-dark-alternative text-light-on-alternative dark:text-dark-on-alternative\"\n [ngClass]=\"{\n 'bg-light-control dark:bg-dark-control text-light-on-control dark:text-dark-on-control':\n date.isCurrentMonth,\n }\"\n >\n <time\n [ngClass]=\"{\n 'font-semibold bg-light-primary-light dark:bg-dark-primary-light text-on-light-primary-light dark:text-dark-on-primary-light':\n date.isToday && date.datetime !== selectedDateRange?.from,\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary':\n date.datetime === selectedDateRange?.from,\n 'bg-gray-500 font-semibold text-white': date.isTheDate,\n }\"\n class=\"mx-auto flex size-7 items-center justify-center rounded-full hover:font-bold\"\n >{{ date.date }}</time\n >\n </button>\n }\n </div>\n </div>\n</div>\n" }]
|
|
1183
1498
|
}], ctorParameters: () => [], propDecorators: { monthSelect: [{
|
|
1184
1499
|
type: ViewChild,
|
|
1185
1500
|
args: ['monthSelect', { static: false }]
|
|
@@ -1237,11 +1552,11 @@ class DialogContainerComponent {
|
|
|
1237
1552
|
this.close.emit();
|
|
1238
1553
|
}
|
|
1239
1554
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: DialogContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1240
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: DialogContainerComponent, isStandalone: true, selector: "haloduck-dialog-container", inputs: { childComponent: "childComponent", data: "data" }, outputs: { close: "close" }, viewQueries: [{ propertyName: "dialogContainer", first: true, predicate: ["dialogContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div
|
|
1555
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: DialogContainerComponent, isStandalone: true, selector: "haloduck-dialog-container", inputs: { childComponent: "childComponent", data: "data" }, outputs: { close: "close" }, viewQueries: [{ propertyName: "dialogContainer", first: true, predicate: ["dialogContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div\n class=\"h-full w-full max-h-full max-w-full fixed inset-0 bg-black/50 flex items-center justify-center overflow-hidden\"\n>\n <!-- <div class=\"w-full h-full max-w-full max-h-full bg-white p-5 rounded-lg overflow-y-auto\"\n (click)=\"$event.stopPropagation()\"> -->\n <ng-container id=\"dialogContainer\" #dialogContainer></ng-container>\n <!-- </div> -->\n</div>\n", styles: [".custom-dialog-panel{width:100%;max-width:100%;height:100%;max-height:100%;margin:0;padding:0}\n"] });
|
|
1241
1556
|
}
|
|
1242
1557
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: DialogContainerComponent, decorators: [{
|
|
1243
1558
|
type: Component,
|
|
1244
|
-
args: [{ selector: 'haloduck-dialog-container', template: "<div
|
|
1559
|
+
args: [{ selector: 'haloduck-dialog-container', template: "<div\n class=\"h-full w-full max-h-full max-w-full fixed inset-0 bg-black/50 flex items-center justify-center overflow-hidden\"\n>\n <!-- <div class=\"w-full h-full max-w-full max-h-full bg-white p-5 rounded-lg overflow-y-auto\"\n (click)=\"$event.stopPropagation()\"> -->\n <ng-container id=\"dialogContainer\" #dialogContainer></ng-container>\n <!-- </div> -->\n</div>\n", styles: [".custom-dialog-panel{width:100%;max-width:100%;height:100%;max-height:100%;margin:0;padding:0}\n"] }]
|
|
1245
1560
|
}], propDecorators: { childComponent: [{
|
|
1246
1561
|
type: Input
|
|
1247
1562
|
}], data: [{
|
|
@@ -1278,7 +1593,7 @@ class DialogService {
|
|
|
1278
1593
|
close(overlayRef) {
|
|
1279
1594
|
if (overlayRef) {
|
|
1280
1595
|
overlayRef.dispose();
|
|
1281
|
-
this.dialogStack = this.dialogStack.filter(ref => ref !== overlayRef);
|
|
1596
|
+
this.dialogStack = this.dialogStack.filter((ref) => ref !== overlayRef);
|
|
1282
1597
|
}
|
|
1283
1598
|
else {
|
|
1284
1599
|
// 마지막 다이얼로그 닫기
|
|
@@ -1307,16 +1622,14 @@ class ConfirmDialogComponent {
|
|
|
1307
1622
|
this.context.clickedButton$.complete();
|
|
1308
1623
|
this.dialogService.close(this.context.overlayRef);
|
|
1309
1624
|
}
|
|
1310
|
-
ngOnInit() {
|
|
1311
|
-
}
|
|
1312
|
-
constructor() {
|
|
1313
|
-
}
|
|
1625
|
+
ngOnInit() { }
|
|
1626
|
+
constructor() { }
|
|
1314
1627
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ConfirmDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1315
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: ConfirmDialogComponent, isStandalone: true, selector: "haloduck-confirm-dialog", inputs: { context: "context" }, ngImport: i0, template: "<div
|
|
1628
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: ConfirmDialogComponent, isStandalone: true, selector: "haloduck-confirm-dialog", inputs: { context: "context" }, ngImport: i0, template: "<div\n class=\"w-120 max-w-full flex flex-col gap-4 text-light-on-background dark:text-dark-on-background bg-light-background dark:bg-dark-background\"\n>\n <div class=\"font-bold\">{{ context.title }}</div>\n <p>{{ context.message }}</p>\n <div class=\"flex items-center justify-center gap-4\">\n @for (button of context.buttons; track button.id) {\n <haloduck-button [variant]=\"button.variant\" (click)=\"onButtonClicked(button.id)\">{{\n button.label\n }}</haloduck-button>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "haloduck-button", inputs: ["disabled", "variant"] }] });
|
|
1316
1629
|
}
|
|
1317
1630
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
|
|
1318
1631
|
type: Component,
|
|
1319
|
-
args: [{ selector: 'haloduck-confirm-dialog', imports: [ButtonComponent], template: "<div
|
|
1632
|
+
args: [{ selector: 'haloduck-confirm-dialog', imports: [ButtonComponent], template: "<div\n class=\"w-120 max-w-full flex flex-col gap-4 text-light-on-background dark:text-dark-on-background bg-light-background dark:bg-dark-background\"\n>\n <div class=\"font-bold\">{{ context.title }}</div>\n <p>{{ context.message }}</p>\n <div class=\"flex items-center justify-center gap-4\">\n @for (button of context.buttons; track button.id) {\n <haloduck-button [variant]=\"button.variant\" (click)=\"onButtonClicked(button.id)\">{{\n button.label\n }}</haloduck-button>\n }\n </div>\n</div>\n" }]
|
|
1320
1633
|
}], ctorParameters: () => [], propDecorators: { context: [{
|
|
1321
1634
|
type: Input
|
|
1322
1635
|
}] } });
|
|
@@ -1355,8 +1668,7 @@ class CopyButtonComponent {
|
|
|
1355
1668
|
this.isAnimating = false;
|
|
1356
1669
|
}, 500); // Animation duration
|
|
1357
1670
|
if (navigator.clipboard && window.isSecureContext) {
|
|
1358
|
-
navigator.clipboard
|
|
1359
|
-
.writeText(this.text);
|
|
1671
|
+
navigator.clipboard.writeText(this.text);
|
|
1360
1672
|
// .then(() => {
|
|
1361
1673
|
// console.log('Text copied to clipboard');
|
|
1362
1674
|
// })
|
|
@@ -1382,11 +1694,11 @@ class CopyButtonComponent {
|
|
|
1382
1694
|
}
|
|
1383
1695
|
}
|
|
1384
1696
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: CopyButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1385
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: CopyButtonComponent, isStandalone: true, selector: "haloduck-copy-button", inputs: { text: "text" }, providers: [provideTranslocoScope('haloduck')], ngImport: i0, template: "<ng-container *transloco=\"let _ts; read: 'haloduck'\">\n <button
|
|
1697
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: CopyButtonComponent, isStandalone: true, selector: "haloduck-copy-button", inputs: { text: "text" }, providers: [provideTranslocoScope('haloduck')], ngImport: i0, template: "<ng-container *transloco=\"let _ts; read: 'haloduck'\">\n <button\n type=\"button\"\n class=\"group inline-flex items-center px-2 py-1 bg-light-alternative dark:bg-dark-alternative hover:brightness-125 rounded text-xs text-light-on-alternative dark:text-dark-on-alternative hover:cursor-pointer active:scale-95 transition-transform\"\n (click)=\"copyToClipboard($event)\"\n title=\"Copy to clipboard\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n [class]=\"\n 'h-4 w-4 mr-1 transition-all duration-500 ' +\n (isAnimating ? 'scale-150 opacity-0' : 'scale-100 opacity-100')\n \"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <rect\n x=\"9\"\n y=\"9\"\n width=\"13\"\n height=\"13\"\n rx=\"2\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n fill=\"none\"\n />\n <rect\n x=\"3\"\n y=\"3\"\n width=\"13\"\n height=\"13\"\n rx=\"2\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n fill=\"none\"\n />\n </svg>\n <span class=\"hidden group-hover:inline\">\n @if (isAnimating) {\n {{ _ts('ui.button.Copied') }}\n } @else {\n {{ _ts('ui.button.Copy') }}\n }\n </span>\n </button>\n</ng-container>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: TranslocoModule }, { kind: "directive", type: i2$1.TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
|
|
1386
1698
|
}
|
|
1387
1699
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: CopyButtonComponent, decorators: [{
|
|
1388
1700
|
type: Component,
|
|
1389
|
-
args: [{ selector: 'haloduck-copy-button', imports: [TranslocoModule], providers: [provideTranslocoScope('haloduck')], template: "<ng-container *transloco=\"let _ts; read: 'haloduck'\">\n <button
|
|
1701
|
+
args: [{ selector: 'haloduck-copy-button', imports: [TranslocoModule], providers: [provideTranslocoScope('haloduck')], template: "<ng-container *transloco=\"let _ts; read: 'haloduck'\">\n <button\n type=\"button\"\n class=\"group inline-flex items-center px-2 py-1 bg-light-alternative dark:bg-dark-alternative hover:brightness-125 rounded text-xs text-light-on-alternative dark:text-dark-on-alternative hover:cursor-pointer active:scale-95 transition-transform\"\n (click)=\"copyToClipboard($event)\"\n title=\"Copy to clipboard\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n [class]=\"\n 'h-4 w-4 mr-1 transition-all duration-500 ' +\n (isAnimating ? 'scale-150 opacity-0' : 'scale-100 opacity-100')\n \"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <rect\n x=\"9\"\n y=\"9\"\n width=\"13\"\n height=\"13\"\n rx=\"2\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n fill=\"none\"\n />\n <rect\n x=\"3\"\n y=\"3\"\n width=\"13\"\n height=\"13\"\n rx=\"2\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n fill=\"none\"\n />\n </svg>\n <span class=\"hidden group-hover:inline\">\n @if (isAnimating) {\n {{ _ts('ui.button.Copied') }}\n } @else {\n {{ _ts('ui.button.Copy') }}\n }\n </span>\n </button>\n</ng-container>\n" }]
|
|
1390
1702
|
}], propDecorators: { text: [{
|
|
1391
1703
|
type: Input
|
|
1392
1704
|
}] } });
|
|
@@ -1442,9 +1754,7 @@ class DatePickerComponent {
|
|
|
1442
1754
|
componentRef.instance.singleDate = true;
|
|
1443
1755
|
componentRef.instance.selectedDate = this.selectedDate;
|
|
1444
1756
|
// Subscribe to events emitted by the CalendarComponent
|
|
1445
|
-
componentRef.instance.dateChange
|
|
1446
|
-
.pipe(takeUntil(this.destroy$))
|
|
1447
|
-
.subscribe((date) => {
|
|
1757
|
+
componentRef.instance.dateChange.pipe(takeUntil(this.destroy$)).subscribe((date) => {
|
|
1448
1758
|
this.onDateChange(date);
|
|
1449
1759
|
this.closeCalendar();
|
|
1450
1760
|
});
|
|
@@ -1500,7 +1810,7 @@ class DatePickerComponent {
|
|
|
1500
1810
|
multi: true,
|
|
1501
1811
|
},
|
|
1502
1812
|
provideTranslocoScope('haloduck'),
|
|
1503
|
-
], viewQueries: [{ propertyName: "origin", first: true, predicate: ["origin"], descendants: true }], ngImport: i0, template: "<label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control\">\n <ng-content></ng-content>\n</label>\n<div
|
|
1813
|
+
], viewQueries: [{ propertyName: "origin", first: true, predicate: ["origin"], descendants: true }], ngImport: i0, template: "<label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control\">\n <ng-content></ng-content>\n</label>\n<div\n #origin\n class=\"py-1.5 relative mt-2 gap-2 rounded-md outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive\"\n [ngClass]=\"{\n 'bg-light-control dark:bg-dark-control focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary':\n !disabled,\n 'bg-light-control/60 dark:bg-dark-control/60 text-light-on-control/60 dark:text-dark-on-control/60':\n disabled,\n }\"\n [tabindex]=\"disabled ? -1 : 0\"\n (click)=\"onClick()\"\n>\n <div class=\"flex items-center\">\n <div\n class=\"flex-1 text-light-on-control dark:text-dark-on-control sm:text-sm/6 text-center\"\n [ngClass]=\"{\n 'text-light-inactive dark:text-dark-inactive': !selectedDate && !disabled,\n 'text-light-on-control dark:text-dark-on-control': selectedDate && !disabled,\n }\"\n >\n {{ selectedDate || placeholder }}\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }] });
|
|
1504
1814
|
}
|
|
1505
1815
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: DatePickerComponent, decorators: [{
|
|
1506
1816
|
type: Component,
|
|
@@ -1511,7 +1821,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
1511
1821
|
multi: true,
|
|
1512
1822
|
},
|
|
1513
1823
|
provideTranslocoScope('haloduck'),
|
|
1514
|
-
], template: "<label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control\">\n <ng-content></ng-content>\n</label>\n<div
|
|
1824
|
+
], template: "<label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control\">\n <ng-content></ng-content>\n</label>\n<div\n #origin\n class=\"py-1.5 relative mt-2 gap-2 rounded-md outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive\"\n [ngClass]=\"{\n 'bg-light-control dark:bg-dark-control focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary':\n !disabled,\n 'bg-light-control/60 dark:bg-dark-control/60 text-light-on-control/60 dark:text-dark-on-control/60':\n disabled,\n }\"\n [tabindex]=\"disabled ? -1 : 0\"\n (click)=\"onClick()\"\n>\n <div class=\"flex items-center\">\n <div\n class=\"flex-1 text-light-on-control dark:text-dark-on-control sm:text-sm/6 text-center\"\n [ngClass]=\"{\n 'text-light-inactive dark:text-dark-inactive': !selectedDate && !disabled,\n 'text-light-on-control dark:text-dark-on-control': selectedDate && !disabled,\n }\"\n >\n {{ selectedDate || placeholder }}\n </div>\n </div>\n</div>\n" }]
|
|
1515
1825
|
}], ctorParameters: () => [], propDecorators: { disabled: [{
|
|
1516
1826
|
type: Input
|
|
1517
1827
|
}], placeholder: [{
|
|
@@ -1614,8 +1924,7 @@ class DateRangeComponent {
|
|
|
1614
1924
|
default:
|
|
1615
1925
|
break;
|
|
1616
1926
|
}
|
|
1617
|
-
return
|
|
1618
|
-
dateRange.to === dateToString(to));
|
|
1927
|
+
return dateRange.from === dateToString(from) && dateRange.to === dateToString(to);
|
|
1619
1928
|
});
|
|
1620
1929
|
if (selectedOption) {
|
|
1621
1930
|
return selectedOption.id || selectedOption.value;
|
|
@@ -1651,9 +1960,7 @@ class DateRangeComponent {
|
|
|
1651
1960
|
componentRef.instance.firstDayOfWeek = this.firstDayOfWeek;
|
|
1652
1961
|
componentRef.instance.selectedDateRange = this.dateRange;
|
|
1653
1962
|
// Subscribe to events emitted by the CalendarComponent
|
|
1654
|
-
componentRef.instance.dateRangeChange
|
|
1655
|
-
.pipe(takeUntil(this.destroy$))
|
|
1656
|
-
.subscribe((date) => {
|
|
1963
|
+
componentRef.instance.dateRangeChange.pipe(takeUntil(this.destroy$)).subscribe((date) => {
|
|
1657
1964
|
this.onDateRangeChange(date);
|
|
1658
1965
|
this.closeCalendar();
|
|
1659
1966
|
});
|
|
@@ -1770,7 +2077,7 @@ class DateRangeComponent {
|
|
|
1770
2077
|
multi: true,
|
|
1771
2078
|
},
|
|
1772
2079
|
provideTranslocoScope('haloduck'),
|
|
1773
|
-
], viewQueries: [{ propertyName: "origin", first: true, predicate: ["origin"], descendants: true }], ngImport: i0, template: "<label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control\">\n <ng-content></ng-content>\n</label>\n<div
|
|
2080
|
+
], viewQueries: [{ propertyName: "origin", first: true, predicate: ["origin"], descendants: true }], ngImport: i0, template: "<label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control\">\n <ng-content></ng-content>\n</label>\n<div\n #origin\n class=\"relative mt-2 gap-2 rounded-md outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive\"\n [ngClass]=\"{\n 'bg-light-control dark:bg-dark-control focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary':\n !disabled,\n 'bg-light-control/60 dark:bg-dark-control/60 text-light-on-control/60 dark:text-dark-on-control/60':\n disabled,\n }\"\n [tabindex]=\"disabled ? -1 : 0\"\n (click)=\"onClick()\"\n>\n <div class=\"flex items-center\">\n <haloduck-select\n [multiselect]=\"false\"\n [disabled]=\"disabled\"\n [options]=\"dateRangeOptions\"\n [atLeastOne]=\"true\"\n (click)=\"$event.stopPropagation()\"\n variant=\"primary\"\n placeholder=\"{{ 'haloduck.ui.calendar.Period' | transloco }}\"\n [(ngModel)]=\"selectedDateRangeOptionId\"\n (ngModelChange)=\"onDateRangeOptionChange($event)\"\n >\n </haloduck-select>\n @if (getSelectedDateRangeString()) {\n <div\n class=\"flex-1 sm:text-sm/6 text-center\"\n [ngClass]=\"{\n 'text-light-on-control dark:text-dark-on-control': !disabled,\n 'text-light-on-control/60 dark:text-light-on-control/60': disabled,\n }\"\n >\n {{ getSelectedDateRangeString() }}\n </div>\n } @else {\n <div\n class=\"flex-1 sm:text-sm/6 text-center\"\n [ngClass]=\"{\n 'text-light-inactive dark:text-dark-inactive': !disabled,\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n }\"\n >\n {{ placeholder }}\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: SelectComponent, selector: "haloduck-select", inputs: ["disabled", "loading", "variant", "asButton", "useIcon", "useFilter", "multiselect", "placeholder", "atLeastOne", "showAll", "showAllItems", "options", "layout", "labelWidth", "value"], outputs: ["selectedChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }] });
|
|
1774
2081
|
}
|
|
1775
2082
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: DateRangeComponent, decorators: [{
|
|
1776
2083
|
type: Component,
|
|
@@ -1781,7 +2088,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
1781
2088
|
multi: true,
|
|
1782
2089
|
},
|
|
1783
2090
|
provideTranslocoScope('haloduck'),
|
|
1784
|
-
], template: "<label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control\">\n <ng-content></ng-content>\n</label>\n<div
|
|
2091
|
+
], template: "<label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control\">\n <ng-content></ng-content>\n</label>\n<div\n #origin\n class=\"relative mt-2 gap-2 rounded-md outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive\"\n [ngClass]=\"{\n 'bg-light-control dark:bg-dark-control focus:outline-2 focus:outline-offset-2 focus:outline-light-primary dark:focus:outline-dark-primary':\n !disabled,\n 'bg-light-control/60 dark:bg-dark-control/60 text-light-on-control/60 dark:text-dark-on-control/60':\n disabled,\n }\"\n [tabindex]=\"disabled ? -1 : 0\"\n (click)=\"onClick()\"\n>\n <div class=\"flex items-center\">\n <haloduck-select\n [multiselect]=\"false\"\n [disabled]=\"disabled\"\n [options]=\"dateRangeOptions\"\n [atLeastOne]=\"true\"\n (click)=\"$event.stopPropagation()\"\n variant=\"primary\"\n placeholder=\"{{ 'haloduck.ui.calendar.Period' | transloco }}\"\n [(ngModel)]=\"selectedDateRangeOptionId\"\n (ngModelChange)=\"onDateRangeOptionChange($event)\"\n >\n </haloduck-select>\n @if (getSelectedDateRangeString()) {\n <div\n class=\"flex-1 sm:text-sm/6 text-center\"\n [ngClass]=\"{\n 'text-light-on-control dark:text-dark-on-control': !disabled,\n 'text-light-on-control/60 dark:text-light-on-control/60': disabled,\n }\"\n >\n {{ getSelectedDateRangeString() }}\n </div>\n } @else {\n <div\n class=\"flex-1 sm:text-sm/6 text-center\"\n [ngClass]=\"{\n 'text-light-inactive dark:text-dark-inactive': !disabled,\n 'text-light-on-control/60 dark:text-dark-on-control/60': disabled,\n }\"\n >\n {{ placeholder }}\n </div>\n }\n </div>\n</div>\n" }]
|
|
1785
2092
|
}], ctorParameters: () => [], propDecorators: { dateRangeOptions: [{
|
|
1786
2093
|
type: Input
|
|
1787
2094
|
}], disabled: [{
|
|
@@ -1851,18 +2158,14 @@ class DrawCanvasComponent {
|
|
|
1851
2158
|
const touch = event.touches[0];
|
|
1852
2159
|
const rect = this.canvasRef.nativeElement.getBoundingClientRect();
|
|
1853
2160
|
this.ctx.beginPath();
|
|
1854
|
-
this.ctx.moveTo((touch.clientX - rect.left) *
|
|
1855
|
-
(this.canvasRef.nativeElement.width / rect.width), (touch.clientY - rect.top) *
|
|
1856
|
-
(this.canvasRef.nativeElement.height / rect.height));
|
|
2161
|
+
this.ctx.moveTo((touch.clientX - rect.left) * (this.canvasRef.nativeElement.width / rect.width), (touch.clientY - rect.top) * (this.canvasRef.nativeElement.height / rect.height));
|
|
1857
2162
|
}
|
|
1858
2163
|
touchDraw(event) {
|
|
1859
2164
|
if (!this.isDrawing)
|
|
1860
2165
|
return;
|
|
1861
2166
|
const touch = event.touches[0];
|
|
1862
2167
|
const rect = this.canvasRef.nativeElement.getBoundingClientRect();
|
|
1863
|
-
this.ctx.lineTo((touch.clientX - rect.left) *
|
|
1864
|
-
(this.canvasRef.nativeElement.width / rect.width), (touch.clientY - rect.top) *
|
|
1865
|
-
(this.canvasRef.nativeElement.height / rect.height));
|
|
2168
|
+
this.ctx.lineTo((touch.clientX - rect.left) * (this.canvasRef.nativeElement.width / rect.width), (touch.clientY - rect.top) * (this.canvasRef.nativeElement.height / rect.height));
|
|
1866
2169
|
this.ctx.stroke();
|
|
1867
2170
|
}
|
|
1868
2171
|
stopDrawing() {
|
|
@@ -1914,7 +2217,7 @@ class DrawCanvasComponent {
|
|
|
1914
2217
|
multi: true,
|
|
1915
2218
|
},
|
|
1916
2219
|
provideTranslocoScope('haloduck'),
|
|
1917
|
-
], viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"draw-canvas-container flex flex-col gap-2\">\n <canvas #canvas width=\"800\" height=\"400\" class=\"max-w-full draw-canvas select-none\"></canvas>\n <haloduck-button variant=\"danger\" (click)=\"onReset()\">{{
|
|
2220
|
+
], viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"draw-canvas-container flex flex-col gap-2\">\n <canvas #canvas width=\"800\" height=\"400\" class=\"max-w-full draw-canvas select-none\"></canvas>\n <haloduck-button variant=\"danger\" (click)=\"onReset()\">{{\n 'haloduck.ui.draw.Clear' | transloco\n }}</haloduck-button>\n</div>\n", styles: [".draw-canvas-container{display:flex;flex-direction:column;align-items:center}.draw-canvas{border:1px solid #ccc;cursor:crosshair}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "haloduck-button", inputs: ["disabled", "variant"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }] });
|
|
1918
2221
|
}
|
|
1919
2222
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: DrawCanvasComponent, decorators: [{
|
|
1920
2223
|
type: Component,
|
|
@@ -1925,7 +2228,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
1925
2228
|
multi: true,
|
|
1926
2229
|
},
|
|
1927
2230
|
provideTranslocoScope('haloduck'),
|
|
1928
|
-
], imports: [ButtonComponent, TranslocoModule], template: "<div class=\"draw-canvas-container flex flex-col gap-2\">\n <canvas #canvas width=\"800\" height=\"400\" class=\"max-w-full draw-canvas select-none\"></canvas>\n <haloduck-button variant=\"danger\" (click)=\"onReset()\">{{
|
|
2231
|
+
], imports: [ButtonComponent, TranslocoModule], template: "<div class=\"draw-canvas-container flex flex-col gap-2\">\n <canvas #canvas width=\"800\" height=\"400\" class=\"max-w-full draw-canvas select-none\"></canvas>\n <haloduck-button variant=\"danger\" (click)=\"onReset()\">{{\n 'haloduck.ui.draw.Clear' | transloco\n }}</haloduck-button>\n</div>\n", styles: [".draw-canvas-container{display:flex;flex-direction:column;align-items:center}.draw-canvas{border:1px solid #ccc;cursor:crosshair}\n"] }]
|
|
1929
2232
|
}], propDecorators: { imagePath: [{
|
|
1930
2233
|
type: Input
|
|
1931
2234
|
}], lineColor: [{
|
|
@@ -1973,9 +2276,7 @@ class FileUploaderComponent {
|
|
|
1973
2276
|
onFileSelected(event) {
|
|
1974
2277
|
const input = event.target;
|
|
1975
2278
|
if (input.files) {
|
|
1976
|
-
const selectedFiles = this.multiple
|
|
1977
|
-
? Array.from(input.files)
|
|
1978
|
-
: [input.files[0]];
|
|
2279
|
+
const selectedFiles = this.multiple ? Array.from(input.files) : [input.files[0]];
|
|
1979
2280
|
this.addFiles(selectedFiles);
|
|
1980
2281
|
}
|
|
1981
2282
|
this.onTouched();
|
|
@@ -2021,8 +2322,7 @@ class FileUploaderComponent {
|
|
|
2021
2322
|
}
|
|
2022
2323
|
return acceptableFileType && acceptableFileSize;
|
|
2023
2324
|
});
|
|
2024
|
-
if (this.maxCount > 0 &&
|
|
2025
|
-
this.files.length + filteredFiles.length > this.maxCount) {
|
|
2325
|
+
if (this.maxCount > 0 && this.files.length + filteredFiles.length > this.maxCount) {
|
|
2026
2326
|
for (let i = this.maxCount; i < this.files.length + filteredFiles.length; i++) {
|
|
2027
2327
|
notAcceptedFiles.push({
|
|
2028
2328
|
error: ERROR_OVER_COUNT,
|
|
@@ -2103,7 +2403,7 @@ class FileUploaderComponent {
|
|
|
2103
2403
|
multi: true,
|
|
2104
2404
|
},
|
|
2105
2405
|
provideTranslocoScope('haloduck'),
|
|
2106
|
-
], ngImport: i0, template: "<div
|
|
2406
|
+
], ngImport: i0, template: "<div\n class=\"p-4 border border-light-inactive dark:border-dark-inactive rounded-md\"\n [class.drag-over]=\"isDragOver\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n @if (!isUploading) {\n <label\n for=\"file-upload\"\n class=\"flex flex-col items-center justify-center w-full border-2 border-dashed border-light-inactive dark:border-dark-inactive rounded-md cursor-pointer hover:border-light-secondary dark:border-dark-secondary p-4\"\n >\n <span class=\"text-light-inactive dark:text-dark-inactive\">{{\n 'haloduck.ui.file.Drag and drop files here, or click to select files' | transloco\n }}</span>\n <input\n id=\"file-upload\"\n type=\"file\"\n class=\"hidden\"\n [attr.accept]=\"accept ? accept.join(',') : null\"\n [attr.multiple]=\"multiple ? '' : null\"\n (cancel)=\"$event.stopPropagation()\"\n (change)=\"onFileSelected($event)\"\n />\n </label>\n }\n <!-- Display file list -->\n @if (files.length > 0) {\n <ul class=\"mt-4 space-y-2\">\n @for (file of files; track file.name; let i = $index) {\n <li\n class=\"flex items-center justify-between p-2 border border-light-inactive dark:border-dark-inactive rounded-md\"\n >\n <!-- Check if the file is an image -->\n <div class=\"flex items-center space-x-4\">\n @if (file.previewUrl) {\n <img\n [src]=\"file.previewUrl\"\n alt=\"{{ file.name }}\"\n class=\"w-12 h-12 object-cover rounded-md\"\n />\n }\n <span class=\"text-sm text-light-inactive dark:text-dark-inactive\">{{ file.name }}</span>\n </div>\n @if (isUploading) {\n @if (file.isUploaded) {\n <span class=\"text-sm text-light-secondary dark:text-dark-secondary\">{{\n 'haloduck.ui.file.Uploaded' | transloco\n }}</span>\n } @else {\n <span class=\"text-sm text-light-primary dark:text-dark-primary\">{{\n 'haloduck.ui.file.Uploading...' | transloco\n }}</span>\n }\n } @else {\n <button\n type=\"button\"\n class=\"text-light-danger dark:text-dark-danger hover:brightness-125\"\n (click)=\"removeFile(i)\"\n >\n {{ 'haloduck.ui.file.Remove' | transloco }}\n </button>\n }\n </li>\n }\n </ul>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }] });
|
|
2107
2407
|
}
|
|
2108
2408
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: FileUploaderComponent, decorators: [{
|
|
2109
2409
|
type: Component,
|
|
@@ -2114,7 +2414,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
2114
2414
|
multi: true,
|
|
2115
2415
|
},
|
|
2116
2416
|
provideTranslocoScope('haloduck'),
|
|
2117
|
-
], template: "<div
|
|
2417
|
+
], template: "<div\n class=\"p-4 border border-light-inactive dark:border-dark-inactive rounded-md\"\n [class.drag-over]=\"isDragOver\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n @if (!isUploading) {\n <label\n for=\"file-upload\"\n class=\"flex flex-col items-center justify-center w-full border-2 border-dashed border-light-inactive dark:border-dark-inactive rounded-md cursor-pointer hover:border-light-secondary dark:border-dark-secondary p-4\"\n >\n <span class=\"text-light-inactive dark:text-dark-inactive\">{{\n 'haloduck.ui.file.Drag and drop files here, or click to select files' | transloco\n }}</span>\n <input\n id=\"file-upload\"\n type=\"file\"\n class=\"hidden\"\n [attr.accept]=\"accept ? accept.join(',') : null\"\n [attr.multiple]=\"multiple ? '' : null\"\n (cancel)=\"$event.stopPropagation()\"\n (change)=\"onFileSelected($event)\"\n />\n </label>\n }\n <!-- Display file list -->\n @if (files.length > 0) {\n <ul class=\"mt-4 space-y-2\">\n @for (file of files; track file.name; let i = $index) {\n <li\n class=\"flex items-center justify-between p-2 border border-light-inactive dark:border-dark-inactive rounded-md\"\n >\n <!-- Check if the file is an image -->\n <div class=\"flex items-center space-x-4\">\n @if (file.previewUrl) {\n <img\n [src]=\"file.previewUrl\"\n alt=\"{{ file.name }}\"\n class=\"w-12 h-12 object-cover rounded-md\"\n />\n }\n <span class=\"text-sm text-light-inactive dark:text-dark-inactive\">{{ file.name }}</span>\n </div>\n @if (isUploading) {\n @if (file.isUploaded) {\n <span class=\"text-sm text-light-secondary dark:text-dark-secondary\">{{\n 'haloduck.ui.file.Uploaded' | transloco\n }}</span>\n } @else {\n <span class=\"text-sm text-light-primary dark:text-dark-primary\">{{\n 'haloduck.ui.file.Uploading...' | transloco\n }}</span>\n }\n } @else {\n <button\n type=\"button\"\n class=\"text-light-danger dark:text-dark-danger hover:brightness-125\"\n (click)=\"removeFile(i)\"\n >\n {{ 'haloduck.ui.file.Remove' | transloco }}\n </button>\n }\n </li>\n }\n </ul>\n }\n</div>\n" }]
|
|
2118
2418
|
}], propDecorators: { disabled: [{
|
|
2119
2419
|
type: Input
|
|
2120
2420
|
}], urlPrefix: [{
|
|
@@ -2149,11 +2449,11 @@ class FlipComponent {
|
|
|
2149
2449
|
this._isOpen.set(!this._isOpen());
|
|
2150
2450
|
}
|
|
2151
2451
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: FlipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2152
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: FlipComponent, isStandalone: true, selector: "haloduck-flip", inputs: { title: "title", isOpen: "isOpen" }, ngImport: i0, template: "<div
|
|
2452
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: FlipComponent, isStandalone: true, selector: "haloduck-flip", inputs: { title: "title", isOpen: "isOpen" }, ngImport: i0, template: "<div\n class=\"relative w-full shadow ring-1 ring-light-inactive/50 dark:ring-dark-inactive/80 sm:rounded-lg bg-light-alternative dark:bg-dark-alternative p-2 flex flex-col gap-2\"\n [class.cursor-pointer]=\"!_isOpen()\"\n (click)=\"!_isOpen() && toggle()\"\n>\n <label\n class=\"text-sm text-light-on-alternative dark:text-dark-on-alternative\"\n [class.cursor-pointer]=\"!_isOpen()\"\n >{{ title }}</label\n >\n @if (_isOpen()) {\n <ng-content></ng-content>\n }\n <button\n variant=\"secondary\"\n class=\"absolute rounded-md border border-inactive px-1 py-0.5 top-1 right-1 hover:cursor-pointer bg-light-inactive dark:bg-dark-inactive text-light-on-inactive dark:text-dark-on-inactive\"\n (click)=\"toggle(); $event.stopPropagation()\"\n >\n @if (_isOpen()) {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 15l-6-6-6 6\" />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 9l6 6 6-6\" />\n </svg>\n }\n </button>\n</div>\n", styles: [""] });
|
|
2153
2453
|
}
|
|
2154
2454
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: FlipComponent, decorators: [{
|
|
2155
2455
|
type: Component,
|
|
2156
|
-
args: [{ selector: 'haloduck-flip', imports: [], template: "<div
|
|
2456
|
+
args: [{ selector: 'haloduck-flip', imports: [], template: "<div\n class=\"relative w-full shadow ring-1 ring-light-inactive/50 dark:ring-dark-inactive/80 sm:rounded-lg bg-light-alternative dark:bg-dark-alternative p-2 flex flex-col gap-2\"\n [class.cursor-pointer]=\"!_isOpen()\"\n (click)=\"!_isOpen() && toggle()\"\n>\n <label\n class=\"text-sm text-light-on-alternative dark:text-dark-on-alternative\"\n [class.cursor-pointer]=\"!_isOpen()\"\n >{{ title }}</label\n >\n @if (_isOpen()) {\n <ng-content></ng-content>\n }\n <button\n variant=\"secondary\"\n class=\"absolute rounded-md border border-inactive px-1 py-0.5 top-1 right-1 hover:cursor-pointer bg-light-inactive dark:bg-dark-inactive text-light-on-inactive dark:text-dark-on-inactive\"\n (click)=\"toggle(); $event.stopPropagation()\"\n >\n @if (_isOpen()) {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 15l-6-6-6 6\" />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 9l6 6 6-6\" />\n </svg>\n }\n </button>\n</div>\n" }]
|
|
2157
2457
|
}], propDecorators: { title: [{
|
|
2158
2458
|
type: Input
|
|
2159
2459
|
}], isOpen: [{
|
|
@@ -2171,11 +2471,11 @@ class ImageViewerComponent {
|
|
|
2171
2471
|
}
|
|
2172
2472
|
}
|
|
2173
2473
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ImageViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2174
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: ImageViewerComponent, isStandalone: true, selector: "haloduck-image-viewer", inputs: { context: "context", imageUrl: "imageUrl", imageAlt: "imageAlt" }, ngImport: i0, template: "<img
|
|
2474
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: ImageViewerComponent, isStandalone: true, selector: "haloduck-image-viewer", inputs: { context: "context", imageUrl: "imageUrl", imageAlt: "imageAlt" }, ngImport: i0, template: "<img\n class=\"max-w-full max-h-full object-cover cursor-pointer\"\n [src]=\"context?.imageUrl\"\n [alt]=\"context?.imageAlt\"\n (click)=\"onClose()\"\n/>\n", styles: [""] });
|
|
2175
2475
|
}
|
|
2176
2476
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ImageViewerComponent, decorators: [{
|
|
2177
2477
|
type: Component,
|
|
2178
|
-
args: [{ selector: 'haloduck-image-viewer', imports: [], template: "<img
|
|
2478
|
+
args: [{ selector: 'haloduck-image-viewer', imports: [], template: "<img\n class=\"max-w-full max-h-full object-cover cursor-pointer\"\n [src]=\"context?.imageUrl\"\n [alt]=\"context?.imageAlt\"\n (click)=\"onClose()\"\n/>\n" }]
|
|
2179
2479
|
}], propDecorators: { context: [{
|
|
2180
2480
|
type: Input
|
|
2181
2481
|
}], imageUrl: [{
|
|
@@ -2340,7 +2640,7 @@ class ImageUploaderComponent {
|
|
|
2340
2640
|
multi: true,
|
|
2341
2641
|
},
|
|
2342
2642
|
provideTranslocoScope('haloduck'),
|
|
2343
|
-
], ngImport: i0, template: "<div class=\"w-full h-full flex flex-col gap-1\">\n
|
|
2643
|
+
], ngImport: i0, template: "<div class=\"w-full h-full flex flex-col gap-1\">\n <label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control\">\n <ng-content></ng-content>\n </label>\n <div\n class=\"h-full w-full p-2 border border-light-inactive dark:border-dark-inactive rounded-md\"\n [class.drag-over]=\"isDragOver\"\n (dragstart)=\"onDragStart($event)\"\n (dragend)=\"onDragEnd($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n >\n <!-- Show image preview if available -->\n @if (imageUrl) {\n @if (!disabled) {\n <div class=\"relative\">\n <button\n type=\"button\"\n class=\"absolute -top-1 -right-1 bg-light-danger dark:bg-dark-danger text-light-on-danger dark:text-dark-on-danger rounded-full px-1 text-xs\"\n (click)=\"removeImage()\"\n >\n x\n </button>\n </div>\n }\n <img\n [src]=\"imageUrl\"\n [id]=\"id + '-image'\"\n [alt]=\"alt || ''\"\n class=\"w-full h-full rounded-md aspect-square\"\n [ngClass]=\"{\n 'filter grayscale': disabled,\n }\"\n (click)=\"previewImage(imageUrl)\"\n />\n } @else {\n <!-- Show upload area -->\n <label\n for=\"{{ id + '-input' }}\"\n class=\"flex flex-col items-center justify-center w-full h-full border-2 border-dashed border-light-inactive dark:border-dark-inactive rounded-md\"\n [ngClass]=\"{\n 'cursor-pointer hover:border-light-primary dark:hover:border-dark-primary': !disabled,\n }\"\n >\n @if (backgroundImage) {\n <img\n [src]=\"backgroundImage\"\n [alt]=\"alt || ''\"\n class=\"w-full h-full rounded-md aspect-square\"\n />\n } @else {\n <span class=\"text-light-inactive dark:text-dark-inactive text-sm p-2\">{{\n 'haloduck.ui.file.Drag and drop an image here, or click to select' | transloco\n }}</span>\n }\n\n @if (!disabled) {\n <input\n [id]=\"id + '-input'\"\n type=\"file\"\n class=\"hidden\"\n accept=\"image/*\"\n [multiple]=\"passToSibling\"\n (cancel)=\"$event.stopPropagation()\"\n (change)=\"onFileSelected($event)\"\n />\n }\n </label>\n }\n </div>\n</div>\n", styles: [".drag-over{border-color:#3b82f6}.relative{position:relative}button{cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }] });
|
|
2344
2644
|
}
|
|
2345
2645
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ImageUploaderComponent, decorators: [{
|
|
2346
2646
|
type: Component,
|
|
@@ -2351,7 +2651,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
2351
2651
|
multi: true,
|
|
2352
2652
|
},
|
|
2353
2653
|
provideTranslocoScope('haloduck'),
|
|
2354
|
-
], template: "<div class=\"w-full h-full flex flex-col gap-1\">\n
|
|
2654
|
+
], template: "<div class=\"w-full h-full flex flex-col gap-1\">\n <label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control\">\n <ng-content></ng-content>\n </label>\n <div\n class=\"h-full w-full p-2 border border-light-inactive dark:border-dark-inactive rounded-md\"\n [class.drag-over]=\"isDragOver\"\n (dragstart)=\"onDragStart($event)\"\n (dragend)=\"onDragEnd($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n >\n <!-- Show image preview if available -->\n @if (imageUrl) {\n @if (!disabled) {\n <div class=\"relative\">\n <button\n type=\"button\"\n class=\"absolute -top-1 -right-1 bg-light-danger dark:bg-dark-danger text-light-on-danger dark:text-dark-on-danger rounded-full px-1 text-xs\"\n (click)=\"removeImage()\"\n >\n x\n </button>\n </div>\n }\n <img\n [src]=\"imageUrl\"\n [id]=\"id + '-image'\"\n [alt]=\"alt || ''\"\n class=\"w-full h-full rounded-md aspect-square\"\n [ngClass]=\"{\n 'filter grayscale': disabled,\n }\"\n (click)=\"previewImage(imageUrl)\"\n />\n } @else {\n <!-- Show upload area -->\n <label\n for=\"{{ id + '-input' }}\"\n class=\"flex flex-col items-center justify-center w-full h-full border-2 border-dashed border-light-inactive dark:border-dark-inactive rounded-md\"\n [ngClass]=\"{\n 'cursor-pointer hover:border-light-primary dark:hover:border-dark-primary': !disabled,\n }\"\n >\n @if (backgroundImage) {\n <img\n [src]=\"backgroundImage\"\n [alt]=\"alt || ''\"\n class=\"w-full h-full rounded-md aspect-square\"\n />\n } @else {\n <span class=\"text-light-inactive dark:text-dark-inactive text-sm p-2\">{{\n 'haloduck.ui.file.Drag and drop an image here, or click to select' | transloco\n }}</span>\n }\n\n @if (!disabled) {\n <input\n [id]=\"id + '-input'\"\n type=\"file\"\n class=\"hidden\"\n accept=\"image/*\"\n [multiple]=\"passToSibling\"\n (cancel)=\"$event.stopPropagation()\"\n (change)=\"onFileSelected($event)\"\n />\n }\n </label>\n }\n </div>\n</div>\n", styles: [".drag-over{border-color:#3b82f6}.relative{position:relative}button{cursor:pointer}\n"] }]
|
|
2355
2655
|
}], propDecorators: { disabled: [{
|
|
2356
2656
|
type: Input
|
|
2357
2657
|
}], id: [{
|
|
@@ -2385,11 +2685,11 @@ class LanguageSelectorOptionComponent {
|
|
|
2385
2685
|
this.languageSelected.emit(language);
|
|
2386
2686
|
}
|
|
2387
2687
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: LanguageSelectorOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2388
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: LanguageSelectorOptionComponent, isStandalone: true, selector: "haloduck-language-selector-option", outputs: { languageSelected: "languageSelected" }, providers: [TranslocoService], ngImport: i0, template: "<div
|
|
2688
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: LanguageSelectorOptionComponent, isStandalone: true, selector: "haloduck-language-selector-option", outputs: { languageSelected: "languageSelected" }, providers: [TranslocoService], ngImport: i0, template: "<div\n class=\"right-0 z-10 mt-2.5 origin-top-right rounded-md bg-light-background dark:bg-dark-background py-2 shadow-lg ring-1 ring-light-inactive dark:ring-dark-inactive\"\n role=\"menu\"\n aria-orientation=\"vertical\"\n aria-labelledby=\"user-menu-button\"\n tabindex=\"0\"\n>\n @for (language of translateService.getAvailableLangs(); track language) {\n <a\n href=\"javascript:void(0)\"\n class=\"px-3 py-2 flex items-center flex-nowrap gap-2\"\n role=\"menuitem\"\n tabindex=\"-1\"\n id=\"language-item-{{ language }}\"\n (click)=\"selectLanguage(language)\"\n >\n <img class=\"w-6 h-6\" [src]=\"'i18n/icons/' + language + '.png'\" />\n </a>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
2389
2689
|
}
|
|
2390
2690
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: LanguageSelectorOptionComponent, decorators: [{
|
|
2391
2691
|
type: Component,
|
|
2392
|
-
args: [{ selector: 'haloduck-language-selector-option', imports: [CommonModule], providers: [TranslocoService], template: "<div
|
|
2692
|
+
args: [{ selector: 'haloduck-language-selector-option', imports: [CommonModule], providers: [TranslocoService], template: "<div\n class=\"right-0 z-10 mt-2.5 origin-top-right rounded-md bg-light-background dark:bg-dark-background py-2 shadow-lg ring-1 ring-light-inactive dark:ring-dark-inactive\"\n role=\"menu\"\n aria-orientation=\"vertical\"\n aria-labelledby=\"user-menu-button\"\n tabindex=\"0\"\n>\n @for (language of translateService.getAvailableLangs(); track language) {\n <a\n href=\"javascript:void(0)\"\n class=\"px-3 py-2 flex items-center flex-nowrap gap-2\"\n role=\"menuitem\"\n tabindex=\"-1\"\n id=\"language-item-{{ language }}\"\n (click)=\"selectLanguage(language)\"\n >\n <img class=\"w-6 h-6\" [src]=\"'i18n/icons/' + language + '.png'\" />\n </a>\n }\n</div>\n" }]
|
|
2393
2693
|
}], propDecorators: { languageSelected: [{
|
|
2394
2694
|
type: Output
|
|
2395
2695
|
}] } });
|
|
@@ -2461,11 +2761,11 @@ class LanguageSelectorComponent {
|
|
|
2461
2761
|
});
|
|
2462
2762
|
}
|
|
2463
2763
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: LanguageSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2464
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: LanguageSelectorComponent, isStandalone: true, selector: "haloduck-language-selector", viewQueries: [{ propertyName: "origin", first: true, predicate: ["origin"], descendants: true }], ngImport: i0, template: "<button
|
|
2764
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: LanguageSelectorComponent, isStandalone: true, selector: "haloduck-language-selector", viewQueries: [{ propertyName: "origin", first: true, predicate: ["origin"], descendants: true }], ngImport: i0, template: "<button\n #origin\n type=\"button\"\n (click)=\"showLanguageOptions()\"\n class=\"-m-1.5 flex items-center p-1.5 hover:cursor-pointer\"\n aria-expanded=\"false\"\n aria-haspopup=\"true\"\n>\n <span class=\"max-lg:hidden flex lg:items-center\">\n <img class=\"w-6 h-6\" [src]=\"'i18n/icons/' + language() + '.png'\" />\n </span>\n</button>\n", styles: [""] });
|
|
2465
2765
|
}
|
|
2466
2766
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: LanguageSelectorComponent, decorators: [{
|
|
2467
2767
|
type: Component,
|
|
2468
|
-
args: [{ selector: 'haloduck-language-selector', imports: [], template: "<button
|
|
2768
|
+
args: [{ selector: 'haloduck-language-selector', imports: [], template: "<button\n #origin\n type=\"button\"\n (click)=\"showLanguageOptions()\"\n class=\"-m-1.5 flex items-center p-1.5 hover:cursor-pointer\"\n aria-expanded=\"false\"\n aria-haspopup=\"true\"\n>\n <span class=\"max-lg:hidden flex lg:items-center\">\n <img class=\"w-6 h-6\" [src]=\"'i18n/icons/' + language() + '.png'\" />\n </span>\n</button>\n" }]
|
|
2469
2769
|
}], propDecorators: { origin: [{
|
|
2470
2770
|
type: ViewChild,
|
|
2471
2771
|
args: ['origin', { static: false }]
|
|
@@ -2539,8 +2839,7 @@ class MapToAddressComponent {
|
|
|
2539
2839
|
}
|
|
2540
2840
|
initMap() {
|
|
2541
2841
|
if (this.currentLngLat) {
|
|
2542
|
-
isDevMode() &&
|
|
2543
|
-
console.log('Using provided location:', this.currentLngLat);
|
|
2842
|
+
isDevMode() && console.log('Using provided location:', this.currentLngLat);
|
|
2544
2843
|
this.initializeMap(this.currentLngLat);
|
|
2545
2844
|
}
|
|
2546
2845
|
else {
|
|
@@ -2549,16 +2848,14 @@ class MapToAddressComponent {
|
|
|
2549
2848
|
lat: position.coords.latitude,
|
|
2550
2849
|
lng: position.coords.longitude,
|
|
2551
2850
|
};
|
|
2552
|
-
isDevMode() &&
|
|
2553
|
-
console.log('Using current location:', currentLocation);
|
|
2851
|
+
isDevMode() && console.log('Using current location:', currentLocation);
|
|
2554
2852
|
this.initializeMap(currentLocation);
|
|
2555
2853
|
}, (error) => {
|
|
2556
2854
|
if (error.code === error.PERMISSION_DENIED) {
|
|
2557
2855
|
isDevMode() &&
|
|
2558
2856
|
console.log('Location permission denied. Using default location.:', this.defaultLngLat);
|
|
2559
2857
|
}
|
|
2560
|
-
else if (error.code === error.POSITION_UNAVAILABLE ||
|
|
2561
|
-
error.code === error.TIMEOUT) {
|
|
2858
|
+
else if (error.code === error.POSITION_UNAVAILABLE || error.code === error.TIMEOUT) {
|
|
2562
2859
|
isDevMode() &&
|
|
2563
2860
|
console.log('Unable to determine location. Using default location.:', this.defaultLngLat);
|
|
2564
2861
|
}
|
|
@@ -2596,14 +2893,12 @@ class MapToAddressComponent {
|
|
|
2596
2893
|
// Explicitly update marker position
|
|
2597
2894
|
this.marker.position = event.latLng;
|
|
2598
2895
|
this.marker.map = this.map; // Ensure marker is attached to the map
|
|
2599
|
-
isDevMode() &&
|
|
2600
|
-
console.log('Marker position updated to:', event.latLng.toJSON());
|
|
2896
|
+
isDevMode() && console.log('Marker position updated to:', event.latLng.toJSON());
|
|
2601
2897
|
this.getAddress(); // Fetch address immediately after click
|
|
2602
2898
|
this.onTouched(); // Mark as touched
|
|
2603
2899
|
}
|
|
2604
2900
|
else {
|
|
2605
|
-
isDevMode() &&
|
|
2606
|
-
console.error('Failed to update marker position: event.latLng is undefined');
|
|
2901
|
+
isDevMode() && console.error('Failed to update marker position: event.latLng is undefined');
|
|
2607
2902
|
}
|
|
2608
2903
|
}
|
|
2609
2904
|
setMapToAddress() {
|
|
@@ -2701,7 +2996,7 @@ class MapToAddressComponent {
|
|
|
2701
2996
|
useExisting: MapToAddressComponent,
|
|
2702
2997
|
multi: true,
|
|
2703
2998
|
},
|
|
2704
|
-
], ngImport: i0, template: "<div class=\"w-full h-full relative\">\n <!-- \uB85C\uB529 \uC0C1\uD0DC -->\n @if(!isGoogleLoaded && !loadError) {\n
|
|
2999
|
+
], ngImport: i0, template: "<div class=\"w-full h-full relative\">\n <!-- \uB85C\uB529 \uC0C1\uD0DC -->\n @if (!isGoogleLoaded && !loadError) {\n <div class=\"absolute inset-0 flex items-center justify-center bg-gray-100 z-10\">\n <div class=\"text-center\">\n <div\n class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto mb-2\"\n ></div>\n <p class=\"text-gray-600 text-sm\">\uC9C0\uB3C4\uB97C \uB85C\uB529 \uC911\uC785\uB2C8\uB2E4...</p>\n </div>\n </div>\n }\n\n <!-- \uC5D0\uB7EC \uC0C1\uD0DC -->\n @if (loadError) {\n <div class=\"absolute inset-0 flex items-center justify-center bg-red-50 z-10\">\n <div class=\"text-center p-4\">\n <div class=\"text-red-500 text-2xl mb-2\">\u26A0\uFE0F</div>\n <p class=\"text-red-700 text-sm font-medium\">{{ loadError }}</p>\n <p class=\"text-red-600 text-xs mt-1\">\n Please check your internet connection and refresh the page.\n </p>\n </div>\n </div>\n }\n\n <div id=\"map\" class=\"w-full h-full\"></div>\n</div>\n", styles: ["#map{border:1px solid #ccc;margin-bottom:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
|
|
2705
3000
|
}
|
|
2706
3001
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: MapToAddressComponent, decorators: [{
|
|
2707
3002
|
type: Component,
|
|
@@ -2711,7 +3006,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
2711
3006
|
useExisting: MapToAddressComponent,
|
|
2712
3007
|
multi: true,
|
|
2713
3008
|
},
|
|
2714
|
-
], template: "<div class=\"w-full h-full relative\">\n <!-- \uB85C\uB529 \uC0C1\uD0DC -->\n @if(!isGoogleLoaded && !loadError) {\n
|
|
3009
|
+
], template: "<div class=\"w-full h-full relative\">\n <!-- \uB85C\uB529 \uC0C1\uD0DC -->\n @if (!isGoogleLoaded && !loadError) {\n <div class=\"absolute inset-0 flex items-center justify-center bg-gray-100 z-10\">\n <div class=\"text-center\">\n <div\n class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto mb-2\"\n ></div>\n <p class=\"text-gray-600 text-sm\">\uC9C0\uB3C4\uB97C \uB85C\uB529 \uC911\uC785\uB2C8\uB2E4...</p>\n </div>\n </div>\n }\n\n <!-- \uC5D0\uB7EC \uC0C1\uD0DC -->\n @if (loadError) {\n <div class=\"absolute inset-0 flex items-center justify-center bg-red-50 z-10\">\n <div class=\"text-center p-4\">\n <div class=\"text-red-500 text-2xl mb-2\">\u26A0\uFE0F</div>\n <p class=\"text-red-700 text-sm font-medium\">{{ loadError }}</p>\n <p class=\"text-red-600 text-xs mt-1\">\n Please check your internet connection and refresh the page.\n </p>\n </div>\n </div>\n }\n\n <div id=\"map\" class=\"w-full h-full\"></div>\n</div>\n", styles: ["#map{border:1px solid #ccc;margin-bottom:10px}\n"] }]
|
|
2715
3010
|
}], propDecorators: { disabled: [{
|
|
2716
3011
|
type: Input
|
|
2717
3012
|
}], language: [{
|
|
@@ -2737,9 +3032,11 @@ class SideMenuItemComponent {
|
|
|
2737
3032
|
ngOnInit() {
|
|
2738
3033
|
if (this.menuItem.iconType === 'svg') {
|
|
2739
3034
|
fetch(this.menuItem.icon || '')
|
|
2740
|
-
.then(response => {
|
|
2741
|
-
.
|
|
2742
|
-
|
|
3035
|
+
.then((response) => {
|
|
3036
|
+
return response.ok ? response : Promise.reject(response);
|
|
3037
|
+
})
|
|
3038
|
+
.then((response) => response.text())
|
|
3039
|
+
.then((svg) => (this.iconSvg = this.sanitizer.bypassSecurityTrustHtml(svg)));
|
|
2743
3040
|
}
|
|
2744
3041
|
}
|
|
2745
3042
|
onMenuItemSelected(menuItem) {
|
|
@@ -2754,11 +3051,11 @@ class SideMenuItemComponent {
|
|
|
2754
3051
|
this.router.navigate(link);
|
|
2755
3052
|
}
|
|
2756
3053
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SideMenuItemComponent, deps: [{ token: i1$3.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
|
|
2757
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: SideMenuItemComponent, isStandalone: true, selector: "haloduck-side-menu-item", inputs: { menuItem: "menuItem", depth: "depth", menuItemSelectHandler: "menuItemSelectHandler" }, ngImport: i0, template: "<a
|
|
3054
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: SideMenuItemComponent, isStandalone: true, selector: "haloduck-side-menu-item", inputs: { menuItem: "menuItem", depth: "depth", menuItemSelectHandler: "menuItemSelectHandler" }, ngImport: i0, template: "<a\n href=\"javascript:void(0)\"\n (click)=\"onMenuItemSelected(menuItem)\"\n class=\"flex items-center gap-2 px-4 py-2 rounded-md cursor-pointer hover:text-light-on-primary dark:hover:text-dark-on-primary hover:bg-light-primary dark:hover:bg-dark-primary hover:cursor-pointer\"\n [ngClass]=\"{\n 'font-bold text-light-on-secondary dark:bg-dark-on-secondary bg-light-secondary dark:bg-dark-secondary':\n menuItem.isSelected,\n }\"\n>\n @if (menuItem.iconType === 'svg') {\n <div [innerHTML]=\"iconSvg\"></div>\n } @else {\n @if (menuItem.icon) {\n <img\n class=\"w-5 h-5\"\n [src]=\"menuItem.icon\"\n [alt]=\"menuItem.title\"\n [title]=\"menuItem.title\"\n [loading]=\"'lazy'\"\n />\n }\n }\n <span\n class=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n title=\"{{ menuItem.title }}\"\n [ngStyle]=\"{ 'margin-left.px': depth ? depth * 16 : 0 }\"\n >\n {{ menuItem.title }}\n </span>\n</a>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
2758
3055
|
}
|
|
2759
3056
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SideMenuItemComponent, decorators: [{
|
|
2760
3057
|
type: Component,
|
|
2761
|
-
args: [{ selector: 'haloduck-side-menu-item', imports: [CommonModule], template: "<a
|
|
3058
|
+
args: [{ selector: 'haloduck-side-menu-item', imports: [CommonModule], template: "<a\n href=\"javascript:void(0)\"\n (click)=\"onMenuItemSelected(menuItem)\"\n class=\"flex items-center gap-2 px-4 py-2 rounded-md cursor-pointer hover:text-light-on-primary dark:hover:text-dark-on-primary hover:bg-light-primary dark:hover:bg-dark-primary hover:cursor-pointer\"\n [ngClass]=\"{\n 'font-bold text-light-on-secondary dark:bg-dark-on-secondary bg-light-secondary dark:bg-dark-secondary':\n menuItem.isSelected,\n }\"\n>\n @if (menuItem.iconType === 'svg') {\n <div [innerHTML]=\"iconSvg\"></div>\n } @else {\n @if (menuItem.icon) {\n <img\n class=\"w-5 h-5\"\n [src]=\"menuItem.icon\"\n [alt]=\"menuItem.title\"\n [title]=\"menuItem.title\"\n [loading]=\"'lazy'\"\n />\n }\n }\n <span\n class=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n title=\"{{ menuItem.title }}\"\n [ngStyle]=\"{ 'margin-left.px': depth ? depth * 16 : 0 }\"\n >\n {{ menuItem.title }}\n </span>\n</a>\n" }]
|
|
2762
3059
|
}], ctorParameters: () => [{ type: i1$3.DomSanitizer }], propDecorators: { menuItem: [{
|
|
2763
3060
|
type: Input
|
|
2764
3061
|
}], depth: [{
|
|
@@ -2772,11 +3069,11 @@ class SideMenuComponent {
|
|
|
2772
3069
|
depth = 0;
|
|
2773
3070
|
menuItemSelected = new EventEmitter();
|
|
2774
3071
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SideMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2775
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: SideMenuComponent, isStandalone: true, selector: "haloduck-side-menu", inputs: { menuItems: "menuItems", depth: "depth" }, outputs: { menuItemSelected: "menuItemSelected" }, ngImport: i0, template: "<div class=\"flex flex-col text-sm text-light-on-background dark:text-dark-on-background\">\n @for (menuItem of menuItems; track menuItem.link) {\n
|
|
3072
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: SideMenuComponent, isStandalone: true, selector: "haloduck-side-menu", inputs: { menuItems: "menuItems", depth: "depth" }, outputs: { menuItemSelected: "menuItemSelected" }, ngImport: i0, template: "<div class=\"flex flex-col text-sm text-light-on-background dark:text-dark-on-background\">\n @for (menuItem of menuItems; track menuItem.link) {\n <haloduck-side-menu-item\n [menuItemSelectHandler]=\"menuItemSelected\"\n [menuItem]=\"menuItem\"\n [depth]=\"depth\"\n ></haloduck-side-menu-item>\n @if (menuItem.children && menuItem.children.length > 0) {\n <haloduck-side-menu\n [menuItems]=\"menuItem.children\"\n [depth]=\"depth + 1\"\n (menuItemSelected)=\"menuItemSelected.emit($event)\"\n ></haloduck-side-menu>\n }\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: SideMenuComponent, selector: "haloduck-side-menu", inputs: ["menuItems", "depth"], outputs: ["menuItemSelected"] }, { kind: "component", type: SideMenuItemComponent, selector: "haloduck-side-menu-item", inputs: ["menuItem", "depth", "menuItemSelectHandler"] }] });
|
|
2776
3073
|
}
|
|
2777
3074
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SideMenuComponent, decorators: [{
|
|
2778
3075
|
type: Component,
|
|
2779
|
-
args: [{ selector: 'haloduck-side-menu', imports: [SideMenuItemComponent], template: "<div class=\"flex flex-col text-sm text-light-on-background dark:text-dark-on-background\">\n @for (menuItem of menuItems; track menuItem.link) {\n
|
|
3076
|
+
args: [{ selector: 'haloduck-side-menu', imports: [SideMenuItemComponent], template: "<div class=\"flex flex-col text-sm text-light-on-background dark:text-dark-on-background\">\n @for (menuItem of menuItems; track menuItem.link) {\n <haloduck-side-menu-item\n [menuItemSelectHandler]=\"menuItemSelected\"\n [menuItem]=\"menuItem\"\n [depth]=\"depth\"\n ></haloduck-side-menu-item>\n @if (menuItem.children && menuItem.children.length > 0) {\n <haloduck-side-menu\n [menuItems]=\"menuItem.children\"\n [depth]=\"depth + 1\"\n (menuItemSelected)=\"menuItemSelected.emit($event)\"\n ></haloduck-side-menu>\n }\n }\n</div>\n" }]
|
|
2780
3077
|
}], propDecorators: { menuItems: [{
|
|
2781
3078
|
type: Input
|
|
2782
3079
|
}], depth: [{
|
|
@@ -2876,11 +3173,11 @@ class StlViewerComponent {
|
|
|
2876
3173
|
}
|
|
2877
3174
|
}
|
|
2878
3175
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: StlViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2879
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: StlViewerComponent, isStandalone: true, selector: "haloduck-stl-viewer", inputs: { fileUrl: "fileUrl", filename: "filename", context: "context" }, providers: [provideTranslocoScope('haloduck')], viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["viewerContainer"], descendants: true }], ngImport: i0, template: "<div class=\"relative w-full h-full flex flex-col items-end\">\n
|
|
3176
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: StlViewerComponent, isStandalone: true, selector: "haloduck-stl-viewer", inputs: { fileUrl: "fileUrl", filename: "filename", context: "context" }, providers: [provideTranslocoScope('haloduck')], viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["viewerContainer"], descendants: true }], ngImport: i0, template: "<div class=\"relative w-full h-full flex flex-col items-end\">\n <div class=\"w-full h-full flex items-start flex-col\">\n <div #viewerContainer class=\"w-full h-full rounded-md\"></div>\n @if (loadingPercentage < 100) {\n <div\n class=\"h-2 bg-light-primary-light dark:bg-dark-primary-light\"\n [ngStyle]=\"{ width: loadingPercentage + '%' }\"\n ></div>\n }\n </div>\n <div class=\"absolute bottom-2 right-0 flex justify-end gap-2\">\n @if (context) {\n <haloduck-button variant=\"primary\" (click)=\"download()\">{{\n 'haloduck.ui.button.Download' | transloco\n }}</haloduck-button>\n <haloduck-button variant=\"danger\" (click)=\"closeDialog()\">{{\n 'haloduck.ui.button.Close' | transloco\n }}</haloduck-button>\n } @else {\n <haloduck-button variant=\"primary\" (click)=\"download()\">{{\n 'haloduck.ui.button.Download' | transloco\n }}</haloduck-button>\n <haloduck-button variant=\"secondary\" (click)=\"showStl()\">{{\n 'haloduck.ui.button.View' | transloco\n }}</haloduck-button>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ButtonComponent, selector: "haloduck-button", inputs: ["disabled", "variant"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }] });
|
|
2880
3177
|
}
|
|
2881
3178
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: StlViewerComponent, decorators: [{
|
|
2882
3179
|
type: Component,
|
|
2883
|
-
args: [{ selector: 'haloduck-stl-viewer', imports: [CommonModule, ButtonComponent, TranslocoModule], providers: [provideTranslocoScope('haloduck')], template: "<div class=\"relative w-full h-full flex flex-col items-end\">\n
|
|
3180
|
+
args: [{ selector: 'haloduck-stl-viewer', imports: [CommonModule, ButtonComponent, TranslocoModule], providers: [provideTranslocoScope('haloduck')], template: "<div class=\"relative w-full h-full flex flex-col items-end\">\n <div class=\"w-full h-full flex items-start flex-col\">\n <div #viewerContainer class=\"w-full h-full rounded-md\"></div>\n @if (loadingPercentage < 100) {\n <div\n class=\"h-2 bg-light-primary-light dark:bg-dark-primary-light\"\n [ngStyle]=\"{ width: loadingPercentage + '%' }\"\n ></div>\n }\n </div>\n <div class=\"absolute bottom-2 right-0 flex justify-end gap-2\">\n @if (context) {\n <haloduck-button variant=\"primary\" (click)=\"download()\">{{\n 'haloduck.ui.button.Download' | transloco\n }}</haloduck-button>\n <haloduck-button variant=\"danger\" (click)=\"closeDialog()\">{{\n 'haloduck.ui.button.Close' | transloco\n }}</haloduck-button>\n } @else {\n <haloduck-button variant=\"primary\" (click)=\"download()\">{{\n 'haloduck.ui.button.Download' | transloco\n }}</haloduck-button>\n <haloduck-button variant=\"secondary\" (click)=\"showStl()\">{{\n 'haloduck.ui.button.View' | transloco\n }}</haloduck-button>\n }\n </div>\n</div>\n" }]
|
|
2884
3181
|
}], propDecorators: { fileUrl: [{
|
|
2885
3182
|
type: Input
|
|
2886
3183
|
}], filename: [{
|
|
@@ -3097,9 +3394,11 @@ class TableComponent {
|
|
|
3097
3394
|
onLoadMore = new EventEmitter();
|
|
3098
3395
|
onRowClick = new EventEmitter();
|
|
3099
3396
|
onRowDblClick = new EventEmitter();
|
|
3100
|
-
settings$ = this.tableName
|
|
3101
|
-
|
|
3102
|
-
|
|
3397
|
+
settings$ = this.tableName
|
|
3398
|
+
? this.tableSettingService.getSettings(this.tableName).pipe(shareReplay(1))
|
|
3399
|
+
: of({ showHeader: this.defaultShowHeader, autoLoad: this.defaultAutoLoad });
|
|
3400
|
+
showHeader$ = this.settings$.pipe(map((settings) => settings.showHeader));
|
|
3401
|
+
autoLoad$ = this.settings$.pipe(map((settings) => settings.autoLoad));
|
|
3103
3402
|
getColumnValue(row, column) {
|
|
3104
3403
|
const value = this.getColumnValueRaw(row, column);
|
|
3105
3404
|
if (column.customRenderFn) {
|
|
@@ -3201,7 +3500,7 @@ class TableComponent {
|
|
|
3201
3500
|
});
|
|
3202
3501
|
}
|
|
3203
3502
|
onAutoLoadTriggered() {
|
|
3204
|
-
this.autoLoad$.pipe(take(1)).subscribe(autoLoad => {
|
|
3503
|
+
this.autoLoad$.pipe(take(1)).subscribe((autoLoad) => {
|
|
3205
3504
|
if (autoLoad) {
|
|
3206
3505
|
this.lastEvaluatedKey.pipe(take(1)).subscribe((lastEvaluatedKey) => {
|
|
3207
3506
|
this.onLoadMore.emit(lastEvaluatedKey);
|
|
@@ -3218,8 +3517,8 @@ class TableComponent {
|
|
|
3218
3517
|
ngOnInit() {
|
|
3219
3518
|
if (this.tableName) {
|
|
3220
3519
|
this.settings$ = this.tableSettingService.getSettings(this.tableName).pipe(shareReplay(1));
|
|
3221
|
-
this.showHeader$ = this.settings$.pipe(map(settings => settings.showHeader));
|
|
3222
|
-
this.autoLoad$ = this.settings$.pipe(map(settings => settings.autoLoad));
|
|
3520
|
+
this.showHeader$ = this.settings$.pipe(map((settings) => settings.showHeader));
|
|
3521
|
+
this.autoLoad$ = this.settings$.pipe(map((settings) => settings.autoLoad));
|
|
3223
3522
|
}
|
|
3224
3523
|
}
|
|
3225
3524
|
openSettings() {
|
|
@@ -3229,11 +3528,11 @@ class TableComponent {
|
|
|
3229
3528
|
}
|
|
3230
3529
|
ngAfterViewInit() { }
|
|
3231
3530
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3232
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: TableComponent, isStandalone: true, selector: "haloduck-table", inputs: { tableLayout: "tableLayout", tableName: "tableName", useLoadMore: "useLoadMore", columns: "columns", rows: "rows", isLoading: "isLoading", isPaging: "isPaging", sort: "sort", expandedTemplate: "expandedTemplate", customTemplates: "customTemplates", lastEvaluatedKey: "lastEvaluatedKey" }, outputs: { onSortChange: "onSortChange", onLoadMore: "onLoadMore", onRowClick: "onRowClick", onRowDblClick: "onRowDblClick" }, providers: [provideTranslocoScope('haloduck')], viewQueries: [{ propertyName: "loadMoreRowRef", first: true, predicate: ["loadMoreRow"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"w-full h-full shadow border border-light-inactive dark:border-dark-inactive rounded-lg overflow-auto\">\n <table class=\"w-full h-full\"\n [ngClass]=\"{\n 'table-fixed': tableLayout === 'fixed',\n 'table-auto': tableLayout === 'auto',\n }\">\n <colgroup>\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <col class=\"{{ column.width || '' }}\" />\n }\n }\n </colgroup>\n @if (showHeader$ | async) {\n <thead class=\"bg-light-inactive/50 dark:bg-dark-inactive/50 rounded-tl-lg rounded-tr-lg\">\n <tr>\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <th scope=\"col\"\n class=\"{{ column.align || '' }} py-3.5 pl-4 pr-3 text-sm font-semibold text-light-on-background dark:text-dark-on-background whitespace-nowrap\">\n <span class=\"group inline-flex\">\n {{ column.label }}\n @if (column.sortable) {\n @switch (getSortDirection(column.sort?.field || column.key) | async)\n {\n @case('desc') {\n <span (click)=\"onUpdateSort(column.sort?.field || column.key, 'asc')\"\n class=\"ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive\">\n <svg class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path fill-rule=\"evenodd\"\n d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\" />\n </svg>\n </span>\n }\n @case('asc') {\n <span (click)=\"onUpdateSort(column.sort?.field || column.key, 'desc')\"\n class=\"ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive\">\n <svg class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path fill-rule=\"evenodd\"\n d=\"M14.78 11.78a.75.75 0 0 1-1.06 0L10 8.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06Z\"\n clip-rule=\"evenodd\" />\n </svg>\n </span>\n }\n @default {\n <span (click)=\"onUpdateSort(column.sort?.field || column.key, 'asc')\"\n class=\"invisible ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive group-hover:visible group-focus:visible\">\n <svg class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path fill-rule=\"evenodd\"\n d=\"M14.78 11.78a.75.75 0 0 1-1.06 0L10 8.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06Z\"\n clip-rule=\"evenodd\" />\n </svg>\n </span>\n }\n }\n }\n </span>\n </th>\n }\n }\n </tr>\n </thead>\n }\n <tbody class=\"overflow-scroll\">\n @for (row of rows | async; track row['id']; let lastRow = $last) {\n <tr class=\"border-t border-light-inactive dark:border-dark-inactive {{ row.bgColor || '' }}\"\n (click)=\"onRowClicked(row)\"\n (dblclick)=\"onRowDblClicked(row)\"\n [ngClass]=\"{'rounded-b-lg': lastRow && (lastEvaluatedKey | async) === null, 'even:bg-light-alternative dark:even:bg-dark-alternative odd:bg-light-background dark:odd:bg-dark-background': !row.bgColor }\"\n [ngStyle]=\"{ 'background-color': row.bgColor || '' }\">\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <td class=\"relative overflow-visible {{ column.align || '' }} whitespace-nowrap px-3 text-sm text-light-on-background dark:text-dark-on-background\"\n [ngClass]=\"{\n 'first:rounded-bl-lg last:rounded-br-lg': lastRow && (lastEvaluatedKey | async) === null,\n 'text-wrap': row.isExpanded && column.type !== 'custom',\n 'overflow-x-hidden text-ellipsis' : !row.isExpanded && column.type !== 'custom',\n 'py-2': column.type === 'custom',\n 'py-4': column.type !== 'custom'\n }\">\n @if (column.type === 'custom') {\n @if (column.customRenderTemplate) {\n <ng-container [ngTemplateOutlet]=\"customTemplates[column.customRenderTemplate]\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"></ng-container>\n }\n }\n @else {\n {{ getColumnValue(row, column) | async }}\n }\n </td>\n }\n }\n </tr>\n\n @if (row.isExpanded && expandedTemplate) {\n <tr>\n <td [attr.colspan]=\"columns.length\">\n </td>\n </tr>\n <tr class=\"even:bg-light-alternative dark:even:bg-dark-alternative odd:bg-light-background dark:odd:bg-dark-background\">\n <td [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 pb-4 text-sm text-center\">\n <ng-container [ngTemplateOutlet]=\"expandedTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row }\"></ng-container>\n </td>\n </tr>\n }\n\n @if (lastRow && (lastEvaluatedKey | async) && !(isLoading | async) && useLoadMore) {\n <tr #loadMoreRow\n class=\"border-t border-light-inactive dark:border-dark-inactive bg-light-background dark:bg-dark-background\"\n haloduckAutoLoad\n [autoLoadEnabled]=\"(autoLoad$ | async) ?? true\"\n [autoLoadThreshold]=\"0.1\"\n (autoLoadTrigger)=\"onAutoLoadTriggered()\">\n <td [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 py-4 text-sm text-light-on-background dark:text-dark-on-background text-center h-16 bg-light-background dark:bg-dark-background rounded-bl-lg rounded-br-lg\">\n <div (click)=\"onLoadMoreClicked()\"\n class=\"cursor-pointer\">\n {{ 'haloduck.ui.table.Load More...' | transloco }}\n </div>\n </td>\n </tr>\n }\n\n } @empty {\n @if(!(isLoading | async)) {\n <tr>\n <td [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 py-4 text-sm text-light-on-background dark:text-dark-on-background text-center h-16 bg-light-background dark:bg-dark-background rounded-bl-lg rounded-br-lg\">\n {{ 'haloduck.ui.table.No data available.' | transloco }}\n </td>\n </tr>\n }\n }\n\n @if(isLoading | async) {\n @for ( i of [0,1,2,3,4]; track i; let lastRow = $last)\n {\n <tr class=\"bg-light-background dark:bg-dark-background border-t border-light-inactive/50 dark:border-dark-inactive/50\">\n @for (column of columns; track column.key) {\n <td class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm\"\n [ngClass]=\"{'first:rounded-bl-lg last:rounded-br-lg': lastRow}\">\n <div class=\"h-4 bg-light-inactive/50 dark:bg-dark-inactive/50 rounded-md animate-pulse\"></div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "directive", type: AutoLoadDirective, selector: "[haloduckAutoLoad]", inputs: ["autoLoadEnabled", "autoLoadThreshold", "autoLoadRootMargin"], outputs: ["autoLoadTrigger"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3531
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: TableComponent, isStandalone: true, selector: "haloduck-table", inputs: { tableLayout: "tableLayout", tableName: "tableName", useLoadMore: "useLoadMore", columns: "columns", rows: "rows", isLoading: "isLoading", isPaging: "isPaging", sort: "sort", expandedTemplate: "expandedTemplate", customTemplates: "customTemplates", lastEvaluatedKey: "lastEvaluatedKey" }, outputs: { onSortChange: "onSortChange", onLoadMore: "onLoadMore", onRowClick: "onRowClick", onRowDblClick: "onRowDblClick" }, providers: [provideTranslocoScope('haloduck')], viewQueries: [{ propertyName: "loadMoreRowRef", first: true, predicate: ["loadMoreRow"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div\n class=\"w-full h-full shadow border border-light-inactive dark:border-dark-inactive rounded-lg overflow-auto\"\n>\n <table\n class=\"w-full h-full\"\n [ngClass]=\"{\n 'table-fixed': tableLayout === 'fixed',\n 'table-auto': tableLayout === 'auto',\n }\"\n >\n <colgroup>\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <col class=\"{{ column.width || '' }}\" />\n }\n }\n </colgroup>\n @if (showHeader$ | async) {\n <thead class=\"bg-light-inactive/50 dark:bg-dark-inactive/50 rounded-tl-lg rounded-tr-lg\">\n <tr>\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <th\n scope=\"col\"\n class=\"{{\n column.align || ''\n }} py-3.5 pl-4 pr-3 text-sm font-semibold text-light-on-background dark:text-dark-on-background whitespace-nowrap\"\n >\n <span class=\"group inline-flex\">\n {{ column.label }}\n @if (column.sortable) {\n @switch (getSortDirection(column.sort?.field || column.key) | async) {\n @case ('desc') {\n <span\n (click)=\"onUpdateSort(column.sort?.field || column.key, 'asc')\"\n class=\"ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive\"\n >\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </span>\n }\n @case ('asc') {\n <span\n (click)=\"onUpdateSort(column.sort?.field || column.key, 'desc')\"\n class=\"ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive\"\n >\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M14.78 11.78a.75.75 0 0 1-1.06 0L10 8.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </span>\n }\n @default {\n <span\n (click)=\"onUpdateSort(column.sort?.field || column.key, 'asc')\"\n class=\"invisible ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive group-hover:visible group-focus:visible\"\n >\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M14.78 11.78a.75.75 0 0 1-1.06 0L10 8.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </span>\n }\n }\n }\n </span>\n </th>\n }\n }\n </tr>\n </thead>\n }\n <tbody class=\"overflow-scroll\">\n @for (row of rows | async; track row['id']; let lastRow = $last) {\n <tr\n class=\"border-t border-light-inactive dark:border-dark-inactive {{ row.bgColor || '' }}\"\n (click)=\"onRowClicked(row)\"\n (dblclick)=\"onRowDblClicked(row)\"\n [ngClass]=\"{\n 'rounded-b-lg': lastRow && (lastEvaluatedKey | async) === null,\n 'even:bg-light-alternative dark:even:bg-dark-alternative odd:bg-light-background dark:odd:bg-dark-background':\n !row.bgColor,\n }\"\n [ngStyle]=\"{ 'background-color': row.bgColor || '' }\"\n >\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <td\n class=\"relative overflow-visible {{\n column.align || ''\n }} whitespace-nowrap px-3 text-sm text-light-on-background dark:text-dark-on-background\"\n [ngClass]=\"{\n 'first:rounded-bl-lg last:rounded-br-lg':\n lastRow && (lastEvaluatedKey | async) === null,\n 'text-wrap': row.isExpanded && column.type !== 'custom',\n 'overflow-x-hidden text-ellipsis': !row.isExpanded && column.type !== 'custom',\n 'py-2': column.type === 'custom',\n 'py-4': column.type !== 'custom',\n }\"\n >\n @if (column.type === 'custom') {\n @if (column.customRenderTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"customTemplates[column.customRenderTemplate]\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n ></ng-container>\n }\n } @else {\n {{ getColumnValue(row, column) | async }}\n }\n </td>\n }\n }\n </tr>\n\n @if (row.isExpanded && expandedTemplate) {\n <tr>\n <td [attr.colspan]=\"columns.length\"></td>\n </tr>\n <tr\n class=\"even:bg-light-alternative dark:even:bg-dark-alternative odd:bg-light-background dark:odd:bg-dark-background\"\n >\n <td\n [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 pb-4 text-sm text-center\"\n >\n <ng-container\n [ngTemplateOutlet]=\"expandedTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row }\"\n ></ng-container>\n </td>\n </tr>\n }\n\n @if (lastRow && (lastEvaluatedKey | async) && !(isLoading | async) && useLoadMore) {\n <tr\n #loadMoreRow\n class=\"border-t border-light-inactive dark:border-dark-inactive bg-light-background dark:bg-dark-background\"\n haloduckAutoLoad\n [autoLoadEnabled]=\"(autoLoad$ | async) ?? true\"\n [autoLoadThreshold]=\"0.1\"\n (autoLoadTrigger)=\"onAutoLoadTriggered()\"\n >\n <td\n [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 py-4 text-sm text-light-on-background dark:text-dark-on-background text-center h-16 bg-light-background dark:bg-dark-background rounded-bl-lg rounded-br-lg\"\n >\n <div (click)=\"onLoadMoreClicked()\" class=\"cursor-pointer\">\n {{ 'haloduck.ui.table.Load More...' | transloco }}\n </div>\n </td>\n </tr>\n }\n } @empty {\n @if (!(isLoading | async)) {\n <tr>\n <td\n [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 py-4 text-sm text-light-on-background dark:text-dark-on-background text-center h-16 bg-light-background dark:bg-dark-background rounded-bl-lg rounded-br-lg\"\n >\n {{ 'haloduck.ui.table.No data available.' | transloco }}\n </td>\n </tr>\n }\n }\n\n @if (isLoading | async) {\n @for (i of [0, 1, 2, 3, 4]; track i; let lastRow = $last) {\n <tr\n class=\"bg-light-background dark:bg-dark-background border-t border-light-inactive/50 dark:border-dark-inactive/50\"\n >\n @for (column of columns; track column.key) {\n <td\n class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm\"\n [ngClass]=\"{ 'first:rounded-bl-lg last:rounded-br-lg': lastRow }\"\n >\n <div\n class=\"h-4 bg-light-inactive/50 dark:bg-dark-inactive/50 rounded-md animate-pulse\"\n ></div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "directive", type: AutoLoadDirective, selector: "[haloduckAutoLoad]", inputs: ["autoLoadEnabled", "autoLoadThreshold", "autoLoadRootMargin"], outputs: ["autoLoadTrigger"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3233
3532
|
}
|
|
3234
3533
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TableComponent, decorators: [{
|
|
3235
3534
|
type: Component,
|
|
3236
|
-
args: [{ selector: 'haloduck-table', imports: [CommonModule, TranslocoModule, AutoLoadDirective], providers: [provideTranslocoScope('haloduck')], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div
|
|
3535
|
+
args: [{ selector: 'haloduck-table', imports: [CommonModule, TranslocoModule, AutoLoadDirective], providers: [provideTranslocoScope('haloduck')], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"w-full h-full shadow border border-light-inactive dark:border-dark-inactive rounded-lg overflow-auto\"\n>\n <table\n class=\"w-full h-full\"\n [ngClass]=\"{\n 'table-fixed': tableLayout === 'fixed',\n 'table-auto': tableLayout === 'auto',\n }\"\n >\n <colgroup>\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <col class=\"{{ column.width || '' }}\" />\n }\n }\n </colgroup>\n @if (showHeader$ | async) {\n <thead class=\"bg-light-inactive/50 dark:bg-dark-inactive/50 rounded-tl-lg rounded-tr-lg\">\n <tr>\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <th\n scope=\"col\"\n class=\"{{\n column.align || ''\n }} py-3.5 pl-4 pr-3 text-sm font-semibold text-light-on-background dark:text-dark-on-background whitespace-nowrap\"\n >\n <span class=\"group inline-flex\">\n {{ column.label }}\n @if (column.sortable) {\n @switch (getSortDirection(column.sort?.field || column.key) | async) {\n @case ('desc') {\n <span\n (click)=\"onUpdateSort(column.sort?.field || column.key, 'asc')\"\n class=\"ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive\"\n >\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </span>\n }\n @case ('asc') {\n <span\n (click)=\"onUpdateSort(column.sort?.field || column.key, 'desc')\"\n class=\"ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive\"\n >\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M14.78 11.78a.75.75 0 0 1-1.06 0L10 8.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </span>\n }\n @default {\n <span\n (click)=\"onUpdateSort(column.sort?.field || column.key, 'asc')\"\n class=\"invisible ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive group-hover:visible group-focus:visible\"\n >\n <svg\n class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M14.78 11.78a.75.75 0 0 1-1.06 0L10 8.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </span>\n }\n }\n }\n </span>\n </th>\n }\n }\n </tr>\n </thead>\n }\n <tbody class=\"overflow-scroll\">\n @for (row of rows | async; track row['id']; let lastRow = $last) {\n <tr\n class=\"border-t border-light-inactive dark:border-dark-inactive {{ row.bgColor || '' }}\"\n (click)=\"onRowClicked(row)\"\n (dblclick)=\"onRowDblClicked(row)\"\n [ngClass]=\"{\n 'rounded-b-lg': lastRow && (lastEvaluatedKey | async) === null,\n 'even:bg-light-alternative dark:even:bg-dark-alternative odd:bg-light-background dark:odd:bg-dark-background':\n !row.bgColor,\n }\"\n [ngStyle]=\"{ 'background-color': row.bgColor || '' }\"\n >\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <td\n class=\"relative overflow-visible {{\n column.align || ''\n }} whitespace-nowrap px-3 text-sm text-light-on-background dark:text-dark-on-background\"\n [ngClass]=\"{\n 'first:rounded-bl-lg last:rounded-br-lg':\n lastRow && (lastEvaluatedKey | async) === null,\n 'text-wrap': row.isExpanded && column.type !== 'custom',\n 'overflow-x-hidden text-ellipsis': !row.isExpanded && column.type !== 'custom',\n 'py-2': column.type === 'custom',\n 'py-4': column.type !== 'custom',\n }\"\n >\n @if (column.type === 'custom') {\n @if (column.customRenderTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"customTemplates[column.customRenderTemplate]\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n ></ng-container>\n }\n } @else {\n {{ getColumnValue(row, column) | async }}\n }\n </td>\n }\n }\n </tr>\n\n @if (row.isExpanded && expandedTemplate) {\n <tr>\n <td [attr.colspan]=\"columns.length\"></td>\n </tr>\n <tr\n class=\"even:bg-light-alternative dark:even:bg-dark-alternative odd:bg-light-background dark:odd:bg-dark-background\"\n >\n <td\n [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 pb-4 text-sm text-center\"\n >\n <ng-container\n [ngTemplateOutlet]=\"expandedTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row }\"\n ></ng-container>\n </td>\n </tr>\n }\n\n @if (lastRow && (lastEvaluatedKey | async) && !(isLoading | async) && useLoadMore) {\n <tr\n #loadMoreRow\n class=\"border-t border-light-inactive dark:border-dark-inactive bg-light-background dark:bg-dark-background\"\n haloduckAutoLoad\n [autoLoadEnabled]=\"(autoLoad$ | async) ?? true\"\n [autoLoadThreshold]=\"0.1\"\n (autoLoadTrigger)=\"onAutoLoadTriggered()\"\n >\n <td\n [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 py-4 text-sm text-light-on-background dark:text-dark-on-background text-center h-16 bg-light-background dark:bg-dark-background rounded-bl-lg rounded-br-lg\"\n >\n <div (click)=\"onLoadMoreClicked()\" class=\"cursor-pointer\">\n {{ 'haloduck.ui.table.Load More...' | transloco }}\n </div>\n </td>\n </tr>\n }\n } @empty {\n @if (!(isLoading | async)) {\n <tr>\n <td\n [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 py-4 text-sm text-light-on-background dark:text-dark-on-background text-center h-16 bg-light-background dark:bg-dark-background rounded-bl-lg rounded-br-lg\"\n >\n {{ 'haloduck.ui.table.No data available.' | transloco }}\n </td>\n </tr>\n }\n }\n\n @if (isLoading | async) {\n @for (i of [0, 1, 2, 3, 4]; track i; let lastRow = $last) {\n <tr\n class=\"bg-light-background dark:bg-dark-background border-t border-light-inactive/50 dark:border-dark-inactive/50\"\n >\n @for (column of columns; track column.key) {\n <td\n class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm\"\n [ngClass]=\"{ 'first:rounded-bl-lg last:rounded-br-lg': lastRow }\"\n >\n <div\n class=\"h-4 bg-light-inactive/50 dark:bg-dark-inactive/50 rounded-md animate-pulse\"\n ></div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n" }]
|
|
3237
3536
|
}], propDecorators: { loadMoreRowRef: [{
|
|
3238
3537
|
type: ViewChild,
|
|
3239
3538
|
args: ['loadMoreRow', { read: ElementRef }]
|
|
@@ -3317,7 +3616,7 @@ class ToggleComponent {
|
|
|
3317
3616
|
useExisting: forwardRef(() => ToggleComponent),
|
|
3318
3617
|
multi: true,
|
|
3319
3618
|
},
|
|
3320
|
-
], viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }], ngImport: i0, template: "<div
|
|
3619
|
+
], viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }], ngImport: i0, template: "<div\n class=\"flex gap-2\"\n [ngClass]=\"{\n 'items-center justify-start': 'horizontal' === layout,\n 'flex-col items-start justify-center ': 'vertical' === layout,\n }\"\n>\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\"\n >\n <ng-content></ng-content>\n </label>\n <button\n class=\"w-12 p-1 rounded-l-full rounded-r-full outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive focus:outline-2 focus:outline-light-primary dark:foucs:outline-dark-primary bg-light-control dark:bg-dark-control disabled:bg-light-control/60 dark:disabled:bg-dark-control/60 flex hover:cursor-pointer\"\n (click)=\"onToggle()\"\n [disabled]=\"disabled\"\n [ngClass]=\"{\n 'justify-end': true === value,\n 'justify-center': null === value,\n 'justify-start': false === value,\n }\"\n >\n <div\n class=\"shrink-0 h-[1.5rem] rounded-l-full rounded-r-full\"\n [ngClass]=\"{\n 'bg-light-primary dark:bg-dark-primary disabled:bg-light-primary/60 dark:disabled:bg-dark-primary/60':\n true === value,\n 'bg-light-inactive dark:bg-dark-inactive disabled:bg-light-inactive/60 dark:disabled:bg-dark-inactive/60':\n false === value,\n 'w-[1.5rem]': true === value || false === value,\n 'bg-light-primary-light dark:bg-dark-primary-light disabled:bg-light-primary-light/60 dark:disabled:bg-dark-primary-light/60 w-[2.4rem]':\n null === value,\n }\"\n ></div>\n </button>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
3321
3620
|
}
|
|
3322
3621
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ToggleComponent, decorators: [{
|
|
3323
3622
|
type: Component,
|
|
@@ -3327,7 +3626,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
3327
3626
|
useExisting: forwardRef(() => ToggleComponent),
|
|
3328
3627
|
multi: true,
|
|
3329
3628
|
},
|
|
3330
|
-
], template: "<div
|
|
3629
|
+
], template: "<div\n class=\"flex gap-2\"\n [ngClass]=\"{\n 'items-center justify-start': 'horizontal' === layout,\n 'flex-col items-start justify-center ': 'vertical' === layout,\n }\"\n>\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\"\n >\n <ng-content></ng-content>\n </label>\n <button\n class=\"w-12 p-1 rounded-l-full rounded-r-full outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive focus:outline-2 focus:outline-light-primary dark:foucs:outline-dark-primary bg-light-control dark:bg-dark-control disabled:bg-light-control/60 dark:disabled:bg-dark-control/60 flex hover:cursor-pointer\"\n (click)=\"onToggle()\"\n [disabled]=\"disabled\"\n [ngClass]=\"{\n 'justify-end': true === value,\n 'justify-center': null === value,\n 'justify-start': false === value,\n }\"\n >\n <div\n class=\"shrink-0 h-[1.5rem] rounded-l-full rounded-r-full\"\n [ngClass]=\"{\n 'bg-light-primary dark:bg-dark-primary disabled:bg-light-primary/60 dark:disabled:bg-dark-primary/60':\n true === value,\n 'bg-light-inactive dark:bg-dark-inactive disabled:bg-light-inactive/60 dark:disabled:bg-dark-inactive/60':\n false === value,\n 'w-[1.5rem]': true === value || false === value,\n 'bg-light-primary-light dark:bg-dark-primary-light disabled:bg-light-primary-light/60 dark:disabled:bg-dark-primary-light/60 w-[2.4rem]':\n null === value,\n }\"\n ></div>\n </button>\n</div>\n" }]
|
|
3331
3630
|
}], propDecorators: { layout: [{
|
|
3332
3631
|
type: Input
|
|
3333
3632
|
}], value: [{
|
|
@@ -3369,9 +3668,7 @@ class TableSettingComponent {
|
|
|
3369
3668
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TableSettingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3370
3669
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: TableSettingComponent, isStandalone: true, selector: "haloduck-table-setting", inputs: { context: "context" }, providers: [provideTranslocoScope('haloduck')], ngImport: i0, template: `
|
|
3371
3670
|
<div class="flex justify-between items-center mb-4">
|
|
3372
|
-
<h2
|
|
3373
|
-
class="text-md font-semibold text-light-on-background dark:text-dark-on-background"
|
|
3374
|
-
>
|
|
3671
|
+
<h2 class="text-md font-semibold text-light-on-background dark:text-dark-on-background">
|
|
3375
3672
|
{{ 'haloduck.ui.table.settings' | transloco }}
|
|
3376
3673
|
</h2>
|
|
3377
3674
|
</div>
|
|
@@ -3405,18 +3702,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
3405
3702
|
type: Component,
|
|
3406
3703
|
args: [{
|
|
3407
3704
|
selector: 'haloduck-table-setting',
|
|
3408
|
-
imports: [
|
|
3409
|
-
CommonModule,
|
|
3410
|
-
TranslocoModule,
|
|
3411
|
-
FormsModule,
|
|
3412
|
-
ButtonComponent,
|
|
3413
|
-
ToggleComponent,
|
|
3414
|
-
],
|
|
3705
|
+
imports: [CommonModule, TranslocoModule, FormsModule, ButtonComponent, ToggleComponent],
|
|
3415
3706
|
template: `
|
|
3416
3707
|
<div class="flex justify-between items-center mb-4">
|
|
3417
|
-
<h2
|
|
3418
|
-
class="text-md font-semibold text-light-on-background dark:text-dark-on-background"
|
|
3419
|
-
>
|
|
3708
|
+
<h2 class="text-md font-semibold text-light-on-background dark:text-dark-on-background">
|
|
3420
3709
|
{{ 'haloduck.ui.table.settings' | transloco }}
|
|
3421
3710
|
</h2>
|
|
3422
3711
|
</div>
|
|
@@ -3504,11 +3793,11 @@ class TabsComponent {
|
|
|
3504
3793
|
this.selectedIndex = this.tabs.length - 1;
|
|
3505
3794
|
}
|
|
3506
3795
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3507
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: TabsComponent, isStandalone: true, selector: "haloduck-tabs", inputs: { tabs: "tabs", selectedIndex: "selectedIndex", layout: "layout", labelWidth: "labelWidth" }, outputs: { selectedIndexChange: "selectedIndexChange" }, viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"flex gap-2 items-start w-full\"
|
|
3796
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: TabsComponent, isStandalone: true, selector: "haloduck-tabs", inputs: { tabs: "tabs", selectedIndex: "selectedIndex", layout: "layout", labelWidth: "labelWidth" }, outputs: { selectedIndexChange: "selectedIndexChange" }, viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"flex gap-2 items-start w-full\" [ngClass]=\"{ 'flex-col': layout === 'vertical' }\">\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control {{\n labelWidth\n }}\"\n [ngClass]=\"{ 'w-full': layout === 'vertical' }\"\n >\n <ng-content select=\"[slot=label]\"></ng-content>\n </label>\n\n <div class=\"flex-1 w-full\">\n <div\n class=\"flex items-center gap-1 border-b border-light-inactive dark:border-dark-inactive text-sm/6\"\n >\n @for (tab of tabs; track tab.label; let i = $index) {\n <button\n type=\"button\"\n class=\"px-3 py-2 rounded-t-md\"\n [ngClass]=\"{\n 'text-light-on-control dark:text-dark-on-control': i !== selectedIndex,\n 'text-light-primary dark:text-dark-primary border-b-2 border-light-primary dark:border-dark-primary':\n i === selectedIndex,\n }\"\n (click)=\"select(i)\"\n >\n {{ tab.label }}\n </button>\n }\n </div>\n\n <div class=\"mt-3\">\n @if (current) {\n <ng-container\n *ngComponentOutlet=\"current!.component; inputs: current!.inputs || {}\"\n ></ng-container>\n }\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] });
|
|
3508
3797
|
}
|
|
3509
3798
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TabsComponent, decorators: [{
|
|
3510
3799
|
type: Component,
|
|
3511
|
-
args: [{ selector: 'haloduck-tabs', imports: [CommonModule], template: "<div class=\"flex gap-2 items-start w-full\"
|
|
3800
|
+
args: [{ selector: 'haloduck-tabs', imports: [CommonModule], template: "<div class=\"flex gap-2 items-start w-full\" [ngClass]=\"{ 'flex-col': layout === 'vertical' }\">\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control {{\n labelWidth\n }}\"\n [ngClass]=\"{ 'w-full': layout === 'vertical' }\"\n >\n <ng-content select=\"[slot=label]\"></ng-content>\n </label>\n\n <div class=\"flex-1 w-full\">\n <div\n class=\"flex items-center gap-1 border-b border-light-inactive dark:border-dark-inactive text-sm/6\"\n >\n @for (tab of tabs; track tab.label; let i = $index) {\n <button\n type=\"button\"\n class=\"px-3 py-2 rounded-t-md\"\n [ngClass]=\"{\n 'text-light-on-control dark:text-dark-on-control': i !== selectedIndex,\n 'text-light-primary dark:text-dark-primary border-b-2 border-light-primary dark:border-dark-primary':\n i === selectedIndex,\n }\"\n (click)=\"select(i)\"\n >\n {{ tab.label }}\n </button>\n }\n </div>\n\n <div class=\"mt-3\">\n @if (current) {\n <ng-container\n *ngComponentOutlet=\"current!.component; inputs: current!.inputs || {}\"\n ></ng-container>\n }\n </div>\n </div>\n</div>\n" }]
|
|
3512
3801
|
}], propDecorators: { tabs: [{
|
|
3513
3802
|
type: Input
|
|
3514
3803
|
}], selectedIndex: [{
|
|
@@ -3533,9 +3822,7 @@ class TagInputComponent {
|
|
|
3533
3822
|
// Two-way binding support independent of CVA
|
|
3534
3823
|
set value(tags) {
|
|
3535
3824
|
if (Array.isArray(tags)) {
|
|
3536
|
-
this.tags = tags
|
|
3537
|
-
.map((t) => (t ?? '').trim())
|
|
3538
|
-
.filter((t) => t.length > 0);
|
|
3825
|
+
this.tags = tags.map((t) => (t ?? '').trim()).filter((t) => t.length > 0);
|
|
3539
3826
|
}
|
|
3540
3827
|
else {
|
|
3541
3828
|
this.tags = [];
|
|
@@ -3548,9 +3835,7 @@ class TagInputComponent {
|
|
|
3548
3835
|
onTouched = () => { };
|
|
3549
3836
|
writeValue(value) {
|
|
3550
3837
|
if (Array.isArray(value)) {
|
|
3551
|
-
this.tags = value
|
|
3552
|
-
.map((t) => (t ?? '').trim())
|
|
3553
|
-
.filter((t) => t.length > 0);
|
|
3838
|
+
this.tags = value.map((t) => (t ?? '').trim()).filter((t) => t.length > 0);
|
|
3554
3839
|
}
|
|
3555
3840
|
else {
|
|
3556
3841
|
this.tags = [];
|
|
@@ -3624,7 +3909,10 @@ class TagInputComponent {
|
|
|
3624
3909
|
return;
|
|
3625
3910
|
}
|
|
3626
3911
|
// If user pasted multiple comma-separated values, split and add all
|
|
3627
|
-
const parts = raw
|
|
3912
|
+
const parts = raw
|
|
3913
|
+
.split(',')
|
|
3914
|
+
.map((p) => p.trim())
|
|
3915
|
+
.filter((p) => p.length > 0);
|
|
3628
3916
|
for (const part of parts) {
|
|
3629
3917
|
this.addTag(part);
|
|
3630
3918
|
}
|
|
@@ -3641,9 +3929,7 @@ class TagInputComponent {
|
|
|
3641
3929
|
this.emitChanges();
|
|
3642
3930
|
}
|
|
3643
3931
|
emitChanges() {
|
|
3644
|
-
const cleaned = this.tags
|
|
3645
|
-
.map((t) => (t ?? '').trim())
|
|
3646
|
-
.filter((t) => t.length > 0);
|
|
3932
|
+
const cleaned = this.tags.map((t) => (t ?? '').trim()).filter((t) => t.length > 0);
|
|
3647
3933
|
if (cleaned.length !== this.tags.length || cleaned.some((t, i) => t !== this.tags[i])) {
|
|
3648
3934
|
this.tags = cleaned;
|
|
3649
3935
|
}
|
|
@@ -3658,7 +3944,7 @@ class TagInputComponent {
|
|
|
3658
3944
|
multi: true,
|
|
3659
3945
|
},
|
|
3660
3946
|
provideTranslocoScope('haloduck'),
|
|
3661
|
-
], viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }, { propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\n <label
|
|
3947
|
+
], viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }, { propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\"\n >\n <ng-content></ng-content>\n </label>\n\n <div\n class=\"tag-input-wrapper block w-full rounded-md bg-light-control dark:bg-dark-control disabled:bg-light-control/60 dark:disabled:bg-dark-control/80 px-2 py-1.5 text-base text-light-on-control dark:text-dark-on-control disabled:cursor-not-allowed disabled:text-light-on-control/60 dark:disabled:text-dark-on-control/80 outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive sm:text-sm/6\"\n >\n <div class=\"flex flex-wrap items-center gap-2\">\n @for (tag of tags; track tag; let i = $index) {\n <span\n class=\"inline-flex items-center gap-1 rounded-md bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary px-2 py-0.5 text-xs\"\n >\n {{ tag }}\n @if (!disabled) {\n <button\n type=\"button\"\n (click)=\"removeTag(i)\"\n class=\"text-light-on-secondary/80 hover:text-light-on-secondary dark:text-dark-on-secondary/80 dark:hover:text-dark-on-secondary hover:cursor-pointer\"\n >\n \u00D7\n </button>\n }\n </span>\n }\n\n <input\n #inputEl\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n class=\"flex-1 min-w-[8rem] bg-transparent outline-none placeholder:text-light-inactive dark:placeholder:text-dark-inactive\"\n [value]=\"inputValue\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n </div>\n </div>\n</div>\n", styles: [":host{display:block}.tag-input-wrapper:focus-within{outline-width:2px;outline-offset:2px;outline-color:var(--color-light-primary)!important}@media (prefers-color-scheme: dark){.tag-input-wrapper:focus-within{outline-color:var(--color-dark-primary)!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
3662
3948
|
}
|
|
3663
3949
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TagInputComponent, decorators: [{
|
|
3664
3950
|
type: Component,
|
|
@@ -3669,7 +3955,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
3669
3955
|
multi: true,
|
|
3670
3956
|
},
|
|
3671
3957
|
provideTranslocoScope('haloduck'),
|
|
3672
|
-
], template: "<div class=\"flex flex-col gap-2\">\n <label
|
|
3958
|
+
], template: "<div class=\"flex flex-col gap-2\">\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\"\n >\n <ng-content></ng-content>\n </label>\n\n <div\n class=\"tag-input-wrapper block w-full rounded-md bg-light-control dark:bg-dark-control disabled:bg-light-control/60 dark:disabled:bg-dark-control/80 px-2 py-1.5 text-base text-light-on-control dark:text-dark-on-control disabled:cursor-not-allowed disabled:text-light-on-control/60 dark:disabled:text-dark-on-control/80 outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive sm:text-sm/6\"\n >\n <div class=\"flex flex-wrap items-center gap-2\">\n @for (tag of tags; track tag; let i = $index) {\n <span\n class=\"inline-flex items-center gap-1 rounded-md bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary px-2 py-0.5 text-xs\"\n >\n {{ tag }}\n @if (!disabled) {\n <button\n type=\"button\"\n (click)=\"removeTag(i)\"\n class=\"text-light-on-secondary/80 hover:text-light-on-secondary dark:text-dark-on-secondary/80 dark:hover:text-dark-on-secondary hover:cursor-pointer\"\n >\n \u00D7\n </button>\n }\n </span>\n }\n\n <input\n #inputEl\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n class=\"flex-1 min-w-[8rem] bg-transparent outline-none placeholder:text-light-inactive dark:placeholder:text-dark-inactive\"\n [value]=\"inputValue\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n </div>\n </div>\n</div>\n", styles: [":host{display:block}.tag-input-wrapper:focus-within{outline-width:2px;outline-offset:2px;outline-color:var(--color-light-primary)!important}@media (prefers-color-scheme: dark){.tag-input-wrapper:focus-within{outline-color:var(--color-dark-primary)!important}}\n"] }]
|
|
3673
3959
|
}], propDecorators: { label: [{
|
|
3674
3960
|
type: ViewChild,
|
|
3675
3961
|
args: ['label']
|
|
@@ -3695,9 +3981,7 @@ class TagViewerComponent {
|
|
|
3695
3981
|
// Accept input as `value` for consistency with tag-input
|
|
3696
3982
|
set value(tags) {
|
|
3697
3983
|
if (Array.isArray(tags)) {
|
|
3698
|
-
this.tags = tags
|
|
3699
|
-
.map((t) => (t ?? '').trim())
|
|
3700
|
-
.filter((t) => t.length > 0);
|
|
3984
|
+
this.tags = tags.map((t) => (t ?? '').trim()).filter((t) => t.length > 0);
|
|
3701
3985
|
}
|
|
3702
3986
|
else {
|
|
3703
3987
|
this.tags = [];
|
|
@@ -3713,11 +3997,11 @@ class TagViewerComponent {
|
|
|
3713
3997
|
}
|
|
3714
3998
|
}
|
|
3715
3999
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TagViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3716
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: TagViewerComponent, isStandalone: true, selector: "haloduck-tag-viewer", inputs: { shouldWrap: "shouldWrap", value: "value" }, providers: [provideTranslocoScope('haloduck')], viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\n <label
|
|
4000
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: TagViewerComponent, isStandalone: true, selector: "haloduck-tag-viewer", inputs: { shouldWrap: "shouldWrap", value: "value" }, providers: [provideTranslocoScope('haloduck')], viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\"\n >\n <ng-content></ng-content>\n </label>\n\n <div\n class=\"block w-full rounded-md px-2 py-1.5 text-base text-light-on-control dark:text-dark-on-control sm:text-sm/6\"\n >\n <div class=\"flex items-center gap-2\" [ngClass]=\"shouldWrap ? 'flex-wrap' : 'flex-nowrap'\">\n @for (tag of tags; track tag) {\n <span\n class=\"inline-flex items-center gap-1 rounded-md bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary px-2 py-0.5 text-xs\"\n >\n {{ tag }}\n </span>\n }\n </div>\n </div>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
3717
4001
|
}
|
|
3718
4002
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TagViewerComponent, decorators: [{
|
|
3719
4003
|
type: Component,
|
|
3720
|
-
args: [{ selector: 'haloduck-tag-viewer', imports: [CommonModule], providers: [provideTranslocoScope('haloduck')], template: "<div class=\"flex flex-col gap-2\">\n <label
|
|
4004
|
+
args: [{ selector: 'haloduck-tag-viewer', imports: [CommonModule], providers: [provideTranslocoScope('haloduck')], template: "<div class=\"flex flex-col gap-2\">\n <label\n #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\"\n >\n <ng-content></ng-content>\n </label>\n\n <div\n class=\"block w-full rounded-md px-2 py-1.5 text-base text-light-on-control dark:text-dark-on-control sm:text-sm/6\"\n >\n <div class=\"flex items-center gap-2\" [ngClass]=\"shouldWrap ? 'flex-wrap' : 'flex-nowrap'\">\n @for (tag of tags; track tag) {\n <span\n class=\"inline-flex items-center gap-1 rounded-md bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary px-2 py-0.5 text-xs\"\n >\n {{ tag }}\n </span>\n }\n </div>\n </div>\n</div>\n", styles: [":host{display:block}\n"] }]
|
|
3721
4005
|
}], propDecorators: { label: [{
|
|
3722
4006
|
type: ViewChild,
|
|
3723
4007
|
args: ['label']
|
|
@@ -3803,8 +4087,8 @@ class GroupedDirective {
|
|
|
3803
4087
|
if (!classString)
|
|
3804
4088
|
return;
|
|
3805
4089
|
// 공백으로 구분된 클래스들을 분리하여 각각 추가
|
|
3806
|
-
const classes = classString.split(' ').filter(className => className.trim());
|
|
3807
|
-
classes.forEach(className => {
|
|
4090
|
+
const classes = classString.split(' ').filter((className) => className.trim());
|
|
4091
|
+
classes.forEach((className) => {
|
|
3808
4092
|
if (className.trim()) {
|
|
3809
4093
|
this.renderer.addClass(element, className.trim());
|
|
3810
4094
|
}
|
|
@@ -3813,15 +4097,49 @@ class GroupedDirective {
|
|
|
3813
4097
|
removeBorderClasses(element) {
|
|
3814
4098
|
// 기본 테두리 클래스들 제거
|
|
3815
4099
|
const defaultBorderClasses = [
|
|
3816
|
-
'border',
|
|
3817
|
-
'border-
|
|
3818
|
-
'
|
|
3819
|
-
'border-
|
|
3820
|
-
'border-
|
|
3821
|
-
'border-
|
|
3822
|
-
'border-
|
|
4100
|
+
'border',
|
|
4101
|
+
'border-2',
|
|
4102
|
+
'border-3',
|
|
4103
|
+
'border-4',
|
|
4104
|
+
'border-8',
|
|
4105
|
+
'border-solid',
|
|
4106
|
+
'border-dashed',
|
|
4107
|
+
'border-dotted',
|
|
4108
|
+
'border-double',
|
|
4109
|
+
'border-none',
|
|
4110
|
+
'rounded-none',
|
|
4111
|
+
'rounded-sm',
|
|
4112
|
+
'rounded',
|
|
4113
|
+
'rounded-md',
|
|
4114
|
+
'rounded-lg',
|
|
4115
|
+
'rounded-xl',
|
|
4116
|
+
'rounded-2xl',
|
|
4117
|
+
'rounded-3xl',
|
|
4118
|
+
'rounded-full',
|
|
4119
|
+
'border-gray-200',
|
|
4120
|
+
'border-gray-300',
|
|
4121
|
+
'border-gray-400',
|
|
4122
|
+
'border-gray-500',
|
|
4123
|
+
'border-gray-600',
|
|
4124
|
+
'border-gray-700',
|
|
4125
|
+
'border-gray-800',
|
|
4126
|
+
'border-gray-900',
|
|
4127
|
+
'border-blue-500',
|
|
4128
|
+
'border-blue-700',
|
|
4129
|
+
'border-red-500',
|
|
4130
|
+
'border-red-600',
|
|
4131
|
+
'border-green-500',
|
|
4132
|
+
'border-green-600',
|
|
4133
|
+
'border-amber-500',
|
|
4134
|
+
'border-amber-600',
|
|
4135
|
+
'border-violet-500',
|
|
4136
|
+
'border-violet-600',
|
|
4137
|
+
'border-pink-500',
|
|
4138
|
+
'border-pink-600',
|
|
4139
|
+
'border-white',
|
|
4140
|
+
'border-black',
|
|
3823
4141
|
];
|
|
3824
|
-
defaultBorderClasses.forEach(className => {
|
|
4142
|
+
defaultBorderClasses.forEach((className) => {
|
|
3825
4143
|
this.renderer.removeClass(element, className);
|
|
3826
4144
|
});
|
|
3827
4145
|
}
|
|
@@ -3849,7 +4167,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
3849
4167
|
type: Directive,
|
|
3850
4168
|
args: [{
|
|
3851
4169
|
selector: '[haloduckGrouped]',
|
|
3852
|
-
standalone: true
|
|
4170
|
+
standalone: true,
|
|
3853
4171
|
}]
|
|
3854
4172
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { haloduckGrouped: [{
|
|
3855
4173
|
type: Input
|
|
@@ -3878,18 +4196,14 @@ class BreadcrumbService {
|
|
|
3878
4196
|
titleService = inject(Title);
|
|
3879
4197
|
constructor(router) {
|
|
3880
4198
|
this.router = router;
|
|
3881
|
-
this.router.events
|
|
3882
|
-
.pipe(filter((event) => event instanceof NavigationEnd))
|
|
3883
|
-
.subscribe(() => {
|
|
4199
|
+
this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe(() => {
|
|
3884
4200
|
const root = this.router.routerState.snapshot.root;
|
|
3885
4201
|
const breadcrumbs = this.createBreadcrumbs(root);
|
|
3886
4202
|
this.breadcrumbs.next(breadcrumbs);
|
|
3887
4203
|
setTimeout(() => {
|
|
3888
4204
|
const titlePrefix = this.coreService.getStage() === 'prod'
|
|
3889
4205
|
? ''
|
|
3890
|
-
: `[${this.coreService.getStage()}] ` +
|
|
3891
|
-
this.coreService.getAppName() +
|
|
3892
|
-
'::';
|
|
4206
|
+
: `[${this.coreService.getStage()}] ` + this.coreService.getAppName() + '::';
|
|
3893
4207
|
const title = titlePrefix +
|
|
3894
4208
|
breadcrumbs.reduce((acc, breadcrumb) => {
|
|
3895
4209
|
return acc ? `${acc}>${breadcrumb.label}` : breadcrumb.label;
|
|
@@ -3904,9 +4218,7 @@ class BreadcrumbService {
|
|
|
3904
4218
|
return breadcrumbs;
|
|
3905
4219
|
}
|
|
3906
4220
|
for (const child of children) {
|
|
3907
|
-
const routeURL = child.url
|
|
3908
|
-
.map((segment) => segment.path)
|
|
3909
|
-
.join('/');
|
|
4221
|
+
const routeURL = child.url.map((segment) => segment.path).join('/');
|
|
3910
4222
|
if (routeURL !== '') {
|
|
3911
4223
|
url += `/${routeURL}`;
|
|
3912
4224
|
}
|
|
@@ -3934,11 +4246,11 @@ class BreadcrumbComponent {
|
|
|
3934
4246
|
});
|
|
3935
4247
|
}
|
|
3936
4248
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: BreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3937
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: BreadcrumbComponent, isStandalone: true, selector: "haloduck-breadcrumb", ngImport: i0, template: "<nav
|
|
4249
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: BreadcrumbComponent, isStandalone: true, selector: "haloduck-breadcrumb", ngImport: i0, template: "<nav\n class=\"flex border-b border-light-inactive dark:border-dark-inactive bg-light-background dark:bg-dark-background\"\n aria-label=\"Breadcrumb\"\n>\n <ol role=\"list\" class=\"flex w-full max-w-(--breakpoint-xl) space-x-4 px-4 sm:px-6 lg:px-8\">\n <li class=\"flex\">\n <div class=\"flex items-center\">\n <a\n routerLink=\"/\"\n class=\"text-light-on-background dark:text-dark-on-background hover:scale-105\"\n >\n <svg\n class=\"size-5 shrink-0\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M9.293 2.293a1 1 0 0 1 1.414 0l7 7A1 1 0 0 1 17 11h-1v6a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v3a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-6H3a1 1 0 0 1-.707-1.707l7-7Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n <span class=\"sr-only\">Home</span>\n </a>\n </div>\n </li>\n @for (breadcrumb of listBreadcrumb; track breadcrumb.label; let last = $last) {\n <li class=\"flex\">\n <div class=\"flex items-center\">\n <svg\n class=\"h-full w-6 shrink-0 text-light-inactive dark:text-dark-inactive\"\n viewBox=\"0 0 24 44\"\n preserveAspectRatio=\"none\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\" />\n </svg>\n @if (!last) {\n <a\n href=\"javascript:void(0)\"\n [routerLink]=\"breadcrumb.url\"\n class=\"ml-4 text-sm font-medium hover:font-bold text-light-on-background dark:text-dark-on-background\"\n >{{ breadcrumb.label | transloco }}</a\n >\n } @else {\n <span\n class=\"ml-4 text-sm font-medium text-light-on-background dark:text-dark-on-background\"\n >{{ breadcrumb.label | transloco }}</span\n >\n }\n </div>\n </li>\n }\n </ol>\n</nav>\n", styles: [""], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }] });
|
|
3938
4250
|
}
|
|
3939
4251
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: BreadcrumbComponent, decorators: [{
|
|
3940
4252
|
type: Component,
|
|
3941
|
-
args: [{ selector: 'haloduck-breadcrumb', imports: [RouterLink, TranslocoModule], template: "<nav
|
|
4253
|
+
args: [{ selector: 'haloduck-breadcrumb', imports: [RouterLink, TranslocoModule], template: "<nav\n class=\"flex border-b border-light-inactive dark:border-dark-inactive bg-light-background dark:bg-dark-background\"\n aria-label=\"Breadcrumb\"\n>\n <ol role=\"list\" class=\"flex w-full max-w-(--breakpoint-xl) space-x-4 px-4 sm:px-6 lg:px-8\">\n <li class=\"flex\">\n <div class=\"flex items-center\">\n <a\n routerLink=\"/\"\n class=\"text-light-on-background dark:text-dark-on-background hover:scale-105\"\n >\n <svg\n class=\"size-5 shrink-0\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M9.293 2.293a1 1 0 0 1 1.414 0l7 7A1 1 0 0 1 17 11h-1v6a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v3a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-6H3a1 1 0 0 1-.707-1.707l7-7Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n <span class=\"sr-only\">Home</span>\n </a>\n </div>\n </li>\n @for (breadcrumb of listBreadcrumb; track breadcrumb.label; let last = $last) {\n <li class=\"flex\">\n <div class=\"flex items-center\">\n <svg\n class=\"h-full w-6 shrink-0 text-light-inactive dark:text-dark-inactive\"\n viewBox=\"0 0 24 44\"\n preserveAspectRatio=\"none\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\" />\n </svg>\n @if (!last) {\n <a\n href=\"javascript:void(0)\"\n [routerLink]=\"breadcrumb.url\"\n class=\"ml-4 text-sm font-medium hover:font-bold text-light-on-background dark:text-dark-on-background\"\n >{{ breadcrumb.label | transloco }}</a\n >\n } @else {\n <span\n class=\"ml-4 text-sm font-medium text-light-on-background dark:text-dark-on-background\"\n >{{ breadcrumb.label | transloco }}</span\n >\n }\n </div>\n </li>\n }\n </ol>\n</nav>\n" }]
|
|
3942
4254
|
}] });
|
|
3943
4255
|
|
|
3944
4256
|
class NotificationComponent {
|
|
@@ -3948,11 +4260,11 @@ class NotificationComponent {
|
|
|
3948
4260
|
this.notificationService.removeNotificationById(id);
|
|
3949
4261
|
}
|
|
3950
4262
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: NotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3951
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: NotificationComponent, isStandalone: true, selector: "haloduck-notification", ngImport: i0, template: "@for (notification of listNotification$ |async; track notification.id) {\n<div
|
|
4263
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: NotificationComponent, isStandalone: true, selector: "haloduck-notification", ngImport: i0, template: "@for (notification of listNotification$ | async; track notification.id) {\n <div\n class=\"relative rounded-lg m-4 px-8 py-4 bg-light-primary dark:bg-dark-primary text-light-on-primary dark:text-dark-on-primary animate-fadeIn\"\n [ngClass]=\"{\n 'bg-light-primary-dark dark:bg-dark-primary-dark text-light-on-primary-dark dark:text-dark-on-primary-dark':\n notification.type === 'info',\n 'bg-light-primary dark:bg-dark-primary text-light-on-primary dark:text-dark-on-primary':\n notification.type === 'success',\n 'bg-light-danger dark:bg-dark-danger text-light-on-danger dark:text-dark-on-danger':\n notification.type === 'error',\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary':\n notification.type === 'warning',\n }\"\n >\n {{ notification.message }}\n <div class=\"absolute top-0 right-0\">\n <button type=\"button\" (click)=\"removeNotification(notification.id)\">\n <span class=\"sr-only\">Close</span>\n <svg\n class=\"size-6 text-white\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n </div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
|
|
3952
4264
|
}
|
|
3953
4265
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: NotificationComponent, decorators: [{
|
|
3954
4266
|
type: Component,
|
|
3955
|
-
args: [{ selector: 'haloduck-notification', standalone: true, imports: [CommonModule], template: "@for (notification of listNotification$ |async; track notification.id) {\n<div
|
|
4267
|
+
args: [{ selector: 'haloduck-notification', standalone: true, imports: [CommonModule], template: "@for (notification of listNotification$ | async; track notification.id) {\n <div\n class=\"relative rounded-lg m-4 px-8 py-4 bg-light-primary dark:bg-dark-primary text-light-on-primary dark:text-dark-on-primary animate-fadeIn\"\n [ngClass]=\"{\n 'bg-light-primary-dark dark:bg-dark-primary-dark text-light-on-primary-dark dark:text-dark-on-primary-dark':\n notification.type === 'info',\n 'bg-light-primary dark:bg-dark-primary text-light-on-primary dark:text-dark-on-primary':\n notification.type === 'success',\n 'bg-light-danger dark:bg-dark-danger text-light-on-danger dark:text-dark-on-danger':\n notification.type === 'error',\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary':\n notification.type === 'warning',\n }\"\n >\n {{ notification.message }}\n <div class=\"absolute top-0 right-0\">\n <button type=\"button\" (click)=\"removeNotification(notification.id)\">\n <span class=\"sr-only\">Close</span>\n <svg\n class=\"size-6 text-white\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n </div>\n}\n" }]
|
|
3956
4268
|
}] });
|
|
3957
4269
|
|
|
3958
4270
|
class PictureNameComponent {
|
|
@@ -3960,11 +4272,11 @@ class PictureNameComponent {
|
|
|
3960
4272
|
pictureKey;
|
|
3961
4273
|
cdnUrl = '';
|
|
3962
4274
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PictureNameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3963
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: PictureNameComponent, isStandalone: true, selector: "haloduck-picture-name", inputs: { name: "name", pictureKey: "pictureKey", cdnUrl: "cdnUrl" }, ngImport: i0, template: "<div class=\"flex items-center justify-start gap-2\">\n
|
|
4275
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: PictureNameComponent, isStandalone: true, selector: "haloduck-picture-name", inputs: { name: "name", pictureKey: "pictureKey", cdnUrl: "cdnUrl" }, ngImport: i0, template: "<div class=\"flex items-center justify-start gap-2\">\n @if (pictureKey) {\n <img src=\"{{ cdnUrl }}/{{ pictureKey }}\" alt=\"\uC0AC\uC9C4\" class=\"w-8 h-8 rounded-full\" />\n } @else {\n <div class=\"w-8 h-8 bg-light-inactive dark:bg-dark-inactive rounded-full\"></div>\n }\n {{ name }}\n @if (name) {\n \n <!-- TODO -->\n }\n</div>\n", styles: [""] });
|
|
3964
4276
|
}
|
|
3965
4277
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PictureNameComponent, decorators: [{
|
|
3966
4278
|
type: Component,
|
|
3967
|
-
args: [{ selector: 'haloduck-picture-name', imports: [], template: "<div class=\"flex items-center justify-start gap-2\">\n
|
|
4279
|
+
args: [{ selector: 'haloduck-picture-name', imports: [], template: "<div class=\"flex items-center justify-start gap-2\">\n @if (pictureKey) {\n <img src=\"{{ cdnUrl }}/{{ pictureKey }}\" alt=\"\uC0AC\uC9C4\" class=\"w-8 h-8 rounded-full\" />\n } @else {\n <div class=\"w-8 h-8 bg-light-inactive dark:bg-dark-inactive rounded-full\"></div>\n }\n {{ name }}\n @if (name) {\n \n <!-- TODO -->\n }\n</div>\n" }]
|
|
3968
4280
|
}], propDecorators: { name: [{
|
|
3969
4281
|
type: Input
|
|
3970
4282
|
}], pictureKey: [{
|