@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.
@@ -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 type=\"button\"\n [disabled]=\"disabled\"\n [ngClass]=\"{\n 'bg-light-primary text-light-on-primary dark:bg-dark-primary dark:text-dark-on-primary': variant === 'primary' && !disabled,\n 'bg-light-primary-light text-light-on-primary-light dark:bg-dark-primary-light dark:text-dark-on-primary-light': variant === 'secondary' && !disabled,\n 'bg-light-danger text-light-on-danger dark:bg-dark-danger dark:text-dark-on-danger': 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' : 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': 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 <ng-content></ng-content>\n</button>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
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 type=\"button\"\n [disabled]=\"disabled\"\n [ngClass]=\"{\n 'bg-light-primary text-light-on-primary dark:bg-dark-primary dark:text-dark-on-primary': variant === 'primary' && !disabled,\n 'bg-light-primary-light text-light-on-primary-light dark:bg-dark-primary-light dark:text-dark-on-primary-light': variant === 'secondary' && !disabled,\n 'bg-light-danger text-light-on-danger dark:bg-dark-danger dark:text-dark-on-danger': 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' : 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': 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 <ng-content></ng-content>\n</button>\n" }]
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 #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\">\n <ng-content></ng-content>\n </label>\n @if (rows > 1) {\n <textarea #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\"></textarea>\n }\n @else {\n <input #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</div>\n", styles: [""] });
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 #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\">\n <ng-content></ng-content>\n </label>\n @if (rows > 1) {\n <textarea #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\"></textarea>\n }\n @else {\n <input #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</div>\n" }]
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 && this.hasUppercase && this.hasLowercase && this.hasNumber && this.hasSpecialChar;
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 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\"\n (ngSubmit)=\"login()\"\n class=\"flex flex-col gap-4\">\n <haloduck-input data-testid=\"authenticate-login-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\" />\n <haloduck-input data-testid=\"authenticate-login-password\"\n type=\"password\"\n formControlName=\"password\"\n placeholder=\"Password\" />\n <haloduck-button data-testid=\"authenticate-login-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"login()\">Sign In</haloduck-button>\n </form>\n }\n @case ('signup') {\n <!-- \uD68C\uC6D0\uAC00\uC785 -->\n <form [formGroup]=\"signupForm\"\n (ngSubmit)=\"signup()\"\n class=\"flex flex-col gap-4\">\n <haloduck-input data-testid=\"authenticate-signup-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\" />\n <haloduck-input data-testid=\"authenticate-signup-password\"\n type=\"password\"\n formControlName=\"password\"\n placeholder=\"Password\" />\n <haloduck-button data-testid=\"authenticate-signup-submit\"\n type=\"submit\"\n variant=\"primary\">Sign Up</haloduck-button>\n </form>\n }\n @case ('reset') {\n <!-- \uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815 \uC694\uCCAD -->\n <form [formGroup]=\"resetForm\"\n (ngSubmit)=\"reset()\"\n class=\"flex flex-col gap-4\">\n <haloduck-input data-testid=\"authenticate-reset-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\" />\n <haloduck-button data-testid=\"authenticate-reset-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"reset()\">Send Verification Code</haloduck-button>\n </form>\n }\n @case ('otpVerify') {\n <!-- OTP \uC778\uC99D \uD6C4 \uC0C8 \uBE44\uBC00\uBC88\uD638 \uC785\uB825 -->\n <form [formGroup]=\"otpForm\"\n (ngSubmit)=\"verifyOtp()\"\n class=\"flex flex-col gap-4\">\n <haloduck-input data-testid=\"authenticate-otp-code\"\n type=\"text\"\n formControlName=\"code\"\n placeholder=\"Verification Code\" />\n <haloduck-input data-testid=\"authenticate-otp-password\"\n type=\"password\"\n formControlName=\"newPassword\"\n placeholder=\"New password\" />\n <haloduck-button data-testid=\"authenticate-otp-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"verifyOtp()\">Reset Password</haloduck-button>\n </form>\n\n }\n @case ('newPassword') {\n <!-- \uC784\uC2DC \uBE44\uBC00\uBC88\uD638 \u2192 \uC0C8 \uBE44\uBC00\uBC88\uD638 \uBCC0\uACBD -->\n <form [formGroup]=\"newPasswordForm\"\n (ngSubmit)=\"confirmNewPassword()\"\n class=\"flex flex-col gap-4\">\n <haloduck-input data-testid=\"authenticate-new-password-password\"\n type=\"password\"\n formControlName=\"newPassword\"\n placeholder=\"New password\">\n </haloduck-input>\n <div class=\"text-sm flex flex-col\">\n @for (rule of passwordRules; track rule.label) {\n <span [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 {{ rule.valid ? '\u2714' : '\u2717' }} {{ rule.label }}\n </span>\n }\n </div>\n <haloduck-button data-testid=\"authenticate-new-password-submit\"\n type=\"submit\"\n (click)=\"confirmNewPassword()\"\n variant=\"primary\"\n [disabled]=\"!isPasswordValid\">Change Password</haloduck-button>\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 data-testid=\"authenticate-to-signin\"\n variant=\"none\"\n (click)=\"switchStage('login')\">to Sign In</haloduck-button>\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 data-testid=\"authenticate-to-reset-password\"\n variant=\"secondary\"\n (click)=\"switchStage('reset')\">Reset Password</haloduck-button>\n }\n </div>\n\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"] }] });
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 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\"\n (ngSubmit)=\"login()\"\n class=\"flex flex-col gap-4\">\n <haloduck-input data-testid=\"authenticate-login-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\" />\n <haloduck-input data-testid=\"authenticate-login-password\"\n type=\"password\"\n formControlName=\"password\"\n placeholder=\"Password\" />\n <haloduck-button data-testid=\"authenticate-login-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"login()\">Sign In</haloduck-button>\n </form>\n }\n @case ('signup') {\n <!-- \uD68C\uC6D0\uAC00\uC785 -->\n <form [formGroup]=\"signupForm\"\n (ngSubmit)=\"signup()\"\n class=\"flex flex-col gap-4\">\n <haloduck-input data-testid=\"authenticate-signup-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\" />\n <haloduck-input data-testid=\"authenticate-signup-password\"\n type=\"password\"\n formControlName=\"password\"\n placeholder=\"Password\" />\n <haloduck-button data-testid=\"authenticate-signup-submit\"\n type=\"submit\"\n variant=\"primary\">Sign Up</haloduck-button>\n </form>\n }\n @case ('reset') {\n <!-- \uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815 \uC694\uCCAD -->\n <form [formGroup]=\"resetForm\"\n (ngSubmit)=\"reset()\"\n class=\"flex flex-col gap-4\">\n <haloduck-input data-testid=\"authenticate-reset-email\"\n type=\"email\"\n formControlName=\"email\"\n placeholder=\"Email\" />\n <haloduck-button data-testid=\"authenticate-reset-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"reset()\">Send Verification Code</haloduck-button>\n </form>\n }\n @case ('otpVerify') {\n <!-- OTP \uC778\uC99D \uD6C4 \uC0C8 \uBE44\uBC00\uBC88\uD638 \uC785\uB825 -->\n <form [formGroup]=\"otpForm\"\n (ngSubmit)=\"verifyOtp()\"\n class=\"flex flex-col gap-4\">\n <haloduck-input data-testid=\"authenticate-otp-code\"\n type=\"text\"\n formControlName=\"code\"\n placeholder=\"Verification Code\" />\n <haloduck-input data-testid=\"authenticate-otp-password\"\n type=\"password\"\n formControlName=\"newPassword\"\n placeholder=\"New password\" />\n <haloduck-button data-testid=\"authenticate-otp-submit\"\n type=\"submit\"\n variant=\"primary\"\n (click)=\"verifyOtp()\">Reset Password</haloduck-button>\n </form>\n\n }\n @case ('newPassword') {\n <!-- \uC784\uC2DC \uBE44\uBC00\uBC88\uD638 \u2192 \uC0C8 \uBE44\uBC00\uBC88\uD638 \uBCC0\uACBD -->\n <form [formGroup]=\"newPasswordForm\"\n (ngSubmit)=\"confirmNewPassword()\"\n class=\"flex flex-col gap-4\">\n <haloduck-input data-testid=\"authenticate-new-password-password\"\n type=\"password\"\n formControlName=\"newPassword\"\n placeholder=\"New password\">\n </haloduck-input>\n <div class=\"text-sm flex flex-col\">\n @for (rule of passwordRules; track rule.label) {\n <span [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 {{ rule.valid ? '\u2714' : '\u2717' }} {{ rule.label }}\n </span>\n }\n </div>\n <haloduck-button data-testid=\"authenticate-new-password-submit\"\n type=\"submit\"\n (click)=\"confirmNewPassword()\"\n variant=\"primary\"\n [disabled]=\"!isPasswordValid\">Change Password</haloduck-button>\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 data-testid=\"authenticate-to-signin\"\n variant=\"none\"\n (click)=\"switchStage('login')\">to Sign In</haloduck-button>\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 data-testid=\"authenticate-to-reset-password\"\n variant=\"secondary\"\n (click)=\"switchStage('reset')\">Reset Password</haloduck-button>\n }\n </div>\n\n </div>\n</div>\n" }]
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' && selectedId.startsWith(prefix) && selectedId.length > prefix.length);
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 || (option.id || option.value);
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 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 @if (useFilter && _options.length >= 5) {\n <input #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 <div class=\"overflow-y-auto\">\n @for ( option of _filteredOptions(); track (option.id) ? option.id : option.value) {\n <div 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 @if(!asButton) {\n @if( isOptionSelected(option)) {\n <svg 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 <path 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 </svg>\n } @else {\n <div class=\"w-4 h-4 inline-block mr-2\"></div>\n }\n }\n @if(option.shouldManualInput && (isOptionSelected(option) || (activeManualKey === (option.manualPrefix ? option.manualPrefix : (option.id || option.value))))) {\n <input type=\"text\"\n [(ngModel)]=\"manualInputValues[option.manualPrefix ? option.manualPrefix : (option.id || option.value)]\"\n [attr.data-manual-key]=\"option.manualPrefix ? option.manualPrefix : (option.id || option.value)\"\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 } @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" }] });
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 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 @if (useFilter && _options.length >= 5) {\n <input #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 <div class=\"overflow-y-auto\">\n @for ( option of _filteredOptions(); track (option.id) ? option.id : option.value) {\n <div 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 @if(!asButton) {\n @if( isOptionSelected(option)) {\n <svg 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 <path 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 </svg>\n } @else {\n <div class=\"w-4 h-4 inline-block mr-2\"></div>\n }\n }\n @if(option.shouldManualInput && (isOptionSelected(option) || (activeManualKey === (option.manualPrefix ? option.manualPrefix : (option.id || option.value))))) {\n <input type=\"text\"\n [(ngModel)]=\"manualInputValues[option.manualPrefix ? option.manualPrefix : (option.id || option.value)]\"\n [attr.data-manual-key]=\"option.manualPrefix ? option.manualPrefix : (option.id || option.value)\"\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 } @else {\n {{ option.value }}\n }\n </div>\n }\n </div>\n</div>\n" }]
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 = (value !== null && value !== undefined && value !== '') ? [value] : [];
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\">&nbsp;</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 &nbsp;\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 &nbsp;\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\">&nbsp;</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 &nbsp;\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 &nbsp;\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 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 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 <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=\"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 </svg>\n </button>\n <div class=\"flex-auto text-sm font-semibold flex justify-center\">\n <div class=\"w-32\">\n <haloduck-select [multiselect]=\"false\"\n [atLeastOne]=\"true\"\n [options]=\"yearList\"\n [value]=\"currentYear + ''\"\n (selectedChange)=\"onSelectYear($event)\">\n </haloduck-select>\n </div>\n </div>\n <button 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 <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=\"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 </svg>\n </button>\n </div>\n\n <div class=\"flex items-center\">\n <button 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\"\n (click)=\"onAdjustMonth(-1)\">\n <span class=\"sr-only\">\uC774\uC804 \uB2EC</span>\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=\"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 </svg>\n </button>\n <div class=\"flex-auto text-sm font-semibold flex justify-center\">\n <div class=\"w-32\">\n <haloduck-select [multiselect]=\"false\"\n [atLeastOne]=\"true\"\n [options]=\"monthList\"\n [value]=\"currentMonth + ''\"\n (selectedChange)=\"onSelectMonth($event)\">\n </haloduck-select>\n </div>\n </div>\n <button 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\"\n (click)=\"onAdjustMonth(1)\">\n <span class=\"sr-only\">\uB2E4\uC74C \uB2EC</span>\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=\"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 </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 <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 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]=\"{'bg-light-control dark:bg-dark-control text-light-on-control dark:text-dark-on-control' : date.isCurrentMonth}\">\n <time [ngClass]=\"{'font-semibold bg-light-primary-light dark:bg-dark-primary-light text-on-light-primary-light dark:text-dark-on-primary-light': date.isToday && date.datetime !== selectedDateRange?.from,\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary': date.datetime === selectedDateRange?.from,\n 'bg-gray-500 font-semibold text-white' : date.isTheDate}\"\n class=\"mx-auto flex size-7 items-center justify-center rounded-full hover:font-bold\">{{date.date}}</time>\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", "options", "layout", "labelWidth", "value"], outputs: ["selectedChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }] });
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 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 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 <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=\"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 </svg>\n </button>\n <div class=\"flex-auto text-sm font-semibold flex justify-center\">\n <div class=\"w-32\">\n <haloduck-select [multiselect]=\"false\"\n [atLeastOne]=\"true\"\n [options]=\"yearList\"\n [value]=\"currentYear + ''\"\n (selectedChange)=\"onSelectYear($event)\">\n </haloduck-select>\n </div>\n </div>\n <button 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 <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=\"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 </svg>\n </button>\n </div>\n\n <div class=\"flex items-center\">\n <button 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\"\n (click)=\"onAdjustMonth(-1)\">\n <span class=\"sr-only\">\uC774\uC804 \uB2EC</span>\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=\"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 </svg>\n </button>\n <div class=\"flex-auto text-sm font-semibold flex justify-center\">\n <div class=\"w-32\">\n <haloduck-select [multiselect]=\"false\"\n [atLeastOne]=\"true\"\n [options]=\"monthList\"\n [value]=\"currentMonth + ''\"\n (selectedChange)=\"onSelectMonth($event)\">\n </haloduck-select>\n </div>\n </div>\n <button 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\"\n (click)=\"onAdjustMonth(1)\">\n <span class=\"sr-only\">\uB2E4\uC74C \uB2EC</span>\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=\"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 </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 <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 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]=\"{'bg-light-control dark:bg-dark-control text-light-on-control dark:text-dark-on-control' : date.isCurrentMonth}\">\n <time [ngClass]=\"{'font-semibold bg-light-primary-light dark:bg-dark-primary-light text-on-light-primary-light dark:text-dark-on-primary-light': date.isToday && date.datetime !== selectedDateRange?.from,\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary': date.datetime === selectedDateRange?.from,\n 'bg-gray-500 font-semibold text-white' : date.isTheDate}\"\n class=\"mx-auto flex size-7 items-center justify-center rounded-full hover:font-bold\">{{date.date}}</time>\n </button>\n }\n </div>\n </div>\n</div>\n" }]
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 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 <!-- <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\"\n #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"] });
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 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 <!-- <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\"\n #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"] }]
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 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 <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\"\n (click)=\"onButtonClicked(button.id)\">{{ button.label }}</haloduck-button>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "haloduck-button", inputs: ["disabled", "variant"] }] });
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 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 <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\"\n (click)=\"onButtonClicked(button.id)\">{{ button.label }}</haloduck-button>\n }\n </div>\n</div>\n" }]
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 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 <svg xmlns=\"http://www.w3.org/2000/svg\"\n [class]=\"'h-4 w-4 mr-1 transition-all duration-500 ' + (isAnimating ? 'scale-150 opacity-0' : 'scale-100 opacity-100')\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\">\n <rect 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 <rect 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 </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"] }] });
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 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 <svg xmlns=\"http://www.w3.org/2000/svg\"\n [class]=\"'h-4 w-4 mr-1 transition-all duration-500 ' + (isAnimating ? 'scale-150 opacity-0' : 'scale-100 opacity-100')\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\">\n <rect 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 <rect 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 </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" }]
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 #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': !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()\">\n <div class=\"flex items-center\">\n <div 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 }\"> {{ selectedDate || placeholder }}</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 }] });
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 #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': !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()\">\n <div class=\"flex items-center\">\n <div 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 }\"> {{ selectedDate || placeholder }}</div>\n </div>\n</div>\n" }]
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 (dateRange.from === dateToString(from) &&
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 #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': !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()\">\n <div class=\"flex items-center\">\n <haloduck-select [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 </haloduck-select>\n @if (getSelectedDateRangeString()) {\n <div 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 }\"> {{ getSelectedDateRangeString() }}</div>\n } @else {\n <div 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 }\"> {{ placeholder }}</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", "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" }] });
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 #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': !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()\">\n <div class=\"flex items-center\">\n <haloduck-select [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 </haloduck-select>\n @if (getSelectedDateRangeString()) {\n <div 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 }\"> {{ getSelectedDateRangeString() }}</div>\n } @else {\n <div 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 }\"> {{ placeholder }}</div>\n }\n </div>\n</div>\n" }]
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()\">{{ 'haloduck.ui.draw.Clear' | transloco }}</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" }] });
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()\">{{ 'haloduck.ui.draw.Clear' | transloco }}</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"] }]
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 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 @if (!isUploading) {\n <label 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 <span class=\"text-light-inactive dark:text-dark-inactive\">{{ 'haloduck.ui.file.Drag and drop files here, or click to select files' | transloco }}</span>\n <input 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 </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 class=\"flex items-center justify-between p-2 border border-light-inactive dark:border-dark-inactive rounded-md\">\n <!-- Check if the file is an image -->\n <div class=\"flex items-center space-x-4\">\n @if (file.previewUrl){\n <img [src]=\"file.previewUrl\"\n alt=\"{{ file.name }}\"\n class=\"w-12 h-12 object-cover rounded-md\" />\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\">{{ 'haloduck.ui.file.Uploaded' | transloco }}</span>\n }@else{\n <span class=\"text-sm text-light-primary dark:text-dark-primary\">{{ 'haloduck.ui.file.Uploading...' | transloco }}</span>\n }\n }@else{\n <button type=\"button\"\n class=\"text-light-danger dark:text-dark-danger hover:brightness-125\"\n (click)=\"removeFile(i)\">\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" }] });
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 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 @if (!isUploading) {\n <label 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 <span class=\"text-light-inactive dark:text-dark-inactive\">{{ 'haloduck.ui.file.Drag and drop files here, or click to select files' | transloco }}</span>\n <input 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 </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 class=\"flex items-center justify-between p-2 border border-light-inactive dark:border-dark-inactive rounded-md\">\n <!-- Check if the file is an image -->\n <div class=\"flex items-center space-x-4\">\n @if (file.previewUrl){\n <img [src]=\"file.previewUrl\"\n alt=\"{{ file.name }}\"\n class=\"w-12 h-12 object-cover rounded-md\" />\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\">{{ 'haloduck.ui.file.Uploaded' | transloco }}</span>\n }@else{\n <span class=\"text-sm text-light-primary dark:text-dark-primary\">{{ 'haloduck.ui.file.Uploading...' | transloco }}</span>\n }\n }@else{\n <button type=\"button\"\n class=\"text-light-danger dark:text-dark-danger hover:brightness-125\"\n (click)=\"removeFile(i)\">\n {{ 'haloduck.ui.file.Remove' | transloco }}\n </button>\n }\n </li>\n }\n </ul>\n }\n</div>\n" }]
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 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 <label class=\"text-sm text-light-on-alternative dark:text-dark-on-alternative\" [class.cursor-pointer]=\"!_isOpen()\">{{ title }}</label>\n @if(_isOpen()) {\n <ng-content></ng-content>\n }\n <button 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 @if(_isOpen()) {\n <svg 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 <path stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M18 15l-6-6-6 6\" />\n </svg>\n }\n @else {\n <svg 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 <path stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M6 9l6 6 6-6\" />\n </svg>\n }\n </button>\n</div>\n", styles: [""] });
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 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 <label class=\"text-sm text-light-on-alternative dark:text-dark-on-alternative\" [class.cursor-pointer]=\"!_isOpen()\">{{ title }}</label>\n @if(_isOpen()) {\n <ng-content></ng-content>\n }\n <button 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 @if(_isOpen()) {\n <svg 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 <path stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M18 15l-6-6-6 6\" />\n </svg>\n }\n @else {\n <svg 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 <path stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M6 9l6 6 6-6\" />\n </svg>\n }\n </button>\n</div>\n" }]
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 class=\"max-w-full max-h-full object-cover cursor-pointer\"\n [src]=\"context?.imageUrl\"\n [alt]=\"context?.imageAlt\"\n (click)=\"onClose()\" />", styles: [""] });
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 class=\"max-w-full max-h-full object-cover cursor-pointer\"\n [src]=\"context?.imageUrl\"\n [alt]=\"context?.imageAlt\"\n (click)=\"onClose()\" />" }]
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 <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 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 <!-- Show image preview if available -->\n @if (imageUrl) {\n @if (!disabled) {\n <div class=\"relative\">\n <button 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 x\n </button>\n </div>\n }\n <img [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 } @else {\n <!-- Show upload area -->\n <label 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]=\"{'cursor-pointer hover:border-light-primary dark:hover:border-dark-primary': !disabled}\">\n @if (backgroundImage) {\n <img [src]=\"backgroundImage\"\n [alt]=\"alt || ''\"\n class=\"w-full h-full rounded-md aspect-square\" />\n }@else {\n <span class=\"text-light-inactive dark:text-dark-inactive text-sm p-2\">{{ 'haloduck.ui.file.Drag and drop an image here, or click to select' | transloco }}</span>\n }\n\n @if(!disabled){\n <input [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 </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" }] });
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 <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 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 <!-- Show image preview if available -->\n @if (imageUrl) {\n @if (!disabled) {\n <div class=\"relative\">\n <button 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 x\n </button>\n </div>\n }\n <img [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 } @else {\n <!-- Show upload area -->\n <label 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]=\"{'cursor-pointer hover:border-light-primary dark:hover:border-dark-primary': !disabled}\">\n @if (backgroundImage) {\n <img [src]=\"backgroundImage\"\n [alt]=\"alt || ''\"\n class=\"w-full h-full rounded-md aspect-square\" />\n }@else {\n <span class=\"text-light-inactive dark:text-dark-inactive text-sm p-2\">{{ 'haloduck.ui.file.Drag and drop an image here, or click to select' | transloco }}</span>\n }\n\n @if(!disabled){\n <input [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 </label>\n }\n </div>\n</div>\n", styles: [".drag-over{border-color:#3b82f6}.relative{position:relative}button{cursor:pointer}\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 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 @for (language of translateService.getAvailableLangs(); track language) {\n <a 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 <img class=\"w-6 h-6\"\n [src]=\"'i18n/icons/' + language + '.png'\">\n </a>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
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 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 @for (language of translateService.getAvailableLangs(); track language) {\n <a 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 <img class=\"w-6 h-6\"\n [src]=\"'i18n/icons/' + language + '.png'\">\n </a>\n }\n</div>\n" }]
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 #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 <span class=\"max-lg:hidden flex lg:items-center\">\n <img class=\"w-6 h-6\"\n [src]=\"'i18n/icons/' + language() + '.png'\">\n </span>\n</button>\n", styles: [""] });
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 #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 <span class=\"max-lg:hidden flex lg:items-center\">\n <img class=\"w-6 h-6\"\n [src]=\"'i18n/icons/' + language() + '.png'\">\n </span>\n</button>\n" }]
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 <div class=\"absolute inset-0 flex items-center justify-center bg-gray-100 z-10\">\n <div class=\"text-center\">\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto mb-2\"></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\">Please check your internet connection and refresh the page.</p>\n </div>\n </div>\n }\n\n <div id=\"map\"\n 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 }] });
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 <div class=\"absolute inset-0 flex items-center justify-center bg-gray-100 z-10\">\n <div class=\"text-center\">\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto mb-2\"></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\">Please check your internet connection and refresh the page.</p>\n </div>\n </div>\n }\n\n <div id=\"map\"\n class=\"w-full h-full\"></div>\n</div>\n", styles: ["#map{border:1px solid #ccc;margin-bottom:10px}\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 => { return response.ok ? response : Promise.reject(response); })
2741
- .then(response => response.text())
2742
- .then(svg => this.iconSvg = this.sanitizer.bypassSecurityTrustHtml(svg));
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 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': menuItem.isSelected,\n }\">\n @if (menuItem.iconType === 'svg') {\n <div [innerHTML]=\"iconSvg\"></div>\n } @else {\n @if (menuItem.icon) {\n <img class=\"w-5 h-5\"\n [src]=\"menuItem.icon\"\n [alt]=\"menuItem.title\"\n [title]=\"menuItem.title\"\n [loading]=\"'lazy'\" />\n }\n }\n <span class=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n title=\"{{ menuItem.title }}\"\n [ngStyle]=\"{'margin-left.px': depth ? depth * 16 : 0}\">\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"] }] });
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 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': menuItem.isSelected,\n }\">\n @if (menuItem.iconType === 'svg') {\n <div [innerHTML]=\"iconSvg\"></div>\n } @else {\n @if (menuItem.icon) {\n <img class=\"w-5 h-5\"\n [src]=\"menuItem.icon\"\n [alt]=\"menuItem.title\"\n [title]=\"menuItem.title\"\n [loading]=\"'lazy'\" />\n }\n }\n <span class=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n title=\"{{ menuItem.title }}\"\n [ngStyle]=\"{'margin-left.px': depth ? depth * 16 : 0}\">\n {{ menuItem.title }}\n </span>\n</a>\n" }]
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 <haloduck-side-menu-item [menuItemSelectHandler]=\"menuItemSelected\"\n [menuItem]=\"menuItem\"\n [depth]=\"depth\"></haloduck-side-menu-item>\n @if (menuItem.children && menuItem.children.length > 0) {\n <haloduck-side-menu [menuItems]=\"menuItem.children\"\n [depth]=\"depth + 1\"\n (menuItemSelected)=\"menuItemSelected.emit($event)\"></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"] }] });
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 <haloduck-side-menu-item [menuItemSelectHandler]=\"menuItemSelected\"\n [menuItem]=\"menuItem\"\n [depth]=\"depth\"></haloduck-side-menu-item>\n @if (menuItem.children && menuItem.children.length > 0) {\n <haloduck-side-menu [menuItems]=\"menuItem.children\"\n [depth]=\"depth + 1\"\n (menuItemSelected)=\"menuItemSelected.emit($event)\"></haloduck-side-menu>\n }\n }\n</div>\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 <div class=\"w-full h-full flex items-start flex-col\">\n <div #viewerContainer\n class=\"w-full h-full rounded-md\"></div>\n @if (loadingPercentage < 100)\n {\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\"\n (click)=\"download()\">{{ 'haloduck.ui.button.Download' | transloco }}</haloduck-button>\n <haloduck-button variant=\"danger\"\n (click)=\"closeDialog()\">{{ 'haloduck.ui.button.Close' | transloco }}</haloduck-button>\n } @else {\n <haloduck-button variant=\"primary\"\n (click)=\"download()\">{{ 'haloduck.ui.button.Download' | transloco }}</haloduck-button>\n <haloduck-button variant=\"secondary\"\n (click)=\"showStl()\">{{ 'haloduck.ui.button.View' | transloco }}</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" }] });
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 <div class=\"w-full h-full flex items-start flex-col\">\n <div #viewerContainer\n class=\"w-full h-full rounded-md\"></div>\n @if (loadingPercentage < 100)\n {\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\"\n (click)=\"download()\">{{ 'haloduck.ui.button.Download' | transloco }}</haloduck-button>\n <haloduck-button variant=\"danger\"\n (click)=\"closeDialog()\">{{ 'haloduck.ui.button.Close' | transloco }}</haloduck-button>\n } @else {\n <haloduck-button variant=\"primary\"\n (click)=\"download()\">{{ 'haloduck.ui.button.Download' | transloco }}</haloduck-button>\n <haloduck-button variant=\"secondary\"\n (click)=\"showStl()\">{{ 'haloduck.ui.button.View' | transloco }}</haloduck-button>\n }\n</div>\n</div>\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 ? this.tableSettingService.getSettings(this.tableName).pipe(shareReplay(1)) : of({ showHeader: this.defaultShowHeader, autoLoad: this.defaultAutoLoad });
3101
- showHeader$ = this.settings$.pipe(map(settings => settings.showHeader));
3102
- autoLoad$ = this.settings$.pipe(map(settings => settings.autoLoad));
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 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" }]
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 class=\"flex gap-2\"\n [ngClass]=\"{'items-center justify-start': 'horizontal' === layout, 'flex-col items-start justify-center ': 'vertical' === layout}\">\n <label #label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\">\n <ng-content></ng-content>\n </label>\n <button 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]=\"{'justify-end': true === value, 'justify-center': null === value, 'justify-start': false === value}\">\n <div class=\"shrink-0 h-[1.5rem] rounded-l-full rounded-r-full\"\n [ngClass]=\"{'bg-light-primary dark:bg-dark-primary disabled:bg-light-primary/60 dark:disabled:bg-dark-primary/60': true === value, 'bg-light-inactive dark:bg-dark-inactive disabled:bg-light-inactive/60 dark:disabled:bg-dark-inactive/60': false === value,\n 'w-[1.5rem]': true === value || false === value, '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]': null === value}\">\n </div>\n </button>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
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 class=\"flex gap-2\"\n [ngClass]=\"{'items-center justify-start': 'horizontal' === layout, 'flex-col items-start justify-center ': 'vertical' === layout}\">\n <label #label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\">\n <ng-content></ng-content>\n </label>\n <button 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]=\"{'justify-end': true === value, 'justify-center': null === value, 'justify-start': false === value}\">\n <div class=\"shrink-0 h-[1.5rem] rounded-l-full rounded-r-full\"\n [ngClass]=\"{'bg-light-primary dark:bg-dark-primary disabled:bg-light-primary/60 dark:disabled:bg-dark-primary/60': true === value, 'bg-light-inactive dark:bg-dark-inactive disabled:bg-light-inactive/60 dark:disabled:bg-dark-inactive/60': false === value,\n 'w-[1.5rem]': true === value || false === value, '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]': null === value}\">\n </div>\n </button>\n</div>\n" }]
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\"\n [ngClass]=\"{'flex-col': 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 </label>\n\n <div class=\"flex-1 w-full\">\n <div class=\"flex items-center gap-1 border-b border-light-inactive dark:border-dark-inactive text-sm/6\">\n @for (tab of tabs; track tab.label; let i = $index) {\n <button 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': i === selectedIndex\n }\"\n (click)=\"select(i)\">\n {{ tab.label }}\n </button>\n }\n </div>\n\n <div class=\"mt-3\">\n @if (current) {\n <ng-container *ngComponentOutlet=\"current!.component; inputs: current!.inputs || {}\"></ng-container>\n }\n </div>\n </div>\n</div>", 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"] }] });
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\"\n [ngClass]=\"{'flex-col': 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 </label>\n\n <div class=\"flex-1 w-full\">\n <div class=\"flex items-center gap-1 border-b border-light-inactive dark:border-dark-inactive text-sm/6\">\n @for (tab of tabs; track tab.label; let i = $index) {\n <button 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': i === selectedIndex\n }\"\n (click)=\"select(i)\">\n {{ tab.label }}\n </button>\n }\n </div>\n\n <div class=\"mt-3\">\n @if (current) {\n <ng-container *ngComponentOutlet=\"current!.component; inputs: current!.inputs || {}\"></ng-container>\n }\n </div>\n </div>\n</div>" }]
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.split(',').map((p) => p.trim()).filter((p) => p.length > 0);
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 #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\">\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 <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 {{ tag }}\n @if (!disabled) {\n <button 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 \u00D7\n </button>\n }\n </span>\n }\n\n <input #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 </div>\n </div>\n</div>", 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 }] });
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 #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\">\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 <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 {{ tag }}\n @if (!disabled) {\n <button 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 \u00D7\n </button>\n }\n </span>\n }\n\n <input #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 </div>\n </div>\n</div>", 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"] }]
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 #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\">\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 <div class=\"flex items-center gap-2\"\n [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 {{ 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"] }] });
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 #label\n class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\">\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 <div class=\"flex items-center gap-2\"\n [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 {{ tag }}\n </span>\n }\n </div>\n </div>\n</div>\n", styles: [":host{display:block}\n"] }]
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', 'border-2', 'border-3', 'border-4', 'border-8',
3817
- 'border-solid', 'border-dashed', 'border-dotted', 'border-double', 'border-none',
3818
- 'rounded-none', 'rounded-sm', 'rounded', 'rounded-md', 'rounded-lg', 'rounded-xl', 'rounded-2xl', 'rounded-3xl', 'rounded-full',
3819
- 'border-gray-200', 'border-gray-300', 'border-gray-400', 'border-gray-500', 'border-gray-600', 'border-gray-700', 'border-gray-800', 'border-gray-900',
3820
- 'border-blue-500', 'border-blue-700', 'border-red-500', 'border-red-600', 'border-green-500', 'border-green-600',
3821
- 'border-amber-500', 'border-amber-600', 'border-violet-500', 'border-violet-600', 'border-pink-500', 'border-pink-600',
3822
- 'border-white', 'border-black'
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 class=\"flex border-b border-light-inactive dark:border-dark-inactive bg-light-background dark:bg-dark-background\"\n aria-label=\"Breadcrumb\">\n <ol role=\"list\"\n 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 routerLink=\"/\"\n class=\"text-light-on-background dark:text-dark-on-background hover:scale-105\">\n <svg class=\"size-5 shrink-0\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path 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 </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 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 <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\" />\n </svg>\n @if (!last) {\n <a 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\">{{ breadcrumb.label | transloco }}</a>\n } @else {\n <span class=\"ml-4 text-sm font-medium text-light-on-background dark:text-dark-on-background\">{{ breadcrumb.label | transloco }}</span>\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" }] });
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 class=\"flex border-b border-light-inactive dark:border-dark-inactive bg-light-background dark:bg-dark-background\"\n aria-label=\"Breadcrumb\">\n <ol role=\"list\"\n 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 routerLink=\"/\"\n class=\"text-light-on-background dark:text-dark-on-background hover:scale-105\">\n <svg class=\"size-5 shrink-0\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path 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 </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 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 <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\" />\n </svg>\n @if (!last) {\n <a 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\">{{ breadcrumb.label | transloco }}</a>\n } @else {\n <span class=\"ml-4 text-sm font-medium text-light-on-background dark:text-dark-on-background\">{{ breadcrumb.label | transloco }}</span>\n }\n </div>\n </li>\n }\n </ol>\n</nav>\n" }]
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 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]=\"{ 'bg-light-primary-dark dark:bg-dark-primary-dark text-light-on-primary-dark dark:text-dark-on-primary-dark': notification.type === 'info',\n 'bg-light-primary dark:bg-dark-primary text-light-on-primary dark:text-dark-on-primary': notification.type === 'success',\n 'bg-light-danger dark:bg-dark-danger text-light-on-danger dark:text-dark-on-danger': notification.type === 'error',\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary': notification.type === 'warning' }\">\n {{notification.message}}\n <div class=\"absolute top-0 right-0\">\n <button type=\"button\"\n (click)=\"removeNotification(notification.id)\">\n <span class=\"sr-only\">Close</span>\n <svg 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 <path stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n 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" }] });
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 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]=\"{ 'bg-light-primary-dark dark:bg-dark-primary-dark text-light-on-primary-dark dark:text-dark-on-primary-dark': notification.type === 'info',\n 'bg-light-primary dark:bg-dark-primary text-light-on-primary dark:text-dark-on-primary': notification.type === 'success',\n 'bg-light-danger dark:bg-dark-danger text-light-on-danger dark:text-dark-on-danger': notification.type === 'error',\n 'bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary': notification.type === 'warning' }\">\n {{notification.message}}\n <div class=\"absolute top-0 right-0\">\n <button type=\"button\"\n (click)=\"removeNotification(notification.id)\">\n <span class=\"sr-only\">Close</span>\n <svg 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 <path stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M6 18 18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n</div>\n}\n" }]
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 @if(pictureKey) {\n <img src=\"{{cdnUrl}}/{{pictureKey}}\"\n alt=\"\uC0AC\uC9C4\"\n 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 &nbsp;&nbsp;&nbsp;&nbsp;\n <!-- TODO -->\n }\n</div>\n", styles: [""] });
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 &nbsp;&nbsp;&nbsp;&nbsp;\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 @if(pictureKey) {\n <img src=\"{{cdnUrl}}/{{pictureKey}}\"\n alt=\"\uC0AC\uC9C4\"\n 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 &nbsp;&nbsp;&nbsp;&nbsp;\n <!-- TODO -->\n }\n</div>\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 &nbsp;&nbsp;&nbsp;&nbsp;\n <!-- TODO -->\n }\n</div>\n" }]
3968
4280
  }], propDecorators: { name: [{
3969
4281
  type: Input
3970
4282
  }], pictureKey: [{