angular-tailwind-components 1.7.1 → 1.8.0

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';
@@ -755,12 +755,14 @@ const iconPixelSizeMap = {
755
755
  lg: 20,
756
756
  xl: 22
757
757
  };
758
+ /** Always transparent background; no tint on hover, focus, or active. */
759
+ 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
760
  class TailwindButton extends TailwindComponent {
759
761
  defaultKind = inject(TAILWIND_BUTTON_KIND, { optional: true });
760
762
  /** Visual color */
761
763
  color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
762
764
  /**
763
- * Visual kind: `flat` = filled like `solid` without border or shadow;
765
+ * Visual kind: `flat` = filled like `solid` without border, shadow, or hover/active background change;
764
766
  * `ghost` = transparent with hover tint; `text` = text color only, no hover background.
765
767
  * Default from {@link TAILWIND_BUTTON_KIND} or `'solid'`.
766
768
  */
@@ -777,6 +779,8 @@ class TailwindButton extends TailwindComponent {
777
779
  icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : /* istanbul ignore next */ []));
778
780
  /** Icon placement when both icon and label are shown */
779
781
  iconPosition = input('left', ...(ngDevMode ? [{ debugName: "iconPosition" }] : /* istanbul ignore next */ []));
782
+ /** Accessible name for icon-only buttons */
783
+ ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
780
784
  /** Emitted when the button is clicked (not disabled). */
781
785
  onClick = output();
782
786
  iconPixelSize = computed(() => iconPixelSizeMap[this.size()], ...(ngDevMode ? [{ debugName: "iconPixelSize" }] : /* istanbul ignore next */ []));
@@ -797,16 +801,18 @@ class TailwindButton extends TailwindComponent {
797
801
  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
802
  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
803
  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'
804
+ 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',
805
+ transparent: transparentColorClasses
801
806
  };
802
- /** Filled surface like `solid`, without box shadow or visible border. */
807
+ /** Filled surface like `solid`, without box shadow, border, or hover/active tint. */
803
808
  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'
809
+ primary: 'bg-primary-600 text-on-primary-600 border-0 shadow-none focus-visible:outline-primary-600',
810
+ secondary: 'bg-neutral-100 text-neutral-800 border-0 shadow-none focus-visible:outline-neutral-500',
811
+ danger: 'bg-danger-600 text-on-danger-600 border-0 shadow-none focus-visible:outline-danger-600',
812
+ success: 'bg-success-600 text-on-success-600 border-0 shadow-none focus-visible:outline-success-600',
813
+ warning: 'bg-warning-500 text-on-warning-500 border-0 shadow-none focus-visible:outline-warning-500',
814
+ info: 'bg-info-600 text-on-info-600 border-0 shadow-none focus-visible:outline-info-600',
815
+ transparent: transparentColorClasses
810
816
  };
811
817
  const outlinedMap = {
812
818
  primary: 'bg-transparent text-primary-600 border-primary-600 hover:bg-primary-50 active:bg-primary-100 focus-visible:outline-primary-600',
@@ -814,7 +820,8 @@ class TailwindButton extends TailwindComponent {
814
820
  danger: 'bg-transparent text-danger-600 border-danger-600 hover:bg-danger-50 active:bg-danger-100 focus-visible:outline-danger-600',
815
821
  success: 'bg-transparent text-success-600 border-success-600 hover:bg-success-50 active:bg-success-100 focus-visible:outline-success-600',
816
822
  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'
823
+ info: 'bg-transparent text-info-600 border-info-600 hover:bg-info-50 active:bg-info-100 focus-visible:outline-info-600',
824
+ transparent: transparentColorClasses
818
825
  };
819
826
  /** Transparent + hover/active background tint (former `text` look). */
820
827
  const ghostMap = {
@@ -823,7 +830,8 @@ class TailwindButton extends TailwindComponent {
823
830
  danger: 'bg-transparent text-danger-600 border-transparent hover:bg-danger-50 active:bg-danger-100 focus-visible:outline-danger-600',
824
831
  success: 'bg-transparent text-success-600 border-transparent hover:bg-success-50 active:bg-success-100 focus-visible:outline-success-600',
825
832
  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'
833
+ info: 'bg-transparent text-info-600 border-transparent hover:bg-info-50 active:bg-info-100 focus-visible:outline-info-600',
834
+ transparent: transparentColorClasses
827
835
  };
828
836
  /** Text color from severity only; background stays transparent on hover/active. */
829
837
  const textMap = {
@@ -832,7 +840,8 @@ class TailwindButton extends TailwindComponent {
832
840
  danger: 'bg-transparent text-danger-600 border-transparent focus-visible:outline-danger-600',
833
841
  success: 'bg-transparent text-success-600 border-transparent focus-visible:outline-success-600',
834
842
  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'
843
+ info: 'bg-transparent text-info-600 border-transparent focus-visible:outline-info-600',
844
+ transparent: transparentColorClasses
836
845
  };
837
846
  const styleMap = {
838
847
  solid: solidMap,
@@ -866,12 +875,12 @@ class TailwindButton extends TailwindComponent {
866
875
  }
867
876
  }
868
877
  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 });
878
+ 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
879
  }
871
880
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindButton, decorators: [{
872
881
  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"] }] } });
882
+ 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"] }]
883
+ }], 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
884
 
876
885
  class TailwindInput extends TailwindComponent {
877
886
  /** Label text */
@@ -1264,7 +1273,7 @@ class TailwindUpload extends TailwindComponent {
1264
1273
  useExisting: forwardRef(() => TailwindUpload),
1265
1274
  multi: true
1266
1275
  }
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 });
1276
+ ], 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
1277
  }
1269
1278
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindUpload, decorators: [{
1270
1279
  type: Component,
@@ -1274,7 +1283,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
1274
1283
  useExisting: forwardRef(() => TailwindUpload),
1275
1284
  multi: true
1276
1285
  }
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"] }]
1286
+ ], 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
1287
  }], 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
1288
 
1280
1289
  class TailwindInputOtp extends TailwindComponent {
@@ -1533,6 +1542,16 @@ class TailwindCheckbox extends TailwindComponent {
1533
1542
  };
1534
1543
  return sizeMap[this.size()];
1535
1544
  }, ...(ngDevMode ? [{ debugName: "boxSizeClass" }] : /* istanbul ignore next */ []));
1545
+ checkIconSize = computed(() => {
1546
+ const sizeMap = {
1547
+ xs: 16,
1548
+ sm: 16,
1549
+ md: 20,
1550
+ lg: 24,
1551
+ xl: 28
1552
+ };
1553
+ return sizeMap[this.size()];
1554
+ }, ...(ngDevMode ? [{ debugName: "checkIconSize" }] : /* istanbul ignore next */ []));
1536
1555
  // CVA
1537
1556
  onChange = () => { };
1538
1557
  onTouched = () => { };
@@ -1561,17 +1580,17 @@ class TailwindCheckbox extends TailwindComponent {
1561
1580
  useExisting: forwardRef(() => TailwindCheckbox),
1562
1581
  multi: true
1563
1582
  }
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 });
1583
+ ], 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
1584
  }
1566
1585
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindCheckbox, decorators: [{
1567
1586
  type: Component,
1568
- args: [{ selector: 'tailwind-checkbox', providers: [
1587
+ args: [{ imports: [TailwindIcon], selector: 'tailwind-checkbox', providers: [
1569
1588
  {
1570
1589
  provide: NG_VALUE_ACCESSOR,
1571
1590
  useExisting: forwardRef(() => TailwindCheckbox),
1572
1591
  multi: true
1573
1592
  }
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"] }]
1593
+ ], 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
1594
  }], 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
1595
 
1577
1596
  class TailwindRadioGroup extends TailwindComponent {
@@ -1937,19 +1956,376 @@ class TailwindSelect extends TailwindComponent {
1937
1956
  useExisting: forwardRef(() => TailwindSelect),
1938
1957
  multi: true
1939
1958
  }
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 });
1959
+ ], 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
1960
  }
1942
1961
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindSelect, decorators: [{
1943
1962
  type: Component,
1944
- args: [{ selector: 'tailwind-select', providers: [
1963
+ args: [{ imports: [TailwindIcon], selector: 'tailwind-select', providers: [
1945
1964
  {
1946
1965
  provide: NG_VALUE_ACCESSOR,
1947
1966
  useExisting: forwardRef(() => TailwindSelect),
1948
1967
  multi: true
1949
1968
  }
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"] }]
1969
+ ], 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
1970
  }], 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
1971
 
1972
+ class TailwindAutocomplete extends TailwindComponent {
1973
+ static nextId = 0;
1974
+ overlay = inject(Overlay);
1975
+ vcr = inject(ViewContainerRef);
1976
+ elRef = inject((ElementRef));
1977
+ cdr = inject(ChangeDetectorRef);
1978
+ ngZone = inject(NgZone);
1979
+ panelTemplate = viewChild.required('panelTemplate');
1980
+ constructor() {
1981
+ super();
1982
+ effect(() => {
1983
+ const opts = this.filteredOptions();
1984
+ if (!this.isOpen())
1985
+ return;
1986
+ const v = this.value();
1987
+ let initial = -1;
1988
+ if (v != null) {
1989
+ initial = opts.findIndex(o => this.optionValueEquals(o.value, v));
1990
+ }
1991
+ else if (opts.length > 0) {
1992
+ initial = 0;
1993
+ }
1994
+ this.activeIndex.set(initial >= 0 ? initial : -1);
1995
+ this.cdr.detectChanges();
1996
+ });
1997
+ }
1998
+ overlayRef = null;
1999
+ outsideSub = null;
2000
+ searchDebounceTimer = null;
2001
+ instanceListboxId = `tailwind-autocomplete-listbox-${++TailwindAutocomplete.nextId}`;
2002
+ /** Label text */
2003
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2004
+ /** Placeholder text */
2005
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
2006
+ /** Available options */
2007
+ options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
2008
+ /** Size variant */
2009
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
2010
+ /** Helper text */
2011
+ helperText = input('', ...(ngDevMode ? [{ debugName: "helperText" }] : /* istanbul ignore next */ []));
2012
+ /** Error text */
2013
+ errorText = input('', ...(ngDevMode ? [{ debugName: "errorText" }] : /* istanbul ignore next */ []));
2014
+ /** Whether in error state */
2015
+ hasError = input(false, ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
2016
+ /** Filter options locally by label when typing */
2017
+ filterLocally = input(true, ...(ngDevMode ? [{ debugName: "filterLocally" }] : /* istanbul ignore next */ []));
2018
+ /** Minimum query length before opening panel and emitting onSearch */
2019
+ minSearchLength = input(0, ...(ngDevMode ? [{ debugName: "minSearchLength" }] : /* istanbul ignore next */ []));
2020
+ /** Debounce delay (ms) for onSearch emission only */
2021
+ debounceMs = input(0, ...(ngDevMode ? [{ debugName: "debounceMs" }] : /* istanbul ignore next */ []));
2022
+ /** On blur, reset input to selected option label or clear invalid text */
2023
+ forceSelection = input(true, ...(ngDevMode ? [{ debugName: "forceSelection" }] : /* istanbul ignore next */ []));
2024
+ /** Selected value (form control) — set only when an option is chosen */
2025
+ value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
2026
+ /** Emits the current search query (after debounce / minSearchLength) */
2027
+ onSearch = output();
2028
+ /** Custom option row template (`ng-template` with `#item`) */
2029
+ itemTemplate = contentChild('item', { ...(ngDevMode ? { debugName: "itemTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
2030
+ /** Text shown in the input */
2031
+ searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
2032
+ isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
2033
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
2034
+ activeIndex = signal(-1, ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
2035
+ listboxId = computed(() => (this.id() ? `${this.id()}-listbox` : this.instanceListboxId), ...(ngDevMode ? [{ debugName: "listboxId" }] : /* istanbul ignore next */ []));
2036
+ selectedOption = computed(() => {
2037
+ const v = this.value();
2038
+ if (v == null)
2039
+ return null;
2040
+ return this.options().find(o => this.optionValueEquals(o.value, v)) ?? null;
2041
+ }, ...(ngDevMode ? [{ debugName: "selectedOption" }] : /* istanbul ignore next */ []));
2042
+ filteredOptions = computed(() => {
2043
+ const opts = this.options();
2044
+ if (!this.filterLocally())
2045
+ return opts;
2046
+ const q = this.searchQuery().trim().toLowerCase();
2047
+ if (!q)
2048
+ return opts;
2049
+ return opts.filter(o => o.label.toLowerCase().includes(q));
2050
+ }, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
2051
+ inputClasses = computed(() => {
2052
+ const sizeMap = {
2053
+ xs: 'text-xs px-2 py-1 rounded-sm',
2054
+ sm: 'text-sm px-2.5 py-1.5 rounded-md',
2055
+ md: 'text-sm px-3 py-2 rounded-md',
2056
+ lg: 'text-base px-3.5 py-2.5 rounded-lg',
2057
+ xl: 'text-base px-4 py-3 rounded-lg'
2058
+ };
2059
+ const stateClass = this.hasError()
2060
+ ? 'border-danger-400 focus:outline-danger-500 text-danger-900'
2061
+ : 'border-neutral-300 focus:outline-primary-500 text-neutral-900';
2062
+ return [
2063
+ 'block w-full bg-white border transition-colors duration-150',
2064
+ 'placeholder:text-neutral-400',
2065
+ 'outline-none focus:outline focus:outline-2 focus:outline-offset-2',
2066
+ 'disabled:bg-neutral-50 disabled:text-neutral-400 disabled:cursor-not-allowed',
2067
+ sizeMap[this.size()],
2068
+ stateClass
2069
+ ].join(' ');
2070
+ }, ...(ngDevMode ? [{ debugName: "inputClasses" }] : /* istanbul ignore next */ []));
2071
+ onChange = () => { };
2072
+ onTouched = () => { };
2073
+ writeValue(value) {
2074
+ this.value.set(value ?? null);
2075
+ const opt = this.options().find(o => this.optionValueEquals(o.value, value));
2076
+ this.searchQuery.set(opt?.label ?? '');
2077
+ }
2078
+ registerOnChange(fn) {
2079
+ this.onChange = fn;
2080
+ }
2081
+ registerOnTouched(fn) {
2082
+ this.onTouched = fn;
2083
+ }
2084
+ setDisabledState(disabled) {
2085
+ this.isDisabled.set(disabled);
2086
+ }
2087
+ ngOnDestroy() {
2088
+ if (this.searchDebounceTimer != null) {
2089
+ clearTimeout(this.searchDebounceTimer);
2090
+ }
2091
+ this.closePanel();
2092
+ }
2093
+ isOptionSelected(option) {
2094
+ const v = this.value();
2095
+ if (v == null)
2096
+ return false;
2097
+ return this.optionValueEquals(option.value, v);
2098
+ }
2099
+ optionClasses(index, option) {
2100
+ const isSelected = this.isOptionSelected(option);
2101
+ const isActive = this.activeIndex() === index;
2102
+ const isDisabled = !!option.disabled;
2103
+ return [
2104
+ 'flex items-center justify-between px-3 py-2 text-sm cursor-pointer select-none',
2105
+ isDisabled
2106
+ ? 'text-neutral-400 cursor-not-allowed'
2107
+ : isSelected
2108
+ ? 'bg-primary-50 text-primary-700 font-medium'
2109
+ : isActive
2110
+ ? 'bg-neutral-100 text-neutral-900'
2111
+ : 'text-neutral-800 hover:bg-neutral-50'
2112
+ ].join(' ');
2113
+ }
2114
+ itemContext(option, index) {
2115
+ return {
2116
+ $implicit: option,
2117
+ option,
2118
+ index,
2119
+ selected: this.isOptionSelected(option),
2120
+ active: this.activeIndex() === index
2121
+ };
2122
+ }
2123
+ onInputChange(event) {
2124
+ const query = event.target.value;
2125
+ this.searchQuery.set(query);
2126
+ this.cdr.markForCheck();
2127
+ const selected = this.selectedOption();
2128
+ if (selected && query !== selected.label) {
2129
+ this.value.set(null);
2130
+ this.onChange(null);
2131
+ }
2132
+ this.emitSearch(query);
2133
+ if (query.length >= this.minSearchLength()) {
2134
+ this.openPanel();
2135
+ }
2136
+ else {
2137
+ this.closePanel();
2138
+ }
2139
+ }
2140
+ onFocus() {
2141
+ if (this.isDisabled())
2142
+ return;
2143
+ if (this.searchQuery().length >= this.minSearchLength()) {
2144
+ this.openPanel();
2145
+ }
2146
+ }
2147
+ onBlur() {
2148
+ this.onTouched();
2149
+ queueMicrotask(() => this.applyForceSelectionOnBlur());
2150
+ }
2151
+ applyForceSelectionOnBlur() {
2152
+ if (!this.forceSelection() || this.isOpen())
2153
+ return;
2154
+ const active = document.activeElement;
2155
+ const host = this.elRef.nativeElement;
2156
+ const pane = this.overlayRef?.overlayElement;
2157
+ if (active && (host.contains(active) || pane?.contains(active)))
2158
+ return;
2159
+ const selected = this.selectedOption();
2160
+ const query = this.searchQuery();
2161
+ if (selected) {
2162
+ if (query !== selected.label) {
2163
+ this.searchQuery.set(selected.label);
2164
+ }
2165
+ return;
2166
+ }
2167
+ if (query) {
2168
+ this.searchQuery.set('');
2169
+ }
2170
+ }
2171
+ selectOption(option) {
2172
+ if (option.disabled)
2173
+ return;
2174
+ this.value.set(option.value);
2175
+ this.searchQuery.set(option.label);
2176
+ this.onChange(option.value);
2177
+ this.onTouched();
2178
+ this.closePanel();
2179
+ }
2180
+ onKeydown(event) {
2181
+ if (this.isDisabled())
2182
+ return;
2183
+ const opts = this.filteredOptions();
2184
+ switch (event.key) {
2185
+ case 'ArrowDown': {
2186
+ event.preventDefault();
2187
+ if (!this.isOpen()) {
2188
+ this.openPanel();
2189
+ return;
2190
+ }
2191
+ let next = this.activeIndex() + 1;
2192
+ while (next < opts.length && opts[next].disabled)
2193
+ next++;
2194
+ if (next < opts.length)
2195
+ this.activeIndex.set(next);
2196
+ break;
2197
+ }
2198
+ case 'ArrowUp': {
2199
+ event.preventDefault();
2200
+ if (!this.isOpen()) {
2201
+ this.openPanel();
2202
+ return;
2203
+ }
2204
+ let prev = this.activeIndex() - 1;
2205
+ while (prev >= 0 && opts[prev].disabled)
2206
+ prev--;
2207
+ if (prev >= 0)
2208
+ this.activeIndex.set(prev);
2209
+ break;
2210
+ }
2211
+ case 'Enter': {
2212
+ event.preventDefault();
2213
+ if (!this.isOpen()) {
2214
+ this.openPanel();
2215
+ return;
2216
+ }
2217
+ const active = this.activeIndex();
2218
+ if (active >= 0 && active < opts.length) {
2219
+ this.selectOption(opts[active]);
2220
+ }
2221
+ break;
2222
+ }
2223
+ case 'Escape':
2224
+ case 'Tab': {
2225
+ this.closePanel();
2226
+ break;
2227
+ }
2228
+ }
2229
+ }
2230
+ optionValueEquals(a, b) {
2231
+ return Object.is(a, b);
2232
+ }
2233
+ emitSearch(query) {
2234
+ if (query.length < this.minSearchLength())
2235
+ return;
2236
+ const debounce = this.debounceMs();
2237
+ if (this.searchDebounceTimer != null) {
2238
+ clearTimeout(this.searchDebounceTimer);
2239
+ this.searchDebounceTimer = null;
2240
+ }
2241
+ if (debounce <= 0) {
2242
+ this.onSearch.emit(query);
2243
+ return;
2244
+ }
2245
+ this.searchDebounceTimer = setTimeout(() => {
2246
+ this.ngZone.run(() => {
2247
+ this.onSearch.emit(query);
2248
+ this.cdr.markForCheck();
2249
+ });
2250
+ this.searchDebounceTimer = null;
2251
+ }, debounce);
2252
+ }
2253
+ openPanel() {
2254
+ if (this.overlayRef || this.isDisabled())
2255
+ return;
2256
+ if (this.searchQuery().length < this.minSearchLength())
2257
+ return;
2258
+ const trigger = this.elRef.nativeElement.querySelector('input[role="combobox"]');
2259
+ if (!trigger)
2260
+ return;
2261
+ const positionStrategy = this.overlay
2262
+ .position()
2263
+ .flexibleConnectedTo(trigger)
2264
+ .withPositions([
2265
+ { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },
2266
+ { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' }
2267
+ ])
2268
+ .withFlexibleDimensions(false)
2269
+ .withPush(false);
2270
+ this.overlayRef = this.overlay.create({
2271
+ positionStrategy,
2272
+ scrollStrategy: this.overlay.scrollStrategies.close(),
2273
+ width: trigger.offsetWidth
2274
+ });
2275
+ const portal = new TemplatePortal(this.panelTemplate(), this.vcr);
2276
+ this.overlayRef.attach(portal);
2277
+ const pane = this.overlayRef.overlayElement;
2278
+ this.outsideSub = new Subscription();
2279
+ this.outsideSub.add(fromEvent(document, 'pointerdown', { capture: true }).subscribe(ev => {
2280
+ const t = ev.target;
2281
+ if (this.elRef.nativeElement.contains(t) || pane.contains(t))
2282
+ return;
2283
+ this.closePanel();
2284
+ }));
2285
+ this.outsideSub.add(fromEvent(document, 'keydown').subscribe(ev => {
2286
+ if (ev.key === 'Escape') {
2287
+ ev.preventDefault();
2288
+ this.closePanel();
2289
+ }
2290
+ }));
2291
+ this.isOpen.set(true);
2292
+ const opts = this.filteredOptions();
2293
+ const v = this.value();
2294
+ let initial = -1;
2295
+ if (v != null) {
2296
+ initial = opts.findIndex(o => this.optionValueEquals(o.value, v));
2297
+ }
2298
+ this.activeIndex.set(initial >= 0 ? initial : -1);
2299
+ }
2300
+ closePanel() {
2301
+ this.overlayRef?.detach();
2302
+ this.overlayRef?.dispose();
2303
+ this.overlayRef = null;
2304
+ this.outsideSub?.unsubscribe();
2305
+ this.outsideSub = null;
2306
+ this.isOpen.set(false);
2307
+ this.activeIndex.set(-1);
2308
+ }
2309
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindAutocomplete, deps: [], target: i0.ɵɵFactoryTarget.Component });
2310
+ 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: [
2311
+ {
2312
+ provide: NG_VALUE_ACCESSOR,
2313
+ useExisting: forwardRef(() => TailwindAutocomplete),
2314
+ multi: true
2315
+ }
2316
+ ], 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 });
2317
+ }
2318
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindAutocomplete, decorators: [{
2319
+ type: Component,
2320
+ args: [{ imports: [NgTemplateOutlet, TailwindIcon], selector: 'tailwind-autocomplete', providers: [
2321
+ {
2322
+ provide: NG_VALUE_ACCESSOR,
2323
+ useExisting: forwardRef(() => TailwindAutocomplete),
2324
+ multi: true
2325
+ }
2326
+ ], 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"] }]
2327
+ }], 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 }] }] } });
2328
+
1953
2329
  class TailwindToggle extends TailwindComponent {
1954
2330
  /** Label text */
1955
2331
  label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
@@ -2186,11 +2562,11 @@ class TailwindAlert extends TailwindComponent {
2186
2562
  this.onDismiss.emit();
2187
2563
  }
2188
2564
  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 });
2565
+ 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
2566
  }
2191
2567
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindAlert, decorators: [{
2192
2568
  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"] }]
2569
+ 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
2570
  }], 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
2571
 
2196
2572
  class TailwindSpinner extends TailwindComponent {
@@ -2209,24 +2585,28 @@ class TailwindSpinner extends TailwindComponent {
2209
2585
  const orient = this.orientation() === 'vertical' ? 'flex-col' : '';
2210
2586
  return `${base} ${orient}`;
2211
2587
  }, ...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
2212
- spinnerClasses = computed(() => {
2588
+ iconPixelSize = computed(() => {
2213
2589
  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'
2590
+ xs: 16,
2591
+ sm: 16,
2592
+ md: 24,
2593
+ lg: 32,
2594
+ xl: 48
2219
2595
  };
2596
+ return sizeMap[this.size()];
2597
+ }, ...(ngDevMode ? [{ debugName: "iconPixelSize" }] : /* istanbul ignore next */ []));
2598
+ iconClasses = computed(() => {
2220
2599
  const colorMap = {
2221
2600
  primary: 'text-primary-600',
2222
2601
  secondary: 'text-secondary-600',
2223
2602
  success: 'text-success-600',
2224
2603
  warning: 'text-warning-600',
2225
2604
  danger: 'text-danger-600',
2226
- info: 'text-info-600'
2605
+ info: 'text-info-600',
2606
+ transparent: 'text-neutral-400'
2227
2607
  };
2228
- return `tailwind-spinner-svg ${sizeMap[this.size()]} ${colorMap[this.color()]}`;
2229
- }, ...(ngDevMode ? [{ debugName: "spinnerClasses" }] : /* istanbul ignore next */ []));
2608
+ return `animate-spin ${colorMap[this.color()]}`;
2609
+ }, ...(ngDevMode ? [{ debugName: "iconClasses" }] : /* istanbul ignore next */ []));
2230
2610
  labelClasses = computed(() => {
2231
2611
  const sizeMap = {
2232
2612
  xs: 'text-xs',
@@ -2238,11 +2618,11 @@ class TailwindSpinner extends TailwindComponent {
2238
2618
  return `${sizeMap[this.size()]} ${this.color()} font-medium`;
2239
2619
  }, ...(ngDevMode ? [{ debugName: "labelClasses" }] : /* istanbul ignore next */ []));
2240
2620
  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 });
2621
+ 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
2622
  }
2243
2623
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindSpinner, decorators: [{
2244
2624
  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"] }]
2625
+ 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
2626
  }], 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
2627
 
2248
2628
  class TailwindModal extends TailwindComponent {
@@ -2297,11 +2677,11 @@ class TailwindModal extends TailwindComponent {
2297
2677
  }, 200);
2298
2678
  }
2299
2679
  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 });
2680
+ 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
2681
  }
2302
2682
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindModal, decorators: [{
2303
2683
  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"] }]
2684
+ 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
2685
  }], 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
2686
 
2307
2687
  class TailwindTab extends TailwindComponent {
@@ -2639,11 +3019,11 @@ class TailwindDrawer extends TailwindComponent {
2639
3019
  }, 300);
2640
3020
  }
2641
3021
  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 });
3022
+ 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
3023
  }
2644
3024
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindDrawer, decorators: [{
2645
3025
  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"] }]
3026
+ 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
3027
  }], 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
3028
 
2649
3029
  class TailwindBreadcrumb extends TailwindComponent {
@@ -2718,11 +3098,11 @@ class TailwindPagination extends TailwindComponent {
2718
3098
  }
2719
3099
  }
2720
3100
  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 });
3101
+ 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
3102
  }
2723
3103
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindPagination, decorators: [{
2724
3104
  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"] }]
3105
+ 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
3106
  }], 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
3107
 
2728
3108
  class TailwindTag extends TailwindComponent {
@@ -2867,14 +3247,14 @@ class TailwindTable extends TailwindComponent {
2867
3247
  this.sort(key);
2868
3248
  }
2869
3249
  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 });
3250
+ 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
3251
  }
2872
3252
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindTable, decorators: [{
2873
3253
  type: Component,
2874
- args: [{ selector: 'tailwind-table', imports: [NgTemplateOutlet, TailwindPagination], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3254
+ args: [{ selector: 'tailwind-table', imports: [NgTemplateOutlet, TailwindPagination, TailwindIcon], changeDetection: ChangeDetectionStrategy.OnPush, host: {
2875
3255
  '[attr.data-tw-sort-key]': 'sortKey()',
2876
3256
  '[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"] }]
3257
+ }, 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
3258
  }], 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
3259
  type: HostListener,
2880
3260
  args: ['click', ['$event']]
@@ -3054,11 +3434,11 @@ class TailwindDatePicker extends TailwindComponent {
3054
3434
  this.showCalendar.set(false);
3055
3435
  }
3056
3436
  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 });
3437
+ 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
3438
  }
3059
3439
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindDatePicker, decorators: [{
3060
3440
  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"] }]
3441
+ 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
3442
  }], 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
3443
  type: HostListener,
3064
3444
  args: ['document:pointerdown', ['$event']]
@@ -3153,11 +3533,11 @@ class TailwindTimePicker extends TailwindComponent {
3153
3533
  this.showPanel.set(false);
3154
3534
  }
3155
3535
  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 });
3536
+ 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
3537
  }
3158
3538
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindTimePicker, decorators: [{
3159
3539
  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"] }]
3540
+ 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
3541
  }], 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
3542
  type: HostListener,
3163
3543
  args: ['document:pointerdown', ['$event']]
@@ -3368,11 +3748,11 @@ class TailwindDateTimePicker extends TailwindComponent {
3368
3748
  this.showPanel.set(false);
3369
3749
  }
3370
3750
  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 });
3751
+ 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
3752
  }
3373
3753
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindDateTimePicker, decorators: [{
3374
3754
  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"] }]
3755
+ 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
3756
  }], 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
3757
  type: HostListener,
3378
3758
  args: ['document:pointerdown', ['$event']]
@@ -3424,11 +3804,11 @@ class TailwindStepper extends TailwindComponent {
3424
3804
  this.activeIndex.update(v => v - 1);
3425
3805
  }
3426
3806
  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 });
3807
+ 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
3808
  }
3429
3809
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindStepper, decorators: [{
3430
3810
  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"] }]
3811
+ 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
3812
  }], 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
3813
 
3434
3814
  class TailwindAccordionItem extends TailwindComponent {
@@ -3443,11 +3823,11 @@ class TailwindAccordionItem extends TailwindComponent {
3443
3823
  }
3444
3824
  }
3445
3825
  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 });
3826
+ 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
3827
  }
3448
3828
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindAccordionItem, decorators: [{
3449
3829
  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"] }]
3830
+ 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
3831
  }], 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
3832
 
3453
3833
  class TailwindAccordion extends TailwindComponent {
@@ -3597,11 +3977,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
3597
3977
  class TailwindToast extends TailwindComponent {
3598
3978
  toastService = inject(TailwindToastService);
3599
3979
  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 });
3980
+ 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
3981
  }
3602
3982
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindToast, decorators: [{
3603
3983
  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"] }]
3984
+ 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
3985
  }] });
3606
3986
 
3607
3987
  class TailwindNotification extends TailwindComponent {
@@ -3620,11 +4000,11 @@ class TailwindNotification extends TailwindComponent {
3620
4000
  return `flex items-start rounded-lg border p-4 ${variantMap[this.severity()]}`;
3621
4001
  }, ...(ngDevMode ? [{ debugName: "computedClasses" }] : /* istanbul ignore next */ []));
3622
4002
  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 });
4003
+ 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
4004
  }
3625
4005
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TailwindNotification, decorators: [{
3626
4006
  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"] }]
4007
+ 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
4008
  }], 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
4009
 
3630
4010
  class TailwindMessage extends TailwindComponent {
@@ -4352,5 +4732,5 @@ function defineTheme(config) {
4352
4732
  * Generated bundle index. Do not edit.
4353
4733
  */
4354
4734
 
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 };
4735
+ 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
4736
  //# sourceMappingURL=angular-tailwind-components.mjs.map