angular-tailwind-components 1.7.1 → 1.8.1

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, Directive, signal, inject, NgZone, ElementRef, viewChild, computed, ChangeDetectionStrategy, Component, ViewContainerRef, HostListener, TemplateRef, InjectionToken, Renderer2, ApplicationRef, EnvironmentInjector, Injector, DestroyRef, afterNextRender, createComponent, output, model, forwardRef, viewChildren, effect, contentChildren, contentChild, Injectable, booleanAttribute, makeEnvironmentProviders, provideAppInitializer, PLATFORM_ID } from '@angular/core';
2
+ import { input, Directive, signal, inject, NgZone, ElementRef, viewChild, computed, ChangeDetectionStrategy, Component, ViewContainerRef, HostListener, TemplateRef, InjectionToken, Renderer2, ApplicationRef, EnvironmentInjector, Injector, DestroyRef, afterNextRender, createComponent, output, model, forwardRef, viewChildren, ChangeDetectorRef, effect, contentChild, contentChildren, Injectable, booleanAttribute, makeEnvironmentProviders, provideAppInitializer, PLATFORM_ID } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { DOCUMENT, NgClass, NgTemplateOutlet, formatDate, CommonModule, isPlatformBrowser } from '@angular/common';
5
5
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
@@ -668,6 +668,7 @@ class TailwindSortHeaderDirective {
668
668
  sortKey = input.required(...(ngDevMode ? [{ debugName: "sortKey" }] : /* istanbul ignore next */ []));
669
669
  host = inject((ElementRef));
670
670
  renderer = inject(Renderer2);
671
+ labelWrapper;
671
672
  appRef = inject(ApplicationRef);
672
673
  environmentInjector = inject(EnvironmentInjector);
673
674
  injector = inject(Injector);
@@ -718,11 +719,12 @@ class TailwindSortHeaderDirective {
718
719
  this.iconRef.changeDetectorRef.detectChanges();
719
720
  };
720
721
  if (!this.iconRef) {
722
+ const labelHost = this.ensureLabelWrapper();
721
723
  this.iconRef = createComponent(TailwindIcon, {
722
724
  environmentInjector: this.environmentInjector,
723
725
  elementInjector: this.injector
724
726
  });
725
- this.renderer.appendChild(this.host.nativeElement, this.iconRef.location.nativeElement);
727
+ this.renderer.appendChild(labelHost, this.iconRef.location.nativeElement);
726
728
  this.appRef.attachView(this.iconRef.hostView);
727
729
  }
728
730
  sync();
@@ -732,8 +734,31 @@ class TailwindSortHeaderDirective {
732
734
  attributeFilter: [TW_TABLE_SORT_KEY_ATTR, TW_TABLE_SORT_DIR_ATTR]
733
735
  });
734
736
  }
737
+ /** Keep `th` as `display: table-cell`; flex only on an inner wrapper (label + icon). */
738
+ ensureLabelWrapper() {
739
+ if (this.labelWrapper)
740
+ return this.labelWrapper;
741
+ const th = this.host.nativeElement;
742
+ const existing = th.querySelector('[data-tw-sort-header-label]');
743
+ if (existing instanceof HTMLElement) {
744
+ this.labelWrapper = existing;
745
+ return existing;
746
+ }
747
+ const wrapper = this.renderer.createElement('span');
748
+ this.renderer.setAttribute(wrapper, 'data-tw-sort-header-label', '');
749
+ this.renderer.addClass(wrapper, 'inline-flex');
750
+ this.renderer.addClass(wrapper, 'items-center');
751
+ this.renderer.addClass(wrapper, 'gap-1.5');
752
+ this.renderer.addClass(wrapper, 'justify-start');
753
+ for (const child of Array.from(th.childNodes)) {
754
+ this.renderer.appendChild(wrapper, child);
755
+ }
756
+ this.renderer.appendChild(th, wrapper);
757
+ this.labelWrapper = wrapper;
758
+ return wrapper;
759
+ }
735
760
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindSortHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
736
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.12", type: TailwindSortHeaderDirective, isStandalone: true, selector: "[tailwindSortHeader]", inputs: { sortKey: { classPropertyName: "sortKey", publicName: "sortKey", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.tabindex": "0", "attr.data-sort-key": "sortKey()" }, classAttribute: "flex cursor-pointer items-center gap-1.5 justify-start whitespace-nowrap text-left select-none hover:text-neutral-900" }, ngImport: i0 });
761
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.12", type: TailwindSortHeaderDirective, isStandalone: true, selector: "[tailwindSortHeader]", inputs: { sortKey: { classPropertyName: "sortKey", publicName: "sortKey", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.tabindex": "0", "attr.data-sort-key": "sortKey()" }, classAttribute: "cursor-pointer whitespace-nowrap text-left select-none hover:text-neutral-900" }, ngImport: i0 });
737
762
  }
738
763
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindSortHeaderDirective, decorators: [{
739
764
  type: Directive,
@@ -741,7 +766,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
741
766
  selector: '[tailwindSortHeader]',
742
767
  standalone: true,
743
768
  host: {
744
- class: 'flex cursor-pointer items-center gap-1.5 justify-start whitespace-nowrap text-left select-none hover:text-neutral-900',
769
+ class: 'cursor-pointer whitespace-nowrap text-left select-none hover:text-neutral-900',
745
770
  '[attr.tabindex]': '0',
746
771
  '[attr.data-sort-key]': 'sortKey()'
747
772
  }
@@ -755,12 +780,14 @@ const iconPixelSizeMap = {
755
780
  lg: 20,
756
781
  xl: 22
757
782
  };
783
+ /** Always transparent background; no tint on hover, focus, or active. */
784
+ const transparentColorClasses = 'bg-transparent hover:bg-transparent active:bg-transparent focus:bg-transparent border-transparent shadow-none text-neutral-500 focus-visible:outline-neutral-400';
758
785
  class TailwindButton extends TailwindComponent {
759
786
  defaultKind = inject(TAILWIND_BUTTON_KIND, { optional: true });
760
787
  /** Visual color */
761
788
  color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
762
789
  /**
763
- * Visual kind: `flat` = filled like `solid` without border or shadow;
790
+ * Visual kind: `flat` = filled like `solid` without border, shadow, or hover/active background change;
764
791
  * `ghost` = transparent with hover tint; `text` = text color only, no hover background.
765
792
  * Default from {@link TAILWIND_BUTTON_KIND} or `'solid'`.
766
793
  */
@@ -777,6 +804,8 @@ class TailwindButton extends TailwindComponent {
777
804
  icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : /* istanbul ignore next */ []));
778
805
  /** Icon placement when both icon and label are shown */
779
806
  iconPosition = input('left', ...(ngDevMode ? [{ debugName: "iconPosition" }] : /* istanbul ignore next */ []));
807
+ /** Accessible name for icon-only buttons */
808
+ ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
780
809
  /** Emitted when the button is clicked (not disabled). */
781
810
  onClick = output();
782
811
  iconPixelSize = computed(() => iconPixelSizeMap[this.size()], ...(ngDevMode ? [{ debugName: "iconPixelSize" }] : /* istanbul ignore next */ []));
@@ -797,16 +826,18 @@ class TailwindButton extends TailwindComponent {
797
826
  danger: 'bg-danger-600 text-on-danger-600 hover:bg-danger-700 hover:text-on-danger-700 active:bg-danger-800 active:text-on-danger-800 border-transparent focus-visible:outline-danger-600 shadow-sm',
798
827
  success: 'bg-success-600 text-on-success-600 hover:bg-success-700 hover:text-on-success-700 active:bg-success-800 active:text-on-success-800 border-transparent focus-visible:outline-success-600 shadow-sm',
799
828
  warning: 'bg-warning-500 text-on-warning-500 hover:bg-warning-600 hover:text-on-warning-600 active:bg-warning-700 active:text-on-warning-700 border-transparent focus-visible:outline-warning-500 shadow-sm',
800
- info: 'bg-info-600 text-on-info-600 hover:bg-info-700 hover:text-on-info-700 active:bg-info-800 active:text-on-info-800 border-transparent focus-visible:outline-info-600 shadow-sm'
829
+ info: 'bg-info-600 text-on-info-600 hover:bg-info-700 hover:text-on-info-700 active:bg-info-800 active:text-on-info-800 border-transparent focus-visible:outline-info-600 shadow-sm',
830
+ transparent: transparentColorClasses
801
831
  };
802
- /** Filled surface like `solid`, without box shadow or visible border. */
832
+ /** Filled surface like `solid`, without box shadow, border, or hover/active tint. */
803
833
  const flatMap = {
804
- primary: 'bg-primary-600 text-on-primary-600 hover:bg-primary-700 hover:text-on-primary-700 active:bg-primary-800 active:text-on-primary-800 border-0 shadow-none focus-visible:outline-primary-600',
805
- secondary: 'bg-neutral-100 text-neutral-800 hover:bg-neutral-200 active:bg-neutral-300 border-0 shadow-none focus-visible:outline-neutral-500',
806
- danger: 'bg-danger-600 text-on-danger-600 hover:bg-danger-700 hover:text-on-danger-700 active:bg-danger-800 active:text-on-danger-800 border-0 shadow-none focus-visible:outline-danger-600',
807
- success: 'bg-success-600 text-on-success-600 hover:bg-success-700 hover:text-on-success-700 active:bg-success-800 active:text-on-success-800 border-0 shadow-none focus-visible:outline-success-600',
808
- warning: 'bg-warning-500 text-on-warning-500 hover:bg-warning-600 hover:text-on-warning-600 active:bg-warning-700 active:text-on-warning-700 border-0 shadow-none focus-visible:outline-warning-500',
809
- info: 'bg-info-600 text-on-info-600 hover:bg-info-700 hover:text-on-info-700 active:bg-info-800 active:text-on-info-800 border-0 shadow-none focus-visible:outline-info-600'
834
+ primary: 'bg-primary-600 text-on-primary-600 border-0 shadow-none focus-visible:outline-primary-600',
835
+ secondary: 'bg-neutral-100 text-neutral-800 border-0 shadow-none focus-visible:outline-neutral-500',
836
+ danger: 'bg-danger-600 text-on-danger-600 border-0 shadow-none focus-visible:outline-danger-600',
837
+ success: 'bg-success-600 text-on-success-600 border-0 shadow-none focus-visible:outline-success-600',
838
+ warning: 'bg-warning-500 text-on-warning-500 border-0 shadow-none focus-visible:outline-warning-500',
839
+ info: 'bg-info-600 text-on-info-600 border-0 shadow-none focus-visible:outline-info-600',
840
+ transparent: transparentColorClasses
810
841
  };
811
842
  const outlinedMap = {
812
843
  primary: 'bg-transparent text-primary-600 border-primary-600 hover:bg-primary-50 active:bg-primary-100 focus-visible:outline-primary-600',
@@ -814,7 +845,8 @@ class TailwindButton extends TailwindComponent {
814
845
  danger: 'bg-transparent text-danger-600 border-danger-600 hover:bg-danger-50 active:bg-danger-100 focus-visible:outline-danger-600',
815
846
  success: 'bg-transparent text-success-600 border-success-600 hover:bg-success-50 active:bg-success-100 focus-visible:outline-success-600',
816
847
  warning: 'bg-transparent text-warning-600 border-warning-500 hover:bg-warning-50 active:bg-warning-100 focus-visible:outline-warning-500',
817
- info: 'bg-transparent text-info-600 border-info-600 hover:bg-info-50 active:bg-info-100 focus-visible:outline-info-600'
848
+ info: 'bg-transparent text-info-600 border-info-600 hover:bg-info-50 active:bg-info-100 focus-visible:outline-info-600',
849
+ transparent: transparentColorClasses
818
850
  };
819
851
  /** Transparent + hover/active background tint (former `text` look). */
820
852
  const ghostMap = {
@@ -823,7 +855,8 @@ class TailwindButton extends TailwindComponent {
823
855
  danger: 'bg-transparent text-danger-600 border-transparent hover:bg-danger-50 active:bg-danger-100 focus-visible:outline-danger-600',
824
856
  success: 'bg-transparent text-success-600 border-transparent hover:bg-success-50 active:bg-success-100 focus-visible:outline-success-600',
825
857
  warning: 'bg-transparent text-warning-600 border-transparent hover:bg-warning-50 active:bg-warning-100 focus-visible:outline-warning-500',
826
- info: 'bg-transparent text-info-600 border-transparent hover:bg-info-50 active:bg-info-100 focus-visible:outline-info-600'
858
+ info: 'bg-transparent text-info-600 border-transparent hover:bg-info-50 active:bg-info-100 focus-visible:outline-info-600',
859
+ transparent: transparentColorClasses
827
860
  };
828
861
  /** Text color from severity only; background stays transparent on hover/active. */
829
862
  const textMap = {
@@ -832,7 +865,8 @@ class TailwindButton extends TailwindComponent {
832
865
  danger: 'bg-transparent text-danger-600 border-transparent focus-visible:outline-danger-600',
833
866
  success: 'bg-transparent text-success-600 border-transparent focus-visible:outline-success-600',
834
867
  warning: 'bg-transparent text-warning-600 border-transparent focus-visible:outline-warning-500',
835
- info: 'bg-transparent text-info-600 border-transparent focus-visible:outline-info-600'
868
+ info: 'bg-transparent text-info-600 border-transparent focus-visible:outline-info-600',
869
+ transparent: transparentColorClasses
836
870
  };
837
871
  const styleMap = {
838
872
  solid: solidMap,
@@ -866,12 +900,12 @@ class TailwindButton extends TailwindComponent {
866
900
  }
867
901
  }
868
902
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindButton, deps: null, target: i0.ɵɵFactoryTarget.Component });
869
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindButton, isStandalone: true, selector: "tailwind-button", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, kind: { classPropertyName: "kind", publicName: "kind", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "iconPosition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick" }, usesInheritance: true, ngImport: i0, template: "<button\n [ngClass]=\"computedClasses()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [attr.role]=\"role()\"\n [attr.aria-disabled]=\"disabled() || null\"\n (click)=\"handleClick($event)\">\n <span class=\"inline-flex min-w-0 items-center justify-center gap-2\">\n @if (icon() && iconPosition() === 'left') {\n <tailwind-icon [icon]=\"icon()!\" [size]=\"iconPixelSize()\" class=\"shrink-0\" />\n }\n <span class=\"tailwind-button-label inline-flex min-w-0 items-center empty:hidden\">\n <ng-content />\n </span>\n @if (icon() && iconPosition() === 'right') {\n <tailwind-icon [icon]=\"icon()!\" [size]=\"iconPixelSize()\" class=\"shrink-0\" />\n }\n </span>\n</button>\n", styles: [":host{display:inline-block}.tailwind-btn-spinner{animation:tailwind-spin 1s linear infinite;width:1em;height:1em}@keyframes tailwind-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
903
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindButton, isStandalone: true, selector: "tailwind-button", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, kind: { classPropertyName: "kind", publicName: "kind", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "iconPosition", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick" }, usesInheritance: true, ngImport: i0, template: "<button\n [ngClass]=\"computedClasses()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [attr.role]=\"role()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-disabled]=\"disabled() || null\"\n (click)=\"handleClick($event)\">\n <span class=\"inline-flex min-w-0 items-center justify-center gap-2\">\n @if (icon() && iconPosition() === 'left') {\n <tailwind-icon [icon]=\"icon()!\" [size]=\"iconPixelSize()\" class=\"shrink-0\" />\n }\n <span class=\"tailwind-button-label inline-flex min-w-0 items-center empty:hidden\">\n <ng-content />\n </span>\n @if (icon() && iconPosition() === 'right') {\n <tailwind-icon [icon]=\"icon()!\" [size]=\"iconPixelSize()\" class=\"shrink-0\" />\n }\n </span>\n</button>\n", styles: [":host{display:inline-block}.tailwind-btn-spinner{animation:tailwind-spin 1s linear infinite;width:1em;height:1em}@keyframes tailwind-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
870
904
  }
871
905
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindButton, decorators: [{
872
906
  type: Component,
873
- args: [{ imports: [NgClass, TailwindIcon], selector: 'tailwind-button', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n [ngClass]=\"computedClasses()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [attr.role]=\"role()\"\n [attr.aria-disabled]=\"disabled() || null\"\n (click)=\"handleClick($event)\">\n <span class=\"inline-flex min-w-0 items-center justify-center gap-2\">\n @if (icon() && iconPosition() === 'left') {\n <tailwind-icon [icon]=\"icon()!\" [size]=\"iconPixelSize()\" class=\"shrink-0\" />\n }\n <span class=\"tailwind-button-label inline-flex min-w-0 items-center empty:hidden\">\n <ng-content />\n </span>\n @if (icon() && iconPosition() === 'right') {\n <tailwind-icon [icon]=\"icon()!\" [size]=\"iconPixelSize()\" class=\"shrink-0\" />\n }\n </span>\n</button>\n", styles: [":host{display:inline-block}.tailwind-btn-spinner{animation:tailwind-spin 1s linear infinite;width:1em;height:1em}@keyframes tailwind-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
874
- }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], kind: [{ type: i0.Input, args: [{ isSignal: true, alias: "kind", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], onClick: [{ type: i0.Output, args: ["onClick"] }] } });
907
+ args: [{ imports: [NgClass, TailwindIcon], selector: 'tailwind-button', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n [ngClass]=\"computedClasses()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [attr.role]=\"role()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-disabled]=\"disabled() || null\"\n (click)=\"handleClick($event)\">\n <span class=\"inline-flex min-w-0 items-center justify-center gap-2\">\n @if (icon() && iconPosition() === 'left') {\n <tailwind-icon [icon]=\"icon()!\" [size]=\"iconPixelSize()\" class=\"shrink-0\" />\n }\n <span class=\"tailwind-button-label inline-flex min-w-0 items-center empty:hidden\">\n <ng-content />\n </span>\n @if (icon() && iconPosition() === 'right') {\n <tailwind-icon [icon]=\"icon()!\" [size]=\"iconPixelSize()\" class=\"shrink-0\" />\n }\n </span>\n</button>\n", styles: [":host{display:inline-block}.tailwind-btn-spinner{animation:tailwind-spin 1s linear infinite;width:1em;height:1em}@keyframes tailwind-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
908
+ }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], kind: [{ type: i0.Input, args: [{ isSignal: true, alias: "kind", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], onClick: [{ type: i0.Output, args: ["onClick"] }] } });
875
909
 
876
910
  class TailwindInput extends TailwindComponent {
877
911
  /** Label text */
@@ -1264,7 +1298,7 @@ class TailwindUpload extends TailwindComponent {
1264
1298
  useExisting: forwardRef(() => TailwindUpload),
1265
1299
  multi: true
1266
1300
  }
1267
- ], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"tailwind-upload-wrapper flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"fileInputId()\" class=\"text-sm font-medium text-neutral-700\" [class.text-danger-600]=\"hasError()\">\n {{ label() }}\n </label>\n }\n\n <input\n #fileInput\n type=\"file\"\n class=\"sr-only\"\n [attr.id]=\"fileInputId()\"\n [accept]=\"accept() ?? null\"\n [attr.multiple]=\"multiple() ? '' : null\"\n [disabled]=\"isDisabled()\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"helperText() || errorText() ? fileInputId() + '-helper' : null\"\n (change)=\"onNativeChange($event)\"\n (blur)=\"blurHost()\" />\n\n @if (variant() === 'button') {\n <div class=\"flex flex-wrap items-center gap-2\">\n <tailwind-button\n type=\"button\"\n color=\"primary\"\n kind=\"solid\"\n [size]=\"size()\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"triggerPicker($event)\">\n {{ buttonLabel() }}\n </tailwind-button>\n @if (showClear() && value()) {\n <button\n type=\"button\"\n class=\"text-sm font-medium text-primary-600 underline-offset-2 hover:underline disabled:cursor-not-allowed disabled:opacity-50\"\n [disabled]=\"isDisabled()\"\n (click)=\"clear($event)\">\n {{ clearText() }}\n </button>\n }\n </div>\n } @else {\n <div class=\"flex flex-col gap-2\">\n <div\n role=\"button\"\n tabindex=\"0\"\n [class]=\"areaClasses()\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n (click)=\"triggerPicker($event)\"\n (keydown)=\"onKeydownArea($event)\"\n (dragenter)=\"onDragEnter($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop($event)\">\n <tailwind-icon icon=\"cloud-arrow-up\" [size]=\"40\" />\n <span class=\"text-sm font-medium\">{{ areaTitle() }}</span>\n <span class=\"text-xs text-neutral-500\">{{ areaHint() }}</span>\n </div>\n @if (showClear() && value()) {\n <button\n type=\"button\"\n class=\"self-start text-sm font-medium text-primary-600 underline-offset-2 hover:underline disabled:cursor-not-allowed disabled:opacity-50\"\n [disabled]=\"isDisabled()\"\n (click)=\"clear($event)\">\n {{ clearText() }}\n </button>\n }\n </div>\n }\n\n @if (selectedNames().length) {\n <p class=\"truncate text-xs text-neutral-600\" [attr.title]=\"selectedNames().join(', ')\">\n {{ selectedNames().join(', ') }}\n </p>\n }\n\n @if (helperText() && !hasError()) {\n <p [attr.id]=\"fileInputId() + '-helper'\" class=\"text-xs text-neutral-500\">\n {{ helperText() }}\n </p>\n }\n @if (errorText() && hasError()) {\n <p [attr.id]=\"fileInputId() + '-helper'\" class=\"text-xs text-danger-600\">\n {{ errorText() }}\n </p>\n }\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }, { kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1301
+ ], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"tailwind-upload-wrapper flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"fileInputId()\" class=\"text-sm font-medium text-neutral-700\" [class.text-danger-600]=\"hasError()\">\n {{ label() }}\n </label>\n }\n\n <input\n #fileInput\n type=\"file\"\n class=\"sr-only\"\n [attr.id]=\"fileInputId()\"\n [accept]=\"accept() ?? null\"\n [attr.multiple]=\"multiple() ? '' : null\"\n [disabled]=\"isDisabled()\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"helperText() || errorText() ? fileInputId() + '-helper' : null\"\n (change)=\"onNativeChange($event)\"\n (blur)=\"blurHost()\" />\n\n @if (variant() === 'button') {\n <div class=\"flex flex-wrap items-center gap-2\">\n <tailwind-button\n type=\"button\"\n color=\"primary\"\n kind=\"solid\"\n [size]=\"size()\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"triggerPicker($event)\">\n {{ buttonLabel() }}\n </tailwind-button>\n @if (showClear() && value()) {\n <tailwind-button\n kind=\"text\"\n color=\"primary\"\n size=\"sm\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"clear($event)\">\n {{ clearText() }}\n </tailwind-button>\n }\n </div>\n } @else {\n <div class=\"flex flex-col gap-2\">\n <div\n role=\"button\"\n tabindex=\"0\"\n [class]=\"areaClasses()\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n (click)=\"triggerPicker($event)\"\n (keydown)=\"onKeydownArea($event)\"\n (dragenter)=\"onDragEnter($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop($event)\">\n <tailwind-icon icon=\"cloud-arrow-up\" [size]=\"40\" />\n <span class=\"text-sm font-medium\">{{ areaTitle() }}</span>\n <span class=\"text-xs text-neutral-500\">{{ areaHint() }}</span>\n </div>\n @if (showClear() && value()) {\n <tailwind-button\n kind=\"text\"\n color=\"primary\"\n size=\"sm\"\n class=\"self-start\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"clear($event)\">\n {{ clearText() }}\n </tailwind-button>\n }\n </div>\n }\n\n @if (selectedNames().length) {\n <p class=\"truncate text-xs text-neutral-600\" [attr.title]=\"selectedNames().join(', ')\">\n {{ selectedNames().join(', ') }}\n </p>\n }\n\n @if (helperText() && !hasError()) {\n <p [attr.id]=\"fileInputId() + '-helper'\" class=\"text-xs text-neutral-500\">\n {{ helperText() }}\n </p>\n }\n @if (errorText() && hasError()) {\n <p [attr.id]=\"fileInputId() + '-helper'\" class=\"text-xs text-danger-600\">\n {{ errorText() }}\n </p>\n }\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }, { kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition", "ariaLabel"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1268
1302
  }
1269
1303
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindUpload, decorators: [{
1270
1304
  type: Component,
@@ -1274,7 +1308,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
1274
1308
  useExisting: forwardRef(() => TailwindUpload),
1275
1309
  multi: true
1276
1310
  }
1277
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"tailwind-upload-wrapper flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"fileInputId()\" class=\"text-sm font-medium text-neutral-700\" [class.text-danger-600]=\"hasError()\">\n {{ label() }}\n </label>\n }\n\n <input\n #fileInput\n type=\"file\"\n class=\"sr-only\"\n [attr.id]=\"fileInputId()\"\n [accept]=\"accept() ?? null\"\n [attr.multiple]=\"multiple() ? '' : null\"\n [disabled]=\"isDisabled()\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"helperText() || errorText() ? fileInputId() + '-helper' : null\"\n (change)=\"onNativeChange($event)\"\n (blur)=\"blurHost()\" />\n\n @if (variant() === 'button') {\n <div class=\"flex flex-wrap items-center gap-2\">\n <tailwind-button\n type=\"button\"\n color=\"primary\"\n kind=\"solid\"\n [size]=\"size()\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"triggerPicker($event)\">\n {{ buttonLabel() }}\n </tailwind-button>\n @if (showClear() && value()) {\n <button\n type=\"button\"\n class=\"text-sm font-medium text-primary-600 underline-offset-2 hover:underline disabled:cursor-not-allowed disabled:opacity-50\"\n [disabled]=\"isDisabled()\"\n (click)=\"clear($event)\">\n {{ clearText() }}\n </button>\n }\n </div>\n } @else {\n <div class=\"flex flex-col gap-2\">\n <div\n role=\"button\"\n tabindex=\"0\"\n [class]=\"areaClasses()\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n (click)=\"triggerPicker($event)\"\n (keydown)=\"onKeydownArea($event)\"\n (dragenter)=\"onDragEnter($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop($event)\">\n <tailwind-icon icon=\"cloud-arrow-up\" [size]=\"40\" />\n <span class=\"text-sm font-medium\">{{ areaTitle() }}</span>\n <span class=\"text-xs text-neutral-500\">{{ areaHint() }}</span>\n </div>\n @if (showClear() && value()) {\n <button\n type=\"button\"\n class=\"self-start text-sm font-medium text-primary-600 underline-offset-2 hover:underline disabled:cursor-not-allowed disabled:opacity-50\"\n [disabled]=\"isDisabled()\"\n (click)=\"clear($event)\">\n {{ clearText() }}\n </button>\n }\n </div>\n }\n\n @if (selectedNames().length) {\n <p class=\"truncate text-xs text-neutral-600\" [attr.title]=\"selectedNames().join(', ')\">\n {{ selectedNames().join(', ') }}\n </p>\n }\n\n @if (helperText() && !hasError()) {\n <p [attr.id]=\"fileInputId() + '-helper'\" class=\"text-xs text-neutral-500\">\n {{ helperText() }}\n </p>\n }\n @if (errorText() && hasError()) {\n <p [attr.id]=\"fileInputId() + '-helper'\" class=\"text-xs text-danger-600\">\n {{ errorText() }}\n </p>\n }\n</div>\n", styles: [":host{display:block}\n"] }]
1311
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"tailwind-upload-wrapper flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"fileInputId()\" class=\"text-sm font-medium text-neutral-700\" [class.text-danger-600]=\"hasError()\">\n {{ label() }}\n </label>\n }\n\n <input\n #fileInput\n type=\"file\"\n class=\"sr-only\"\n [attr.id]=\"fileInputId()\"\n [accept]=\"accept() ?? null\"\n [attr.multiple]=\"multiple() ? '' : null\"\n [disabled]=\"isDisabled()\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"helperText() || errorText() ? fileInputId() + '-helper' : null\"\n (change)=\"onNativeChange($event)\"\n (blur)=\"blurHost()\" />\n\n @if (variant() === 'button') {\n <div class=\"flex flex-wrap items-center gap-2\">\n <tailwind-button\n type=\"button\"\n color=\"primary\"\n kind=\"solid\"\n [size]=\"size()\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"triggerPicker($event)\">\n {{ buttonLabel() }}\n </tailwind-button>\n @if (showClear() && value()) {\n <tailwind-button\n kind=\"text\"\n color=\"primary\"\n size=\"sm\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"clear($event)\">\n {{ clearText() }}\n </tailwind-button>\n }\n </div>\n } @else {\n <div class=\"flex flex-col gap-2\">\n <div\n role=\"button\"\n tabindex=\"0\"\n [class]=\"areaClasses()\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n (click)=\"triggerPicker($event)\"\n (keydown)=\"onKeydownArea($event)\"\n (dragenter)=\"onDragEnter($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop($event)\">\n <tailwind-icon icon=\"cloud-arrow-up\" [size]=\"40\" />\n <span class=\"text-sm font-medium\">{{ areaTitle() }}</span>\n <span class=\"text-xs text-neutral-500\">{{ areaHint() }}</span>\n </div>\n @if (showClear() && value()) {\n <tailwind-button\n kind=\"text\"\n color=\"primary\"\n size=\"sm\"\n class=\"self-start\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"clear($event)\">\n {{ clearText() }}\n </tailwind-button>\n }\n </div>\n }\n\n @if (selectedNames().length) {\n <p class=\"truncate text-xs text-neutral-600\" [attr.title]=\"selectedNames().join(', ')\">\n {{ selectedNames().join(', ') }}\n </p>\n }\n\n @if (helperText() && !hasError()) {\n <p [attr.id]=\"fileInputId() + '-helper'\" class=\"text-xs text-neutral-500\">\n {{ helperText() }}\n </p>\n }\n @if (errorText() && hasError()) {\n <p [attr.id]=\"fileInputId() + '-helper'\" class=\"text-xs text-danger-600\">\n {{ errorText() }}\n </p>\n }\n</div>\n", styles: [":host{display:block}\n"] }]
1278
1312
  }], propDecorators: { fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }], areaTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "areaTitle", required: false }] }], areaHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "areaHint", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], maxFileSizeBytes: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSizeBytes", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], showClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClear", required: false }] }], clearText: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearText", required: false }] }], helperText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helperText", required: false }] }], errorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorText", required: false }] }], hasError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasError", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], filesSelected: [{ type: i0.Output, args: ["filesSelected"] }], validationError: [{ type: i0.Output, args: ["validationError"] }] } });
1279
1313
 
1280
1314
  class TailwindInputOtp extends TailwindComponent {
@@ -1533,6 +1567,16 @@ class TailwindCheckbox extends TailwindComponent {
1533
1567
  };
1534
1568
  return sizeMap[this.size()];
1535
1569
  }, ...(ngDevMode ? [{ debugName: "boxSizeClass" }] : /* istanbul ignore next */ []));
1570
+ checkIconSize = computed(() => {
1571
+ const sizeMap = {
1572
+ xs: 16,
1573
+ sm: 16,
1574
+ md: 20,
1575
+ lg: 24,
1576
+ xl: 28
1577
+ };
1578
+ return sizeMap[this.size()];
1579
+ }, ...(ngDevMode ? [{ debugName: "checkIconSize" }] : /* istanbul ignore next */ []));
1536
1580
  // CVA
1537
1581
  onChange = () => { };
1538
1582
  onTouched = () => { };
@@ -1561,17 +1605,17 @@ class TailwindCheckbox extends TailwindComponent {
1561
1605
  useExisting: forwardRef(() => TailwindCheckbox),
1562
1606
  multi: true
1563
1607
  }
1564
- ], usesInheritance: true, ngImport: i0, template: "<div class=\"inline-flex items-center gap-2.5 select-none\" [class.opacity-50]=\"isDisabled()\">\n <label\n class=\"relative flex items-center justify-center shrink-0\"\n [class.cursor-pointer]=\"!isDisabled()\"\n [class.cursor-not-allowed]=\"isDisabled()\"\n [attr.for]=\"id() ? id() + '-inner' : null\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"checkbox\"\n class=\"peer sr-only\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-describedby]=\"description() && id() ? id() + '-desc' : null\"\n [attr.aria-labelledby]=\"label() && id() ? id() + '-label' : null\"\n (change)=\"onCheckboxChange($event)\" />\n <div\n class=\"w-full h-full border-2 transition-all duration-150 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-500/30 peer-focus-visible:ring-offset-1\"\n [class.rounded-sm]=\"size() === 'xs' || size() === 'sm'\"\n [class.rounded-md]=\"size() !== 'xs' && size() !== 'sm'\"\n [class.border-neutral-300]=\"!checked()\"\n [class.bg-white]=\"!checked()\"\n [class.border-primary-600]=\"checked()\"\n [class.bg-primary-600]=\"checked()\">\n @if (checked()) {\n <svg class=\"w-full h-full text-white p-0.5\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M13.5 4.5L6.5 11.5L3 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n }\n </div>\n </label>\n\n <div class=\"flex flex-col gap-0.5 pt-0.5\">\n @if (label()) {\n <span [attr.id]=\"id() ? id() + '-label' : null\" class=\"text-sm font-medium text-neutral-800 leading-tight\">{{\n label()\n }}</span>\n }\n @if (description()) {\n <span [attr.id]=\"id() ? id() + '-desc' : null\" class=\"text-xs text-neutral-500 leading-snug\">\n {{ description() }}\n </span>\n }\n </div>\n</div>\n", styles: [":host{display:inline-block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1608
+ ], usesInheritance: true, ngImport: i0, template: "<div class=\"inline-flex items-center gap-2.5 select-none\" [class.opacity-50]=\"isDisabled()\">\n <label\n class=\"relative flex items-center justify-center shrink-0\"\n [class.cursor-pointer]=\"!isDisabled()\"\n [class.cursor-not-allowed]=\"isDisabled()\"\n [attr.for]=\"id() ? id() + '-inner' : null\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"checkbox\"\n class=\"peer sr-only\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-describedby]=\"description() && id() ? id() + '-desc' : null\"\n [attr.aria-labelledby]=\"label() && id() ? id() + '-label' : null\"\n (change)=\"onCheckboxChange($event)\" />\n <div\n class=\"w-full h-full border-2 transition-all duration-150 flex items-center justify-center peer-focus-visible:ring-2 peer-focus-visible:ring-primary-500/30 peer-focus-visible:ring-offset-1\"\n [class.rounded-sm]=\"size() === 'xs' || size() === 'sm'\"\n [class.rounded-md]=\"size() !== 'xs' && size() !== 'sm'\"\n [class.border-neutral-300]=\"!checked()\"\n [class.bg-white]=\"!checked()\"\n [class.border-primary-600]=\"checked()\"\n [class.bg-primary-600]=\"checked()\">\n @if (checked()) {\n <tailwind-icon icon=\"check\" [size]=\"checkIconSize()\" class=\"text-white shrink-0\" />\n }\n </div>\n </label>\n\n <div class=\"flex flex-col gap-0.5 pt-0.5\">\n @if (label()) {\n <span [attr.id]=\"id() ? id() + '-label' : null\" class=\"text-sm font-medium text-neutral-800 leading-tight\">{{\n label()\n }}</span>\n }\n @if (description()) {\n <span [attr.id]=\"id() ? id() + '-desc' : null\" class=\"text-xs text-neutral-500 leading-snug\">\n {{ description() }}\n </span>\n }\n </div>\n</div>\n", styles: [":host{display:inline-block}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1565
1609
  }
1566
1610
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindCheckbox, decorators: [{
1567
1611
  type: Component,
1568
- args: [{ selector: 'tailwind-checkbox', providers: [
1612
+ args: [{ imports: [TailwindIcon], selector: 'tailwind-checkbox', providers: [
1569
1613
  {
1570
1614
  provide: NG_VALUE_ACCESSOR,
1571
1615
  useExisting: forwardRef(() => TailwindCheckbox),
1572
1616
  multi: true
1573
1617
  }
1574
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"inline-flex items-center gap-2.5 select-none\" [class.opacity-50]=\"isDisabled()\">\n <label\n class=\"relative flex items-center justify-center shrink-0\"\n [class.cursor-pointer]=\"!isDisabled()\"\n [class.cursor-not-allowed]=\"isDisabled()\"\n [attr.for]=\"id() ? id() + '-inner' : null\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"checkbox\"\n class=\"peer sr-only\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-describedby]=\"description() && id() ? id() + '-desc' : null\"\n [attr.aria-labelledby]=\"label() && id() ? id() + '-label' : null\"\n (change)=\"onCheckboxChange($event)\" />\n <div\n class=\"w-full h-full border-2 transition-all duration-150 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-500/30 peer-focus-visible:ring-offset-1\"\n [class.rounded-sm]=\"size() === 'xs' || size() === 'sm'\"\n [class.rounded-md]=\"size() !== 'xs' && size() !== 'sm'\"\n [class.border-neutral-300]=\"!checked()\"\n [class.bg-white]=\"!checked()\"\n [class.border-primary-600]=\"checked()\"\n [class.bg-primary-600]=\"checked()\">\n @if (checked()) {\n <svg class=\"w-full h-full text-white p-0.5\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M13.5 4.5L6.5 11.5L3 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n }\n </div>\n </label>\n\n <div class=\"flex flex-col gap-0.5 pt-0.5\">\n @if (label()) {\n <span [attr.id]=\"id() ? id() + '-label' : null\" class=\"text-sm font-medium text-neutral-800 leading-tight\">{{\n label()\n }}</span>\n }\n @if (description()) {\n <span [attr.id]=\"id() ? id() + '-desc' : null\" class=\"text-xs text-neutral-500 leading-snug\">\n {{ description() }}\n </span>\n }\n </div>\n</div>\n", styles: [":host{display:inline-block}\n"] }]
1618
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"inline-flex items-center gap-2.5 select-none\" [class.opacity-50]=\"isDisabled()\">\n <label\n class=\"relative flex items-center justify-center shrink-0\"\n [class.cursor-pointer]=\"!isDisabled()\"\n [class.cursor-not-allowed]=\"isDisabled()\"\n [attr.for]=\"id() ? id() + '-inner' : null\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"checkbox\"\n class=\"peer sr-only\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-describedby]=\"description() && id() ? id() + '-desc' : null\"\n [attr.aria-labelledby]=\"label() && id() ? id() + '-label' : null\"\n (change)=\"onCheckboxChange($event)\" />\n <div\n class=\"w-full h-full border-2 transition-all duration-150 flex items-center justify-center peer-focus-visible:ring-2 peer-focus-visible:ring-primary-500/30 peer-focus-visible:ring-offset-1\"\n [class.rounded-sm]=\"size() === 'xs' || size() === 'sm'\"\n [class.rounded-md]=\"size() !== 'xs' && size() !== 'sm'\"\n [class.border-neutral-300]=\"!checked()\"\n [class.bg-white]=\"!checked()\"\n [class.border-primary-600]=\"checked()\"\n [class.bg-primary-600]=\"checked()\">\n @if (checked()) {\n <tailwind-icon icon=\"check\" [size]=\"checkIconSize()\" class=\"text-white shrink-0\" />\n }\n </div>\n </label>\n\n <div class=\"flex flex-col gap-0.5 pt-0.5\">\n @if (label()) {\n <span [attr.id]=\"id() ? id() + '-label' : null\" class=\"text-sm font-medium text-neutral-800 leading-tight\">{{\n label()\n }}</span>\n }\n @if (description()) {\n <span [attr.id]=\"id() ? id() + '-desc' : null\" class=\"text-xs text-neutral-500 leading-snug\">\n {{ description() }}\n </span>\n }\n </div>\n</div>\n", styles: [":host{display:inline-block}\n"] }]
1575
1619
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }] } });
1576
1620
 
1577
1621
  class TailwindRadioGroup extends TailwindComponent {
@@ -1937,19 +1981,376 @@ class TailwindSelect extends TailwindComponent {
1937
1981
  useExisting: forwardRef(() => TailwindSelect),
1938
1982
  multi: true
1939
1983
  }
1940
- ], viewQueries: [{ propertyName: "panelTemplate", first: true, predicate: ["panelTemplate"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label\n [attr.for]=\"id() ? id() + '-inner' : null\"\n class=\"text-sm font-medium text-neutral-700\"\n [class.text-danger-600]=\"hasError()\">\n {{ label() }}\n </label>\n }\n\n <!-- Trigger button -->\n <button\n type=\"button\"\n [attr.id]=\"id() ? id() + '-inner' : null\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"(helperText() || errorText()) && id() ? id() + '-helper' : null\"\n [disabled]=\"isDisabled()\"\n [class]=\"triggerClasses()\"\n (click)=\"toggleDropdown()\"\n (keydown)=\"onKeydown($event)\">\n @if (multiple()) {\n <span class=\"flex flex-wrap gap-1 flex-1 min-w-0 mr-2\" [class.text-neutral-400]=\"selectedOptions().length === 0\">\n @if (selectedOptions().length === 0) {\n {{ placeholder() }}\n } @else {\n @for (opt of selectedOptions(); track opt) {\n <span class=\"rounded-md bg-neutral-100 px-2 py-0.5 text-sm text-neutral-800\">{{ opt.label }}</span>\n }\n }\n </span>\n } @else {\n <span [class.text-neutral-400]=\"!selectedOption()\">\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n }\n\n <svg\n class=\"shrink-0 ml-2 w-4 h-4 text-neutral-400 transition-transform duration-150\"\n [class.rotate-180]=\"isOpen()\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n\n @if (helperText() && !hasError()) {\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-neutral-500\">{{ helperText() }}</p>\n }\n @if (errorText() && hasError()) {\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-danger-600\">{{ errorText() }}</p>\n }\n</div>\n\n<!-- Dropdown panel \u2014 rendered via CDK Overlay outside the component DOM -->\n<ng-template #panelTemplate>\n <ul\n role=\"listbox\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n class=\"w-full bg-white border border-neutral-200 rounded-md shadow-lg py-1 max-h-60 overflow-auto\">\n @if (placeholder()) {\n <li role=\"option\" aria-disabled=\"true\" class=\"px-3 py-2 text-sm text-neutral-400 cursor-default select-none\">\n {{ placeholder() }}\n </li>\n }\n @for (option of options(); track option.value; let i = $index) {\n <li\n role=\"option\"\n [attr.aria-selected]=\"isOptionSelected(option)\"\n [attr.aria-disabled]=\"option.disabled || null\"\n [class]=\"optionClasses(i, option)\"\n (click)=\"selectOption(option)\"\n (mouseenter)=\"!option.disabled && activeIndex.set(i)\">\n <span>{{ option.label }}</span>\n\n @if (isOptionSelected(option)) {\n <svg\n class=\"w-4 h-4 text-primary-600 shrink-0\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n </li>\n }\n </ul>\n</ng-template>\n", styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1984
+ ], viewQueries: [{ propertyName: "panelTemplate", first: true, predicate: ["panelTemplate"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label\n [attr.for]=\"id() ? id() + '-inner' : null\"\n class=\"text-sm font-medium text-neutral-700\"\n [class.text-danger-600]=\"hasError()\">\n {{ label() }}\n </label>\n }\n\n <!-- Trigger button -->\n <button\n type=\"button\"\n [attr.id]=\"id() ? id() + '-inner' : null\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"(helperText() || errorText()) && id() ? id() + '-helper' : null\"\n [disabled]=\"isDisabled()\"\n [class]=\"triggerClasses()\"\n (click)=\"toggleDropdown()\"\n (keydown)=\"onKeydown($event)\">\n @if (multiple()) {\n <span class=\"flex flex-wrap gap-1 flex-1 min-w-0 mr-2\" [class.text-neutral-400]=\"selectedOptions().length === 0\">\n @if (selectedOptions().length === 0) {\n {{ placeholder() }}\n } @else {\n @for (opt of selectedOptions(); track opt) {\n <span class=\"rounded-md bg-neutral-100 px-2 py-0.5 text-sm text-neutral-800\">{{ opt.label }}</span>\n }\n }\n </span>\n } @else {\n <span [class.text-neutral-400]=\"!selectedOption()\">\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n }\n\n <tailwind-icon\n icon=\"chevron-down\"\n [size]=\"16\"\n class=\"shrink-0 ml-2 text-neutral-400 transition-transform duration-150\"\n [class.rotate-180]=\"isOpen()\"\n aria-hidden=\"true\" />\n </button>\n\n @if (helperText() && !hasError()) {\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-neutral-500\">{{ helperText() }}</p>\n }\n @if (errorText() && hasError()) {\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-danger-600\">{{ errorText() }}</p>\n }\n</div>\n\n<!-- Dropdown panel \u2014 rendered via CDK Overlay outside the component DOM -->\n<ng-template #panelTemplate>\n <ul\n role=\"listbox\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n class=\"w-full bg-white border border-neutral-200 rounded-md shadow-lg py-1 max-h-60 overflow-auto\">\n @if (placeholder()) {\n <li role=\"option\" aria-disabled=\"true\" class=\"px-3 py-2 text-sm text-neutral-400 cursor-default select-none\">\n {{ placeholder() }}\n </li>\n }\n @for (option of options(); track option.value; let i = $index) {\n <li\n role=\"option\"\n [attr.aria-selected]=\"isOptionSelected(option)\"\n [attr.aria-disabled]=\"option.disabled || null\"\n [class]=\"optionClasses(i, option)\"\n (click)=\"selectOption(option)\"\n (mouseenter)=\"!option.disabled && activeIndex.set(i)\">\n <span>{{ option.label }}</span>\n\n @if (isOptionSelected(option)) {\n <tailwind-icon icon=\"check\" [size]=\"16\" class=\"text-primary-600 shrink-0\" aria-hidden=\"true\" />\n }\n </li>\n }\n </ul>\n</ng-template>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1941
1985
  }
1942
1986
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindSelect, decorators: [{
1943
1987
  type: Component,
1944
- args: [{ selector: 'tailwind-select', providers: [
1988
+ args: [{ imports: [TailwindIcon], selector: 'tailwind-select', providers: [
1945
1989
  {
1946
1990
  provide: NG_VALUE_ACCESSOR,
1947
1991
  useExisting: forwardRef(() => TailwindSelect),
1948
1992
  multi: true
1949
1993
  }
1950
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label\n [attr.for]=\"id() ? id() + '-inner' : null\"\n class=\"text-sm font-medium text-neutral-700\"\n [class.text-danger-600]=\"hasError()\">\n {{ label() }}\n </label>\n }\n\n <!-- Trigger button -->\n <button\n type=\"button\"\n [attr.id]=\"id() ? id() + '-inner' : null\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"(helperText() || errorText()) && id() ? id() + '-helper' : null\"\n [disabled]=\"isDisabled()\"\n [class]=\"triggerClasses()\"\n (click)=\"toggleDropdown()\"\n (keydown)=\"onKeydown($event)\">\n @if (multiple()) {\n <span class=\"flex flex-wrap gap-1 flex-1 min-w-0 mr-2\" [class.text-neutral-400]=\"selectedOptions().length === 0\">\n @if (selectedOptions().length === 0) {\n {{ placeholder() }}\n } @else {\n @for (opt of selectedOptions(); track opt) {\n <span class=\"rounded-md bg-neutral-100 px-2 py-0.5 text-sm text-neutral-800\">{{ opt.label }}</span>\n }\n }\n </span>\n } @else {\n <span [class.text-neutral-400]=\"!selectedOption()\">\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n }\n\n <svg\n class=\"shrink-0 ml-2 w-4 h-4 text-neutral-400 transition-transform duration-150\"\n [class.rotate-180]=\"isOpen()\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n\n @if (helperText() && !hasError()) {\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-neutral-500\">{{ helperText() }}</p>\n }\n @if (errorText() && hasError()) {\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-danger-600\">{{ errorText() }}</p>\n }\n</div>\n\n<!-- Dropdown panel \u2014 rendered via CDK Overlay outside the component DOM -->\n<ng-template #panelTemplate>\n <ul\n role=\"listbox\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n class=\"w-full bg-white border border-neutral-200 rounded-md shadow-lg py-1 max-h-60 overflow-auto\">\n @if (placeholder()) {\n <li role=\"option\" aria-disabled=\"true\" class=\"px-3 py-2 text-sm text-neutral-400 cursor-default select-none\">\n {{ placeholder() }}\n </li>\n }\n @for (option of options(); track option.value; let i = $index) {\n <li\n role=\"option\"\n [attr.aria-selected]=\"isOptionSelected(option)\"\n [attr.aria-disabled]=\"option.disabled || null\"\n [class]=\"optionClasses(i, option)\"\n (click)=\"selectOption(option)\"\n (mouseenter)=\"!option.disabled && activeIndex.set(i)\">\n <span>{{ option.label }}</span>\n\n @if (isOptionSelected(option)) {\n <svg\n class=\"w-4 h-4 text-primary-600 shrink-0\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n </li>\n }\n </ul>\n</ng-template>\n", styles: [":host{display:block}\n"] }]
1994
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label\n [attr.for]=\"id() ? id() + '-inner' : null\"\n class=\"text-sm font-medium text-neutral-700\"\n [class.text-danger-600]=\"hasError()\">\n {{ label() }}\n </label>\n }\n\n <!-- Trigger button -->\n <button\n type=\"button\"\n [attr.id]=\"id() ? id() + '-inner' : null\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"(helperText() || errorText()) && id() ? id() + '-helper' : null\"\n [disabled]=\"isDisabled()\"\n [class]=\"triggerClasses()\"\n (click)=\"toggleDropdown()\"\n (keydown)=\"onKeydown($event)\">\n @if (multiple()) {\n <span class=\"flex flex-wrap gap-1 flex-1 min-w-0 mr-2\" [class.text-neutral-400]=\"selectedOptions().length === 0\">\n @if (selectedOptions().length === 0) {\n {{ placeholder() }}\n } @else {\n @for (opt of selectedOptions(); track opt) {\n <span class=\"rounded-md bg-neutral-100 px-2 py-0.5 text-sm text-neutral-800\">{{ opt.label }}</span>\n }\n }\n </span>\n } @else {\n <span [class.text-neutral-400]=\"!selectedOption()\">\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n }\n\n <tailwind-icon\n icon=\"chevron-down\"\n [size]=\"16\"\n class=\"shrink-0 ml-2 text-neutral-400 transition-transform duration-150\"\n [class.rotate-180]=\"isOpen()\"\n aria-hidden=\"true\" />\n </button>\n\n @if (helperText() && !hasError()) {\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-neutral-500\">{{ helperText() }}</p>\n }\n @if (errorText() && hasError()) {\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-danger-600\">{{ errorText() }}</p>\n }\n</div>\n\n<!-- Dropdown panel \u2014 rendered via CDK Overlay outside the component DOM -->\n<ng-template #panelTemplate>\n <ul\n role=\"listbox\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n class=\"w-full bg-white border border-neutral-200 rounded-md shadow-lg py-1 max-h-60 overflow-auto\">\n @if (placeholder()) {\n <li role=\"option\" aria-disabled=\"true\" class=\"px-3 py-2 text-sm text-neutral-400 cursor-default select-none\">\n {{ placeholder() }}\n </li>\n }\n @for (option of options(); track option.value; let i = $index) {\n <li\n role=\"option\"\n [attr.aria-selected]=\"isOptionSelected(option)\"\n [attr.aria-disabled]=\"option.disabled || null\"\n [class]=\"optionClasses(i, option)\"\n (click)=\"selectOption(option)\"\n (mouseenter)=\"!option.disabled && activeIndex.set(i)\">\n <span>{{ option.label }}</span>\n\n @if (isOptionSelected(option)) {\n <tailwind-icon icon=\"check\" [size]=\"16\" class=\"text-primary-600 shrink-0\" aria-hidden=\"true\" />\n }\n </li>\n }\n </ul>\n</ng-template>\n", styles: [":host{display:block}\n"] }]
1951
1995
  }], propDecorators: { panelTemplate: [{ type: i0.ViewChild, args: ['panelTemplate', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], helperText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helperText", required: false }] }], errorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorText", required: false }] }], hasError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasError", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
1952
1996
 
1997
+ class TailwindAutocomplete extends TailwindComponent {
1998
+ static nextId = 0;
1999
+ overlay = inject(Overlay);
2000
+ vcr = inject(ViewContainerRef);
2001
+ elRef = inject((ElementRef));
2002
+ cdr = inject(ChangeDetectorRef);
2003
+ ngZone = inject(NgZone);
2004
+ panelTemplate = viewChild.required('panelTemplate');
2005
+ constructor() {
2006
+ super();
2007
+ effect(() => {
2008
+ const opts = this.filteredOptions();
2009
+ if (!this.isOpen())
2010
+ return;
2011
+ const v = this.value();
2012
+ let initial = -1;
2013
+ if (v != null) {
2014
+ initial = opts.findIndex(o => this.optionValueEquals(o.value, v));
2015
+ }
2016
+ else if (opts.length > 0) {
2017
+ initial = 0;
2018
+ }
2019
+ this.activeIndex.set(initial >= 0 ? initial : -1);
2020
+ this.cdr.detectChanges();
2021
+ });
2022
+ }
2023
+ overlayRef = null;
2024
+ outsideSub = null;
2025
+ searchDebounceTimer = null;
2026
+ instanceListboxId = `tailwind-autocomplete-listbox-${++TailwindAutocomplete.nextId}`;
2027
+ /** Label text */
2028
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2029
+ /** Placeholder text */
2030
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
2031
+ /** Available options */
2032
+ options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
2033
+ /** Size variant */
2034
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
2035
+ /** Helper text */
2036
+ helperText = input('', ...(ngDevMode ? [{ debugName: "helperText" }] : /* istanbul ignore next */ []));
2037
+ /** Error text */
2038
+ errorText = input('', ...(ngDevMode ? [{ debugName: "errorText" }] : /* istanbul ignore next */ []));
2039
+ /** Whether in error state */
2040
+ hasError = input(false, ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
2041
+ /** Filter options locally by label when typing */
2042
+ filterLocally = input(true, ...(ngDevMode ? [{ debugName: "filterLocally" }] : /* istanbul ignore next */ []));
2043
+ /** Minimum query length before opening panel and emitting onSearch */
2044
+ minSearchLength = input(0, ...(ngDevMode ? [{ debugName: "minSearchLength" }] : /* istanbul ignore next */ []));
2045
+ /** Debounce delay (ms) for onSearch emission only */
2046
+ debounceMs = input(0, ...(ngDevMode ? [{ debugName: "debounceMs" }] : /* istanbul ignore next */ []));
2047
+ /** On blur, reset input to selected option label or clear invalid text */
2048
+ forceSelection = input(true, ...(ngDevMode ? [{ debugName: "forceSelection" }] : /* istanbul ignore next */ []));
2049
+ /** Selected value (form control) — set only when an option is chosen */
2050
+ value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
2051
+ /** Emits the current search query (after debounce / minSearchLength) */
2052
+ onSearch = output();
2053
+ /** Custom option row template (`ng-template` with `#item`) */
2054
+ itemTemplate = contentChild('item', { ...(ngDevMode ? { debugName: "itemTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
2055
+ /** Text shown in the input */
2056
+ searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
2057
+ isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
2058
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
2059
+ activeIndex = signal(-1, ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
2060
+ listboxId = computed(() => (this.id() ? `${this.id()}-listbox` : this.instanceListboxId), ...(ngDevMode ? [{ debugName: "listboxId" }] : /* istanbul ignore next */ []));
2061
+ selectedOption = computed(() => {
2062
+ const v = this.value();
2063
+ if (v == null)
2064
+ return null;
2065
+ return this.options().find(o => this.optionValueEquals(o.value, v)) ?? null;
2066
+ }, ...(ngDevMode ? [{ debugName: "selectedOption" }] : /* istanbul ignore next */ []));
2067
+ filteredOptions = computed(() => {
2068
+ const opts = this.options();
2069
+ if (!this.filterLocally())
2070
+ return opts;
2071
+ const q = this.searchQuery().trim().toLowerCase();
2072
+ if (!q)
2073
+ return opts;
2074
+ return opts.filter(o => o.label.toLowerCase().includes(q));
2075
+ }, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
2076
+ inputClasses = computed(() => {
2077
+ const sizeMap = {
2078
+ xs: 'text-xs px-2 py-1 rounded-sm',
2079
+ sm: 'text-sm px-2.5 py-1.5 rounded-md',
2080
+ md: 'text-sm px-3 py-2 rounded-md',
2081
+ lg: 'text-base px-3.5 py-2.5 rounded-lg',
2082
+ xl: 'text-base px-4 py-3 rounded-lg'
2083
+ };
2084
+ const stateClass = this.hasError()
2085
+ ? 'border-danger-400 focus:outline-danger-500 text-danger-900'
2086
+ : 'border-neutral-300 focus:outline-primary-500 text-neutral-900';
2087
+ return [
2088
+ 'block w-full bg-white border transition-colors duration-150',
2089
+ 'placeholder:text-neutral-400',
2090
+ 'outline-none focus:outline focus:outline-2 focus:outline-offset-2',
2091
+ 'disabled:bg-neutral-50 disabled:text-neutral-400 disabled:cursor-not-allowed',
2092
+ sizeMap[this.size()],
2093
+ stateClass
2094
+ ].join(' ');
2095
+ }, ...(ngDevMode ? [{ debugName: "inputClasses" }] : /* istanbul ignore next */ []));
2096
+ onChange = () => { };
2097
+ onTouched = () => { };
2098
+ writeValue(value) {
2099
+ this.value.set(value ?? null);
2100
+ const opt = this.options().find(o => this.optionValueEquals(o.value, value));
2101
+ this.searchQuery.set(opt?.label ?? '');
2102
+ }
2103
+ registerOnChange(fn) {
2104
+ this.onChange = fn;
2105
+ }
2106
+ registerOnTouched(fn) {
2107
+ this.onTouched = fn;
2108
+ }
2109
+ setDisabledState(disabled) {
2110
+ this.isDisabled.set(disabled);
2111
+ }
2112
+ ngOnDestroy() {
2113
+ if (this.searchDebounceTimer != null) {
2114
+ clearTimeout(this.searchDebounceTimer);
2115
+ }
2116
+ this.closePanel();
2117
+ }
2118
+ isOptionSelected(option) {
2119
+ const v = this.value();
2120
+ if (v == null)
2121
+ return false;
2122
+ return this.optionValueEquals(option.value, v);
2123
+ }
2124
+ optionClasses(index, option) {
2125
+ const isSelected = this.isOptionSelected(option);
2126
+ const isActive = this.activeIndex() === index;
2127
+ const isDisabled = !!option.disabled;
2128
+ return [
2129
+ 'flex items-center justify-between px-3 py-2 text-sm cursor-pointer select-none',
2130
+ isDisabled
2131
+ ? 'text-neutral-400 cursor-not-allowed'
2132
+ : isSelected
2133
+ ? 'bg-primary-50 text-primary-700 font-medium'
2134
+ : isActive
2135
+ ? 'bg-neutral-100 text-neutral-900'
2136
+ : 'text-neutral-800 hover:bg-neutral-50'
2137
+ ].join(' ');
2138
+ }
2139
+ itemContext(option, index) {
2140
+ return {
2141
+ $implicit: option,
2142
+ option,
2143
+ index,
2144
+ selected: this.isOptionSelected(option),
2145
+ active: this.activeIndex() === index
2146
+ };
2147
+ }
2148
+ onInputChange(event) {
2149
+ const query = event.target.value;
2150
+ this.searchQuery.set(query);
2151
+ this.cdr.markForCheck();
2152
+ const selected = this.selectedOption();
2153
+ if (selected && query !== selected.label) {
2154
+ this.value.set(null);
2155
+ this.onChange(null);
2156
+ }
2157
+ this.emitSearch(query);
2158
+ if (query.length >= this.minSearchLength()) {
2159
+ this.openPanel();
2160
+ }
2161
+ else {
2162
+ this.closePanel();
2163
+ }
2164
+ }
2165
+ onFocus() {
2166
+ if (this.isDisabled())
2167
+ return;
2168
+ if (this.searchQuery().length >= this.minSearchLength()) {
2169
+ this.openPanel();
2170
+ }
2171
+ }
2172
+ onBlur() {
2173
+ this.onTouched();
2174
+ queueMicrotask(() => this.applyForceSelectionOnBlur());
2175
+ }
2176
+ applyForceSelectionOnBlur() {
2177
+ if (!this.forceSelection() || this.isOpen())
2178
+ return;
2179
+ const active = document.activeElement;
2180
+ const host = this.elRef.nativeElement;
2181
+ const pane = this.overlayRef?.overlayElement;
2182
+ if (active && (host.contains(active) || pane?.contains(active)))
2183
+ return;
2184
+ const selected = this.selectedOption();
2185
+ const query = this.searchQuery();
2186
+ if (selected) {
2187
+ if (query !== selected.label) {
2188
+ this.searchQuery.set(selected.label);
2189
+ }
2190
+ return;
2191
+ }
2192
+ if (query) {
2193
+ this.searchQuery.set('');
2194
+ }
2195
+ }
2196
+ selectOption(option) {
2197
+ if (option.disabled)
2198
+ return;
2199
+ this.value.set(option.value);
2200
+ this.searchQuery.set(option.label);
2201
+ this.onChange(option.value);
2202
+ this.onTouched();
2203
+ this.closePanel();
2204
+ }
2205
+ onKeydown(event) {
2206
+ if (this.isDisabled())
2207
+ return;
2208
+ const opts = this.filteredOptions();
2209
+ switch (event.key) {
2210
+ case 'ArrowDown': {
2211
+ event.preventDefault();
2212
+ if (!this.isOpen()) {
2213
+ this.openPanel();
2214
+ return;
2215
+ }
2216
+ let next = this.activeIndex() + 1;
2217
+ while (next < opts.length && opts[next].disabled)
2218
+ next++;
2219
+ if (next < opts.length)
2220
+ this.activeIndex.set(next);
2221
+ break;
2222
+ }
2223
+ case 'ArrowUp': {
2224
+ event.preventDefault();
2225
+ if (!this.isOpen()) {
2226
+ this.openPanel();
2227
+ return;
2228
+ }
2229
+ let prev = this.activeIndex() - 1;
2230
+ while (prev >= 0 && opts[prev].disabled)
2231
+ prev--;
2232
+ if (prev >= 0)
2233
+ this.activeIndex.set(prev);
2234
+ break;
2235
+ }
2236
+ case 'Enter': {
2237
+ event.preventDefault();
2238
+ if (!this.isOpen()) {
2239
+ this.openPanel();
2240
+ return;
2241
+ }
2242
+ const active = this.activeIndex();
2243
+ if (active >= 0 && active < opts.length) {
2244
+ this.selectOption(opts[active]);
2245
+ }
2246
+ break;
2247
+ }
2248
+ case 'Escape':
2249
+ case 'Tab': {
2250
+ this.closePanel();
2251
+ break;
2252
+ }
2253
+ }
2254
+ }
2255
+ optionValueEquals(a, b) {
2256
+ return Object.is(a, b);
2257
+ }
2258
+ emitSearch(query) {
2259
+ if (query.length < this.minSearchLength())
2260
+ return;
2261
+ const debounce = this.debounceMs();
2262
+ if (this.searchDebounceTimer != null) {
2263
+ clearTimeout(this.searchDebounceTimer);
2264
+ this.searchDebounceTimer = null;
2265
+ }
2266
+ if (debounce <= 0) {
2267
+ this.onSearch.emit(query);
2268
+ return;
2269
+ }
2270
+ this.searchDebounceTimer = setTimeout(() => {
2271
+ this.ngZone.run(() => {
2272
+ this.onSearch.emit(query);
2273
+ this.cdr.markForCheck();
2274
+ });
2275
+ this.searchDebounceTimer = null;
2276
+ }, debounce);
2277
+ }
2278
+ openPanel() {
2279
+ if (this.overlayRef || this.isDisabled())
2280
+ return;
2281
+ if (this.searchQuery().length < this.minSearchLength())
2282
+ return;
2283
+ const trigger = this.elRef.nativeElement.querySelector('input[role="combobox"]');
2284
+ if (!trigger)
2285
+ return;
2286
+ const positionStrategy = this.overlay
2287
+ .position()
2288
+ .flexibleConnectedTo(trigger)
2289
+ .withPositions([
2290
+ { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },
2291
+ { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' }
2292
+ ])
2293
+ .withFlexibleDimensions(false)
2294
+ .withPush(false);
2295
+ this.overlayRef = this.overlay.create({
2296
+ positionStrategy,
2297
+ scrollStrategy: this.overlay.scrollStrategies.close(),
2298
+ width: trigger.offsetWidth
2299
+ });
2300
+ const portal = new TemplatePortal(this.panelTemplate(), this.vcr);
2301
+ this.overlayRef.attach(portal);
2302
+ const pane = this.overlayRef.overlayElement;
2303
+ this.outsideSub = new Subscription();
2304
+ this.outsideSub.add(fromEvent(document, 'pointerdown', { capture: true }).subscribe(ev => {
2305
+ const t = ev.target;
2306
+ if (this.elRef.nativeElement.contains(t) || pane.contains(t))
2307
+ return;
2308
+ this.closePanel();
2309
+ }));
2310
+ this.outsideSub.add(fromEvent(document, 'keydown').subscribe(ev => {
2311
+ if (ev.key === 'Escape') {
2312
+ ev.preventDefault();
2313
+ this.closePanel();
2314
+ }
2315
+ }));
2316
+ this.isOpen.set(true);
2317
+ const opts = this.filteredOptions();
2318
+ const v = this.value();
2319
+ let initial = -1;
2320
+ if (v != null) {
2321
+ initial = opts.findIndex(o => this.optionValueEquals(o.value, v));
2322
+ }
2323
+ this.activeIndex.set(initial >= 0 ? initial : -1);
2324
+ }
2325
+ closePanel() {
2326
+ this.overlayRef?.detach();
2327
+ this.overlayRef?.dispose();
2328
+ this.overlayRef = null;
2329
+ this.outsideSub?.unsubscribe();
2330
+ this.outsideSub = null;
2331
+ this.isOpen.set(false);
2332
+ this.activeIndex.set(-1);
2333
+ }
2334
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindAutocomplete, deps: [], target: i0.ɵɵFactoryTarget.Component });
2335
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindAutocomplete, isStandalone: true, selector: "tailwind-autocomplete", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, helperText: { classPropertyName: "helperText", publicName: "helperText", isSignal: true, isRequired: false, transformFunction: null }, errorText: { classPropertyName: "errorText", publicName: "errorText", isSignal: true, isRequired: false, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: true, isRequired: false, transformFunction: null }, filterLocally: { classPropertyName: "filterLocally", publicName: "filterLocally", isSignal: true, isRequired: false, transformFunction: null }, minSearchLength: { classPropertyName: "minSearchLength", publicName: "minSearchLength", isSignal: true, isRequired: false, transformFunction: null }, debounceMs: { classPropertyName: "debounceMs", publicName: "debounceMs", isSignal: true, isRequired: false, transformFunction: null }, forceSelection: { classPropertyName: "forceSelection", publicName: "forceSelection", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onSearch: "onSearch" }, providers: [
2336
+ {
2337
+ provide: NG_VALUE_ACCESSOR,
2338
+ useExisting: forwardRef(() => TailwindAutocomplete),
2339
+ multi: true
2340
+ }
2341
+ ], queries: [{ propertyName: "itemTemplate", first: true, predicate: ["item"], descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "panelTemplate", first: true, predicate: ["panelTemplate"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-1.5\">\r\n @if (label()) {\r\n <label\r\n [attr.for]=\"id() ? id() + '-inner' : null\"\r\n class=\"text-sm font-medium text-neutral-700\"\r\n [class.text-danger-600]=\"hasError()\">\r\n {{ label() }}\r\n </label>\r\n }\r\n\r\n <input\r\n type=\"text\"\r\n role=\"combobox\"\r\n aria-autocomplete=\"list\"\r\n [attr.id]=\"id() ? id() + '-inner' : null\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n [attr.aria-controls]=\"listboxId()\"\r\n [attr.aria-activedescendant]=\"\r\n isOpen() && activeIndex() >= 0 ? listboxId() + '-option-' + activeIndex() : null\r\n \"\r\n [attr.aria-invalid]=\"hasError() || null\"\r\n [attr.aria-describedby]=\"(helperText() || errorText()) && id() ? id() + '-helper' : null\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"isDisabled()\"\r\n [value]=\"searchQuery()\"\r\n [class]=\"inputClasses()\"\r\n (input)=\"onInputChange($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n (keydown)=\"onKeydown($event)\" />\r\n\r\n <ng-content />\r\n\r\n @if (helperText() && !hasError()) {\r\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-neutral-500\">{{ helperText() }}</p>\r\n }\r\n @if (errorText() && hasError()) {\r\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-danger-600\">{{ errorText() }}</p>\r\n }\r\n</div>\r\n\r\n<ng-template #panelTemplate>\r\n <ul\r\n role=\"listbox\"\r\n [attr.id]=\"listboxId()\"\r\n class=\"w-full bg-white border border-neutral-200 rounded-md shadow-lg py-1 max-h-60 overflow-auto\">\r\n @for (option of filteredOptions(); track option.value; let i = $index) {\r\n <li\r\n role=\"option\"\r\n [attr.id]=\"listboxId() + '-option-' + i\"\r\n [attr.aria-selected]=\"isOptionSelected(option)\"\r\n [attr.aria-disabled]=\"option.disabled || null\"\r\n [class]=\"optionClasses(i, option)\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n (click)=\"selectOption(option)\"\r\n (mouseenter)=\"!option.disabled && activeIndex.set(i)\">\r\n @if (itemTemplate()) {\r\n <ng-container\r\n *ngTemplateOutlet=\"itemTemplate()!; context: itemContext(option, i)\" />\r\n } @else {\r\n <span>{{ option.label }}</span>\r\n @if (isOptionSelected(option)) {\r\n <tailwind-icon icon=\"check\" [size]=\"16\" class=\"text-primary-600 shrink-0\" aria-hidden=\"true\" />\r\n }\r\n }\r\n </li>\r\n } @empty {\r\n <li role=\"option\" aria-disabled=\"true\" class=\"px-3 py-2 text-sm text-neutral-400 cursor-default select-none\">\r\n {{ placeholder() || 'Nessun risultato' }}\r\n </li>\r\n }\r\n </ul>\r\n</ng-template>\r\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2342
+ }
2343
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindAutocomplete, decorators: [{
2344
+ type: Component,
2345
+ args: [{ imports: [NgTemplateOutlet, TailwindIcon], selector: 'tailwind-autocomplete', providers: [
2346
+ {
2347
+ provide: NG_VALUE_ACCESSOR,
2348
+ useExisting: forwardRef(() => TailwindAutocomplete),
2349
+ multi: true
2350
+ }
2351
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-1.5\">\r\n @if (label()) {\r\n <label\r\n [attr.for]=\"id() ? id() + '-inner' : null\"\r\n class=\"text-sm font-medium text-neutral-700\"\r\n [class.text-danger-600]=\"hasError()\">\r\n {{ label() }}\r\n </label>\r\n }\r\n\r\n <input\r\n type=\"text\"\r\n role=\"combobox\"\r\n aria-autocomplete=\"list\"\r\n [attr.id]=\"id() ? id() + '-inner' : null\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n [attr.aria-controls]=\"listboxId()\"\r\n [attr.aria-activedescendant]=\"\r\n isOpen() && activeIndex() >= 0 ? listboxId() + '-option-' + activeIndex() : null\r\n \"\r\n [attr.aria-invalid]=\"hasError() || null\"\r\n [attr.aria-describedby]=\"(helperText() || errorText()) && id() ? id() + '-helper' : null\"\r\n [placeholder]=\"placeholder()\"\r\n [disabled]=\"isDisabled()\"\r\n [value]=\"searchQuery()\"\r\n [class]=\"inputClasses()\"\r\n (input)=\"onInputChange($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n (keydown)=\"onKeydown($event)\" />\r\n\r\n <ng-content />\r\n\r\n @if (helperText() && !hasError()) {\r\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-neutral-500\">{{ helperText() }}</p>\r\n }\r\n @if (errorText() && hasError()) {\r\n <p [attr.id]=\"id() ? id() + '-helper' : null\" class=\"text-xs text-danger-600\">{{ errorText() }}</p>\r\n }\r\n</div>\r\n\r\n<ng-template #panelTemplate>\r\n <ul\r\n role=\"listbox\"\r\n [attr.id]=\"listboxId()\"\r\n class=\"w-full bg-white border border-neutral-200 rounded-md shadow-lg py-1 max-h-60 overflow-auto\">\r\n @for (option of filteredOptions(); track option.value; let i = $index) {\r\n <li\r\n role=\"option\"\r\n [attr.id]=\"listboxId() + '-option-' + i\"\r\n [attr.aria-selected]=\"isOptionSelected(option)\"\r\n [attr.aria-disabled]=\"option.disabled || null\"\r\n [class]=\"optionClasses(i, option)\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n (click)=\"selectOption(option)\"\r\n (mouseenter)=\"!option.disabled && activeIndex.set(i)\">\r\n @if (itemTemplate()) {\r\n <ng-container\r\n *ngTemplateOutlet=\"itemTemplate()!; context: itemContext(option, i)\" />\r\n } @else {\r\n <span>{{ option.label }}</span>\r\n @if (isOptionSelected(option)) {\r\n <tailwind-icon icon=\"check\" [size]=\"16\" class=\"text-primary-600 shrink-0\" aria-hidden=\"true\" />\r\n }\r\n }\r\n </li>\r\n } @empty {\r\n <li role=\"option\" aria-disabled=\"true\" class=\"px-3 py-2 text-sm text-neutral-400 cursor-default select-none\">\r\n {{ placeholder() || 'Nessun risultato' }}\r\n </li>\r\n }\r\n </ul>\r\n</ng-template>\r\n", styles: [":host{display:block}\n"] }]
2352
+ }], ctorParameters: () => [], propDecorators: { panelTemplate: [{ type: i0.ViewChild, args: ['panelTemplate', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], helperText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helperText", required: false }] }], errorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorText", required: false }] }], hasError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasError", required: false }] }], filterLocally: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterLocally", required: false }] }], minSearchLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSearchLength", required: false }] }], debounceMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceMs", required: false }] }], forceSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "forceSelection", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], onSearch: [{ type: i0.Output, args: ["onSearch"] }], itemTemplate: [{ type: i0.ContentChild, args: ['item', { ...{ read: TemplateRef }, isSignal: true }] }] } });
2353
+
1953
2354
  class TailwindToggle extends TailwindComponent {
1954
2355
  /** Label text */
1955
2356
  label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
@@ -2186,11 +2587,11 @@ class TailwindAlert extends TailwindComponent {
2186
2587
  this.onDismiss.emit();
2187
2588
  }
2188
2589
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindAlert, deps: null, target: i0.ɵɵFactoryTarget.Component });
2189
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindAlert, isStandalone: true, selector: "tailwind-alert", inputs: { severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDismiss: "onDismiss" }, usesInheritance: true, ngImport: i0, template: "@if (!dismissed()) {\n <div [class]=\"computedClasses()\" role=\"alert\" [attr.aria-live]=\"severity() === 'danger' ? 'assertive' : 'polite'\">\n <!-- Icon -->\n <div class=\"shrink-0 mt-0.5\">\n @switch (severity()) {\n @case ('success') {\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n @case ('warning') {\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 6a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 6zm0 9a1 1 0 100-2 1 1 0 000 2z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n @case ('danger') {\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n @case ('info') {\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n }\n </div>\n\n <!-- Content -->\n <div class=\"flex-1 min-w-0\">\n @if (title()) {\n <h3 class=\"text-sm font-semibold mb-0.5\">{{ title() }}</h3>\n }\n <div class=\"text-sm\">\n <ng-content />\n </div>\n </div>\n\n <!-- Dismiss button -->\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"shrink-0 -m-1 p-1 rounded-md opacity-70 hover:opacity-100 transition-opacity focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 cursor-pointer\"\n [attr.aria-label]=\"'Dismiss alert'\"\n (click)=\"dismiss()\">\n <svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\" />\n </svg>\n </button>\n }\n </div>\n}\n", styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2590
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindAlert, isStandalone: true, selector: "tailwind-alert", inputs: { severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDismiss: "onDismiss" }, usesInheritance: true, ngImport: i0, template: "@if (!dismissed()) {\n <div [class]=\"computedClasses()\" role=\"alert\" [attr.aria-live]=\"severity() === 'danger' ? 'assertive' : 'polite'\">\n <!-- Icon -->\n <div class=\"shrink-0 mt-0.5\">\n @switch (severity()) {\n @case ('success') {\n <tailwind-icon icon=\"check-circle\" [size]=\"20\" />\n }\n @case ('warning') {\n <tailwind-icon icon=\"exclamation-triangle\" [size]=\"20\" />\n }\n @case ('danger') {\n <tailwind-icon icon=\"x-circle\" [size]=\"20\" />\n }\n @case ('info') {\n <tailwind-icon icon=\"information-circle\" [size]=\"20\" />\n }\n }\n </div>\n\n <!-- Content -->\n <div class=\"flex-1 min-w-0\">\n @if (title()) {\n <h3 class=\"text-sm font-semibold mb-0.5\">{{ title() }}</h3>\n }\n <div class=\"text-sm\">\n <ng-content />\n </div>\n </div>\n\n <!-- Dismiss button -->\n @if (dismissible()) {\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"x-mark\"\n class=\"shrink-0 -m-1 opacity-70 hover:opacity-100\"\n ariaLabel=\"Dismiss alert\"\n (onClick)=\"dismiss()\" />\n }\n </div>\n}\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }, { kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition", "ariaLabel"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2190
2591
  }
2191
2592
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindAlert, decorators: [{
2192
2593
  type: Component,
2193
- args: [{ selector: 'tailwind-alert', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (!dismissed()) {\n <div [class]=\"computedClasses()\" role=\"alert\" [attr.aria-live]=\"severity() === 'danger' ? 'assertive' : 'polite'\">\n <!-- Icon -->\n <div class=\"shrink-0 mt-0.5\">\n @switch (severity()) {\n @case ('success') {\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n @case ('warning') {\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 6a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 6zm0 9a1 1 0 100-2 1 1 0 000 2z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n @case ('danger') {\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n @case ('info') {\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z\"\n clip-rule=\"evenodd\" />\n </svg>\n }\n }\n </div>\n\n <!-- Content -->\n <div class=\"flex-1 min-w-0\">\n @if (title()) {\n <h3 class=\"text-sm font-semibold mb-0.5\">{{ title() }}</h3>\n }\n <div class=\"text-sm\">\n <ng-content />\n </div>\n </div>\n\n <!-- Dismiss button -->\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"shrink-0 -m-1 p-1 rounded-md opacity-70 hover:opacity-100 transition-opacity focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 cursor-pointer\"\n [attr.aria-label]=\"'Dismiss alert'\"\n (click)=\"dismiss()\">\n <svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\" />\n </svg>\n </button>\n }\n </div>\n}\n", styles: [":host{display:block}\n"] }]
2594
+ args: [{ imports: [TailwindIcon, TailwindButton], selector: 'tailwind-alert', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (!dismissed()) {\n <div [class]=\"computedClasses()\" role=\"alert\" [attr.aria-live]=\"severity() === 'danger' ? 'assertive' : 'polite'\">\n <!-- Icon -->\n <div class=\"shrink-0 mt-0.5\">\n @switch (severity()) {\n @case ('success') {\n <tailwind-icon icon=\"check-circle\" [size]=\"20\" />\n }\n @case ('warning') {\n <tailwind-icon icon=\"exclamation-triangle\" [size]=\"20\" />\n }\n @case ('danger') {\n <tailwind-icon icon=\"x-circle\" [size]=\"20\" />\n }\n @case ('info') {\n <tailwind-icon icon=\"information-circle\" [size]=\"20\" />\n }\n }\n </div>\n\n <!-- Content -->\n <div class=\"flex-1 min-w-0\">\n @if (title()) {\n <h3 class=\"text-sm font-semibold mb-0.5\">{{ title() }}</h3>\n }\n <div class=\"text-sm\">\n <ng-content />\n </div>\n </div>\n\n <!-- Dismiss button -->\n @if (dismissible()) {\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"x-mark\"\n class=\"shrink-0 -m-1 opacity-70 hover:opacity-100\"\n ariaLabel=\"Dismiss alert\"\n (onClick)=\"dismiss()\" />\n }\n </div>\n}\n", styles: [":host{display:block}\n"] }]
2194
2595
  }], propDecorators: { severity: [{ type: i0.Input, args: [{ isSignal: true, alias: "severity", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], onDismiss: [{ type: i0.Output, args: ["onDismiss"] }] } });
2195
2596
 
2196
2597
  class TailwindSpinner extends TailwindComponent {
@@ -2209,24 +2610,28 @@ class TailwindSpinner extends TailwindComponent {
2209
2610
  const orient = this.orientation() === 'vertical' ? 'flex-col' : '';
2210
2611
  return `${base} ${orient}`;
2211
2612
  }, ...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
2212
- spinnerClasses = computed(() => {
2613
+ iconPixelSize = computed(() => {
2213
2614
  const sizeMap = {
2214
- xs: 'w-3 h-3',
2215
- sm: 'w-4 h-4',
2216
- md: 'w-6 h-6',
2217
- lg: 'w-8 h-8',
2218
- xl: 'w-12 h-12'
2615
+ xs: 16,
2616
+ sm: 16,
2617
+ md: 24,
2618
+ lg: 32,
2619
+ xl: 48
2219
2620
  };
2621
+ return sizeMap[this.size()];
2622
+ }, ...(ngDevMode ? [{ debugName: "iconPixelSize" }] : /* istanbul ignore next */ []));
2623
+ iconClasses = computed(() => {
2220
2624
  const colorMap = {
2221
2625
  primary: 'text-primary-600',
2222
2626
  secondary: 'text-secondary-600',
2223
2627
  success: 'text-success-600',
2224
2628
  warning: 'text-warning-600',
2225
2629
  danger: 'text-danger-600',
2226
- info: 'text-info-600'
2630
+ info: 'text-info-600',
2631
+ transparent: 'text-neutral-400'
2227
2632
  };
2228
- return `tailwind-spinner-svg ${sizeMap[this.size()]} ${colorMap[this.color()]}`;
2229
- }, ...(ngDevMode ? [{ debugName: "spinnerClasses" }] : /* istanbul ignore next */ []));
2633
+ return `animate-spin ${colorMap[this.color()]}`;
2634
+ }, ...(ngDevMode ? [{ debugName: "iconClasses" }] : /* istanbul ignore next */ []));
2230
2635
  labelClasses = computed(() => {
2231
2636
  const sizeMap = {
2232
2637
  xs: 'text-xs',
@@ -2238,11 +2643,11 @@ class TailwindSpinner extends TailwindComponent {
2238
2643
  return `${sizeMap[this.size()]} ${this.color()} font-medium`;
2239
2644
  }, ...(ngDevMode ? [{ debugName: "labelClasses" }] : /* istanbul ignore next */ []));
2240
2645
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindSpinner, deps: null, target: i0.ɵɵFactoryTarget.Component });
2241
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindSpinner, isStandalone: true, selector: "tailwind-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div [class]=\"containerClasses()\" role=\"status\" [attr.aria-label]=\"ariaLabel()\">\n <svg [class]=\"spinnerClasses()\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-20\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path\n class=\"opacity-80\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n\n @if (label()) {\n <span [class]=\"labelClasses()\">{{ label() }}</span>\n }\n</div>\n", styles: [":host{display:inline-flex}@keyframes tailwind-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.tailwind-spinner-svg{animation:tailwind-spin .75s linear infinite}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2646
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindSpinner, isStandalone: true, selector: "tailwind-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div [class]=\"containerClasses()\" role=\"status\" [attr.aria-label]=\"ariaLabel()\">\n <tailwind-icon icon=\"arrow-path\" [size]=\"iconPixelSize()\" [class]=\"iconClasses()\" />\n\n @if (label()) {\n <span [class]=\"labelClasses()\">{{ label() }}</span>\n }\n</div>\n", styles: [":host{display:inline-flex}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2242
2647
  }
2243
2648
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindSpinner, decorators: [{
2244
2649
  type: Component,
2245
- args: [{ selector: 'tailwind-spinner', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"containerClasses()\" role=\"status\" [attr.aria-label]=\"ariaLabel()\">\n <svg [class]=\"spinnerClasses()\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-20\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path\n class=\"opacity-80\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n\n @if (label()) {\n <span [class]=\"labelClasses()\">{{ label() }}</span>\n }\n</div>\n", styles: [":host{display:inline-flex}@keyframes tailwind-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.tailwind-spinner-svg{animation:tailwind-spin .75s linear infinite}\n"] }]
2650
+ args: [{ imports: [TailwindIcon], selector: 'tailwind-spinner', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"containerClasses()\" role=\"status\" [attr.aria-label]=\"ariaLabel()\">\n <tailwind-icon icon=\"arrow-path\" [size]=\"iconPixelSize()\" [class]=\"iconClasses()\" />\n\n @if (label()) {\n <span [class]=\"labelClasses()\">{{ label() }}</span>\n }\n</div>\n", styles: [":host{display:inline-flex}\n"] }]
2246
2651
  }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }] } });
2247
2652
 
2248
2653
  class TailwindModal extends TailwindComponent {
@@ -2297,11 +2702,11 @@ class TailwindModal extends TailwindComponent {
2297
2702
  }, 200);
2298
2703
  }
2299
2704
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
2300
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindModal, isStandalone: true, selector: "tailwind-modal", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, showCloseButton: { classPropertyName: "showCloseButton", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdrop: { classPropertyName: "closeOnBackdrop", publicName: "closeOnBackdrop", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClose: "onClose" }, viewQueries: [{ propertyName: "modalPanel", first: true, predicate: ["modalPanel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (isOpen()) {\n <!-- Backdrop -->\n <div\n class=\"fixed inset-0 bg-black/50 backdrop-blur-sm z-1040 transition-opacity duration-200\"\n [class.opacity-100]=\"isVisible()\"\n [class.opacity-0]=\"!isVisible()\"\n (click)=\"closeOnBackdrop() && close()\"\n aria-hidden=\"true\"></div>\n\n <!-- Modal -->\n <div\n role=\"dialog\"\n class=\"fixed inset-0 z-1050 overflow-y-auto\"\n [attr.aria-modal]=\"true\"\n (keydown.escape)=\"closeOnEscape() && close()\">\n <div class=\"flex min-h-full items-center justify-center p-4\">\n <div #modalPanel [class]=\"panelClasses()\" tabindex=\"-1\">\n <!-- Header -->\n <div class=\"flex items-center justify-between px-6 py-4 border-b border-neutral-200\">\n <h2 class=\"text-lg font-semibold text-neutral-900 pr-2\">\n <ng-content />\n </h2>\n @if (showCloseButton()) {\n <button\n type=\"button\"\n class=\"p-1.5 -m-1.5 shrink-0 rounded-lg text-neutral-400 hover:text-neutral-600 hover:bg-neutral-100 transition-colors cursor-pointer\"\n aria-label=\"Close\"\n (click)=\"close()\">\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\" />\n </svg>\n </button>\n }\n </div>\n\n <!-- Body -->\n <div class=\"px-6 py-5\">\n <ng-content select=\"[tailwind-modal-content]\" />\n </div>\n\n <!-- Footer -->\n <div class=\"border-t border-neutral-200 px-6 py-4\">\n <ng-content select=\"[tailwind-modal-footer]\" />\n </div>\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2705
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindModal, isStandalone: true, selector: "tailwind-modal", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, showCloseButton: { classPropertyName: "showCloseButton", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdrop: { classPropertyName: "closeOnBackdrop", publicName: "closeOnBackdrop", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClose: "onClose" }, viewQueries: [{ propertyName: "modalPanel", first: true, predicate: ["modalPanel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (isOpen()) {\n <!-- Backdrop -->\n <div\n class=\"fixed inset-0 bg-black/50 backdrop-blur-sm z-1040 transition-opacity duration-200\"\n [class.opacity-100]=\"isVisible()\"\n [class.opacity-0]=\"!isVisible()\"\n (click)=\"closeOnBackdrop() && close()\"\n aria-hidden=\"true\"></div>\n\n <!-- Modal -->\n <div\n role=\"dialog\"\n class=\"fixed inset-0 z-1050 overflow-y-auto\"\n [attr.aria-modal]=\"true\"\n (keydown.escape)=\"closeOnEscape() && close()\">\n <div class=\"flex min-h-full items-center justify-center p-4\">\n <div #modalPanel [class]=\"panelClasses()\" tabindex=\"-1\">\n <!-- Header -->\n <div class=\"flex items-center justify-between px-6 py-4 border-b border-neutral-200\">\n <h2 class=\"text-lg font-semibold text-neutral-900 pr-2\">\n <ng-content />\n </h2>\n @if (showCloseButton()) {\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"x-mark\"\n class=\"shrink-0 -m-1.5\"\n ariaLabel=\"Close\"\n (onClick)=\"close()\" />\n }\n </div>\n\n <!-- Body -->\n <div class=\"px-6 py-5\">\n <ng-content select=\"[tailwind-modal-content]\" />\n </div>\n\n <!-- Footer -->\n <div class=\"border-t border-neutral-200 px-6 py-4\">\n <ng-content select=\"[tailwind-modal-footer]\" />\n </div>\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}\n"], dependencies: [{ kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition", "ariaLabel"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2301
2706
  }
2302
2707
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindModal, decorators: [{
2303
2708
  type: Component,
2304
- args: [{ selector: 'tailwind-modal', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (isOpen()) {\n <!-- Backdrop -->\n <div\n class=\"fixed inset-0 bg-black/50 backdrop-blur-sm z-1040 transition-opacity duration-200\"\n [class.opacity-100]=\"isVisible()\"\n [class.opacity-0]=\"!isVisible()\"\n (click)=\"closeOnBackdrop() && close()\"\n aria-hidden=\"true\"></div>\n\n <!-- Modal -->\n <div\n role=\"dialog\"\n class=\"fixed inset-0 z-1050 overflow-y-auto\"\n [attr.aria-modal]=\"true\"\n (keydown.escape)=\"closeOnEscape() && close()\">\n <div class=\"flex min-h-full items-center justify-center p-4\">\n <div #modalPanel [class]=\"panelClasses()\" tabindex=\"-1\">\n <!-- Header -->\n <div class=\"flex items-center justify-between px-6 py-4 border-b border-neutral-200\">\n <h2 class=\"text-lg font-semibold text-neutral-900 pr-2\">\n <ng-content />\n </h2>\n @if (showCloseButton()) {\n <button\n type=\"button\"\n class=\"p-1.5 -m-1.5 shrink-0 rounded-lg text-neutral-400 hover:text-neutral-600 hover:bg-neutral-100 transition-colors cursor-pointer\"\n aria-label=\"Close\"\n (click)=\"close()\">\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\" />\n </svg>\n </button>\n }\n </div>\n\n <!-- Body -->\n <div class=\"px-6 py-5\">\n <ng-content select=\"[tailwind-modal-content]\" />\n </div>\n\n <!-- Footer -->\n <div class=\"border-t border-neutral-200 px-6 py-4\">\n <ng-content select=\"[tailwind-modal-footer]\" />\n </div>\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}\n"] }]
2709
+ args: [{ imports: [TailwindButton], selector: 'tailwind-modal', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (isOpen()) {\n <!-- Backdrop -->\n <div\n class=\"fixed inset-0 bg-black/50 backdrop-blur-sm z-1040 transition-opacity duration-200\"\n [class.opacity-100]=\"isVisible()\"\n [class.opacity-0]=\"!isVisible()\"\n (click)=\"closeOnBackdrop() && close()\"\n aria-hidden=\"true\"></div>\n\n <!-- Modal -->\n <div\n role=\"dialog\"\n class=\"fixed inset-0 z-1050 overflow-y-auto\"\n [attr.aria-modal]=\"true\"\n (keydown.escape)=\"closeOnEscape() && close()\">\n <div class=\"flex min-h-full items-center justify-center p-4\">\n <div #modalPanel [class]=\"panelClasses()\" tabindex=\"-1\">\n <!-- Header -->\n <div class=\"flex items-center justify-between px-6 py-4 border-b border-neutral-200\">\n <h2 class=\"text-lg font-semibold text-neutral-900 pr-2\">\n <ng-content />\n </h2>\n @if (showCloseButton()) {\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"x-mark\"\n class=\"shrink-0 -m-1.5\"\n ariaLabel=\"Close\"\n (onClick)=\"close()\" />\n }\n </div>\n\n <!-- Body -->\n <div class=\"px-6 py-5\">\n <ng-content select=\"[tailwind-modal-content]\" />\n </div>\n\n <!-- Footer -->\n <div class=\"border-t border-neutral-200 px-6 py-4\">\n <ng-content select=\"[tailwind-modal-footer]\" />\n </div>\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}\n"] }]
2305
2710
  }], ctorParameters: () => [], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], showCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], closeOnBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdrop", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], onClose: [{ type: i0.Output, args: ["onClose"] }], modalPanel: [{ type: i0.ViewChild, args: ['modalPanel', { isSignal: true }] }] } });
2306
2711
 
2307
2712
  class TailwindTab extends TailwindComponent {
@@ -2639,11 +3044,11 @@ class TailwindDrawer extends TailwindComponent {
2639
3044
  }, 300);
2640
3045
  }
2641
3046
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindDrawer, deps: null, target: i0.ɵɵFactoryTarget.Component });
2642
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindDrawer, isStandalone: true, selector: "tailwind-drawer", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdrop: { classPropertyName: "closeOnBackdrop", publicName: "closeOnBackdrop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClose: "onClose" }, usesInheritance: true, ngImport: i0, template: "@if (isOpen()) {\n <!-- Backdrop -->\n <div\n class=\"fixed inset-0 bg-black/40 backdrop-blur-sm z-1040 transition-opacity duration-300\"\n [class.opacity-100]=\"isVisible()\"\n [class.opacity-0]=\"!isVisible()\"\n (click)=\"closeOnBackdrop() && close()\"\n aria-hidden=\"true\"></div>\n\n <!-- Drawer Panel -->\n <div [class]=\"panelClasses()\" role=\"dialog\" [attr.aria-modal]=\"true\" [attr.aria-label]=\"title()\">\n <!-- Header -->\n <div class=\"flex items-center justify-between px-6 py-4 border-b border-neutral-200\">\n @if (title()) {\n <h2 class=\"text-lg font-semibold text-neutral-900\">{{ title() }}</h2>\n }\n <button\n type=\"button\"\n class=\"p-1.5 -m-1.5 rounded-lg text-neutral-400 hover:text-neutral-600 hover:bg-neutral-100 transition-colors ml-auto cursor-pointer\"\n aria-label=\"Close\"\n (click)=\"close()\">\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\" />\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"flex-1 overflow-y-auto px-6 py-5\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n <ng-content select=\"[tailwind-drawer-footer]\" />\n </div>\n}\n", styles: [":host{display:contents}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3047
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindDrawer, isStandalone: true, selector: "tailwind-drawer", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdrop: { classPropertyName: "closeOnBackdrop", publicName: "closeOnBackdrop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClose: "onClose" }, usesInheritance: true, ngImport: i0, template: "@if (isOpen()) {\n <!-- Backdrop -->\n <div\n class=\"fixed inset-0 bg-black/40 backdrop-blur-sm z-1040 transition-opacity duration-300\"\n [class.opacity-100]=\"isVisible()\"\n [class.opacity-0]=\"!isVisible()\"\n (click)=\"closeOnBackdrop() && close()\"\n aria-hidden=\"true\"></div>\n\n <!-- Drawer Panel -->\n <div [class]=\"panelClasses()\" role=\"dialog\" [attr.aria-modal]=\"true\" [attr.aria-label]=\"title()\">\n <!-- Header -->\n <div class=\"flex items-center justify-between px-6 py-4 border-b border-neutral-200\">\n @if (title()) {\n <h2 class=\"text-lg font-semibold text-neutral-900\">{{ title() }}</h2>\n }\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"x-mark\"\n class=\"ml-auto shrink-0 -m-1.5\"\n ariaLabel=\"Close\"\n (onClick)=\"close()\" />\n </div>\n\n <!-- Body -->\n <div class=\"flex-1 overflow-y-auto px-6 py-5\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n <ng-content select=\"[tailwind-drawer-footer]\" />\n </div>\n}\n", styles: [":host{display:contents}\n"], dependencies: [{ kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition", "ariaLabel"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2643
3048
  }
2644
3049
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindDrawer, decorators: [{
2645
3050
  type: Component,
2646
- args: [{ selector: 'tailwind-drawer', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (isOpen()) {\n <!-- Backdrop -->\n <div\n class=\"fixed inset-0 bg-black/40 backdrop-blur-sm z-1040 transition-opacity duration-300\"\n [class.opacity-100]=\"isVisible()\"\n [class.opacity-0]=\"!isVisible()\"\n (click)=\"closeOnBackdrop() && close()\"\n aria-hidden=\"true\"></div>\n\n <!-- Drawer Panel -->\n <div [class]=\"panelClasses()\" role=\"dialog\" [attr.aria-modal]=\"true\" [attr.aria-label]=\"title()\">\n <!-- Header -->\n <div class=\"flex items-center justify-between px-6 py-4 border-b border-neutral-200\">\n @if (title()) {\n <h2 class=\"text-lg font-semibold text-neutral-900\">{{ title() }}</h2>\n }\n <button\n type=\"button\"\n class=\"p-1.5 -m-1.5 rounded-lg text-neutral-400 hover:text-neutral-600 hover:bg-neutral-100 transition-colors ml-auto cursor-pointer\"\n aria-label=\"Close\"\n (click)=\"close()\">\n <svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\" />\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"flex-1 overflow-y-auto px-6 py-5\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n <ng-content select=\"[tailwind-drawer-footer]\" />\n </div>\n}\n", styles: [":host{display:contents}\n"] }]
3051
+ args: [{ imports: [TailwindButton], selector: 'tailwind-drawer', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (isOpen()) {\n <!-- Backdrop -->\n <div\n class=\"fixed inset-0 bg-black/40 backdrop-blur-sm z-1040 transition-opacity duration-300\"\n [class.opacity-100]=\"isVisible()\"\n [class.opacity-0]=\"!isVisible()\"\n (click)=\"closeOnBackdrop() && close()\"\n aria-hidden=\"true\"></div>\n\n <!-- Drawer Panel -->\n <div [class]=\"panelClasses()\" role=\"dialog\" [attr.aria-modal]=\"true\" [attr.aria-label]=\"title()\">\n <!-- Header -->\n <div class=\"flex items-center justify-between px-6 py-4 border-b border-neutral-200\">\n @if (title()) {\n <h2 class=\"text-lg font-semibold text-neutral-900\">{{ title() }}</h2>\n }\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"x-mark\"\n class=\"ml-auto shrink-0 -m-1.5\"\n ariaLabel=\"Close\"\n (onClick)=\"close()\" />\n </div>\n\n <!-- Body -->\n <div class=\"flex-1 overflow-y-auto px-6 py-5\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n <ng-content select=\"[tailwind-drawer-footer]\" />\n </div>\n}\n", styles: [":host{display:contents}\n"] }]
2647
3052
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], closeOnBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdrop", required: false }] }], onClose: [{ type: i0.Output, args: ["onClose"] }] } });
2648
3053
 
2649
3054
  class TailwindBreadcrumb extends TailwindComponent {
@@ -2718,11 +3123,11 @@ class TailwindPagination extends TailwindComponent {
2718
3123
  }
2719
3124
  }
2720
3125
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindPagination, deps: null, target: i0.ɵɵFactoryTarget.Component });
2721
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindPagination, isStandalone: true, selector: "tailwind-pagination", inputs: { totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, lengthOptions: { classPropertyName: "lengthOptions", publicName: "lengthOptions", isSignal: true, isRequired: false, transformFunction: null }, currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, summary: { classPropertyName: "summary", publicName: "summary", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageSize: "pageSizeChange", currentPage: "currentPageChange", onPageChange: "onPageChange", onPageSizeChange: "onPageSizeChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-wrap items-center justify-between gap-4 w-full\">\n <div class=\"flex flex-wrap items-center gap-3 min-w-0\">\n @if (summary()) {\n <span class=\"text-sm text-neutral-700 dark:text-neutral-300\">\n {{ summaryText() }}\n </span>\n }\n\n @if (lengthOptions().length > 0) {\n <div class=\"w-20 shrink-0\">\n <tailwind-select\n size=\"sm\"\n [options]=\"pageSizeSelectOptions()\"\n [value]=\"pageSize()\"\n (valueChange)=\"onPageSizeValueChange($event)\" />\n </div>\n }\n </div>\n\n <nav [attr.aria-label]=\"ariaLabel()\" class=\"flex items-center gap-1\">\n <!-- Previous -->\n <button\n type=\"button\"\n [disabled]=\"currentPage() <= 1\"\n (click)=\"goToPage(currentPage() - 1)\"\n class=\"p-2 rounded-lg text-neutral-500 hover:bg-neutral-100 disabled:opacity-40 disabled:cursor-not-allowed transition-colors cursor-pointer\">\n <svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n\n @for (page of visiblePages(); track page) {\n <button\n type=\"button\"\n (click)=\"goToPage(page)\"\n class=\"min-w-8 h-8 px-2 rounded-lg text-sm font-medium transition-colors cursor-pointer\"\n [class.bg-primary-600]=\"page === currentPage()\"\n [class.text-white]=\"page === currentPage()\"\n [class.text-neutral-600]=\"page !== currentPage()\"\n [class.hover:bg-neutral-100]=\"page !== currentPage()\">\n {{ page }}\n </button>\n }\n\n <!-- Next -->\n <button\n type=\"button\"\n [disabled]=\"currentPage() >= totalPages()\"\n (click)=\"goToPage(currentPage() + 1)\"\n class=\"p-2 rounded-lg text-neutral-500 hover:bg-neutral-100 disabled:opacity-40 disabled:cursor-not-allowed transition-colors cursor-pointer\">\n <svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n </nav>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: TailwindSelect, selector: "tailwind-select", inputs: ["label", "placeholder", "options", "size", "helperText", "errorText", "hasError", "multiple", "value"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3126
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindPagination, isStandalone: true, selector: "tailwind-pagination", inputs: { totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, lengthOptions: { classPropertyName: "lengthOptions", publicName: "lengthOptions", isSignal: true, isRequired: false, transformFunction: null }, currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, summary: { classPropertyName: "summary", publicName: "summary", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageSize: "pageSizeChange", currentPage: "currentPageChange", onPageChange: "onPageChange", onPageSizeChange: "onPageSizeChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-wrap items-center justify-between gap-4 w-full\">\n <div class=\"flex flex-wrap items-center gap-3 min-w-0\">\n @if (summary()) {\n <span class=\"text-sm text-neutral-700 dark:text-neutral-300\">\n {{ summaryText() }}\n </span>\n }\n\n @if (lengthOptions().length > 0) {\n <div class=\"w-20 shrink-0\">\n <tailwind-select\n size=\"sm\"\n [options]=\"pageSizeSelectOptions()\"\n [value]=\"pageSize()\"\n (valueChange)=\"onPageSizeValueChange($event)\" />\n </div>\n }\n </div>\n\n <nav [attr.aria-label]=\"ariaLabel()\" class=\"flex items-center gap-1\">\n <!-- Previous -->\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-left\"\n [disabled]=\"currentPage() <= 1\"\n ariaLabel=\"Previous page\"\n (onClick)=\"goToPage(currentPage() - 1)\" />\n\n @for (page of visiblePages(); track page) {\n <tailwind-button\n size=\"sm\"\n [kind]=\"page === currentPage() ? 'flat' : 'ghost'\"\n [color]=\"page === currentPage() ? 'primary' : 'secondary'\"\n class=\"min-w-8\"\n (onClick)=\"goToPage(page)\">\n {{ page }}\n </tailwind-button>\n }\n\n <!-- Next -->\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-right\"\n [disabled]=\"currentPage() >= totalPages()\"\n ariaLabel=\"Next page\"\n (onClick)=\"goToPage(currentPage() + 1)\" />\n </nav>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: TailwindSelect, selector: "tailwind-select", inputs: ["label", "placeholder", "options", "size", "helperText", "errorText", "hasError", "multiple", "value"], outputs: ["valueChange"] }, { kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition", "ariaLabel"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2722
3127
  }
2723
3128
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindPagination, decorators: [{
2724
3129
  type: Component,
2725
- args: [{ selector: 'tailwind-pagination', imports: [TailwindSelect], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-wrap items-center justify-between gap-4 w-full\">\n <div class=\"flex flex-wrap items-center gap-3 min-w-0\">\n @if (summary()) {\n <span class=\"text-sm text-neutral-700 dark:text-neutral-300\">\n {{ summaryText() }}\n </span>\n }\n\n @if (lengthOptions().length > 0) {\n <div class=\"w-20 shrink-0\">\n <tailwind-select\n size=\"sm\"\n [options]=\"pageSizeSelectOptions()\"\n [value]=\"pageSize()\"\n (valueChange)=\"onPageSizeValueChange($event)\" />\n </div>\n }\n </div>\n\n <nav [attr.aria-label]=\"ariaLabel()\" class=\"flex items-center gap-1\">\n <!-- Previous -->\n <button\n type=\"button\"\n [disabled]=\"currentPage() <= 1\"\n (click)=\"goToPage(currentPage() - 1)\"\n class=\"p-2 rounded-lg text-neutral-500 hover:bg-neutral-100 disabled:opacity-40 disabled:cursor-not-allowed transition-colors cursor-pointer\">\n <svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n\n @for (page of visiblePages(); track page) {\n <button\n type=\"button\"\n (click)=\"goToPage(page)\"\n class=\"min-w-8 h-8 px-2 rounded-lg text-sm font-medium transition-colors cursor-pointer\"\n [class.bg-primary-600]=\"page === currentPage()\"\n [class.text-white]=\"page === currentPage()\"\n [class.text-neutral-600]=\"page !== currentPage()\"\n [class.hover:bg-neutral-100]=\"page !== currentPage()\">\n {{ page }}\n </button>\n }\n\n <!-- Next -->\n <button\n type=\"button\"\n [disabled]=\"currentPage() >= totalPages()\"\n (click)=\"goToPage(currentPage() + 1)\"\n class=\"p-2 rounded-lg text-neutral-500 hover:bg-neutral-100 disabled:opacity-40 disabled:cursor-not-allowed transition-colors cursor-pointer\">\n <svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n </nav>\n</div>\n", styles: [":host{display:block}\n"] }]
3130
+ args: [{ selector: 'tailwind-pagination', imports: [TailwindSelect, TailwindButton], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-wrap items-center justify-between gap-4 w-full\">\n <div class=\"flex flex-wrap items-center gap-3 min-w-0\">\n @if (summary()) {\n <span class=\"text-sm text-neutral-700 dark:text-neutral-300\">\n {{ summaryText() }}\n </span>\n }\n\n @if (lengthOptions().length > 0) {\n <div class=\"w-20 shrink-0\">\n <tailwind-select\n size=\"sm\"\n [options]=\"pageSizeSelectOptions()\"\n [value]=\"pageSize()\"\n (valueChange)=\"onPageSizeValueChange($event)\" />\n </div>\n }\n </div>\n\n <nav [attr.aria-label]=\"ariaLabel()\" class=\"flex items-center gap-1\">\n <!-- Previous -->\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-left\"\n [disabled]=\"currentPage() <= 1\"\n ariaLabel=\"Previous page\"\n (onClick)=\"goToPage(currentPage() - 1)\" />\n\n @for (page of visiblePages(); track page) {\n <tailwind-button\n size=\"sm\"\n [kind]=\"page === currentPage() ? 'flat' : 'ghost'\"\n [color]=\"page === currentPage() ? 'primary' : 'secondary'\"\n class=\"min-w-8\"\n (onClick)=\"goToPage(page)\">\n {{ page }}\n </tailwind-button>\n }\n\n <!-- Next -->\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-right\"\n [disabled]=\"currentPage() >= totalPages()\"\n ariaLabel=\"Next page\"\n (onClick)=\"goToPage(currentPage() + 1)\" />\n </nav>\n</div>\n", styles: [":host{display:block}\n"] }]
2726
3131
  }], propDecorators: { totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: true }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }, { type: i0.Output, args: ["pageSizeChange"] }], lengthOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "lengthOptions", required: false }] }], currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], summary: [{ type: i0.Input, args: [{ isSignal: true, alias: "summary", required: false }] }], onPageChange: [{ type: i0.Output, args: ["onPageChange"] }], onPageSizeChange: [{ type: i0.Output, args: ["onPageSizeChange"] }] } });
2727
3132
 
2728
3133
  class TailwindTag extends TailwindComponent {
@@ -2867,14 +3272,14 @@ class TailwindTable extends TailwindComponent {
2867
3272
  this.sort(key);
2868
3273
  }
2869
3274
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
2870
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindTable, isStandalone: true, selector: "tailwind-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, emptyColspan: { classPropertyName: "emptyColspan", publicName: "emptyColspan", isSignal: true, isRequired: false, transformFunction: null }, paginated: { classPropertyName: "paginated", publicName: "paginated", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSortChange: "onSortChange", onSelectionChange: "onSelectionChange" }, host: { listeners: { "click": "onSortZoneClick($event)", "keydown": "onSortZoneKeydown($event)" }, properties: { "attr.data-tw-sort-key": "sortKey()", "attr.data-tw-sort-dir": "sortDir()" } }, queries: [{ propertyName: "rowTemplate", first: true, predicate: TailwindTableRowDirective, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"w-full overflow-x-auto rounded-lg border border-neutral-200\">\n @if (loading()) {\n <div class=\"flex items-center justify-center py-16 text-neutral-400\">\n <svg class=\"animate-spin w-6 h-6 mr-2\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8v8z\" />\n </svg>\n Loading...\n </div>\n } @else {\n <!-- `table-fixed`: consente `w-*` / `min-w-*` / `max-w-*` sulle celle e sugli `th` proiettati. -->\n <table class=\"w-full min-w-0 table-fixed text-sm text-left divide-y divide-neutral-100\">\n <ng-content select=\"thead\" />\n @for (row of displayedData(); track $index; let i = $index) {\n <ng-container *ngTemplateOutlet=\"rowTemplate().templateRef; context: rowContext(row, i)\" />\n } @empty {\n <tbody>\n <tr>\n <td [attr.colspan]=\"emptyColspan()\">\n {{ emptyMessage() }}\n </td>\n </tr>\n </tbody>\n }\n </table>\n\n @if (paginated() && data().length > 0) {\n <div class=\"px-4 py-3 border-t border-neutral-200 bg-white\">\n <tailwind-pagination\n [totalItems]=\"pagination()?.totalItems ?? data().length\"\n [pageSize]=\"pageSize()\"\n (pageSizeChange)=\"pageSize.set($event)\"\n [lengthOptions]=\"paginationLengthOptions()\"\n [currentPage]=\"currentPage()\"\n (onPageChange)=\"currentPage.set($event)\"\n [ariaLabel]=\"pagination()?.ariaLabel ?? 'Pagination'\"\n [summary]=\"paginationSummary()\">\n </tailwind-pagination>\n </div>\n }\n }\n</div>\n", styles: ["@layer components{:host{display:block}:host ::ng-deep :where(thead){background-color:var(--color-neutral-50);border-bottom:1px solid var(--color-neutral-200)}:host ::ng-deep :where(thead th){padding:.75rem 1rem;font-weight:600;color:var(--color-neutral-700);text-align:left;white-space:nowrap;vertical-align:middle}:host ::ng-deep :where(tbody td){padding:.75rem 1rem;color:var(--color-neutral-700)}:host ::ng-deep :where(tbody td[colspan]){padding:2rem 1rem;text-align:center;color:var(--color-neutral-400)}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TailwindPagination, selector: "tailwind-pagination", inputs: ["totalItems", "pageSize", "lengthOptions", "currentPage", "ariaLabel", "summary"], outputs: ["pageSizeChange", "currentPageChange", "onPageChange", "onPageSizeChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3275
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindTable, isStandalone: true, selector: "tailwind-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, emptyColspan: { classPropertyName: "emptyColspan", publicName: "emptyColspan", isSignal: true, isRequired: false, transformFunction: null }, paginated: { classPropertyName: "paginated", publicName: "paginated", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSortChange: "onSortChange", onSelectionChange: "onSelectionChange" }, host: { listeners: { "click": "onSortZoneClick($event)", "keydown": "onSortZoneKeydown($event)" }, properties: { "attr.data-tw-sort-key": "sortKey()", "attr.data-tw-sort-dir": "sortDir()" } }, queries: [{ propertyName: "rowTemplate", first: true, predicate: TailwindTableRowDirective, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"w-full overflow-x-auto rounded-lg border border-neutral-200\">\n @if (loading()) {\n <div class=\"flex items-center justify-center py-16 text-neutral-400\">\n <tailwind-icon icon=\"arrow-path\" [size]=\"24\" class=\"animate-spin mr-2 text-neutral-400\" />\n Loading...\n </div>\n } @else {\n <!-- `table-fixed`: consente `w-*` / `min-w-*` / `max-w-*` sulle celle e sugli `th` proiettati. -->\n <table class=\"w-full min-w-0 table-fixed text-sm text-left divide-y divide-neutral-100\">\n <ng-content select=\"thead\" />\n @for (row of displayedData(); track $index; let i = $index) {\n <ng-container *ngTemplateOutlet=\"rowTemplate().templateRef; context: rowContext(row, i)\" />\n } @empty {\n <tbody>\n <tr>\n <td [attr.colspan]=\"emptyColspan()\">\n {{ emptyMessage() }}\n </td>\n </tr>\n </tbody>\n }\n </table>\n\n @if (paginated() && data().length > 0) {\n <div class=\"px-4 py-3 border-t border-neutral-200 bg-white\">\n <tailwind-pagination\n [totalItems]=\"pagination()?.totalItems ?? data().length\"\n [pageSize]=\"pageSize()\"\n (pageSizeChange)=\"pageSize.set($event)\"\n [lengthOptions]=\"paginationLengthOptions()\"\n [currentPage]=\"currentPage()\"\n (onPageChange)=\"currentPage.set($event)\"\n [ariaLabel]=\"pagination()?.ariaLabel ?? 'Pagination'\"\n [summary]=\"paginationSummary()\">\n </tailwind-pagination>\n </div>\n }\n }\n</div>\n", styles: ["@layer components{:host{display:block}:host ::ng-deep :where(thead){background-color:var(--color-neutral-50);border-bottom:1px solid var(--color-neutral-200)}:host ::ng-deep :where(thead th){padding:.75rem 1rem;font-weight:600;color:var(--color-neutral-700);text-align:left;white-space:nowrap;vertical-align:middle}:host ::ng-deep :where(tbody td){padding:.75rem 1rem;color:var(--color-neutral-700)}:host ::ng-deep :where(tbody td[colspan]){padding:2rem 1rem;text-align:center;color:var(--color-neutral-400)}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TailwindPagination, selector: "tailwind-pagination", inputs: ["totalItems", "pageSize", "lengthOptions", "currentPage", "ariaLabel", "summary"], outputs: ["pageSizeChange", "currentPageChange", "onPageChange", "onPageSizeChange"] }, { kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2871
3276
  }
2872
3277
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindTable, decorators: [{
2873
3278
  type: Component,
2874
- args: [{ selector: 'tailwind-table', imports: [NgTemplateOutlet, TailwindPagination], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3279
+ args: [{ selector: 'tailwind-table', imports: [NgTemplateOutlet, TailwindPagination, TailwindIcon], changeDetection: ChangeDetectionStrategy.OnPush, host: {
2875
3280
  '[attr.data-tw-sort-key]': 'sortKey()',
2876
3281
  '[attr.data-tw-sort-dir]': 'sortDir()'
2877
- }, template: "<div class=\"w-full overflow-x-auto rounded-lg border border-neutral-200\">\n @if (loading()) {\n <div class=\"flex items-center justify-center py-16 text-neutral-400\">\n <svg class=\"animate-spin w-6 h-6 mr-2\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8v8z\" />\n </svg>\n Loading...\n </div>\n } @else {\n <!-- `table-fixed`: consente `w-*` / `min-w-*` / `max-w-*` sulle celle e sugli `th` proiettati. -->\n <table class=\"w-full min-w-0 table-fixed text-sm text-left divide-y divide-neutral-100\">\n <ng-content select=\"thead\" />\n @for (row of displayedData(); track $index; let i = $index) {\n <ng-container *ngTemplateOutlet=\"rowTemplate().templateRef; context: rowContext(row, i)\" />\n } @empty {\n <tbody>\n <tr>\n <td [attr.colspan]=\"emptyColspan()\">\n {{ emptyMessage() }}\n </td>\n </tr>\n </tbody>\n }\n </table>\n\n @if (paginated() && data().length > 0) {\n <div class=\"px-4 py-3 border-t border-neutral-200 bg-white\">\n <tailwind-pagination\n [totalItems]=\"pagination()?.totalItems ?? data().length\"\n [pageSize]=\"pageSize()\"\n (pageSizeChange)=\"pageSize.set($event)\"\n [lengthOptions]=\"paginationLengthOptions()\"\n [currentPage]=\"currentPage()\"\n (onPageChange)=\"currentPage.set($event)\"\n [ariaLabel]=\"pagination()?.ariaLabel ?? 'Pagination'\"\n [summary]=\"paginationSummary()\">\n </tailwind-pagination>\n </div>\n }\n }\n</div>\n", styles: ["@layer components{:host{display:block}:host ::ng-deep :where(thead){background-color:var(--color-neutral-50);border-bottom:1px solid var(--color-neutral-200)}:host ::ng-deep :where(thead th){padding:.75rem 1rem;font-weight:600;color:var(--color-neutral-700);text-align:left;white-space:nowrap;vertical-align:middle}:host ::ng-deep :where(tbody td){padding:.75rem 1rem;color:var(--color-neutral-700)}:host ::ng-deep :where(tbody td[colspan]){padding:2rem 1rem;text-align:center;color:var(--color-neutral-400)}}\n"] }]
3282
+ }, template: "<div class=\"w-full overflow-x-auto rounded-lg border border-neutral-200\">\n @if (loading()) {\n <div class=\"flex items-center justify-center py-16 text-neutral-400\">\n <tailwind-icon icon=\"arrow-path\" [size]=\"24\" class=\"animate-spin mr-2 text-neutral-400\" />\n Loading...\n </div>\n } @else {\n <!-- `table-fixed`: consente `w-*` / `min-w-*` / `max-w-*` sulle celle e sugli `th` proiettati. -->\n <table class=\"w-full min-w-0 table-fixed text-sm text-left divide-y divide-neutral-100\">\n <ng-content select=\"thead\" />\n @for (row of displayedData(); track $index; let i = $index) {\n <ng-container *ngTemplateOutlet=\"rowTemplate().templateRef; context: rowContext(row, i)\" />\n } @empty {\n <tbody>\n <tr>\n <td [attr.colspan]=\"emptyColspan()\">\n {{ emptyMessage() }}\n </td>\n </tr>\n </tbody>\n }\n </table>\n\n @if (paginated() && data().length > 0) {\n <div class=\"px-4 py-3 border-t border-neutral-200 bg-white\">\n <tailwind-pagination\n [totalItems]=\"pagination()?.totalItems ?? data().length\"\n [pageSize]=\"pageSize()\"\n (pageSizeChange)=\"pageSize.set($event)\"\n [lengthOptions]=\"paginationLengthOptions()\"\n [currentPage]=\"currentPage()\"\n (onPageChange)=\"currentPage.set($event)\"\n [ariaLabel]=\"pagination()?.ariaLabel ?? 'Pagination'\"\n [summary]=\"paginationSummary()\">\n </tailwind-pagination>\n </div>\n }\n }\n</div>\n", styles: ["@layer components{:host{display:block}:host ::ng-deep :where(thead){background-color:var(--color-neutral-50);border-bottom:1px solid var(--color-neutral-200)}:host ::ng-deep :where(thead th){padding:.75rem 1rem;font-weight:600;color:var(--color-neutral-700);text-align:left;white-space:nowrap;vertical-align:middle}:host ::ng-deep :where(tbody td){padding:.75rem 1rem;color:var(--color-neutral-700)}:host ::ng-deep :where(tbody td[colspan]){padding:2rem 1rem;text-align:center;color:var(--color-neutral-400)}}\n"] }]
2878
3283
  }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], striped: [{ type: i0.Input, args: [{ isSignal: true, alias: "striped", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], emptyColspan: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyColspan", required: false }] }], paginated: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginated", required: false }] }], pagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "pagination", required: false }] }], onSortChange: [{ type: i0.Output, args: ["onSortChange"] }], onSelectionChange: [{ type: i0.Output, args: ["onSelectionChange"] }], rowTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TailwindTableRowDirective), { isSignal: true }] }], onSortZoneClick: [{
2879
3284
  type: HostListener,
2880
3285
  args: ['click', ['$event']]
@@ -3054,11 +3459,11 @@ class TailwindDatePicker extends TailwindComponent {
3054
3459
  this.showCalendar.set(false);
3055
3460
  }
3056
3461
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindDatePicker, deps: null, target: i0.ɵɵFactoryTarget.Component });
3057
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindDatePicker, isStandalone: true, selector: "tailwind-date-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "document:pointerdown": "onDocumentPointerDown($event)", "document:keydown": "onDocumentKeydown($event)" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindDatePicker), multi: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"effectivePlaceholder()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggleCalendar()\" />\n <svg\n class=\"absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400 pointer-events-none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z\"\n clip-rule=\"evenodd\" />\n </svg>\n </div>\n\n @if (showCalendar()) {\n <div class=\"absolute z-popover mt-1 bg-white rounded-xl border border-neutral-200 shadow-xl p-4 w-72\">\n <!-- Month/Year nav -->\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prevMonth()\"\n class=\"p-1 rounded-lg hover:bg-neutral-100 transition-colors cursor-pointer\">\n <svg\n class=\"w-4 h-4 text-neutral-600\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n <span class=\"text-sm font-semibold text-neutral-800\">{{ monthYearLabel() }}</span>\n <button\n type=\"button\"\n (click)=\"nextMonth()\"\n class=\"p-1 rounded-lg hover:bg-neutral-100 transition-colors cursor-pointer\">\n <svg\n class=\"w-4 h-4 text-neutral-600\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n </div>\n <!-- Weekdays -->\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (day of weekDays; track $index) {\n <div class=\"text-center text-xs font-medium text-neutral-400 py-1\">{{ day }}</div>\n }\n </div>\n <!-- Days -->\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day === 0) {\n <div></div>\n } @else {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"h-8 w-8 mx-auto rounded-lg text-sm transition-colors cursor-pointer hover:bg-neutral-100\"\n [class.bg-primary-600]=\"isSelected(day)\"\n [class.text-white]=\"isSelected(day)\"\n [class.hover:bg-primary-700]=\"isSelected(day)\"\n [class.text-neutral-700]=\"!isSelected(day) && !isToday(day)\"\n [class.font-semibold]=\"isToday(day)\"\n [class.text-primary-600]=\"isToday(day) && !isSelected(day)\">\n {{ day }}\n </button>\n }\n }\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <button\n type=\"button\"\n (click)=\"goToToday()\"\n [disabled]=\"isDisabled()\"\n class=\"text-xs text-primary-600 font-medium hover:underline cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed disabled:no-underline\">\n {{ i18n.today }}\n </button>\n <button\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"isDisabled() || !draft()\"\n class=\"px-3 py-1.5 text-xs font-medium rounded-md bg-primary-600 text-white hover:bg-primary-700 cursor-pointer disabled:bg-neutral-200 disabled:text-neutral-500 disabled:cursor-not-allowed\">\n {{ i18n.confirm }}\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;position:relative}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3462
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindDatePicker, isStandalone: true, selector: "tailwind-date-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "document:pointerdown": "onDocumentPointerDown($event)", "document:keydown": "onDocumentKeydown($event)" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindDatePicker), multi: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"effectivePlaceholder()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggleCalendar()\" />\n <tailwind-icon\n icon=\"calendar-days\"\n [size]=\"16\"\n class=\"absolute right-3 top-1/2 -translate-y-1/2 text-neutral-400 pointer-events-none\" />\n </div>\n\n @if (showCalendar()) {\n <div class=\"absolute z-popover mt-1 bg-white rounded-xl border border-neutral-200 shadow-xl p-4 w-72\">\n <!-- Month/Year nav -->\n <div class=\"flex items-center justify-between mb-3\">\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-left\"\n ariaLabel=\"Previous month\"\n (onClick)=\"prevMonth()\" />\n <span class=\"text-sm font-semibold text-neutral-800\">{{ monthYearLabel() }}</span>\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-right\"\n ariaLabel=\"Next month\"\n (onClick)=\"nextMonth()\" />\n </div>\n <!-- Weekdays -->\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (day of weekDays; track $index) {\n <div class=\"text-center text-xs font-medium text-neutral-400 py-1\">{{ day }}</div>\n }\n </div>\n <!-- Days -->\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day === 0) {\n <div></div>\n } @else {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"h-8 w-8 mx-auto rounded-lg text-sm transition-colors cursor-pointer hover:bg-neutral-100\"\n [class.bg-primary-600]=\"isSelected(day)\"\n [class.text-white]=\"isSelected(day)\"\n [class.hover:bg-primary-700]=\"isSelected(day)\"\n [class.text-neutral-700]=\"!isSelected(day) && !isToday(day)\"\n [class.font-semibold]=\"isToday(day)\"\n [class.text-primary-600]=\"isToday(day) && !isSelected(day)\">\n {{ day }}\n </button>\n }\n }\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <tailwind-button\n kind=\"text\"\n color=\"primary\"\n size=\"xs\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"goToToday()\">\n {{ i18n.today }}\n </tailwind-button>\n <tailwind-button\n kind=\"solid\"\n color=\"primary\"\n size=\"sm\"\n [disabled]=\"isDisabled() || !draft()\"\n (onClick)=\"apply()\">\n {{ i18n.confirm }}\n </tailwind-button>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;position:relative}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }, { kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition", "ariaLabel"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3058
3463
  }
3059
3464
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindDatePicker, decorators: [{
3060
3465
  type: Component,
3061
- args: [{ selector: 'tailwind-date-picker', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindDatePicker), multi: true }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"effectivePlaceholder()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggleCalendar()\" />\n <svg\n class=\"absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400 pointer-events-none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z\"\n clip-rule=\"evenodd\" />\n </svg>\n </div>\n\n @if (showCalendar()) {\n <div class=\"absolute z-popover mt-1 bg-white rounded-xl border border-neutral-200 shadow-xl p-4 w-72\">\n <!-- Month/Year nav -->\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prevMonth()\"\n class=\"p-1 rounded-lg hover:bg-neutral-100 transition-colors cursor-pointer\">\n <svg\n class=\"w-4 h-4 text-neutral-600\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n <span class=\"text-sm font-semibold text-neutral-800\">{{ monthYearLabel() }}</span>\n <button\n type=\"button\"\n (click)=\"nextMonth()\"\n class=\"p-1 rounded-lg hover:bg-neutral-100 transition-colors cursor-pointer\">\n <svg\n class=\"w-4 h-4 text-neutral-600\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n </div>\n <!-- Weekdays -->\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (day of weekDays; track $index) {\n <div class=\"text-center text-xs font-medium text-neutral-400 py-1\">{{ day }}</div>\n }\n </div>\n <!-- Days -->\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day === 0) {\n <div></div>\n } @else {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"h-8 w-8 mx-auto rounded-lg text-sm transition-colors cursor-pointer hover:bg-neutral-100\"\n [class.bg-primary-600]=\"isSelected(day)\"\n [class.text-white]=\"isSelected(day)\"\n [class.hover:bg-primary-700]=\"isSelected(day)\"\n [class.text-neutral-700]=\"!isSelected(day) && !isToday(day)\"\n [class.font-semibold]=\"isToday(day)\"\n [class.text-primary-600]=\"isToday(day) && !isSelected(day)\">\n {{ day }}\n </button>\n }\n }\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <button\n type=\"button\"\n (click)=\"goToToday()\"\n [disabled]=\"isDisabled()\"\n class=\"text-xs text-primary-600 font-medium hover:underline cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed disabled:no-underline\">\n {{ i18n.today }}\n </button>\n <button\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"isDisabled() || !draft()\"\n class=\"px-3 py-1.5 text-xs font-medium rounded-md bg-primary-600 text-white hover:bg-primary-700 cursor-pointer disabled:bg-neutral-200 disabled:text-neutral-500 disabled:cursor-not-allowed\">\n {{ i18n.confirm }}\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;position:relative}\n"] }]
3466
+ args: [{ imports: [TailwindIcon, TailwindButton], selector: 'tailwind-date-picker', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindDatePicker), multi: true }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"effectivePlaceholder()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggleCalendar()\" />\n <tailwind-icon\n icon=\"calendar-days\"\n [size]=\"16\"\n class=\"absolute right-3 top-1/2 -translate-y-1/2 text-neutral-400 pointer-events-none\" />\n </div>\n\n @if (showCalendar()) {\n <div class=\"absolute z-popover mt-1 bg-white rounded-xl border border-neutral-200 shadow-xl p-4 w-72\">\n <!-- Month/Year nav -->\n <div class=\"flex items-center justify-between mb-3\">\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-left\"\n ariaLabel=\"Previous month\"\n (onClick)=\"prevMonth()\" />\n <span class=\"text-sm font-semibold text-neutral-800\">{{ monthYearLabel() }}</span>\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-right\"\n ariaLabel=\"Next month\"\n (onClick)=\"nextMonth()\" />\n </div>\n <!-- Weekdays -->\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (day of weekDays; track $index) {\n <div class=\"text-center text-xs font-medium text-neutral-400 py-1\">{{ day }}</div>\n }\n </div>\n <!-- Days -->\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day === 0) {\n <div></div>\n } @else {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"h-8 w-8 mx-auto rounded-lg text-sm transition-colors cursor-pointer hover:bg-neutral-100\"\n [class.bg-primary-600]=\"isSelected(day)\"\n [class.text-white]=\"isSelected(day)\"\n [class.hover:bg-primary-700]=\"isSelected(day)\"\n [class.text-neutral-700]=\"!isSelected(day) && !isToday(day)\"\n [class.font-semibold]=\"isToday(day)\"\n [class.text-primary-600]=\"isToday(day) && !isSelected(day)\">\n {{ day }}\n </button>\n }\n }\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <tailwind-button\n kind=\"text\"\n color=\"primary\"\n size=\"xs\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"goToToday()\">\n {{ i18n.today }}\n </tailwind-button>\n <tailwind-button\n kind=\"solid\"\n color=\"primary\"\n size=\"sm\"\n [disabled]=\"isDisabled() || !draft()\"\n (onClick)=\"apply()\">\n {{ i18n.confirm }}\n </tailwind-button>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;position:relative}\n"] }]
3062
3467
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], onDocumentPointerDown: [{
3063
3468
  type: HostListener,
3064
3469
  args: ['document:pointerdown', ['$event']]
@@ -3153,11 +3558,11 @@ class TailwindTimePicker extends TailwindComponent {
3153
3558
  this.showPanel.set(false);
3154
3559
  }
3155
3560
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindTimePicker, deps: null, target: i0.ɵɵFactoryTarget.Component });
3156
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindTimePicker, isStandalone: true, selector: "tailwind-time-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "document:pointerdown": "onDocumentPointerDown($event)", "document:keydown": "onDocumentKeydown($event)" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindTimePicker), multi: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"i18n.placeholder\"\n [disabled]=\"isDisabled()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n (click)=\"togglePanel()\" />\n <svg\n class=\"absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400 pointer-events-none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z\"\n clip-rule=\"evenodd\" />\n </svg>\n\n @if (showPanel()) {\n <div\n class=\"absolute left-0 top-full z-popover mt-1 w-52 rounded-xl border border-neutral-200 bg-white p-4 shadow-xl\">\n <div class=\"flex items-center gap-2\">\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled()\"\n (change)=\"onHourChange($event)\">\n @for (h of hours; track h) {\n <option [value]=\"h\" [selected]=\"h === (draft()?.h ?? 0)\">\n {{ h.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n <span class=\"text-neutral-400 text-sm shrink-0\">:</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled()\"\n (change)=\"onMinuteChange($event)\">\n @for (m of minutes; track m) {\n <option [value]=\"m\" [selected]=\"m === (draft()?.m ?? 0)\">\n {{ m.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <button\n type=\"button\"\n (click)=\"goToNow()\"\n [disabled]=\"isDisabled()\"\n class=\"text-xs text-primary-600 font-medium hover:underline cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed disabled:no-underline\">\n {{ i18n.now }}\n </button>\n <button\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"isDisabled()\"\n class=\"px-3 py-1.5 text-xs font-medium rounded-md bg-primary-600 text-white hover:bg-primary-700 cursor-pointer disabled:bg-neutral-200 disabled:text-neutral-500 disabled:cursor-not-allowed\">\n {{ i18n.apply }}\n </button>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3561
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindTimePicker, isStandalone: true, selector: "tailwind-time-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "document:pointerdown": "onDocumentPointerDown($event)", "document:keydown": "onDocumentKeydown($event)" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindTimePicker), multi: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"i18n.placeholder\"\n [disabled]=\"isDisabled()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n (click)=\"togglePanel()\" />\n <tailwind-icon\n icon=\"clock\"\n [size]=\"16\"\n class=\"absolute right-3 top-1/2 -translate-y-1/2 text-neutral-400 pointer-events-none\" />\n\n @if (showPanel()) {\n <div\n class=\"absolute left-0 top-full z-popover mt-1 w-52 rounded-xl border border-neutral-200 bg-white p-4 shadow-xl\">\n <div class=\"flex items-center gap-2\">\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled()\"\n (change)=\"onHourChange($event)\">\n @for (h of hours; track h) {\n <option [value]=\"h\" [selected]=\"h === (draft()?.h ?? 0)\">\n {{ h.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n <span class=\"text-neutral-400 text-sm shrink-0\">:</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled()\"\n (change)=\"onMinuteChange($event)\">\n @for (m of minutes; track m) {\n <option [value]=\"m\" [selected]=\"m === (draft()?.m ?? 0)\">\n {{ m.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <tailwind-button\n kind=\"text\"\n color=\"primary\"\n size=\"xs\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"goToNow()\">\n {{ i18n.now }}\n </tailwind-button>\n <tailwind-button\n kind=\"solid\"\n color=\"primary\"\n size=\"sm\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"apply()\">\n {{ i18n.apply }}\n </tailwind-button>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }, { kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition", "ariaLabel"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3157
3562
  }
3158
3563
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindTimePicker, decorators: [{
3159
3564
  type: Component,
3160
- args: [{ selector: 'tailwind-time-picker', imports: [], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindTimePicker), multi: true }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"i18n.placeholder\"\n [disabled]=\"isDisabled()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n (click)=\"togglePanel()\" />\n <svg\n class=\"absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400 pointer-events-none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z\"\n clip-rule=\"evenodd\" />\n </svg>\n\n @if (showPanel()) {\n <div\n class=\"absolute left-0 top-full z-popover mt-1 w-52 rounded-xl border border-neutral-200 bg-white p-4 shadow-xl\">\n <div class=\"flex items-center gap-2\">\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled()\"\n (change)=\"onHourChange($event)\">\n @for (h of hours; track h) {\n <option [value]=\"h\" [selected]=\"h === (draft()?.h ?? 0)\">\n {{ h.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n <span class=\"text-neutral-400 text-sm shrink-0\">:</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled()\"\n (change)=\"onMinuteChange($event)\">\n @for (m of minutes; track m) {\n <option [value]=\"m\" [selected]=\"m === (draft()?.m ?? 0)\">\n {{ m.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <button\n type=\"button\"\n (click)=\"goToNow()\"\n [disabled]=\"isDisabled()\"\n class=\"text-xs text-primary-600 font-medium hover:underline cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed disabled:no-underline\">\n {{ i18n.now }}\n </button>\n <button\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"isDisabled()\"\n class=\"px-3 py-1.5 text-xs font-medium rounded-md bg-primary-600 text-white hover:bg-primary-700 cursor-pointer disabled:bg-neutral-200 disabled:text-neutral-500 disabled:cursor-not-allowed\">\n {{ i18n.apply }}\n </button>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block}\n"] }]
3565
+ args: [{ selector: 'tailwind-time-picker', imports: [TailwindIcon, TailwindButton], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindTimePicker), multi: true }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"i18n.placeholder\"\n [disabled]=\"isDisabled()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n (click)=\"togglePanel()\" />\n <tailwind-icon\n icon=\"clock\"\n [size]=\"16\"\n class=\"absolute right-3 top-1/2 -translate-y-1/2 text-neutral-400 pointer-events-none\" />\n\n @if (showPanel()) {\n <div\n class=\"absolute left-0 top-full z-popover mt-1 w-52 rounded-xl border border-neutral-200 bg-white p-4 shadow-xl\">\n <div class=\"flex items-center gap-2\">\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled()\"\n (change)=\"onHourChange($event)\">\n @for (h of hours; track h) {\n <option [value]=\"h\" [selected]=\"h === (draft()?.h ?? 0)\">\n {{ h.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n <span class=\"text-neutral-400 text-sm shrink-0\">:</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled()\"\n (change)=\"onMinuteChange($event)\">\n @for (m of minutes; track m) {\n <option [value]=\"m\" [selected]=\"m === (draft()?.m ?? 0)\">\n {{ m.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <tailwind-button\n kind=\"text\"\n color=\"primary\"\n size=\"xs\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"goToNow()\">\n {{ i18n.now }}\n </tailwind-button>\n <tailwind-button\n kind=\"solid\"\n color=\"primary\"\n size=\"sm\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"apply()\">\n {{ i18n.apply }}\n </tailwind-button>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block}\n"] }]
3161
3566
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], onDocumentPointerDown: [{
3162
3567
  type: HostListener,
3163
3568
  args: ['document:pointerdown', ['$event']]
@@ -3368,11 +3773,11 @@ class TailwindDateTimePicker extends TailwindComponent {
3368
3773
  this.showPanel.set(false);
3369
3774
  }
3370
3775
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindDateTimePicker, deps: null, target: i0.ɵɵFactoryTarget.Component });
3371
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindDateTimePicker, isStandalone: true, selector: "tailwind-datetime-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:pointerdown": "onDocumentPointerDown($event)", "document:keydown": "onDocumentKeydown($event)" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindDateTimePicker), multi: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"effectivePlaceholder()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n [disabled]=\"isDisabled()\"\n (click)=\"togglePanel()\" />\n <svg\n class=\"absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400 pointer-events-none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z\"\n clip-rule=\"evenodd\" />\n </svg>\n\n @if (showPanel()) {\n <div\n class=\"absolute left-0 top-full z-popover mt-1 w-80 max-w-full rounded-xl border border-neutral-200 bg-white p-4 shadow-xl\">\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prevMonth()\"\n class=\"p-1 rounded-lg hover:bg-neutral-100 transition-colors cursor-pointer\">\n <svg\n class=\"w-4 h-4 text-neutral-600\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n <span class=\"text-sm font-semibold text-neutral-800\">{{ monthYearLabel() }}</span>\n <button\n type=\"button\"\n (click)=\"nextMonth()\"\n class=\"p-1 rounded-lg hover:bg-neutral-100 transition-colors cursor-pointer\">\n <svg\n class=\"w-4 h-4 text-neutral-600\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n </div>\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (day of weekDays; track day) {\n <div class=\"text-center text-xs font-medium text-neutral-400 py-1\">{{ day }}</div>\n }\n </div>\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day === 0) {\n <div></div>\n } @else {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"h-8 w-8 mx-auto rounded-lg text-sm transition-colors cursor-pointer hover:bg-neutral-100\"\n [class.bg-primary-600]=\"isSelected(day)\"\n [class.text-white]=\"isSelected(day)\"\n [class.hover:bg-primary-700]=\"isSelected(day)\"\n [class.text-neutral-700]=\"!isSelected(day) && !isToday(day)\"\n [class.font-semibold]=\"isToday(day)\"\n [class.text-primary-600]=\"isToday(day) && !isSelected(day)\">\n {{ day }}\n </button>\n }\n }\n </div>\n <div class=\"mt-3 pt-3 border-t border-neutral-100 flex items-center gap-2\">\n <span class=\"text-xs font-medium text-neutral-600 shrink-0\">{{ i18n.time }}</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled() || !draft()\"\n (change)=\"onHourChange($event)\">\n @for (h of hours; track h) {\n <option [value]=\"h\" [selected]=\"h === (draft()?.getHours() ?? 0)\">\n {{ h.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n <span class=\"text-neutral-400 text-sm\">:</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled() || !draft()\"\n (change)=\"onMinuteChange($event)\">\n @for (m of minutes; track m) {\n <option [value]=\"m\" [selected]=\"m === (draft()?.getMinutes() ?? 0)\">\n {{ m.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <button\n type=\"button\"\n (click)=\"goToToday()\"\n [disabled]=\"isDisabled()\"\n class=\"text-xs text-primary-600 font-medium hover:underline cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed disabled:no-underline\">\n {{ i18n.today }}\n </button>\n <button\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"isDisabled() || !draft()\"\n class=\"px-3 py-1.5 text-xs font-medium rounded-md bg-primary-600 text-white hover:bg-primary-700 cursor-pointer disabled:bg-neutral-200 disabled:text-neutral-500 disabled:cursor-not-allowed\">\n {{ i18n.confirm }}\n </button>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;position:relative;overflow:visible}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3776
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindDateTimePicker, isStandalone: true, selector: "tailwind-datetime-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:pointerdown": "onDocumentPointerDown($event)", "document:keydown": "onDocumentKeydown($event)" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindDateTimePicker), multi: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"effectivePlaceholder()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n [disabled]=\"isDisabled()\"\n (click)=\"togglePanel()\" />\n <tailwind-icon\n icon=\"calendar-days\"\n [size]=\"16\"\n class=\"absolute right-3 top-1/2 -translate-y-1/2 text-neutral-400 pointer-events-none\" />\n\n @if (showPanel()) {\n <div\n class=\"absolute left-0 top-full z-popover mt-1 w-80 max-w-full rounded-xl border border-neutral-200 bg-white p-4 shadow-xl\">\n <div class=\"flex items-center justify-between mb-3\">\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-left\"\n ariaLabel=\"Previous month\"\n (onClick)=\"prevMonth()\" />\n <span class=\"text-sm font-semibold text-neutral-800\">{{ monthYearLabel() }}</span>\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-right\"\n ariaLabel=\"Next month\"\n (onClick)=\"nextMonth()\" />\n </div>\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (day of weekDays; track day) {\n <div class=\"text-center text-xs font-medium text-neutral-400 py-1\">{{ day }}</div>\n }\n </div>\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day === 0) {\n <div></div>\n } @else {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"h-8 w-8 mx-auto rounded-lg text-sm transition-colors cursor-pointer hover:bg-neutral-100\"\n [class.bg-primary-600]=\"isSelected(day)\"\n [class.text-white]=\"isSelected(day)\"\n [class.hover:bg-primary-700]=\"isSelected(day)\"\n [class.text-neutral-700]=\"!isSelected(day) && !isToday(day)\"\n [class.font-semibold]=\"isToday(day)\"\n [class.text-primary-600]=\"isToday(day) && !isSelected(day)\">\n {{ day }}\n </button>\n }\n }\n </div>\n <div class=\"mt-3 pt-3 border-t border-neutral-100 flex items-center gap-2\">\n <span class=\"text-xs font-medium text-neutral-600 shrink-0\">{{ i18n.time }}</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled() || !draft()\"\n (change)=\"onHourChange($event)\">\n @for (h of hours; track h) {\n <option [value]=\"h\" [selected]=\"h === (draft()?.getHours() ?? 0)\">\n {{ h.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n <span class=\"text-neutral-400 text-sm\">:</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled() || !draft()\"\n (change)=\"onMinuteChange($event)\">\n @for (m of minutes; track m) {\n <option [value]=\"m\" [selected]=\"m === (draft()?.getMinutes() ?? 0)\">\n {{ m.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <tailwind-button\n kind=\"text\"\n color=\"primary\"\n size=\"xs\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"goToToday()\">\n {{ i18n.today }}\n </tailwind-button>\n <tailwind-button\n kind=\"solid\"\n color=\"primary\"\n size=\"sm\"\n [disabled]=\"isDisabled() || !draft()\"\n (onClick)=\"apply()\">\n {{ i18n.confirm }}\n </tailwind-button>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;position:relative;overflow:visible}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }, { kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition", "ariaLabel"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3372
3777
  }
3373
3778
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindDateTimePicker, decorators: [{
3374
3779
  type: Component,
3375
- args: [{ selector: 'tailwind-datetime-picker', imports: [], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindDateTimePicker), multi: true }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"effectivePlaceholder()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n [disabled]=\"isDisabled()\"\n (click)=\"togglePanel()\" />\n <svg\n class=\"absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400 pointer-events-none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z\"\n clip-rule=\"evenodd\" />\n </svg>\n\n @if (showPanel()) {\n <div\n class=\"absolute left-0 top-full z-popover mt-1 w-80 max-w-full rounded-xl border border-neutral-200 bg-white p-4 shadow-xl\">\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prevMonth()\"\n class=\"p-1 rounded-lg hover:bg-neutral-100 transition-colors cursor-pointer\">\n <svg\n class=\"w-4 h-4 text-neutral-600\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n <span class=\"text-sm font-semibold text-neutral-800\">{{ monthYearLabel() }}</span>\n <button\n type=\"button\"\n (click)=\"nextMonth()\"\n class=\"p-1 rounded-lg hover:bg-neutral-100 transition-colors cursor-pointer\">\n <svg\n class=\"w-4 h-4 text-neutral-600\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n </div>\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (day of weekDays; track day) {\n <div class=\"text-center text-xs font-medium text-neutral-400 py-1\">{{ day }}</div>\n }\n </div>\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day === 0) {\n <div></div>\n } @else {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"h-8 w-8 mx-auto rounded-lg text-sm transition-colors cursor-pointer hover:bg-neutral-100\"\n [class.bg-primary-600]=\"isSelected(day)\"\n [class.text-white]=\"isSelected(day)\"\n [class.hover:bg-primary-700]=\"isSelected(day)\"\n [class.text-neutral-700]=\"!isSelected(day) && !isToday(day)\"\n [class.font-semibold]=\"isToday(day)\"\n [class.text-primary-600]=\"isToday(day) && !isSelected(day)\">\n {{ day }}\n </button>\n }\n }\n </div>\n <div class=\"mt-3 pt-3 border-t border-neutral-100 flex items-center gap-2\">\n <span class=\"text-xs font-medium text-neutral-600 shrink-0\">{{ i18n.time }}</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled() || !draft()\"\n (change)=\"onHourChange($event)\">\n @for (h of hours; track h) {\n <option [value]=\"h\" [selected]=\"h === (draft()?.getHours() ?? 0)\">\n {{ h.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n <span class=\"text-neutral-400 text-sm\">:</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled() || !draft()\"\n (change)=\"onMinuteChange($event)\">\n @for (m of minutes; track m) {\n <option [value]=\"m\" [selected]=\"m === (draft()?.getMinutes() ?? 0)\">\n {{ m.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <button\n type=\"button\"\n (click)=\"goToToday()\"\n [disabled]=\"isDisabled()\"\n class=\"text-xs text-primary-600 font-medium hover:underline cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed disabled:no-underline\">\n {{ i18n.today }}\n </button>\n <button\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"isDisabled() || !draft()\"\n class=\"px-3 py-1.5 text-xs font-medium rounded-md bg-primary-600 text-white hover:bg-primary-700 cursor-pointer disabled:bg-neutral-200 disabled:text-neutral-500 disabled:cursor-not-allowed\">\n {{ i18n.confirm }}\n </button>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;position:relative;overflow:visible}\n"] }]
3780
+ args: [{ selector: 'tailwind-datetime-picker', imports: [TailwindIcon, TailwindButton], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TailwindDateTimePicker), multi: true }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-1.5\">\n @if (label()) {\n <label [attr.for]=\"id() ? id() + '-inner' : null\" class=\"text-sm font-medium text-neutral-700\">{{ label() }}</label>\n }\n <div class=\"relative\">\n <input\n [attr.id]=\"id() ? id() + '-inner' : null\"\n type=\"text\"\n readonly\n [value]=\"displayValue()\"\n [placeholder]=\"effectivePlaceholder()\"\n class=\"block w-full bg-white border border-neutral-300 rounded-md px-3 py-2 text-sm text-neutral-900 placeholder:text-neutral-400 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 cursor-pointer disabled:bg-neutral-50 disabled:cursor-not-allowed pr-10\"\n [disabled]=\"isDisabled()\"\n (click)=\"togglePanel()\" />\n <tailwind-icon\n icon=\"calendar-days\"\n [size]=\"16\"\n class=\"absolute right-3 top-1/2 -translate-y-1/2 text-neutral-400 pointer-events-none\" />\n\n @if (showPanel()) {\n <div\n class=\"absolute left-0 top-full z-popover mt-1 w-80 max-w-full rounded-xl border border-neutral-200 bg-white p-4 shadow-xl\">\n <div class=\"flex items-center justify-between mb-3\">\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-left\"\n ariaLabel=\"Previous month\"\n (onClick)=\"prevMonth()\" />\n <span class=\"text-sm font-semibold text-neutral-800\">{{ monthYearLabel() }}</span>\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"chevron-right\"\n ariaLabel=\"Next month\"\n (onClick)=\"nextMonth()\" />\n </div>\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (day of weekDays; track day) {\n <div class=\"text-center text-xs font-medium text-neutral-400 py-1\">{{ day }}</div>\n }\n </div>\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day === 0) {\n <div></div>\n } @else {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"h-8 w-8 mx-auto rounded-lg text-sm transition-colors cursor-pointer hover:bg-neutral-100\"\n [class.bg-primary-600]=\"isSelected(day)\"\n [class.text-white]=\"isSelected(day)\"\n [class.hover:bg-primary-700]=\"isSelected(day)\"\n [class.text-neutral-700]=\"!isSelected(day) && !isToday(day)\"\n [class.font-semibold]=\"isToday(day)\"\n [class.text-primary-600]=\"isToday(day) && !isSelected(day)\">\n {{ day }}\n </button>\n }\n }\n </div>\n <div class=\"mt-3 pt-3 border-t border-neutral-100 flex items-center gap-2\">\n <span class=\"text-xs font-medium text-neutral-600 shrink-0\">{{ i18n.time }}</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled() || !draft()\"\n (change)=\"onHourChange($event)\">\n @for (h of hours; track h) {\n <option [value]=\"h\" [selected]=\"h === (draft()?.getHours() ?? 0)\">\n {{ h.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n <span class=\"text-neutral-400 text-sm\">:</span>\n <select\n class=\"flex-1 min-w-0 block bg-white border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-900 outline-none focus:outline focus:outline-primary-500 focus:outline-offset-2 disabled:bg-neutral-50 disabled:cursor-not-allowed\"\n [disabled]=\"isDisabled() || !draft()\"\n (change)=\"onMinuteChange($event)\">\n @for (m of minutes; track m) {\n <option [value]=\"m\" [selected]=\"m === (draft()?.getMinutes() ?? 0)\">\n {{ m.toString().padStart(2, '0') }}\n </option>\n }\n </select>\n </div>\n <div class=\"mt-2 pt-2 border-t border-neutral-100 flex items-center justify-between gap-2\">\n <tailwind-button\n kind=\"text\"\n color=\"primary\"\n size=\"xs\"\n [disabled]=\"isDisabled()\"\n (onClick)=\"goToToday()\">\n {{ i18n.today }}\n </tailwind-button>\n <tailwind-button\n kind=\"solid\"\n color=\"primary\"\n size=\"sm\"\n [disabled]=\"isDisabled() || !draft()\"\n (onClick)=\"apply()\">\n {{ i18n.confirm }}\n </tailwind-button>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;position:relative;overflow:visible}\n"] }]
3376
3781
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], onDocumentPointerDown: [{
3377
3782
  type: HostListener,
3378
3783
  args: ['document:pointerdown', ['$event']]
@@ -3424,11 +3829,11 @@ class TailwindStepper extends TailwindComponent {
3424
3829
  this.activeIndex.update(v => v - 1);
3425
3830
  }
3426
3831
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindStepper, deps: [], target: i0.ɵɵFactoryTarget.Component });
3427
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindStepper, isStandalone: true, selector: "tailwind-stepper", inputs: { activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeIndex: "activeIndexChange" }, queries: [{ propertyName: "steps", predicate: TailwindStep, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- Step indicators -->\n<div class=\"flex items-center mb-6\">\n @for (step of steps(); track step.label(); let i = $index; let last = $last) {\n <div class=\"flex items-center\" [class.flex-1]=\"!last\">\n <button\n type=\"button\"\n (click)=\"goToStep(i)\"\n class=\"flex items-center gap-2 cursor-pointer group\"\n [attr.aria-current]=\"activeIndex() === i ? 'step' : null\">\n <div\n class=\"w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold border-2 transition-all duration-200\"\n [class.bg-primary-600]=\"i <= activeIndex()\"\n [class.border-primary-600]=\"i <= activeIndex()\"\n [class.text-white]=\"i <= activeIndex()\"\n [class.border-neutral-300]=\"i > activeIndex()\"\n [class.text-neutral-500]=\"i > activeIndex()\">\n @if (step.completed()) {\n <svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z\"\n clip-rule=\"evenodd\" />\n </svg>\n } @else {\n {{ i + 1 }}\n }\n </div>\n <div class=\"hidden sm:block\">\n <p\n class=\"text-sm font-medium\"\n [class.text-primary-600]=\"i <= activeIndex()\"\n [class.text-neutral-500]=\"i > activeIndex()\">\n {{ step.label() }}\n </p>\n @if (step.description()) {\n <p class=\"text-xs text-neutral-400\">{{ step.description() }}</p>\n }\n </div>\n </button>\n @if (!last) {\n <div\n class=\"flex-1 h-0.5 mx-3 rounded-full transition-colors duration-200\"\n [class.bg-primary-600]=\"i < activeIndex()\"\n [class.bg-neutral-200]=\"i >= activeIndex()\"></div>\n }\n </div>\n }\n</div>\n<!-- Step content -->\n<ng-content />\n", styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3832
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindStepper, isStandalone: true, selector: "tailwind-stepper", inputs: { activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeIndex: "activeIndexChange" }, queries: [{ propertyName: "steps", predicate: TailwindStep, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- Step indicators -->\n<div class=\"flex items-center mb-6\">\n @for (step of steps(); track step.label(); let i = $index; let last = $last) {\n <div class=\"flex items-center\" [class.flex-1]=\"!last\">\n <button\n type=\"button\"\n (click)=\"goToStep(i)\"\n class=\"flex items-center gap-2 cursor-pointer group\"\n [attr.aria-current]=\"activeIndex() === i ? 'step' : null\">\n <div\n class=\"w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold border-2 transition-all duration-200\"\n [class.bg-primary-600]=\"i <= activeIndex()\"\n [class.border-primary-600]=\"i <= activeIndex()\"\n [class.text-white]=\"i <= activeIndex()\"\n [class.border-neutral-300]=\"i > activeIndex()\"\n [class.text-neutral-500]=\"i > activeIndex()\">\n @if (step.completed()) {\n <tailwind-icon icon=\"check\" [size]=\"16\" />\n } @else {\n {{ i + 1 }}\n }\n </div>\n <div class=\"hidden sm:block\">\n <p\n class=\"text-sm font-medium\"\n [class.text-primary-600]=\"i <= activeIndex()\"\n [class.text-neutral-500]=\"i > activeIndex()\">\n {{ step.label() }}\n </p>\n @if (step.description()) {\n <p class=\"text-xs text-neutral-400\">{{ step.description() }}</p>\n }\n </div>\n </button>\n @if (!last) {\n <div\n class=\"flex-1 h-0.5 mx-3 rounded-full transition-colors duration-200\"\n [class.bg-primary-600]=\"i < activeIndex()\"\n [class.bg-neutral-200]=\"i >= activeIndex()\"></div>\n }\n </div>\n }\n</div>\n<!-- Step content -->\n<ng-content />\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3428
3833
  }
3429
3834
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindStepper, decorators: [{
3430
3835
  type: Component,
3431
- args: [{ selector: 'tailwind-stepper', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Step indicators -->\n<div class=\"flex items-center mb-6\">\n @for (step of steps(); track step.label(); let i = $index; let last = $last) {\n <div class=\"flex items-center\" [class.flex-1]=\"!last\">\n <button\n type=\"button\"\n (click)=\"goToStep(i)\"\n class=\"flex items-center gap-2 cursor-pointer group\"\n [attr.aria-current]=\"activeIndex() === i ? 'step' : null\">\n <div\n class=\"w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold border-2 transition-all duration-200\"\n [class.bg-primary-600]=\"i <= activeIndex()\"\n [class.border-primary-600]=\"i <= activeIndex()\"\n [class.text-white]=\"i <= activeIndex()\"\n [class.border-neutral-300]=\"i > activeIndex()\"\n [class.text-neutral-500]=\"i > activeIndex()\">\n @if (step.completed()) {\n <svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z\"\n clip-rule=\"evenodd\" />\n </svg>\n } @else {\n {{ i + 1 }}\n }\n </div>\n <div class=\"hidden sm:block\">\n <p\n class=\"text-sm font-medium\"\n [class.text-primary-600]=\"i <= activeIndex()\"\n [class.text-neutral-500]=\"i > activeIndex()\">\n {{ step.label() }}\n </p>\n @if (step.description()) {\n <p class=\"text-xs text-neutral-400\">{{ step.description() }}</p>\n }\n </div>\n </button>\n @if (!last) {\n <div\n class=\"flex-1 h-0.5 mx-3 rounded-full transition-colors duration-200\"\n [class.bg-primary-600]=\"i < activeIndex()\"\n [class.bg-neutral-200]=\"i >= activeIndex()\"></div>\n }\n </div>\n }\n</div>\n<!-- Step content -->\n<ng-content />\n", styles: [":host{display:block}\n"] }]
3836
+ args: [{ imports: [TailwindIcon], selector: 'tailwind-stepper', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Step indicators -->\n<div class=\"flex items-center mb-6\">\n @for (step of steps(); track step.label(); let i = $index; let last = $last) {\n <div class=\"flex items-center\" [class.flex-1]=\"!last\">\n <button\n type=\"button\"\n (click)=\"goToStep(i)\"\n class=\"flex items-center gap-2 cursor-pointer group\"\n [attr.aria-current]=\"activeIndex() === i ? 'step' : null\">\n <div\n class=\"w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold border-2 transition-all duration-200\"\n [class.bg-primary-600]=\"i <= activeIndex()\"\n [class.border-primary-600]=\"i <= activeIndex()\"\n [class.text-white]=\"i <= activeIndex()\"\n [class.border-neutral-300]=\"i > activeIndex()\"\n [class.text-neutral-500]=\"i > activeIndex()\">\n @if (step.completed()) {\n <tailwind-icon icon=\"check\" [size]=\"16\" />\n } @else {\n {{ i + 1 }}\n }\n </div>\n <div class=\"hidden sm:block\">\n <p\n class=\"text-sm font-medium\"\n [class.text-primary-600]=\"i <= activeIndex()\"\n [class.text-neutral-500]=\"i > activeIndex()\">\n {{ step.label() }}\n </p>\n @if (step.description()) {\n <p class=\"text-xs text-neutral-400\">{{ step.description() }}</p>\n }\n </div>\n </button>\n @if (!last) {\n <div\n class=\"flex-1 h-0.5 mx-3 rounded-full transition-colors duration-200\"\n [class.bg-primary-600]=\"i < activeIndex()\"\n [class.bg-neutral-200]=\"i >= activeIndex()\"></div>\n }\n </div>\n }\n</div>\n<!-- Step content -->\n<ng-content />\n", styles: [":host{display:block}\n"] }]
3432
3837
  }], ctorParameters: () => [], propDecorators: { activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }, { type: i0.Output, args: ["activeIndexChange"] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], steps: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TailwindStep), { isSignal: true }] }] } });
3433
3838
 
3434
3839
  class TailwindAccordionItem extends TailwindComponent {
@@ -3443,11 +3848,11 @@ class TailwindAccordionItem extends TailwindComponent {
3443
3848
  }
3444
3849
  }
3445
3850
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindAccordionItem, deps: null, target: i0.ɵɵFactoryTarget.Component });
3446
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindAccordionItem, isStandalone: true, selector: "tailwind-accordion-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onToggle: "onToggle" }, usesInheritance: true, ngImport: i0, template: "<div [id]=\"id()\" [ngClass]=\"class()\" class=\"border-b border-neutral-200 last:border-b-0\">\n <button\n type=\"button\"\n (click)=\"toggle()\"\n class=\"flex items-center justify-between w-full px-5 py-4 text-left text-sm font-medium text-neutral-800 hover:bg-neutral-50 transition-colors cursor-pointer\"\n [attr.aria-expanded]=\"isExpanded()\">\n <span>{{ title() }}</span>\n <svg\n class=\"w-4 h-4 text-neutral-400 transition-transform duration-200\"\n [class.rotate-180]=\"isExpanded()\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n @if (isExpanded()) {\n <div class=\"px-5 py-4 text-sm text-neutral-600\">\n <ng-content />\n </div>\n }\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3851
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindAccordionItem, isStandalone: true, selector: "tailwind-accordion-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onToggle: "onToggle" }, usesInheritance: true, ngImport: i0, template: "<div [id]=\"id()\" [ngClass]=\"class()\" class=\"border-b border-neutral-200 last:border-b-0\">\n <button\n type=\"button\"\n (click)=\"toggle()\"\n class=\"flex items-center justify-between w-full px-5 py-4 text-left text-sm font-medium text-neutral-800 hover:bg-neutral-50 transition-colors cursor-pointer\"\n [attr.aria-expanded]=\"isExpanded()\">\n <span>{{ title() }}</span>\n <tailwind-icon\n icon=\"chevron-down\"\n [size]=\"16\"\n class=\"text-neutral-400 transition-transform duration-200\"\n [class.rotate-180]=\"isExpanded()\" />\n </button>\n @if (isExpanded()) {\n <div class=\"px-5 py-4 text-sm text-neutral-600\">\n <ng-content />\n </div>\n }\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3447
3852
  }
3448
3853
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindAccordionItem, decorators: [{
3449
3854
  type: Component,
3450
- args: [{ imports: [CommonModule], selector: 'tailwind-accordion-item', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [id]=\"id()\" [ngClass]=\"class()\" class=\"border-b border-neutral-200 last:border-b-0\">\n <button\n type=\"button\"\n (click)=\"toggle()\"\n class=\"flex items-center justify-between w-full px-5 py-4 text-left text-sm font-medium text-neutral-800 hover:bg-neutral-50 transition-colors cursor-pointer\"\n [attr.aria-expanded]=\"isExpanded()\">\n <span>{{ title() }}</span>\n <svg\n class=\"w-4 h-4 text-neutral-400 transition-transform duration-200\"\n [class.rotate-180]=\"isExpanded()\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n fill-rule=\"evenodd\"\n d=\"M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z\"\n clip-rule=\"evenodd\" />\n </svg>\n </button>\n @if (isExpanded()) {\n <div class=\"px-5 py-4 text-sm text-neutral-600\">\n <ng-content />\n </div>\n }\n</div>\n", styles: [":host{display:block}\n"] }]
3855
+ args: [{ imports: [CommonModule, TailwindIcon], selector: 'tailwind-accordion-item', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [id]=\"id()\" [ngClass]=\"class()\" class=\"border-b border-neutral-200 last:border-b-0\">\n <button\n type=\"button\"\n (click)=\"toggle()\"\n class=\"flex items-center justify-between w-full px-5 py-4 text-left text-sm font-medium text-neutral-800 hover:bg-neutral-50 transition-colors cursor-pointer\"\n [attr.aria-expanded]=\"isExpanded()\">\n <span>{{ title() }}</span>\n <tailwind-icon\n icon=\"chevron-down\"\n [size]=\"16\"\n class=\"text-neutral-400 transition-transform duration-200\"\n [class.rotate-180]=\"isExpanded()\" />\n </button>\n @if (isExpanded()) {\n <div class=\"px-5 py-4 text-sm text-neutral-600\">\n <ng-content />\n </div>\n }\n</div>\n", styles: [":host{display:block}\n"] }]
3451
3856
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], onToggle: [{ type: i0.Output, args: ["onToggle"] }] } });
3452
3857
 
3453
3858
  class TailwindAccordion extends TailwindComponent {
@@ -3597,11 +4002,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
3597
4002
  class TailwindToast extends TailwindComponent {
3598
4003
  toastService = inject(TailwindToastService);
3599
4004
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindToast, deps: null, target: i0.ɵɵFactoryTarget.Component });
3600
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindToast, isStandalone: true, selector: "tailwind-toast", usesInheritance: true, ngImport: i0, template: "<div class=\"fixed bottom-4 right-4 z-1080 flex flex-col gap-2 max-w-sm w-full pointer-events-none\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"pointer-events-auto rounded-xl border shadow-lg p-4 flex gap-3 animate-in slide-in-from-right-full duration-300\"\n [class.bg-success-50]=\"toast.severity === 'success'\"\n [class.border-success-200]=\"toast.severity === 'success'\"\n [class.bg-warning-50]=\"toast.severity === 'warning'\"\n [class.border-warning-200]=\"toast.severity === 'warning'\"\n [class.bg-danger-50]=\"toast.severity === 'danger'\"\n [class.border-danger-200]=\"toast.severity === 'danger'\"\n [class.bg-info-50]=\"toast.severity === 'info'\"\n [class.border-info-200]=\"toast.severity === 'info'\"\n role=\"alert\">\n <div class=\"flex-1 min-w-0\">\n @if (toast.title) {\n <p class=\"text-sm font-semibold mb-0.5\">{{ toast.title }}</p>\n }\n <p class=\"text-sm\">{{ toast.message }}</p>\n </div>\n @if (toast.dismissible) {\n <button\n type=\"button\"\n (click)=\"toastService.dismiss(toast.id)\"\n class=\"shrink-0 p-1 rounded-lg opacity-60 hover:opacity-100 transition-opacity cursor-pointer\"\n aria-label=\"Dismiss\">\n <svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\" />\n </svg>\n </button>\n }\n </div>\n }\n</div>\n", styles: [":host{display:contents}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4005
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindToast, isStandalone: true, selector: "tailwind-toast", usesInheritance: true, ngImport: i0, template: "<div class=\"fixed bottom-4 right-4 z-1080 flex flex-col gap-2 max-w-sm w-full pointer-events-none\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"pointer-events-auto rounded-xl border shadow-lg p-4 flex gap-3 animate-in slide-in-from-right-full duration-300\"\n [class.bg-success-50]=\"toast.severity === 'success'\"\n [class.border-success-200]=\"toast.severity === 'success'\"\n [class.bg-warning-50]=\"toast.severity === 'warning'\"\n [class.border-warning-200]=\"toast.severity === 'warning'\"\n [class.bg-danger-50]=\"toast.severity === 'danger'\"\n [class.border-danger-200]=\"toast.severity === 'danger'\"\n [class.bg-info-50]=\"toast.severity === 'info'\"\n [class.border-info-200]=\"toast.severity === 'info'\"\n role=\"alert\">\n <div class=\"flex-1 min-w-0\">\n @if (toast.title) {\n <p class=\"text-sm font-semibold mb-0.5\">{{ toast.title }}</p>\n }\n <p class=\"text-sm\">{{ toast.message }}</p>\n </div>\n @if (toast.dismissible) {\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"x-mark\"\n class=\"shrink-0 opacity-60 hover:opacity-100\"\n ariaLabel=\"Dismiss\"\n (onClick)=\"toastService.dismiss(toast.id)\" />\n }\n </div>\n }\n</div>\n", styles: [":host{display:contents}\n"], dependencies: [{ kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition", "ariaLabel"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3601
4006
  }
3602
4007
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindToast, decorators: [{
3603
4008
  type: Component,
3604
- args: [{ selector: 'tailwind-toast', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fixed bottom-4 right-4 z-1080 flex flex-col gap-2 max-w-sm w-full pointer-events-none\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"pointer-events-auto rounded-xl border shadow-lg p-4 flex gap-3 animate-in slide-in-from-right-full duration-300\"\n [class.bg-success-50]=\"toast.severity === 'success'\"\n [class.border-success-200]=\"toast.severity === 'success'\"\n [class.bg-warning-50]=\"toast.severity === 'warning'\"\n [class.border-warning-200]=\"toast.severity === 'warning'\"\n [class.bg-danger-50]=\"toast.severity === 'danger'\"\n [class.border-danger-200]=\"toast.severity === 'danger'\"\n [class.bg-info-50]=\"toast.severity === 'info'\"\n [class.border-info-200]=\"toast.severity === 'info'\"\n role=\"alert\">\n <div class=\"flex-1 min-w-0\">\n @if (toast.title) {\n <p class=\"text-sm font-semibold mb-0.5\">{{ toast.title }}</p>\n }\n <p class=\"text-sm\">{{ toast.message }}</p>\n </div>\n @if (toast.dismissible) {\n <button\n type=\"button\"\n (click)=\"toastService.dismiss(toast.id)\"\n class=\"shrink-0 p-1 rounded-lg opacity-60 hover:opacity-100 transition-opacity cursor-pointer\"\n aria-label=\"Dismiss\">\n <svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\" />\n </svg>\n </button>\n }\n </div>\n }\n</div>\n", styles: [":host{display:contents}\n"] }]
4009
+ args: [{ imports: [TailwindButton], selector: 'tailwind-toast', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fixed bottom-4 right-4 z-1080 flex flex-col gap-2 max-w-sm w-full pointer-events-none\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"pointer-events-auto rounded-xl border shadow-lg p-4 flex gap-3 animate-in slide-in-from-right-full duration-300\"\n [class.bg-success-50]=\"toast.severity === 'success'\"\n [class.border-success-200]=\"toast.severity === 'success'\"\n [class.bg-warning-50]=\"toast.severity === 'warning'\"\n [class.border-warning-200]=\"toast.severity === 'warning'\"\n [class.bg-danger-50]=\"toast.severity === 'danger'\"\n [class.border-danger-200]=\"toast.severity === 'danger'\"\n [class.bg-info-50]=\"toast.severity === 'info'\"\n [class.border-info-200]=\"toast.severity === 'info'\"\n role=\"alert\">\n <div class=\"flex-1 min-w-0\">\n @if (toast.title) {\n <p class=\"text-sm font-semibold mb-0.5\">{{ toast.title }}</p>\n }\n <p class=\"text-sm\">{{ toast.message }}</p>\n </div>\n @if (toast.dismissible) {\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"x-mark\"\n class=\"shrink-0 opacity-60 hover:opacity-100\"\n ariaLabel=\"Dismiss\"\n (onClick)=\"toastService.dismiss(toast.id)\" />\n }\n </div>\n }\n</div>\n", styles: [":host{display:contents}\n"] }]
3605
4010
  }] });
3606
4011
 
3607
4012
  class TailwindNotification extends TailwindComponent {
@@ -3620,11 +4025,11 @@ class TailwindNotification extends TailwindComponent {
3620
4025
  return `flex items-start rounded-lg border p-4 ${variantMap[this.severity()]}`;
3621
4026
  }, ...(ngDevMode ? [{ debugName: "computedClasses" }] : /* istanbul ignore next */ []));
3622
4027
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindNotification, deps: null, target: i0.ɵɵFactoryTarget.Component });
3623
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindNotification, isStandalone: true, selector: "tailwind-notification", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDismiss: "onDismiss" }, usesInheritance: true, ngImport: i0, template: "<div [class]=\"computedClasses()\" role=\"alert\">\n <div class=\"flex-1 min-w-0\">\n @if (title()) {\n <p class=\"text-sm font-semibold mb-0.5\">{{ title() }}</p>\n }\n <p class=\"text-sm\"><ng-content /></p>\n @if (showActions()) {\n <div class=\"pt-3\">\n <ng-content select=\"[tailwind-notification-actions]\" />\n </div>\n }\n </div>\n @if (dismissible()) {\n <button\n type=\"button\"\n (click)=\"onDismiss.emit()\"\n class=\"shrink-0 p-1 -m-1 rounded-lg opacity-60 hover:opacity-100 transition-opacity cursor-pointer\"\n aria-label=\"Dismiss\">\n <tailwind-icon icon=\"x-mark\" [size]=\"16\" class=\"shrink-0\" />\n </button>\n }\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: TailwindIcon, selector: "tailwind-icon", inputs: ["icon", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4028
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TailwindNotification, isStandalone: true, selector: "tailwind-notification", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDismiss: "onDismiss" }, usesInheritance: true, ngImport: i0, template: "<div [class]=\"computedClasses()\" role=\"alert\">\n <div class=\"flex-1 min-w-0\">\n @if (title()) {\n <p class=\"text-sm font-semibold mb-0.5\">{{ title() }}</p>\n }\n <p class=\"text-sm\"><ng-content /></p>\n @if (showActions()) {\n <div class=\"pt-3\">\n <ng-content select=\"[tailwind-notification-actions]\" />\n </div>\n }\n </div>\n @if (dismissible()) {\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"x-mark\"\n class=\"shrink-0 -m-1 opacity-60 hover:opacity-100\"\n ariaLabel=\"Dismiss\"\n (onClick)=\"onDismiss.emit()\" />\n }\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: TailwindButton, selector: "tailwind-button", inputs: ["color", "kind", "size", "disabled", "type", "role", "icon", "iconPosition", "ariaLabel"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3624
4029
  }
3625
4030
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindNotification, decorators: [{
3626
4031
  type: Component,
3627
- args: [{ imports: [TailwindIcon], selector: 'tailwind-notification', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"computedClasses()\" role=\"alert\">\n <div class=\"flex-1 min-w-0\">\n @if (title()) {\n <p class=\"text-sm font-semibold mb-0.5\">{{ title() }}</p>\n }\n <p class=\"text-sm\"><ng-content /></p>\n @if (showActions()) {\n <div class=\"pt-3\">\n <ng-content select=\"[tailwind-notification-actions]\" />\n </div>\n }\n </div>\n @if (dismissible()) {\n <button\n type=\"button\"\n (click)=\"onDismiss.emit()\"\n class=\"shrink-0 p-1 -m-1 rounded-lg opacity-60 hover:opacity-100 transition-opacity cursor-pointer\"\n aria-label=\"Dismiss\">\n <tailwind-icon icon=\"x-mark\" [size]=\"16\" class=\"shrink-0\" />\n </button>\n }\n</div>\n", styles: [":host{display:block}\n"] }]
4032
+ args: [{ imports: [TailwindButton], selector: 'tailwind-notification', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"computedClasses()\" role=\"alert\">\n <div class=\"flex-1 min-w-0\">\n @if (title()) {\n <p class=\"text-sm font-semibold mb-0.5\">{{ title() }}</p>\n }\n <p class=\"text-sm\"><ng-content /></p>\n @if (showActions()) {\n <div class=\"pt-3\">\n <ng-content select=\"[tailwind-notification-actions]\" />\n </div>\n }\n </div>\n @if (dismissible()) {\n <tailwind-button\n kind=\"ghost\"\n color=\"transparent\"\n size=\"sm\"\n icon=\"x-mark\"\n class=\"shrink-0 -m-1 opacity-60 hover:opacity-100\"\n ariaLabel=\"Dismiss\"\n (onClick)=\"onDismiss.emit()\" />\n }\n</div>\n", styles: [":host{display:block}\n"] }]
3628
4033
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], severity: [{ type: i0.Input, args: [{ isSignal: true, alias: "severity", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], showActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActions", required: false }] }], onDismiss: [{ type: i0.Output, args: ["onDismiss"] }] } });
3629
4034
 
3630
4035
  class TailwindMessage extends TailwindComponent {
@@ -4352,5 +4757,5 @@ function defineTheme(config) {
4352
4757
  * Generated bundle index. Do not edit.
4353
4758
  */
4354
4759
 
4355
- export { DEFAULT_PAGINATION_LENGTH_OPTIONS, TAILWIND_BUTTON_KIND, TAILWIND_COMPONENTS_SIZE, TAILWIND_DATETIME_LANGUAGE, TAILWIND_HEROICON_NAMES, TAILWIND_ICON_SIZE, TAILWIND_MODAL_DATA, TAILWIND_PAGINATION_SUMMARY, TW_TABLE_SORT_DIR_ATTR, TW_TABLE_SORT_KEY_ATTR, TailwindAccordion, TailwindAccordionItem, TailwindAlert, TailwindBadge, TailwindBreadcrumb, TailwindButton, TailwindCard, TailwindCheckbox, TailwindDatePicker, TailwindDateTimePicker, TailwindDivider, TailwindDrawer, TailwindIcon, TailwindInput, TailwindInputOtp, TailwindMenu, TailwindMessage, TailwindMeter, TailwindModal, TailwindModalRef, TailwindModalService, TailwindNotification, TailwindPagination, TailwindProgressBar, TailwindRadioGroup, TailwindSelect, TailwindSkeleton, TailwindSlider, TailwindSortHeaderDirective, TailwindSpinner, TailwindStep, TailwindStepper, TailwindTab, TailwindTabGroup, TailwindTable, TailwindTableRowDirective, TailwindTableRowDirective as TailwindTableRowTemplateDirective, TailwindTag, TailwindTextarea, TailwindTimePicker, TailwindTitle, TailwindToast, TailwindToastService, TailwindToggle, TailwindToolbar, TailwindTooltip, TailwindTooltipDirective, TailwindUpload, buildTailwindThemeVariableEntries, defineTheme, provideTailwindComponents };
4760
+ export { DEFAULT_PAGINATION_LENGTH_OPTIONS, TAILWIND_BUTTON_KIND, TAILWIND_COMPONENTS_SIZE, TAILWIND_DATETIME_LANGUAGE, TAILWIND_HEROICON_NAMES, TAILWIND_ICON_SIZE, TAILWIND_MODAL_DATA, TAILWIND_PAGINATION_SUMMARY, TW_TABLE_SORT_DIR_ATTR, TW_TABLE_SORT_KEY_ATTR, TailwindAccordion, TailwindAccordionItem, TailwindAlert, TailwindAutocomplete, TailwindBadge, TailwindBreadcrumb, TailwindButton, TailwindCard, TailwindCheckbox, TailwindDatePicker, TailwindDateTimePicker, TailwindDivider, TailwindDrawer, TailwindIcon, TailwindInput, TailwindInputOtp, TailwindMenu, TailwindMessage, TailwindMeter, TailwindModal, TailwindModalRef, TailwindModalService, TailwindNotification, TailwindPagination, TailwindProgressBar, TailwindRadioGroup, TailwindSelect, TailwindSkeleton, TailwindSlider, TailwindSortHeaderDirective, TailwindSpinner, TailwindStep, TailwindStepper, TailwindTab, TailwindTabGroup, TailwindTable, TailwindTableRowDirective, TailwindTableRowDirective as TailwindTableRowTemplateDirective, TailwindTag, TailwindTextarea, TailwindTimePicker, TailwindTitle, TailwindToast, TailwindToastService, TailwindToggle, TailwindToolbar, TailwindTooltip, TailwindTooltipDirective, TailwindUpload, buildTailwindThemeVariableEntries, defineTheme, provideTailwindComponents };
4356
4761
  //# sourceMappingURL=angular-tailwind-components.mjs.map