@nettyapps/ntyui 21.1.2 → 21.1.5

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.
@@ -423,7 +423,7 @@ class NettyUIDateTime extends UiBase {
423
423
  useExisting: NettyUIDateTime,
424
424
  multi: true,
425
425
  },
426
- ], viewQueries: [{ propertyName: "dateModel", first: true, predicate: ["dateModel"], descendants: true, isSignal: true }, { propertyName: "timeModel", first: true, predicate: ["timeModel"], descendants: true, isSignal: true }, { propertyName: "inputModel", first: true, predicate: ["dateInputModel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"datetime-container\">\n <!-- Datetime -->\n <mat-form-field\n [appearance]=\"appearance()\"\n class=\"datepicker\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && dateValue()\"\n >\n @if (label()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n #dateInputModel=\"ngModel\"\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeholder()\"\n [ngModel]=\"dateValue()\"\n (dateChange)=\"onDateChange($event)\"\n [min]=\"minDate() ?? undefined\"\n [max]=\"maxDate() ?? undefined\"\n />\n\n @if (dateValue() && !disabled()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"clearInput()\"\n aria-label=\"Clear\"\n class=\"clear-btn date-clear\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n } @if (dateInputModel.invalid && (dateInputModel.dirty ||\n dateInputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n\n <!-- Timepicker -->\n <mat-form-field\n class=\"time-field\"\n [appearance]=\"appearance()\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && timeValue()\"\n >\n @if (timeLabel()) {\n <mat-label>{{ timeLabel() }}</mat-label>\n }\n <input\n #timeInputModel=\"ngModel\"\n matInput\n [matTimepicker]=\"timepicker\"\n [ngModel]=\"timeValue()\"\n (ngModelChange)=\"onTimeChange($event)\"\n [ngModelOptions]=\"{updateOn: 'blur'}\"\n [disabled]=\"disabled()\"\n />\n\n @if ( timeInputModel.invalid && ( timeInputModel.dirty ||\n timeInputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-timepicker #timepicker />\n <mat-timepicker-toggle [for]=\"timepicker\" matSuffix />\n </mat-form-field>\n</div>\n", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.datetime-container{display:flex;align-items:flex-start}@media(max-width:600px){.datetime-container{flex-wrap:nowrap;overflow-x:auto;align-items:flex-start}}.datepicker,.time-field{width:50%}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTimepickerModule }, { kind: "component", type: i6.MatTimepicker, selector: "mat-timepicker", inputs: ["interval", "options", "disableRipple", "aria-label", "aria-labelledby", "panelClass"], outputs: ["selected", "opened", "closed"], exportAs: ["matTimepicker"] }, { kind: "directive", type: i6.MatTimepickerInput, selector: "input[matTimepicker]", inputs: ["value", "matTimepicker", "matTimepickerMin", "matTimepickerMax", "matTimepickerOpenOnClick", "disabled"], outputs: ["valueChange"], exportAs: ["matTimepickerInput"] }, { kind: "component", type: i6.MatTimepickerToggle, selector: "mat-timepicker-toggle", inputs: ["for", "aria-label", "aria-labelledby", "disabled", "tabIndex", "disableRipple"], exportAs: ["matTimepickerToggle"] }] });
426
+ ], viewQueries: [{ propertyName: "dateModel", first: true, predicate: ["dateModel"], descendants: true, isSignal: true }, { propertyName: "timeModel", first: true, predicate: ["timeModel"], descendants: true, isSignal: true }, { propertyName: "inputModel", first: true, predicate: ["dateInputModel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"datetime-container\">\n <!-- Datetime -->\n <mat-form-field\n [appearance]=\"appearance()\"\n class=\"datepicker\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && dateValue()\"\n >\n @if (label()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n #dateInputModel=\"ngModel\"\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeholder()\"\n [ngModel]=\"dateValue()\"\n (dateChange)=\"onDateChange($event)\"\n [min]=\"minDate() ?? undefined\"\n [max]=\"maxDate() ?? undefined\"\n />\n\n @if (dateValue() && !disabled()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"clearInput()\"\n aria-label=\"Clear\"\n class=\"clear-btn date-clear\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n } @if (dateInputModel.invalid && (dateInputModel.dirty ||\n dateInputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n\n <!-- Timepicker -->\n <mat-form-field\n class=\"time-field\"\n [appearance]=\"appearance()\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && timeValue()\"\n >\n @if (timeLabel()) {\n <mat-label>{{ timeLabel() }}</mat-label>\n }\n <input\n #timeInputModel=\"ngModel\"\n matInput\n [matTimepicker]=\"timepicker\"\n [ngModel]=\"timeValue()\"\n (ngModelChange)=\"onTimeChange($event)\"\n [ngModelOptions]=\"{updateOn: 'blur'}\"\n [disabled]=\"disabled()\"\n />\n\n @if ( timeInputModel.invalid && ( timeInputModel.dirty ||\n timeInputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-timepicker #timepicker />\n <mat-timepicker-toggle [for]=\"timepicker\" matSuffix />\n </mat-form-field>\n</div>\n", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.datetime-container{display:flex;align-items:flex-start}@media(max-width:600px){.datetime-container{flex-wrap:nowrap;overflow-x:auto;align-items:flex-start}}.datepicker,.time-field{width:50%}::ng-deep .mat-mdc-form-field-icon-prefix,::ng-deep .mat-mdc-form-field-icon-suffix{display:flex!important;flex-direction:row!important;align-items:center!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTimepickerModule }, { kind: "component", type: i6.MatTimepicker, selector: "mat-timepicker", inputs: ["interval", "options", "disableRipple", "aria-label", "aria-labelledby", "panelClass"], outputs: ["selected", "opened", "closed"], exportAs: ["matTimepicker"] }, { kind: "directive", type: i6.MatTimepickerInput, selector: "input[matTimepicker]", inputs: ["value", "matTimepicker", "matTimepickerMin", "matTimepickerMax", "matTimepickerOpenOnClick", "disabled"], outputs: ["valueChange"], exportAs: ["matTimepickerInput"] }, { kind: "component", type: i6.MatTimepickerToggle, selector: "mat-timepicker-toggle", inputs: ["for", "aria-label", "aria-labelledby", "disabled", "tabIndex", "disableRipple"], exportAs: ["matTimepickerToggle"] }] });
427
427
  }
428
428
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyUIDateTime, decorators: [{
429
429
  type: Component,
@@ -442,7 +442,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
442
442
  useExisting: NettyUIDateTime,
443
443
  multi: true,
444
444
  },
445
- ], host: { 'ntyui-id': 'NettyUIDateTime' }, template: "<div class=\"datetime-container\">\n <!-- Datetime -->\n <mat-form-field\n [appearance]=\"appearance()\"\n class=\"datepicker\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && dateValue()\"\n >\n @if (label()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n #dateInputModel=\"ngModel\"\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeholder()\"\n [ngModel]=\"dateValue()\"\n (dateChange)=\"onDateChange($event)\"\n [min]=\"minDate() ?? undefined\"\n [max]=\"maxDate() ?? undefined\"\n />\n\n @if (dateValue() && !disabled()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"clearInput()\"\n aria-label=\"Clear\"\n class=\"clear-btn date-clear\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n } @if (dateInputModel.invalid && (dateInputModel.dirty ||\n dateInputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n\n <!-- Timepicker -->\n <mat-form-field\n class=\"time-field\"\n [appearance]=\"appearance()\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && timeValue()\"\n >\n @if (timeLabel()) {\n <mat-label>{{ timeLabel() }}</mat-label>\n }\n <input\n #timeInputModel=\"ngModel\"\n matInput\n [matTimepicker]=\"timepicker\"\n [ngModel]=\"timeValue()\"\n (ngModelChange)=\"onTimeChange($event)\"\n [ngModelOptions]=\"{updateOn: 'blur'}\"\n [disabled]=\"disabled()\"\n />\n\n @if ( timeInputModel.invalid && ( timeInputModel.dirty ||\n timeInputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-timepicker #timepicker />\n <mat-timepicker-toggle [for]=\"timepicker\" matSuffix />\n </mat-form-field>\n</div>\n", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.datetime-container{display:flex;align-items:flex-start}@media(max-width:600px){.datetime-container{flex-wrap:nowrap;overflow-x:auto;align-items:flex-start}}.datepicker,.time-field{width:50%}\n"] }]
445
+ ], host: { 'ntyui-id': 'NettyUIDateTime' }, template: "<div class=\"datetime-container\">\n <!-- Datetime -->\n <mat-form-field\n [appearance]=\"appearance()\"\n class=\"datepicker\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && dateValue()\"\n >\n @if (label()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n #dateInputModel=\"ngModel\"\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeholder()\"\n [ngModel]=\"dateValue()\"\n (dateChange)=\"onDateChange($event)\"\n [min]=\"minDate() ?? undefined\"\n [max]=\"maxDate() ?? undefined\"\n />\n\n @if (dateValue() && !disabled()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"clearInput()\"\n aria-label=\"Clear\"\n class=\"clear-btn date-clear\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n } @if (dateInputModel.invalid && (dateInputModel.dirty ||\n dateInputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n\n <!-- Timepicker -->\n <mat-form-field\n class=\"time-field\"\n [appearance]=\"appearance()\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && timeValue()\"\n >\n @if (timeLabel()) {\n <mat-label>{{ timeLabel() }}</mat-label>\n }\n <input\n #timeInputModel=\"ngModel\"\n matInput\n [matTimepicker]=\"timepicker\"\n [ngModel]=\"timeValue()\"\n (ngModelChange)=\"onTimeChange($event)\"\n [ngModelOptions]=\"{updateOn: 'blur'}\"\n [disabled]=\"disabled()\"\n />\n\n @if ( timeInputModel.invalid && ( timeInputModel.dirty ||\n timeInputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-timepicker #timepicker />\n <mat-timepicker-toggle [for]=\"timepicker\" matSuffix />\n </mat-form-field>\n</div>\n", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.datetime-container{display:flex;align-items:flex-start}@media(max-width:600px){.datetime-container{flex-wrap:nowrap;overflow-x:auto;align-items:flex-start}}.datepicker,.time-field{width:50%}::ng-deep .mat-mdc-form-field-icon-prefix,::ng-deep .mat-mdc-form-field-icon-suffix{display:flex!important;flex-direction:row!important;align-items:center!important}\n"] }]
446
446
  }], ctorParameters: () => [], propDecorators: { dateTimeValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateTimeValue", required: false }] }, { type: i0.Output, args: ["dateTimeValueChange"] }], timeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeLabel", required: false }] }], dateRestriction: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateRestriction", required: false }] }], timeFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeFormat", required: false }] }], dateModel: [{ type: i0.ViewChild, args: ['dateModel', { isSignal: true }] }], timeModel: [{ type: i0.ViewChild, args: ['timeModel', { isSignal: true }] }], inputModel: [{ type: i0.ViewChild, args: ['dateInputModel', { isSignal: true }] }] } });
447
447
 
448
448
  class NettyUIDatePicker extends UiBase {
@@ -534,6 +534,67 @@ class NettyUIDatePicker extends UiBase {
534
534
  this.onChange(this.required() ? null : this.NULL_DATE);
535
535
  this.onTouched();
536
536
  }
537
+ /**
538
+ * Handles the blur event of the input element.
539
+ * If the input value is a partial date (e.g., "23" or "23/11"), it attempts to parse and set it.
540
+ * @param event The blur event from the input element.
541
+ */
542
+ onInputBlur(event) {
543
+ const input = event.target;
544
+ const value = input.value;
545
+ if (!value || value.trim() === '') {
546
+ return;
547
+ }
548
+ // If it's just a number or D/M format, try to complete it
549
+ const parsedDate = this.parsePartialDate(value);
550
+ if (parsedDate) {
551
+ this.selectedDate.set(parsedDate);
552
+ this.onChange(parsedDate.toISOString());
553
+ this.onTouched();
554
+ }
555
+ }
556
+ parsePartialDate(value) {
557
+ // Normalize separators
558
+ const normalized = value.replace(/[.\-]/g, '/');
559
+ const parts = normalized.split('/');
560
+ if (parts.length > 2) {
561
+ return null; // Let the default parser handle full dates
562
+ }
563
+ const today = new Date();
564
+ let day = today.getDate();
565
+ let month = today.getMonth();
566
+ let year = today.getFullYear();
567
+ if (parts.length === 1) {
568
+ // Only "D" provided
569
+ const d = parseInt(parts[0], 10);
570
+ if (isNaN(d) || d < 1 || d > 31)
571
+ return null;
572
+ day = d;
573
+ }
574
+ else if (parts.length === 2) {
575
+ // "D/M" provided
576
+ const d = parseInt(parts[0], 10);
577
+ const m = parseInt(parts[1], 10);
578
+ if (isNaN(d) || isNaN(m) || d < 1 || d > 31 || m < 1 || m > 12)
579
+ return null;
580
+ day = d;
581
+ month = m - 1;
582
+ }
583
+ // Create local date to validate day of month (e.g. Feb 30)
584
+ const date = new Date(year, month, day);
585
+ if (isNaN(date.getTime()) ||
586
+ date.getDate() !== day ||
587
+ date.getMonth() !== month) {
588
+ return null;
589
+ }
590
+ // Convert to UTC as the component expects
591
+ const utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
592
+ // Check restrictions
593
+ if (!this.isDateValid(utcDate)) {
594
+ return null;
595
+ }
596
+ return utcDate;
597
+ }
537
598
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyUIDatePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
538
599
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: NettyUIDatePicker, isStandalone: true, selector: "ntyui-date-picker", inputs: { dateRestriction: { classPropertyName: "dateRestriction", publicName: "dateRestriction", isSignal: true, isRequired: false, transformFunction: null }, dateValue: { classPropertyName: "dateValue", publicName: "dateValue", isSignal: true, isRequired: false, transformFunction: null }, selectedDate: { classPropertyName: "selectedDate", publicName: "selectedDate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateValue: "dateValueChange", selectedDate: "selectedDateChange" }, host: { attributes: { "ntyui-id": "NettyUIDatePicker" } }, providers: [
539
600
  {
@@ -541,7 +602,7 @@ class NettyUIDatePicker extends UiBase {
541
602
  useExisting: NettyUIDatePicker,
542
603
  multi: true,
543
604
  },
544
- ], usesInheritance: true, ngImport: i0, template: "<mat-form-field\n [appearance]=\"appearance()\"\n class=\"example-full-width\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && selectedDate()\"\n>\n @if (label()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n #inputModel=\"ngModel\"\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeholder()\"\n [(ngModel)]=\"selectedDate\"\n (dateChange)=\"onDateChange($event)\"\n [min]=\"minDate() ?? undefined\"\n [max]=\"maxDate() ?? undefined\"\n />\n\n <button\n mat-icon-button\n matSuffix\n [class.invisible]=\"!selectedDate() || disabled()\"\n (click)=\"clearInput()\"\n aria-label=\"Clear\"\n class=\"clear-btn date-clear\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n\n @if (inputModel.invalid && (inputModel.dirty || inputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n</mat-form-field>\n", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.mat-datepicker-toggle{margin-right:5px}.clear-btn{opacity:1;transition:opacity .2s}.clear-btn.invisible{opacity:0;pointer-events:none}.mat-form-field-suffix{display:flex;align-items:center;gap:4px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
605
+ ], usesInheritance: true, ngImport: i0, template: "<mat-form-field\n [appearance]=\"appearance()\"\n class=\"example-full-width\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && selectedDate()\"\n>\n @if (label()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n #inputModel=\"ngModel\"\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeholder()\"\n [(ngModel)]=\"selectedDate\"\n (dateChange)=\"onDateChange($event)\"\n (blur)=\"onInputBlur($event)\"\n [min]=\"minDate() ?? undefined\"\n [max]=\"maxDate() ?? undefined\"\n />\n\n <button\n mat-icon-button\n matSuffix\n [class.invisible]=\"!selectedDate() || disabled()\"\n (click)=\"clearInput()\"\n aria-label=\"Clear\"\n class=\"clear-btn date-clear\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n\n @if (inputModel.invalid && (inputModel.dirty || inputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n</mat-form-field>\n", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.mat-datepicker-toggle{margin-right:5px}.clear-btn{opacity:1;transition:opacity .2s}.clear-btn.invisible{opacity:0;pointer-events:none}.mat-form-field-suffix{display:flex;align-items:center;gap:4px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
545
606
  }
546
607
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyUIDatePicker, decorators: [{
547
608
  type: Component,
@@ -559,7 +620,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
559
620
  useExisting: NettyUIDatePicker,
560
621
  multi: true,
561
622
  },
562
- ], host: { 'ntyui-id': 'NettyUIDatePicker' }, template: "<mat-form-field\n [appearance]=\"appearance()\"\n class=\"example-full-width\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && selectedDate()\"\n>\n @if (label()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n #inputModel=\"ngModel\"\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeholder()\"\n [(ngModel)]=\"selectedDate\"\n (dateChange)=\"onDateChange($event)\"\n [min]=\"minDate() ?? undefined\"\n [max]=\"maxDate() ?? undefined\"\n />\n\n <button\n mat-icon-button\n matSuffix\n [class.invisible]=\"!selectedDate() || disabled()\"\n (click)=\"clearInput()\"\n aria-label=\"Clear\"\n class=\"clear-btn date-clear\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n\n @if (inputModel.invalid && (inputModel.dirty || inputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n</mat-form-field>\n", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.mat-datepicker-toggle{margin-right:5px}.clear-btn{opacity:1;transition:opacity .2s}.clear-btn.invisible{opacity:0;pointer-events:none}.mat-form-field-suffix{display:flex;align-items:center;gap:4px}\n"] }]
623
+ ], host: { 'ntyui-id': 'NettyUIDatePicker' }, template: "<mat-form-field\n [appearance]=\"appearance()\"\n class=\"example-full-width\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && selectedDate()\"\n>\n @if (label()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n #inputModel=\"ngModel\"\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeholder()\"\n [(ngModel)]=\"selectedDate\"\n (dateChange)=\"onDateChange($event)\"\n (blur)=\"onInputBlur($event)\"\n [min]=\"minDate() ?? undefined\"\n [max]=\"maxDate() ?? undefined\"\n />\n\n <button\n mat-icon-button\n matSuffix\n [class.invisible]=\"!selectedDate() || disabled()\"\n (click)=\"clearInput()\"\n aria-label=\"Clear\"\n class=\"clear-btn date-clear\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n\n @if (inputModel.invalid && (inputModel.dirty || inputModel.touched)) {\n <mat-error> {{ getErrorMessage() }} </mat-error>\n }\n\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n</mat-form-field>\n", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.mat-datepicker-toggle{margin-right:5px}.clear-btn{opacity:1;transition:opacity .2s}.clear-btn.invisible{opacity:0;pointer-events:none}.mat-form-field-suffix{display:flex;align-items:center;gap:4px}\n"] }]
563
624
  }], ctorParameters: () => [], propDecorators: { dateRestriction: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateRestriction", required: false }] }], dateValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateValue", required: false }] }, { type: i0.Output, args: ["dateValueChange"] }], selectedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedDate", required: false }] }, { type: i0.Output, args: ["selectedDateChange"] }] } });
564
625
 
565
626
  class NettyUIMaskedInput extends UiBase {
@@ -804,7 +865,7 @@ class NettyUICheckboxToggle extends UiBase {
804
865
  useExisting: NettyUICheckboxToggle,
805
866
  multi: true,
806
867
  },
807
- ], usesInheritance: true, ngImport: i0, template: "<div class=\"nty-checkbox-frame\">\n @if (type() === 'checkbox') {\n\n <mat-checkbox #inputModel=\"ngModel\" [ngModel]=\"checked()\" (ngModelChange)=\"onValueChange($event)\"\n [disabled]=\"disabled()\" [labelPosition]=\"labelPosition()\" [class.circle]=\"shape() === 'circle'\"\n [class.rectangle]=\"shape() === 'rectangle'\">\n {{ label() }}\n </mat-checkbox>\n } @else {\n <mat-slide-toggle #inputModel=\"ngModel\" [ngModel]=\"checked()\" (ngModelChange)=\"onValueChange($event)\"\n [disabled]=\"disabled()\" class=\"slide-toggle\">\n {{ label() }}\n </mat-slide-toggle>\n }\n\n <!-- Error message display using UiBase's getErrorMessage() -->\n @if (ngModel?.invalid && (ngModel?.dirty || ngModel?.touched)) {\n <div class=\"error-message\">{{ getErrorMessage() }}</div>\n }\n</div>", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.nty-checkbox-frame{display:flex;align-items:center;box-sizing:border-box;align-content:center;height:3.5rem;min-height:3.3rem;margin-bottom:.5rem}.nty-checkbox-frame .mat-mdc-checkbox{border:1px solid var(--mat-sys-outline);border-radius:4px}::ng-deep .nty-checkbox-frame mat-checkbox{width:100%}::ng-deep .nty-checkbox-frame .mdc-label,::ng-deep .nty-checkbox-frame .mdc-form-field{flex:1;min-width:0;overflow-x:auto!important;overflow-y:hidden!important;white-space:nowrap!important}::ng-deep .nty-checkbox-frame .mat-mdc-checkbox{display:flex;flex:1}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i2$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
868
+ ], usesInheritance: true, ngImport: i0, template: "<div class=\"nty-checkbox-frame\">\n @if (type() === 'checkbox') {\n\n <mat-checkbox #inputModel=\"ngModel\" [ngModel]=\"checked()\" (ngModelChange)=\"onValueChange($event)\"\n [disabled]=\"disabled()\" [labelPosition]=\"labelPosition()\" [class.circle]=\"shape() === 'circle'\"\n [class.rectangle]=\"shape() === 'rectangle'\">\n {{ label() }}\n </mat-checkbox>\n } @else {\n <mat-slide-toggle #inputModel=\"ngModel\" [ngModel]=\"checked()\" (ngModelChange)=\"onValueChange($event)\"\n [disabled]=\"disabled()\" class=\"slide-toggle\">\n {{ label() }}\n </mat-slide-toggle>\n }\n\n @if (ngModel?.invalid && (ngModel?.dirty || ngModel?.touched)) {\n <div class=\"error-message\">{{ getErrorMessage() }}</div>\n }\n</div>", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.nty-checkbox-frame{display:flex;align-items:center;box-sizing:border-box;align-content:center;height:3.5rem;min-height:3.3rem;margin-bottom:.5rem}.nty-checkbox-frame .mat-mdc-checkbox{border:1px solid var(--mat-sys-outline);border-radius:4px}::ng-deep .nty-checkbox-frame mat-checkbox{width:100%}::ng-deep .nty-checkbox-frame .mdc-label,::ng-deep .nty-checkbox-frame .mdc-form-field{flex:1;min-width:0;overflow-x:auto!important;overflow-y:hidden!important;white-space:nowrap!important}::ng-deep .nty-checkbox-frame .mat-mdc-checkbox{display:flex;flex:1}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i2$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
808
869
  }
809
870
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyUICheckboxToggle, decorators: [{
810
871
  type: Component,
@@ -814,7 +875,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
814
875
  useExisting: NettyUICheckboxToggle,
815
876
  multi: true,
816
877
  },
817
- ], host: { 'ntyui-id': 'NettyUICheckboxToggle' }, template: "<div class=\"nty-checkbox-frame\">\n @if (type() === 'checkbox') {\n\n <mat-checkbox #inputModel=\"ngModel\" [ngModel]=\"checked()\" (ngModelChange)=\"onValueChange($event)\"\n [disabled]=\"disabled()\" [labelPosition]=\"labelPosition()\" [class.circle]=\"shape() === 'circle'\"\n [class.rectangle]=\"shape() === 'rectangle'\">\n {{ label() }}\n </mat-checkbox>\n } @else {\n <mat-slide-toggle #inputModel=\"ngModel\" [ngModel]=\"checked()\" (ngModelChange)=\"onValueChange($event)\"\n [disabled]=\"disabled()\" class=\"slide-toggle\">\n {{ label() }}\n </mat-slide-toggle>\n }\n\n <!-- Error message display using UiBase's getErrorMessage() -->\n @if (ngModel?.invalid && (ngModel?.dirty || ngModel?.touched)) {\n <div class=\"error-message\">{{ getErrorMessage() }}</div>\n }\n</div>", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.nty-checkbox-frame{display:flex;align-items:center;box-sizing:border-box;align-content:center;height:3.5rem;min-height:3.3rem;margin-bottom:.5rem}.nty-checkbox-frame .mat-mdc-checkbox{border:1px solid var(--mat-sys-outline);border-radius:4px}::ng-deep .nty-checkbox-frame mat-checkbox{width:100%}::ng-deep .nty-checkbox-frame .mdc-label,::ng-deep .nty-checkbox-frame .mdc-form-field{flex:1;min-width:0;overflow-x:auto!important;overflow-y:hidden!important;white-space:nowrap!important}::ng-deep .nty-checkbox-frame .mat-mdc-checkbox{display:flex;flex:1}\n"] }]
878
+ ], host: { 'ntyui-id': 'NettyUICheckboxToggle' }, template: "<div class=\"nty-checkbox-frame\">\n @if (type() === 'checkbox') {\n\n <mat-checkbox #inputModel=\"ngModel\" [ngModel]=\"checked()\" (ngModelChange)=\"onValueChange($event)\"\n [disabled]=\"disabled()\" [labelPosition]=\"labelPosition()\" [class.circle]=\"shape() === 'circle'\"\n [class.rectangle]=\"shape() === 'rectangle'\">\n {{ label() }}\n </mat-checkbox>\n } @else {\n <mat-slide-toggle #inputModel=\"ngModel\" [ngModel]=\"checked()\" (ngModelChange)=\"onValueChange($event)\"\n [disabled]=\"disabled()\" class=\"slide-toggle\">\n {{ label() }}\n </mat-slide-toggle>\n }\n\n @if (ngModel?.invalid && (ngModel?.dirty || ngModel?.touched)) {\n <div class=\"error-message\">{{ getErrorMessage() }}</div>\n }\n</div>", styles: [".example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.nty-checkbox-frame{display:flex;align-items:center;box-sizing:border-box;align-content:center;height:3.5rem;min-height:3.3rem;margin-bottom:.5rem}.nty-checkbox-frame .mat-mdc-checkbox{border:1px solid var(--mat-sys-outline);border-radius:4px}::ng-deep .nty-checkbox-frame mat-checkbox{width:100%}::ng-deep .nty-checkbox-frame .mdc-label,::ng-deep .nty-checkbox-frame .mdc-form-field{flex:1;min-width:0;overflow-x:auto!important;overflow-y:hidden!important;white-space:nowrap!important}::ng-deep .nty-checkbox-frame .mat-mdc-checkbox{display:flex;flex:1}\n"] }]
818
879
  }], ctorParameters: () => [], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }] } });
819
880
 
820
881
  class NettyUIButton extends UiBase {
@@ -865,7 +926,7 @@ class NettyUIButton extends UiBase {
865
926
  this.timerSub?.unsubscribe();
866
927
  }
867
928
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyUIButton, deps: null, target: i0.ɵɵFactoryTarget.Component });
868
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: NettyUIButton, isStandalone: true, selector: "ntyui-button", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, isFilled: { classPropertyName: "isFilled", publicName: "isFilled", isSignal: true, isRequired: false, transformFunction: null }, menuReference: { classPropertyName: "menuReference", publicName: "menuReference", isSignal: true, isRequired: false, transformFunction: null }, disableOnClick: { classPropertyName: "disableOnClick", publicName: "disableOnClick", isSignal: true, isRequired: false, transformFunction: null }, disableDuration: { classPropertyName: "disableDuration", publicName: "disableDuration", isSignal: true, isRequired: false, transformFunction: null }, waitingText: { classPropertyName: "waitingText", publicName: "waitingText", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, toolTip: { classPropertyName: "toolTip", publicName: "toolTip", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, host: { attributes: { "ntyui-id": "NettyUIButton" } }, usesInheritance: true, ngImport: i0, template: "@switch (type()) { @case ('menu') {\n<button\n type=\"button\"\n mat-button\n [matTooltip]=\"toolTip()\"\n [class]=\"getDisplayText().length > 0 ? 'ui-menu-button-text' : 'ui-menu-button'\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matMenuTriggerFor]=\"menuReference()\"\n>\n @if (icon() && countdown() === 0) {\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> }\n <span>{{ getDisplayText() }}</span>\n @if (menuReference() && !(countdown() > 0)){\n <mat-icon class=\"menu-icon\">arrow_drop_down</mat-icon>\n }\n</button>\n} @case ('close') {\n<div class=\"flex-container\">\n <button\n mat-stroked-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"ui-close-button\"\n >\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } @else\n {<mat-icon> close </mat-icon>} {{ getDisplayText() }}\n </button>\n</div>\n} @default { @if(isFilled()){\n<button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"regular-button\"\n matButton=\"filled\"\n>\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } {{\n getDisplayText() }}\n</button>\n} @else {\n<button\n mat-stroked-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"regular-button\"\n>\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } {{\n getDisplayText() }}\n</button>\n} } }\n", styles: ["@charset \"UTF-8\";.example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.flex-container{display:flex;justify-content:flex-end;align-items:center;width:100%;height:0}.ui-menu-button{flex-direction:row-reverse;width:25px;min-width:25px;padding:0;margin:0;height:40px}.ui-menu-button mat-icon{font-size:20px;width:20px;height:20px;margin:0;padding:0}ui-menu-button-text{flex-direction:row-reverse;max-width:75px;min-width:25px;flex-grow:1;padding:0;margin:0;height:40px}ui-menu-button-text mat-icon{font-size:20px;width:20px;height:20px;margin:0;padding:0}.ui-menu-button:hover{background-color:var(--mat-sys-primary);color:var(--mat-sys-surface);border-radius:5px;height:30px}.ui-menu-button .menu-icon{margin-left:15px}.ui-close-button{margin-left:auto;margin-bottom:40px;width:30px;min-width:20px;padding:5px;height:25px;border-radius:5px;background-color:var(--mat-sys-secondary)}.ui-close-button mat-icon{color:var(--mat-sys-on-secondary);font-size:20px;margin:0;padding-right:1px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
929
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: NettyUIButton, isStandalone: true, selector: "ntyui-button", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, isFilled: { classPropertyName: "isFilled", publicName: "isFilled", isSignal: true, isRequired: false, transformFunction: null }, menuReference: { classPropertyName: "menuReference", publicName: "menuReference", isSignal: true, isRequired: false, transformFunction: null }, disableOnClick: { classPropertyName: "disableOnClick", publicName: "disableOnClick", isSignal: true, isRequired: false, transformFunction: null }, disableDuration: { classPropertyName: "disableDuration", publicName: "disableDuration", isSignal: true, isRequired: false, transformFunction: null }, waitingText: { classPropertyName: "waitingText", publicName: "waitingText", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, toolTip: { classPropertyName: "toolTip", publicName: "toolTip", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, host: { attributes: { "ntyui-id": "NettyUIButton" } }, usesInheritance: true, ngImport: i0, template: "@switch (type()) { @case ('menu') {\n<button\n type=\"button\"\n mat-button\n [matTooltip]=\"toolTip()\"\n [class]=\"getDisplayText().length > 0 ? 'ui-menu-button-text' : 'ui-menu-button'\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matMenuTriggerFor]=\"menuReference()\"\n>\n @if (icon() && countdown() === 0) {\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> }\n <span>{{ getDisplayText() }}</span>\n @if (menuReference() && !(countdown() > 0)){\n <mat-icon class=\"menu-icon\">arrow_drop_down</mat-icon>\n }\n</button>\n} @case ('close') {\n<div class=\"flex-container\">\n <button\n mat-stroked-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"ui-close-button\"\n >\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } @else\n {<mat-icon> close </mat-icon>} {{ getDisplayText() }}\n </button>\n</div>\n} @default { @if(isFilled()){\n<button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"regular-button\"\n matButton=\"filled\"\n>\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } {{\n getDisplayText() }}\n</button>\n} @else {\n<button\n mat-stroked-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"regular-button\"\n>\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } {{\n getDisplayText() }}\n</button>\n} } }\n", styles: ["@charset \"UTF-8\";.example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.flex-container{display:flex;justify-content:flex-end;align-items:center;width:100%;height:0}.ui-menu-button{flex-direction:row-reverse;width:25px;min-width:25px;padding:0;margin:0;height:40px}.ui-menu-button mat-icon{font-size:20px;width:20px;height:20px;margin:0;padding:0}.ui-menu-button-text{flex-direction:row-reverse;max-width:75px;min-width:25px;flex-grow:1;padding:0;margin:0 15px 0 0;height:20px;min-width:fit-content}.ui-menu-button-text mat-icon{font-size:20px;width:20px;height:20px;margin:0;padding:0}.ui-menu-button:hover{background-color:var(--mat-sys-primary);color:var(--mat-sys-surface);border-radius:5px;height:30px}.ui-menu-button .menu-icon{margin-left:15px}.ui-close-button{margin-left:auto;margin-bottom:40px;width:30px;min-width:20px;padding:5px;height:25px;border-radius:5px;background-color:var(--mat-sys-secondary)}.ui-close-button mat-icon{color:var(--mat-sys-on-secondary);font-size:20px;margin:0;padding-right:1px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
869
930
  }
870
931
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyUIButton, decorators: [{
871
932
  type: Component,
@@ -874,7 +935,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
874
935
  MatTooltipModule,
875
936
  MatIconModule,
876
937
  MatMenuModule
877
- ], host: { 'ntyui-id': 'NettyUIButton' }, template: "@switch (type()) { @case ('menu') {\n<button\n type=\"button\"\n mat-button\n [matTooltip]=\"toolTip()\"\n [class]=\"getDisplayText().length > 0 ? 'ui-menu-button-text' : 'ui-menu-button'\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matMenuTriggerFor]=\"menuReference()\"\n>\n @if (icon() && countdown() === 0) {\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> }\n <span>{{ getDisplayText() }}</span>\n @if (menuReference() && !(countdown() > 0)){\n <mat-icon class=\"menu-icon\">arrow_drop_down</mat-icon>\n }\n</button>\n} @case ('close') {\n<div class=\"flex-container\">\n <button\n mat-stroked-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"ui-close-button\"\n >\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } @else\n {<mat-icon> close </mat-icon>} {{ getDisplayText() }}\n </button>\n</div>\n} @default { @if(isFilled()){\n<button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"regular-button\"\n matButton=\"filled\"\n>\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } {{\n getDisplayText() }}\n</button>\n} @else {\n<button\n mat-stroked-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"regular-button\"\n>\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } {{\n getDisplayText() }}\n</button>\n} } }\n", styles: ["@charset \"UTF-8\";.example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.flex-container{display:flex;justify-content:flex-end;align-items:center;width:100%;height:0}.ui-menu-button{flex-direction:row-reverse;width:25px;min-width:25px;padding:0;margin:0;height:40px}.ui-menu-button mat-icon{font-size:20px;width:20px;height:20px;margin:0;padding:0}ui-menu-button-text{flex-direction:row-reverse;max-width:75px;min-width:25px;flex-grow:1;padding:0;margin:0;height:40px}ui-menu-button-text mat-icon{font-size:20px;width:20px;height:20px;margin:0;padding:0}.ui-menu-button:hover{background-color:var(--mat-sys-primary);color:var(--mat-sys-surface);border-radius:5px;height:30px}.ui-menu-button .menu-icon{margin-left:15px}.ui-close-button{margin-left:auto;margin-bottom:40px;width:30px;min-width:20px;padding:5px;height:25px;border-radius:5px;background-color:var(--mat-sys-secondary)}.ui-close-button mat-icon{color:var(--mat-sys-on-secondary);font-size:20px;margin:0;padding-right:1px}\n"] }]
938
+ ], host: { 'ntyui-id': 'NettyUIButton' }, template: "@switch (type()) { @case ('menu') {\n<button\n type=\"button\"\n mat-button\n [matTooltip]=\"toolTip()\"\n [class]=\"getDisplayText().length > 0 ? 'ui-menu-button-text' : 'ui-menu-button'\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matMenuTriggerFor]=\"menuReference()\"\n>\n @if (icon() && countdown() === 0) {\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> }\n <span>{{ getDisplayText() }}</span>\n @if (menuReference() && !(countdown() > 0)){\n <mat-icon class=\"menu-icon\">arrow_drop_down</mat-icon>\n }\n</button>\n} @case ('close') {\n<div class=\"flex-container\">\n <button\n mat-stroked-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"ui-close-button\"\n >\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } @else\n {<mat-icon> close </mat-icon>} {{ getDisplayText() }}\n </button>\n</div>\n} @default { @if(isFilled()){\n<button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"regular-button\"\n matButton=\"filled\"\n>\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } {{\n getDisplayText() }}\n</button>\n} @else {\n<button\n mat-stroked-button\n color=\"primary\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClicked()\"\n [matTooltip]=\"toolTip()\"\n class=\"regular-button\"\n>\n @if(icon()){\n <mat-icon class=\"material-symbols-outlined\">{{ icon() }}</mat-icon> } {{\n getDisplayText() }}\n</button>\n} } }\n", styles: ["@charset \"UTF-8\";.example-full-width{width:100%;max-width:500px}.mat-mdc-form-field-subscript-wrapper{width:auto;height:0}.clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}.search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}.search-icon:hover,.clear-btn:hover{color:var(--mat-sys-primary)}.required-field{background-color:var(--mat-sys-required)}.required-with-value{background-color:transparent!important}::ng-deep .circle .mdc-checkbox__background{border-radius:50%!important}::ng-deep .circle .mdc-checkbox__background:before{border-radius:50%!important}.flex-container{display:flex;justify-content:flex-end;align-items:center;width:100%;height:0}.ui-menu-button{flex-direction:row-reverse;width:25px;min-width:25px;padding:0;margin:0;height:40px}.ui-menu-button mat-icon{font-size:20px;width:20px;height:20px;margin:0;padding:0}.ui-menu-button-text{flex-direction:row-reverse;max-width:75px;min-width:25px;flex-grow:1;padding:0;margin:0 15px 0 0;height:20px;min-width:fit-content}.ui-menu-button-text mat-icon{font-size:20px;width:20px;height:20px;margin:0;padding:0}.ui-menu-button:hover{background-color:var(--mat-sys-primary);color:var(--mat-sys-surface);border-radius:5px;height:30px}.ui-menu-button .menu-icon{margin-left:15px}.ui-close-button{margin-left:auto;margin-bottom:40px;width:30px;min-width:20px;padding:5px;height:25px;border-radius:5px;background-color:var(--mat-sys-secondary)}.ui-close-button mat-icon{color:var(--mat-sys-on-secondary);font-size:20px;margin:0;padding-right:1px}\n"] }]
878
939
  }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], isFilled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isFilled", required: false }] }], menuReference: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuReference", required: false }] }], disableOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableOnClick", required: false }] }], disableDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableDuration", required: false }] }], waitingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "waitingText", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], toolTip: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolTip", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
879
940
 
880
941
  class NettyUIFilterButton extends UiBase {
@@ -1580,6 +1641,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
1580
1641
  ], host: { 'ntyui-id': 'NettyUIColorPicker' }, template: "<mat-form-field appearance=\"outline\" class=\"color-picker-input-container\">\n <span\n matPrefix\n class=\"color-preview\"\n [style.background-color]=\"selectedColor()\"\n (click)=\"togglePicker()\"\n ></span>\n\n <input\n matInput\n [ngModel]=\"selectedColor()\"\n (ngModelChange)=\"onInputChange($event)\"\n placeholder=\"Renk Kodu (\u00F6rn: #FFFFFF)\"\n />\n\n <mat-icon matSuffix (click)=\"togglePicker()\">search</mat-icon>\n</mat-form-field>\n\n<input\n type=\"color\"\n class=\"hidden-color-input\"\n #colorInput\n [value]=\"selectedColor()\"\n (change)=\"onColorPickerChange($event)\"\n/>\n\n<!-- Custom color picker pop-up -->\n@if (isPickerVisible()) {\n<div class=\"custom-color-picker-overlay\" (click)=\"closePicker()\">\n <div class=\"custom-color-picker\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"picker-header\">\n <h3>{{'@choose_Color' | translate}}</h3>\n <button class=\"close-btn\" (click)=\"closePicker()\" type=\"button\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"picker-content\">\n <!-- Custom color picker -->\n <div class=\"color-input-section\">\n <label class=\"section-label\"\n >{{'@choose_Custom_Color' | translate}}</label\n >\n <input\n type=\"color\"\n [value]=\"selectedColor()\"\n (change)=\"onCustomColorChange($event)\"\n class=\"native-color-input\"\n />\n <span class=\"current-color\"\n >{{'@available' | translate}}: {{ selectedColor() }}</span\n >\n </div>\n\n <!-- Custom colors -->\n @if (hasCustomColors()) {\n <div class=\"color-presets-section\">\n <label class=\"section-label\">{{'@defined_Colors' | translate}}</label>\n <div class=\"color-presets-grid\">\n @for (color of customColorPresets(); track color) {\n <div\n class=\"color-preset\"\n [style.background-color]=\"color\"\n (click)=\"selectColor(color)\"\n [class.selected]=\"color === selectedColor()\"\n [title]=\"color\"\n >\n @if (color === selectedColor()) {\n <mat-icon class=\"check-icon\">check</mat-icon>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Standard colors -->\n <div class=\"color-presets-section\">\n <label class=\"section-label\">\n {{ hasCustomColors() ? ('@standard_Colors' | translate) :\n ('@color_Palette' | translate) }}\n </label>\n <div class=\"color-presets-grid\">\n @for (color of defaultColorPresets(); track color) {\n <div\n class=\"color-preset\"\n [style.background-color]=\"color\"\n (click)=\"selectColor(color)\"\n [class.selected]=\"color === selectedColor()\"\n [title]=\"color\"\n >\n @if (color === selectedColor()) {\n <mat-icon class=\"check-icon\">check</mat-icon>\n }\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".color-picker-input-container{width:100%;max-width:280px}.color-preview{display:inline-block;width:20px;height:20px;margin-left:16px;border-radius:50%;border:2px solid #e0e0e0;cursor:pointer;margin-right:8px;transition:all .2s ease}.color-preview:hover{border-color:#999;transform:scale(1.1)}.hidden-color-input{display:none}.custom-color-picker-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000;animation:fadeIn .2s ease}.custom-color-picker{background:#fff;border-radius:12px;box-shadow:0 8px 32px #0003;width:min(90vw,340px);max-height:min(80vh,600px);overflow:hidden;animation:slideUp .2s ease}.picker-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid #e0e0e0;background:#fff}.picker-header h3{margin:0;font-size:16px;font-weight:600;color:#333}.picker-header .close-btn{background:none;border:none;cursor:pointer;color:#666;display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%}.picker-header .close-btn:hover{background-color:#f5f5f5;color:#333}.picker-header .close-btn mat-icon{font-size:20px;width:20px;height:20px}.picker-content{padding:20px;display:flex;flex-direction:column;gap:24px}.color-input-section{display:flex;flex-direction:column;gap:12px}.color-input-section .section-label{font-weight:600;color:#333;font-size:14px}.color-input-section .native-color-input{width:100%;height:48px;cursor:pointer;border:2px solid #e0e0e0;border-radius:8px}.color-input-section .native-color-input:hover{border-color:#ccc}.color-input-section .current-color{font-size:12px;color:#666;text-align:center}.color-presets-section .section-label{display:block;font-weight:600;color:#333;font-size:14px;margin-bottom:12px}.color-presets-section .color-presets-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:8px}.color-presets-section .color-presets-grid .color-preset{position:relative;width:100%;aspect-ratio:1;border-radius:8px;cursor:pointer;border:2px solid #e0e0e0;transition:all .2s ease}.color-presets-section .color-presets-grid .color-preset:hover{transform:scale(1.1);border-color:#999;box-shadow:0 4px 12px #00000026}.color-presets-section .color-presets-grid .color-preset.selected{border-color:#333;transform:scale(1.05)}.color-presets-section .color-presets-grid .color-preset .check-icon{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff;font-size:16px;width:16px;height:16px;filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] }]
1581
1642
  }], propDecorators: { selectedColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedColor", required: false }] }, { type: i0.Output, args: ["selectedColorChange"] }], customColorPresets: [{ type: i0.Input, args: [{ isSignal: true, alias: "customColorPresets", required: false }] }], colorChange: [{ type: i0.Output, args: ["colorChange"] }], colorInput: [{ type: i0.ViewChild, args: ['colorInput', { isSignal: true }] }] } });
1582
1643
 
1644
+ class NettyuUIDateTimeRange extends UiBase {
1645
+ endValue = model(null, ...(ngDevMode ? [{ debugName: "endValue" }] : []));
1646
+ endLabel = input('', ...(ngDevMode ? [{ debugName: "endLabel" }] : []));
1647
+ constructor() {
1648
+ super();
1649
+ effect(() => {
1650
+ this.onChange({
1651
+ start: this.value(),
1652
+ end: this.endValue()
1653
+ });
1654
+ });
1655
+ }
1656
+ writeValue(val) {
1657
+ if (val && typeof val === 'object') {
1658
+ this.value.set(val.start || null);
1659
+ this.endValue.set(val.end || null);
1660
+ }
1661
+ else {
1662
+ this.value.set('');
1663
+ this.endValue.set(null);
1664
+ }
1665
+ }
1666
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyuUIDateTimeRange, deps: [], target: i0.ɵɵFactoryTarget.Component });
1667
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: NettyuUIDateTimeRange, isStandalone: true, selector: "ntyui-date-time-range", inputs: { endValue: { classPropertyName: "endValue", publicName: "endValue", isSignal: true, isRequired: false, transformFunction: null }, endLabel: { classPropertyName: "endLabel", publicName: "endLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { endValue: "endValueChange" }, providers: [
1668
+ {
1669
+ provide: NG_VALUE_ACCESSOR,
1670
+ useExisting: NettyuUIDateTimeRange,
1671
+ multi: true,
1672
+ },
1673
+ ], usesInheritance: true, ngImport: i0, template: "<div class=\"datetime-range-wrapper\">\n <div class=\"range-field\">\n <ntyui-date-time\n [label]=\"label()\"\n [appearance]=\"appearance()\"\n [required]=\"required()\"\n [forFilter]=\"forFilter()\"\n [disabled]=\"disabled()\"\n [(ngModel)]=\"value\"\n ></ntyui-date-time>\n </div>\n\n <div class=\"range-separator\">\n <span class=\"dash\">\u2014</span>\n </div>\n\n <div class=\"range-field\">\n <ntyui-date-time\n [label]=\"endLabel() || label()\"\n [appearance]=\"appearance()\"\n [required]=\"required()\"\n [forFilter]=\"forFilter()\"\n [disabled]=\"disabled()\"\n [(ngModel)]=\"endValue\"\n ></ntyui-date-time>\n </div>\n</div>", styles: [".datetime-range-wrapper{display:flex;flex-direction:row;align-items:flex-start;gap:12px;width:100%}.datetime-range-wrapper .range-field{flex:1;min-width:0}.datetime-range-wrapper .range-separator{display:flex;align-items:center;height:56px;color:#00000061;font-weight:700}@media(max-width:768px){.datetime-range-wrapper{flex-direction:column;gap:0}.datetime-range-wrapper .range-separator{display:none}}\n"], dependencies: [{ kind: "component", type: NettyUIDateTime, selector: "ntyui-date-time", inputs: ["dateTimeValue", "timeLabel", "dateRestriction", "timeFormat"], outputs: ["dateTimeValueChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
1674
+ }
1675
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyuUIDateTimeRange, decorators: [{
1676
+ type: Component,
1677
+ args: [{ selector: 'ntyui-date-time-range', imports: [NettyUIDateTime, FormsModule], providers: [
1678
+ {
1679
+ provide: NG_VALUE_ACCESSOR,
1680
+ useExisting: NettyuUIDateTimeRange,
1681
+ multi: true,
1682
+ },
1683
+ ], template: "<div class=\"datetime-range-wrapper\">\n <div class=\"range-field\">\n <ntyui-date-time\n [label]=\"label()\"\n [appearance]=\"appearance()\"\n [required]=\"required()\"\n [forFilter]=\"forFilter()\"\n [disabled]=\"disabled()\"\n [(ngModel)]=\"value\"\n ></ntyui-date-time>\n </div>\n\n <div class=\"range-separator\">\n <span class=\"dash\">\u2014</span>\n </div>\n\n <div class=\"range-field\">\n <ntyui-date-time\n [label]=\"endLabel() || label()\"\n [appearance]=\"appearance()\"\n [required]=\"required()\"\n [forFilter]=\"forFilter()\"\n [disabled]=\"disabled()\"\n [(ngModel)]=\"endValue\"\n ></ntyui-date-time>\n </div>\n</div>", styles: [".datetime-range-wrapper{display:flex;flex-direction:row;align-items:flex-start;gap:12px;width:100%}.datetime-range-wrapper .range-field{flex:1;min-width:0}.datetime-range-wrapper .range-separator{display:flex;align-items:center;height:56px;color:#00000061;font-weight:700}@media(max-width:768px){.datetime-range-wrapper{flex-direction:column;gap:0}.datetime-range-wrapper .range-separator{display:none}}\n"] }]
1684
+ }], ctorParameters: () => [], propDecorators: { endValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "endValue", required: false }] }, { type: i0.Output, args: ["endValueChange"] }], endLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "endLabel", required: false }] }] } });
1685
+
1583
1686
  class NettyEnumValues {
1584
1687
  languageCode = '';
1585
1688
  enumName = '';
@@ -1630,5 +1733,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
1630
1733
  * Generated bundle index. Do not edit.
1631
1734
  */
1632
1735
 
1633
- export { NettyEnumStorageProxy, NettyEnumValues, NettyUIButton, NettyUICarousel, NettyUICheckboxToggle, NettyUIColorPicker, NettyUIDatePicker, NettyUIDateTime, NettyUIEmailInput, NettyUIFilterButton, NettyUIMaskedInput, NettyUINumberInput, NettyUISearchInput, NettyUISelect, NettyUITextInput, NettyUITimePicker, NettyUITree, NettyUIVisibleSwitchButton, Ntyui, NtyuiModule, UiBase };
1736
+ export { NettyEnumStorageProxy, NettyEnumValues, NettyUIButton, NettyUICarousel, NettyUICheckboxToggle, NettyUIColorPicker, NettyUIDatePicker, NettyUIDateTime, NettyUIEmailInput, NettyUIFilterButton, NettyUIMaskedInput, NettyUINumberInput, NettyUISearchInput, NettyUISelect, NettyUITextInput, NettyUITimePicker, NettyUITree, NettyUIVisibleSwitchButton, NettyuUIDateTimeRange, Ntyui, NtyuiModule, UiBase };
1634
1737
  //# sourceMappingURL=nettyapps-ntyui.mjs.map