ten-minds-ui-kit 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,921 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Component, input, output, computed, model, signal, ChangeDetectionStrategy, Injectable, inject, Directive, ViewContainerRef, ElementRef, TemplateRef, ViewChild, HostListener, ContentChild } from '@angular/core';
3
+ import * as i1 from 'lucide-angular';
4
+ import { LucideAngularModule, Info, CircleX, TriangleAlert, CircleCheck, X, ShoppingCart, Sun, Moon, ChevronDown, CheckIcon } from 'lucide-angular';
5
+ import { FormsModule } from '@angular/forms';
6
+ import { NgIf, NgFor, NgTemplateOutlet } from '@angular/common';
7
+ import { Overlay, OverlayModule } from '@angular/cdk/overlay';
8
+ import { TemplatePortal } from '@angular/cdk/portal';
9
+
10
+ class TwCart {
11
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TwCart, deps: [], target: i0.ɵɵFactoryTarget.Component });
12
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: TwCart, isStandalone: true, selector: "lib-tw-cart", ngImport: i0, template: "<div class=\"bg-[#161616] border border-[#2a2a2a] rounded-2xl overflow-hidden w-full max-w-md\">\n\n <!-- Header -->\n <div class=\"flex items-center justify-between px-6 py-5 border-b border-[#1f1f1f]\">\n <div class=\"flex items-center gap-2.5\">\n <div class=\"w-8 h-8 bg-[#1a1a1a] border border-[#2a2a2a] rounded-lg flex items-center justify-center\">\n <svg class=\"w-4 h-4 text-[#e2e2e2]\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M1 1h2l2.5 8h7l1.5-5H4.5\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <circle cx=\"7\" cy=\"13\" r=\"1\" fill=\"currentColor\"/>\n <circle cx=\"11\" cy=\"13\" r=\"1\" fill=\"currentColor\"/>\n </svg>\n </div>\n <span class=\"text-[15px] font-medium text-[#e2e2e2] tracking-tight\">Your cart</span>\n <span class=\"text-[11px] font-mono bg-[#1f1f1f] border border-[#2a2a2a] text-[#666] px-2 py-0.5 rounded-full\">3</span>\n </div>\n </div>\n\n <!-- Items -->\n <div class=\"divide-y divide-[#1f1f1f]\">\n\n <!-- Item -->\n <div class=\"flex items-center gap-4 px-6 py-4\">\n <div class=\"w-12 h-12 rounded-xl bg-[#1e2a20] border border-[#2a3a2c] flex-shrink-0 flex items-center justify-center text-xl\">\n \uD83C\uDFA7\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-[13px] font-medium text-[#d8d8d8] truncate\">Studio Headphones Pro</p>\n <p class=\"text-[11px] text-[#555] mt-0.5 font-mono\">Midnight Black</p>\n </div>\n <div class=\"flex items-center gap-3 flex-shrink-0\">\n <div class=\"flex items-center bg-[#1f1f1f] border border-[#2a2a2a] rounded-lg overflow-hidden\">\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">\u2212</span>\n <span class=\"text-[12px] text-[#d8d8d8] font-mono min-w-[20px] text-center\">1</span>\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">+</span>\n </div>\n <span class=\"text-[13px] font-semibold text-[#e2e2e2] font-mono w-14 text-right\">$249</span>\n </div>\n </div>\n\n <!-- Item -->\n <div class=\"flex items-center gap-4 px-6 py-4\">\n <div class=\"w-12 h-12 rounded-xl bg-[#201a2a] border border-[#362a40] flex-shrink-0 flex items-center justify-center text-xl\">\n \u231A\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-[13px] font-medium text-[#d8d8d8] truncate\">Smart Watch Series X</p>\n <p class=\"text-[11px] text-[#555] mt-0.5 font-mono\">45mm \u00B7 Space Gray</p>\n </div>\n <div class=\"flex items-center gap-3 flex-shrink-0\">\n <div class=\"flex items-center bg-[#1f1f1f] border border-[#2a2a2a] rounded-lg overflow-hidden\">\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">\u2212</span>\n <span class=\"text-[12px] text-[#d8d8d8] font-mono min-w-[20px] text-center\">2</span>\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">+</span>\n </div>\n <span class=\"text-[13px] font-semibold text-[#e2e2e2] font-mono w-14 text-right\">$798</span>\n </div>\n </div>\n\n <!-- Item -->\n <div class=\"flex items-center gap-4 px-6 py-4\">\n <div class=\"w-12 h-12 rounded-xl bg-[#2a1e1a] border border-[#402d28] flex-shrink-0 flex items-center justify-center text-xl\">\n \uD83D\uDDB1\uFE0F\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-[13px] font-medium text-[#d8d8d8] truncate\">Ergonomic Mouse Ultra</p>\n <p class=\"text-[11px] text-[#555] mt-0.5 font-mono\">Wireless \u00B7 Graphite</p>\n </div>\n <div class=\"flex items-center gap-3 flex-shrink-0\">\n <div class=\"flex items-center bg-[#1f1f1f] border border-[#2a2a2a] rounded-lg overflow-hidden\">\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">\u2212</span>\n <span class=\"text-[12px] text-[#d8d8d8] font-mono min-w-[20px] text-center\">1</span>\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">+</span>\n </div>\n <span class=\"text-[13px] font-semibold text-[#e2e2e2] font-mono w-14 text-right\">$89</span>\n </div>\n </div>\n\n </div>\n\n <!-- Summary -->\n <div class=\"px-6 py-4 border-t border-[#1f1f1f] flex flex-col gap-2\">\n <div class=\"flex justify-between\">\n <span class=\"text-[12px] text-[#555]\">Subtotal</span>\n <span class=\"text-[12px] text-[#888] font-mono\">$1,136.00</span>\n </div>\n <div class=\"flex justify-between\">\n <span class=\"text-[12px] text-[#555]\">Shipping</span>\n <span class=\"text-[12px] text-emerald-400 font-mono\">Free</span>\n </div>\n <div class=\"flex justify-between pt-3 mt-1 border-t border-[#1f1f1f]\">\n <span class=\"text-[14px] font-medium text-[#d8d8d8] tracking-tight\">Total</span>\n <span class=\"text-[16px] font-semibold text-[#e2e2e2] font-mono tracking-tight\">$1,136.00</span>\n </div>\n </div>\n\n <!-- CTA -->\n <div class=\"px-6 pb-6 flex flex-col gap-2\">\n <button class=\"w-full py-3.5 bg-[#e2e2e2] rounded-xl text-[14px] font-semibold text-[#0f0f0f] tracking-tight\">\n Checkout \u2014 $1,136.00\n </button>\n <button class=\"w-full py-2.5 text-[12px] text-[#444] bg-transparent border-none\">\n Continue shopping \u2192\n </button>\n </div>\n\n</div>\n", styles: [""] });
13
+ }
14
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TwCart, decorators: [{
15
+ type: Component,
16
+ args: [{ selector: 'lib-tw-cart', imports: [], template: "<div class=\"bg-[#161616] border border-[#2a2a2a] rounded-2xl overflow-hidden w-full max-w-md\">\n\n <!-- Header -->\n <div class=\"flex items-center justify-between px-6 py-5 border-b border-[#1f1f1f]\">\n <div class=\"flex items-center gap-2.5\">\n <div class=\"w-8 h-8 bg-[#1a1a1a] border border-[#2a2a2a] rounded-lg flex items-center justify-center\">\n <svg class=\"w-4 h-4 text-[#e2e2e2]\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M1 1h2l2.5 8h7l1.5-5H4.5\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <circle cx=\"7\" cy=\"13\" r=\"1\" fill=\"currentColor\"/>\n <circle cx=\"11\" cy=\"13\" r=\"1\" fill=\"currentColor\"/>\n </svg>\n </div>\n <span class=\"text-[15px] font-medium text-[#e2e2e2] tracking-tight\">Your cart</span>\n <span class=\"text-[11px] font-mono bg-[#1f1f1f] border border-[#2a2a2a] text-[#666] px-2 py-0.5 rounded-full\">3</span>\n </div>\n </div>\n\n <!-- Items -->\n <div class=\"divide-y divide-[#1f1f1f]\">\n\n <!-- Item -->\n <div class=\"flex items-center gap-4 px-6 py-4\">\n <div class=\"w-12 h-12 rounded-xl bg-[#1e2a20] border border-[#2a3a2c] flex-shrink-0 flex items-center justify-center text-xl\">\n \uD83C\uDFA7\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-[13px] font-medium text-[#d8d8d8] truncate\">Studio Headphones Pro</p>\n <p class=\"text-[11px] text-[#555] mt-0.5 font-mono\">Midnight Black</p>\n </div>\n <div class=\"flex items-center gap-3 flex-shrink-0\">\n <div class=\"flex items-center bg-[#1f1f1f] border border-[#2a2a2a] rounded-lg overflow-hidden\">\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">\u2212</span>\n <span class=\"text-[12px] text-[#d8d8d8] font-mono min-w-[20px] text-center\">1</span>\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">+</span>\n </div>\n <span class=\"text-[13px] font-semibold text-[#e2e2e2] font-mono w-14 text-right\">$249</span>\n </div>\n </div>\n\n <!-- Item -->\n <div class=\"flex items-center gap-4 px-6 py-4\">\n <div class=\"w-12 h-12 rounded-xl bg-[#201a2a] border border-[#362a40] flex-shrink-0 flex items-center justify-center text-xl\">\n \u231A\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-[13px] font-medium text-[#d8d8d8] truncate\">Smart Watch Series X</p>\n <p class=\"text-[11px] text-[#555] mt-0.5 font-mono\">45mm \u00B7 Space Gray</p>\n </div>\n <div class=\"flex items-center gap-3 flex-shrink-0\">\n <div class=\"flex items-center bg-[#1f1f1f] border border-[#2a2a2a] rounded-lg overflow-hidden\">\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">\u2212</span>\n <span class=\"text-[12px] text-[#d8d8d8] font-mono min-w-[20px] text-center\">2</span>\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">+</span>\n </div>\n <span class=\"text-[13px] font-semibold text-[#e2e2e2] font-mono w-14 text-right\">$798</span>\n </div>\n </div>\n\n <!-- Item -->\n <div class=\"flex items-center gap-4 px-6 py-4\">\n <div class=\"w-12 h-12 rounded-xl bg-[#2a1e1a] border border-[#402d28] flex-shrink-0 flex items-center justify-center text-xl\">\n \uD83D\uDDB1\uFE0F\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-[13px] font-medium text-[#d8d8d8] truncate\">Ergonomic Mouse Ultra</p>\n <p class=\"text-[11px] text-[#555] mt-0.5 font-mono\">Wireless \u00B7 Graphite</p>\n </div>\n <div class=\"flex items-center gap-3 flex-shrink-0\">\n <div class=\"flex items-center bg-[#1f1f1f] border border-[#2a2a2a] rounded-lg overflow-hidden\">\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">\u2212</span>\n <span class=\"text-[12px] text-[#d8d8d8] font-mono min-w-[20px] text-center\">1</span>\n <span class=\"w-7 h-7 flex items-center justify-center text-[#555] text-sm\">+</span>\n </div>\n <span class=\"text-[13px] font-semibold text-[#e2e2e2] font-mono w-14 text-right\">$89</span>\n </div>\n </div>\n\n </div>\n\n <!-- Summary -->\n <div class=\"px-6 py-4 border-t border-[#1f1f1f] flex flex-col gap-2\">\n <div class=\"flex justify-between\">\n <span class=\"text-[12px] text-[#555]\">Subtotal</span>\n <span class=\"text-[12px] text-[#888] font-mono\">$1,136.00</span>\n </div>\n <div class=\"flex justify-between\">\n <span class=\"text-[12px] text-[#555]\">Shipping</span>\n <span class=\"text-[12px] text-emerald-400 font-mono\">Free</span>\n </div>\n <div class=\"flex justify-between pt-3 mt-1 border-t border-[#1f1f1f]\">\n <span class=\"text-[14px] font-medium text-[#d8d8d8] tracking-tight\">Total</span>\n <span class=\"text-[16px] font-semibold text-[#e2e2e2] font-mono tracking-tight\">$1,136.00</span>\n </div>\n </div>\n\n <!-- CTA -->\n <div class=\"px-6 pb-6 flex flex-col gap-2\">\n <button class=\"w-full py-3.5 bg-[#e2e2e2] rounded-xl text-[14px] font-semibold text-[#0f0f0f] tracking-tight\">\n Checkout \u2014 $1,136.00\n </button>\n <button class=\"w-full py-2.5 text-[12px] text-[#444] bg-transparent border-none\">\n Continue shopping \u2192\n </button>\n </div>\n\n</div>\n" }]
17
+ }] });
18
+
19
+ class BtnPrimary {
20
+ color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
21
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
22
+ type = input('filled', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
23
+ active = input(false, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
24
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
25
+ iconLeft = input(...(ngDevMode ? [undefined, { debugName: "iconLeft" }] : /* istanbul ignore next */ []));
26
+ iconRight = input(...(ngDevMode ? [undefined, { debugName: "iconRight" }] : /* istanbul ignore next */ []));
27
+ rounded = input('default', ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
28
+ customClass = input('', ...(ngDevMode ? [{ debugName: "customClass" }] : /* istanbul ignore next */ []));
29
+ clicked = output();
30
+ iconSize = computed(() => {
31
+ const sizeMap = { lg: 20, md: 16, sm: 14 };
32
+ return sizeMap[this.size()];
33
+ }, ...(ngDevMode ? [{ debugName: "iconSize" }] : /* istanbul ignore next */ []));
34
+ leftIcon = computed(() => !!this.iconLeft(), ...(ngDevMode ? [{ debugName: "leftIcon" }] : /* istanbul ignore next */ []));
35
+ rightIcon = computed(() => !!this.iconRight(), ...(ngDevMode ? [{ debugName: "rightIcon" }] : /* istanbul ignore next */ []));
36
+ classes = computed(() => {
37
+ const base = 'inline-flex items-center justify-center font-medium transition-all duration-200 whitespace-nowrap';
38
+ const roundedMap = {
39
+ default: 'rounded-lg',
40
+ full: 'rounded-full',
41
+ };
42
+ const sizes = {
43
+ lg: 'h-11 min-h-11 px-5 py-3 gap-2.5 text-sm-medium ',
44
+ md: 'h-10 px-4 py-2.5 gap-2 text-sm-medium',
45
+ sm: 'h-9 px-3 py-2 gap-2 text-xs-medium',
46
+ };
47
+ const variants = {
48
+ primary: {
49
+ filled: 'bg-tm-brand text-tm-inverse hover:bg-tm-brand-hover-default hover:border-tm-brand-hover-default',
50
+ outlined: 'border border-tm-default text-tm-primary hover:bg-tm-brand-hover-subtle hover:border-tm-default',
51
+ ghost: 'text-tm-primary border-transparent hover:bg-tm-brand-hover-subtle',
52
+ },
53
+ danger: {
54
+ filled: 'bg-tm-red-500 text-tm-base-white hover:bg-tm-red-600 hover:border-tm-red-600',
55
+ outlined: 'text-red-500 border border-tm-default hover:bg-tm-red-500/10 hover:border-tm-default',
56
+ ghost: 'text-tm-red-500 border-transparent hover:bg-tm-red-500/10',
57
+ },
58
+ success: {
59
+ filled: 'bg-tm-green-500 text-tm-base-white hover:bg-tm-green-600 hover:border-tm-green-600',
60
+ outlined: 'text-tm-green-500 border border-tm-default hover:bg-tm-green-500/10',
61
+ ghost: 'text-tm-green-500 border-transparent hover:bg-tm-green-500/10',
62
+ },
63
+ warning: {
64
+ filled: 'bg-tm-yellow-500 text-tm-base-black hover:bg-tm-yellow-600 hover:border-tm-yellow-600',
65
+ outlined: 'text-tm-yellow-500 border border-tm-default hover:bg-tm-yellow-500/10',
66
+ ghost: 'text-tm-yellow-600 border-transparent hover:bg-tm-yellow-500/10',
67
+ },
68
+ };
69
+ const activeClass = this.active() ? 'brightness-90' : '';
70
+ const disabledClass = this.disabled() ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer';
71
+ return [
72
+ base,
73
+ sizes[this.size()],
74
+ variants[this.color()][this.type()],
75
+ roundedMap[this.rounded()],
76
+ activeClass,
77
+ disabledClass,
78
+ this.customClass(),
79
+ ]
80
+ .filter(Boolean)
81
+ .join(' ');
82
+ }, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
83
+ onButtonClick(event) {
84
+ if (!this.disabled()) {
85
+ this.clicked.emit(event);
86
+ }
87
+ }
88
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BtnPrimary, deps: [], target: i0.ɵɵFactoryTarget.Component });
89
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: BtnPrimary, isStandalone: true, selector: "tm-button", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, iconLeft: { classPropertyName: "iconLeft", publicName: "iconLeft", isSignal: true, isRequired: false, transformFunction: null }, iconRight: { classPropertyName: "iconRight", publicName: "iconRight", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, customClass: { classPropertyName: "customClass", publicName: "customClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, host: { properties: { "attr.disabled": "disabled() || null" } }, ngImport: i0, template: "<button [class]=\"classes()\" [disabled]=\"disabled()\" (click)=\"onButtonClick($event)\">\n @if (leftIcon()) {\n <lucide-icon [img]=\"iconLeft()!\" [size]=\"iconSize()\" [strokeWidth]=\"1.75\" />\n }\n <span><ng-content /></span>\n @if (rightIcon()) {\n <lucide-icon [img]=\"iconRight()!\" [size]=\"iconSize()\" [strokeWidth]=\"1.75\" />\n }\n</button>\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
90
+ }
91
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BtnPrimary, decorators: [{
92
+ type: Component,
93
+ args: [{ selector: 'tm-button', imports: [LucideAngularModule], host: {
94
+ '[attr.disabled]': 'disabled() || null',
95
+ }, template: "<button [class]=\"classes()\" [disabled]=\"disabled()\" (click)=\"onButtonClick($event)\">\n @if (leftIcon()) {\n <lucide-icon [img]=\"iconLeft()!\" [size]=\"iconSize()\" [strokeWidth]=\"1.75\" />\n }\n <span><ng-content /></span>\n @if (rightIcon()) {\n <lucide-icon [img]=\"iconRight()!\" [size]=\"iconSize()\" [strokeWidth]=\"1.75\" />\n }\n</button>\n" }]
96
+ }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], iconLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconLeft", required: false }] }], iconRight: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconRight", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], customClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "customClass", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
97
+
98
+ const SIZE_WRAPPER$1 = {
99
+ md: 'h-11 min-h-11 px-4 py-2 gap-2.5 text-sm',
100
+ sm: 'h-10 min-h-10 px-4 py-2 gap-2 text-xs',
101
+ };
102
+ const ICON_SIZE_PX = {
103
+ md: 20,
104
+ sm: 16,
105
+ };
106
+ const BASE_WRAPPER$1 = 'inline-flex items-center rounded-lg border w-[273px] ' +
107
+ 'transition-all duration-300 cursor-text hover:shadow-md';
108
+ const STATE_WRAPPER$1 = {
109
+ default: 'border-tm-default text-tm-secondary hover:border-tm-strong',
110
+ active: 'border-tm-default text-tm-primary ring-2 ring-tm-default/20 ',
111
+ hover: 'border-tm-strong text-tm-secondary',
112
+ disabled: 'border-tm-subtle text-tm-secondary bg-tm-subtle cursor-not-allowed hover:shadow-none',
113
+ error: 'border-tm-red-500 text-tm-secondary',
114
+ };
115
+ const BASE_INPUT = 'flex-1 bg-transparent outline-none ' +
116
+ 'placeholder:text-tm-secondary disabled:cursor-not-allowed';
117
+ class InputTen {
118
+ // ── Inputs
119
+ value = model('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
120
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
121
+ type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
122
+ placeholder = input('placeholder', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
123
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
124
+ hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
125
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
126
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
127
+ error = input('', ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
128
+ iconLeft = input(...(ngDevMode ? [undefined, { debugName: "iconLeft" }] : /* istanbul ignore next */ []));
129
+ iconRight = input(...(ngDevMode ? [undefined, { debugName: "iconRight" }] : /* istanbul ignore next */ []));
130
+ // ── Outputs
131
+ focused = output();
132
+ blurred = output();
133
+ // ── Estado interno
134
+ isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : /* istanbul ignore next */ []));
135
+ currentState = computed(() => {
136
+ if (this.disabled())
137
+ return 'disabled';
138
+ if (this.error())
139
+ return 'error';
140
+ if (this.isFocused())
141
+ return 'active';
142
+ return 'default';
143
+ }, ...(ngDevMode ? [{ debugName: "currentState" }] : /* istanbul ignore next */ []));
144
+ iconSizePx = computed(() => ICON_SIZE_PX[this.size()], ...(ngDevMode ? [{ debugName: "iconSizePx" }] : /* istanbul ignore next */ []));
145
+ wrapperClasses = computed(() => [BASE_WRAPPER$1, SIZE_WRAPPER$1[this.size()], STATE_WRAPPER$1[this.currentState()]].join(' '), ...(ngDevMode ? [{ debugName: "wrapperClasses" }] : /* istanbul ignore next */ []));
146
+ iconColorClass = computed(() => {
147
+ if (this.currentState() === 'error')
148
+ return 'text-tm-color-500';
149
+ if (this.currentState() === 'active')
150
+ return 'text-tm-primary';
151
+ return 'text-tm-secondary';
152
+ }, ...(ngDevMode ? [{ debugName: "iconColorClass" }] : /* istanbul ignore next */ []));
153
+ showLabel = computed(() => !!this.label(), ...(ngDevMode ? [{ debugName: "showLabel" }] : /* istanbul ignore next */ []));
154
+ showHint = computed(() => !!this.hint() && this.currentState() !== 'error', ...(ngDevMode ? [{ debugName: "showHint" }] : /* istanbul ignore next */ []));
155
+ showError = computed(() => !!this.error(), ...(ngDevMode ? [{ debugName: "showError" }] : /* istanbul ignore next */ []));
156
+ inputClasses = BASE_INPUT;
157
+ onFocus(event) {
158
+ this.isFocused.set(true);
159
+ this.focused.emit(event);
160
+ }
161
+ onBlur(event) {
162
+ this.isFocused.set(false);
163
+ this.blurred.emit(event);
164
+ }
165
+ onInput(event) {
166
+ const val = event.target.value;
167
+ this.value.set(val);
168
+ }
169
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: InputTen, deps: [], target: i0.ɵɵFactoryTarget.Component });
170
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: InputTen, isStandalone: true, selector: "tm-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, iconLeft: { classPropertyName: "iconLeft", publicName: "iconLeft", isSignal: true, isRequired: false, transformFunction: null }, iconRight: { classPropertyName: "iconRight", publicName: "iconRight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", focused: "focused", blurred: "blurred" }, ngImport: i0, template: "<!-- Label -->\n@if (showLabel()) {\n <label class=\"block text-sm font-medium text-tm-primary mb-1.5\">\n {{ label() }}\n @if (required()) {\n <span class=\"text-text-danger ml-0.5\">*</span>\n }\n </label>\n}\n\n<!-- Wrapper del input -->\n<div [class]=\"wrapperClasses()\">\n\n <!-- Icono izquierdo -->\n @if (iconLeft()) {\n <lucide-icon\n [img]=\"iconLeft()!\"\n [size]=\"iconSizePx()\"\n [strokeWidth]=\"1.75\"\n [class]=\"iconColorClass()\"\n />\n }\n\n <!-- Input nativo -->\n <input\n [class]=\"inputClasses\"\n [type]=\"type()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [value]=\"value()\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\"\n (input)=\"onInput($event)\"\n />\n\n <!-- Icono derecho -->\n @if (iconRight()) {\n <lucide-icon\n [img]=\"iconRight()!\"\n [size]=\"iconSizePx()\"\n [strokeWidth]=\"1.75\"\n [class]=\"iconColorClass()\"\n />\n }\n\n</div>\n\n<!-- Hint -->\n@if (showHint()) {\n <p class=\"mt-1.5 text-xs text-tm-secondary\">\n {{ hint() }}\n </p>\n}\n\n<!-- Error -->\n@if (showError()) {\n <p class=\"mt-1.5 text-xs text-tm-red-500\">\n {{ error() }}\n </p>\n}\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
171
+ }
172
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: InputTen, decorators: [{
173
+ type: Component,
174
+ args: [{ selector: 'tm-input', standalone: true, imports: [LucideAngularModule, FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Label -->\n@if (showLabel()) {\n <label class=\"block text-sm font-medium text-tm-primary mb-1.5\">\n {{ label() }}\n @if (required()) {\n <span class=\"text-text-danger ml-0.5\">*</span>\n }\n </label>\n}\n\n<!-- Wrapper del input -->\n<div [class]=\"wrapperClasses()\">\n\n <!-- Icono izquierdo -->\n @if (iconLeft()) {\n <lucide-icon\n [img]=\"iconLeft()!\"\n [size]=\"iconSizePx()\"\n [strokeWidth]=\"1.75\"\n [class]=\"iconColorClass()\"\n />\n }\n\n <!-- Input nativo -->\n <input\n [class]=\"inputClasses\"\n [type]=\"type()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [value]=\"value()\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\"\n (input)=\"onInput($event)\"\n />\n\n <!-- Icono derecho -->\n @if (iconRight()) {\n <lucide-icon\n [img]=\"iconRight()!\"\n [size]=\"iconSizePx()\"\n [strokeWidth]=\"1.75\"\n [class]=\"iconColorClass()\"\n />\n }\n\n</div>\n\n<!-- Hint -->\n@if (showHint()) {\n <p class=\"mt-1.5 text-xs text-tm-secondary\">\n {{ hint() }}\n </p>\n}\n\n<!-- Error -->\n@if (showError()) {\n <p class=\"mt-1.5 text-xs text-tm-red-500\">\n {{ error() }}\n </p>\n}\n" }]
175
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], iconLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconLeft", required: false }] }], iconRight: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconRight", required: false }] }], focused: [{ type: i0.Output, args: ["focused"] }], blurred: [{ type: i0.Output, args: ["blurred"] }] } });
176
+
177
+ class Snackbar {
178
+ color = input('success', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
179
+ type = input('alert', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
180
+ title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
181
+ description = input(...(ngDevMode ? [undefined, { debugName: "description" }] : /* istanbul ignore next */ []));
182
+ position = input('top-right', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
183
+ closed = output();
184
+ iconMap = {
185
+ success: CircleCheck,
186
+ warning: TriangleAlert,
187
+ error: CircleX,
188
+ info: Info,
189
+ };
190
+ closeIcon = X;
191
+ icon = computed(() => this.iconMap[this.color()], ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
192
+ alertClasses = {
193
+ success: 'bg-tm-green-500/10 outline outline-1 outline-offset-[-1px] outline-tm-green-500/50',
194
+ warning: 'bg-tm-yellow-500/10 outline outline-1 outline-offset-[-1px] outline-tm-yellow-500/50',
195
+ error: 'bg-tm-red-500/10 outline outline-1 outline-offset-[-1px] outline-tm-red-500/50',
196
+ info: 'bg-tm-blue-500/10 outline outline-1 outline-offset-[-1px] outline-tm-blue-500/50',
197
+ };
198
+ iconColorClasses = {
199
+ success: 'text-tm-green-500',
200
+ warning: 'text-tm-yellow-500',
201
+ error: 'text-tm-red-500',
202
+ info: 'text-tm-blue-500',
203
+ };
204
+ accentBarColorMap = {
205
+ success: 'bg-tm-green-500',
206
+ warning: 'bg-tm-yellow-500',
207
+ error: 'bg-tm-red-500',
208
+ info: 'bg-tm-blue-500',
209
+ };
210
+ accentBarClasses = computed(() => `w-1.5 self-stretch ${this.accentBarColorMap[this.color()]}`, ...(ngDevMode ? [{ debugName: "accentBarClasses" }] : /* istanbul ignore next */ []));
211
+ titleAlertClasses = {
212
+ success: 'text-tm-green-700',
213
+ warning: 'text-tm-yellow-700',
214
+ error: 'text-tm-red-700',
215
+ info: 'text-tm-blue-700',
216
+ };
217
+ positionClasses = {
218
+ 'top-left': 'top-4 left-4 items-start',
219
+ 'top-center': 'top-4 left-1/2 -translate-x-1/2 items-center',
220
+ 'top-right': 'top-4 right-4 items-end',
221
+ 'bottom-left': 'bottom-4 left-4 items-start',
222
+ 'bottom-center': 'bottom-4 left-1/2 -translate-x-1/2 items-center',
223
+ 'bottom-right': 'bottom-4 right-4 items-end',
224
+ };
225
+ containerClasses = computed(() => {
226
+ const base = 'animate-slide-in-right flex items-stretch w-96 rounded-xl overflow-hidden';
227
+ const typeClass = this.type() === 'alert' ? this.alertClasses[this.color()] : 'bg-tm-surface shadow-md';
228
+ return `${base} ${typeClass}`;
229
+ }, ...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
230
+ wrapperClasses = computed(() => {
231
+ return `fixed z-50 flex flex-col ${this.positionClasses[this.position()]}`;
232
+ }, ...(ngDevMode ? [{ debugName: "wrapperClasses" }] : /* istanbul ignore next */ []));
233
+ iconClasses = computed(() => this.iconColorClasses[this.color()], ...(ngDevMode ? [{ debugName: "iconClasses" }] : /* istanbul ignore next */ []));
234
+ titleClasses = computed(() => {
235
+ const colorClass = this.type() === 'notification' ? 'text-tm-primary' : this.titleAlertClasses[this.color()];
236
+ return `text-sm-semibold ${colorClass}`;
237
+ }, ...(ngDevMode ? [{ debugName: "titleClasses" }] : /* istanbul ignore next */ []));
238
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Snackbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
239
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: Snackbar, isStandalone: true, selector: "tm-snackbar", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, ngImport: i0, template: "<div [class]=\"containerClasses()\">\n @if (type() === 'notification') {\n <div [class]=\"accentBarClasses()\"></div>\n }\n <div class=\"flex items-start gap-3 flex-1 p-5\">\n <lucide-icon [img]=\"icon()\" [size]=\"20\" [class]=\"iconClasses()\" />\n <div class=\"flex-1 flex flex-col gap-0.5\">\n <span [class]=\"titleClasses()\">{{ title() }}</span>\n @if (description()) {\n <span class=\"text-xs-regular text-tm-secondary\">{{ description() }}</span>\n }\n </div>\n @if (type() === 'notification') {\n <button\n (click)=\"closed.emit()\"\n class=\"text-tm-tertiary hover:text-tm-primary transition-colors cursor-pointer\"\n >\n <lucide-icon [img]=\"closeIcon\" [size]=\"16\" />\n </button>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
240
+ }
241
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Snackbar, decorators: [{
242
+ type: Component,
243
+ args: [{ selector: 'tm-snackbar', imports: [NgIf, LucideAngularModule], template: "<div [class]=\"containerClasses()\">\n @if (type() === 'notification') {\n <div [class]=\"accentBarClasses()\"></div>\n }\n <div class=\"flex items-start gap-3 flex-1 p-5\">\n <lucide-icon [img]=\"icon()\" [size]=\"20\" [class]=\"iconClasses()\" />\n <div class=\"flex-1 flex flex-col gap-0.5\">\n <span [class]=\"titleClasses()\">{{ title() }}</span>\n @if (description()) {\n <span class=\"text-xs-regular text-tm-secondary\">{{ description() }}</span>\n }\n </div>\n @if (type() === 'notification') {\n <button\n (click)=\"closed.emit()\"\n class=\"text-tm-tertiary hover:text-tm-primary transition-colors cursor-pointer\"\n >\n <lucide-icon [img]=\"closeIcon\" [size]=\"16\" />\n </button>\n }\n </div>\n</div>\n" }]
244
+ }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
245
+
246
+ class SnackbarService {
247
+ items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
248
+ add(type, color, title, description, duration, position) {
249
+ const id = crypto.randomUUID();
250
+ this.items.update((current) => [
251
+ { id, type, color, title, description, duration: duration ?? 5000, position: position ?? 'top-right' },
252
+ ...current,
253
+ ]);
254
+ if (type === 'alert') {
255
+ setTimeout(() => this.remove(id), duration ?? 5000);
256
+ }
257
+ }
258
+ alert(color, title, description, duration, position) {
259
+ this.add('alert', color, title, description, duration, position);
260
+ }
261
+ notify(color, title, description, position) {
262
+ this.add('notification', color, title, description, undefined, position);
263
+ }
264
+ remove(id) {
265
+ this.items.update((current) => current.filter((item) => item.id !== id));
266
+ }
267
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnackbarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
268
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnackbarService, providedIn: 'root' });
269
+ }
270
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnackbarService, decorators: [{
271
+ type: Injectable,
272
+ args: [{ providedIn: 'root' }]
273
+ }] });
274
+
275
+ class SnackbarHost {
276
+ snackbarService = inject(SnackbarService);
277
+ containerClasses = {
278
+ 'top-left': 'fixed top-4 left-4 flex flex-col gap-3 z-50',
279
+ 'top-center': 'fixed top-4 left-1/2 -translate-x-1/2 flex flex-col gap-3 z-50',
280
+ 'top-right': 'fixed top-4 right-4 flex flex-col gap-3 z-50',
281
+ 'bottom-left': 'fixed bottom-4 left-4 flex flex-col-reverse gap-3 z-50',
282
+ 'bottom-center': 'fixed bottom-4 left-1/2 -translate-x-1/2 flex flex-col-reverse gap-3 z-50',
283
+ 'bottom-right': 'fixed bottom-4 right-4 flex flex-col-reverse gap-3 z-50',
284
+ };
285
+ positions = [
286
+ 'top-left', 'top-center', 'top-right',
287
+ 'bottom-left', 'bottom-center', 'bottom-right',
288
+ ];
289
+ itemsByPosition = computed(() => {
290
+ const items = this.snackbarService.items();
291
+ return this.positions.map(position => ({
292
+ position,
293
+ classes: this.containerClasses[position],
294
+ items: items.filter(i => i.position === position),
295
+ }));
296
+ }, ...(ngDevMode ? [{ debugName: "itemsByPosition" }] : /* istanbul ignore next */ []));
297
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnackbarHost, deps: [], target: i0.ɵɵFactoryTarget.Component });
298
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: SnackbarHost, isStandalone: true, selector: "tm-snackbar-host", ngImport: i0, template: "@for (group of itemsByPosition(); track group.position) {\n @if (group.items.length > 0) {\n <div [class]=\"group.classes\">\n <tm-snackbar\n *ngFor=\"let item of group.items\"\n [type]=\"item.type\"\n [color]=\"item.color\"\n [title]=\"item.title\"\n [description]=\"item.description\"\n [position]=\"item.position\"\n (closed)=\"snackbarService.remove(item.id)\"\n />\n </div>\n }\n}\n", dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: Snackbar, selector: "tm-snackbar", inputs: ["color", "type", "title", "description", "position"], outputs: ["closed"] }] });
299
+ }
300
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnackbarHost, decorators: [{
301
+ type: Component,
302
+ args: [{ selector: 'tm-snackbar-host', imports: [NgFor, Snackbar], template: "@for (group of itemsByPosition(); track group.position) {\n @if (group.items.length > 0) {\n <div [class]=\"group.classes\">\n <tm-snackbar\n *ngFor=\"let item of group.items\"\n [type]=\"item.type\"\n [color]=\"item.color\"\n [title]=\"item.title\"\n [description]=\"item.description\"\n [position]=\"item.position\"\n (closed)=\"snackbarService.remove(item.id)\"\n />\n </div>\n }\n}\n" }]
303
+ }] });
304
+
305
+ class Chip {
306
+ status = input('brand', ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
307
+ type = input('filled', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
308
+ rounded = input('default', ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
309
+ iconLeft = input(...(ngDevMode ? [undefined, { debugName: "iconLeft" }] : /* istanbul ignore next */ []));
310
+ iconRight = input(...(ngDevMode ? [undefined, { debugName: "iconRight" }] : /* istanbul ignore next */ []));
311
+ clickable = input(false, ...(ngDevMode ? [{ debugName: "clickable" }] : /* istanbul ignore next */ []));
312
+ clicked = output();
313
+ roundedClasses = {
314
+ default: 'rounded-md',
315
+ full: 'rounded-[999px]',
316
+ };
317
+ filledClasses = {
318
+ success: 'bg-tm-green-500 text-tm-base-white',
319
+ warning: 'bg-tm-yellow-500 text-tm-base-black',
320
+ indigo: 'bg-tm-indigo-500 text-tm-base-white',
321
+ danger: 'bg-tm-red-500 text-tm-base-white',
322
+ info: 'bg-tm-blue-500 text-tm-base-white',
323
+ brand: 'bg-tm-brand text-tm-inverse',
324
+ };
325
+ subtleClasses = {
326
+ success: 'bg-tm-green-500/10 text-tm-green-500',
327
+ warning: 'bg-tm-yellow-500/10 text-tm-yellow-500',
328
+ indigo: 'bg-tm-indigo-500/10 text-tm-indigo-500',
329
+ danger: 'bg-tm-red-500/10 text-tm-red-500',
330
+ info: 'bg-tm-blue-500/10 text-tm-blue-500',
331
+ brand: 'bg-tm-brand/10 text-tm-secondary',
332
+ };
333
+ outlinedClasses = {
334
+ success: 'outline outline-1 outline-tm-default text-tm-green-500',
335
+ warning: 'outline outline-1 outline-tm-default text-tm-yellow-500',
336
+ indigo: 'outline outline-1 outline-tm-default text-indigo-500',
337
+ danger: 'outline outline-1 outline-tm-default text-tm-red-500',
338
+ info: 'outline outline-1 outline-tm-default text-tm-blue-500',
339
+ brand: 'outline outline-1 outline-tm-default text-tm-secondary',
340
+ };
341
+ containerClasses = computed(() => {
342
+ const typeMap = {
343
+ filled: this.filledClasses[this.status()],
344
+ subtle: this.subtleClasses[this.status()],
345
+ outlined: this.outlinedClasses[this.status()],
346
+ };
347
+ const base = 'h-7 min-w-10 min-h-7 inline-flex items-center gap-2 px-2.5 py-1 text-xs-medium transition-colors inline-flex justify-center leading-none';
348
+ const rounded = this.roundedClasses[this.rounded()];
349
+ const typeClass = typeMap[this.type()];
350
+ const cursor = this.clickable() ? 'cursor-pointer hover:opacity-80' : 'cursor-default';
351
+ return `${base} ${rounded} ${typeClass} ${cursor}`;
352
+ }, ...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
353
+ handleClick() {
354
+ if (this.clickable()) {
355
+ this.clicked.emit();
356
+ }
357
+ }
358
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Chip, deps: [], target: i0.ɵɵFactoryTarget.Component });
359
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: Chip, isStandalone: true, selector: "tm-chip", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, iconLeft: { classPropertyName: "iconLeft", publicName: "iconLeft", isSignal: true, isRequired: false, transformFunction: null }, iconRight: { classPropertyName: "iconRight", publicName: "iconRight", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<span [class]=\"containerClasses()\" (click)=\"handleClick()\">\n @if (iconLeft()) {\n <lucide-icon [img]=\"iconLeft()!\" [size]=\"14\" [strokeWidth]=\"1.75\" />\n }\n <ng-content />\n @if (iconRight()) {\n <lucide-icon [img]=\"iconRight()!\" [size]=\"14\" [strokeWidth]=\"1.75\" />\n }\n</span>\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
360
+ }
361
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Chip, decorators: [{
362
+ type: Component,
363
+ args: [{ selector: 'tm-chip', imports: [LucideAngularModule], template: "<span [class]=\"containerClasses()\" (click)=\"handleClick()\">\n @if (iconLeft()) {\n <lucide-icon [img]=\"iconLeft()!\" [size]=\"14\" [strokeWidth]=\"1.75\" />\n }\n <ng-content />\n @if (iconRight()) {\n <lucide-icon [img]=\"iconRight()!\" [size]=\"14\" [strokeWidth]=\"1.75\" />\n }\n</span>\n" }]
364
+ }], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], iconLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconLeft", required: false }] }], iconRight: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconRight", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
365
+
366
+ class Toggle {
367
+ value = input(false, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
368
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
369
+ changed = output();
370
+ trackClasses = computed(() => {
371
+ const base = 'relative w-12 h-7 rounded-[999px] border border-tm-strong transition-colors duration-200';
372
+ const state = this.value() ? 'bg-bg-brand' : 'bg-tm-subtle';
373
+ const cursor = this.disabled() ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer';
374
+ return `${base} ${state} ${cursor}`;
375
+ }, ...(ngDevMode ? [{ debugName: "trackClasses" }] : /* istanbul ignore next */ []));
376
+ thumbClasses = computed(() => {
377
+ const base = 'absolute top-[3px] w-5 h-5 rounded-full bg-tm-base-white shadow-md transition-all duration-200';
378
+ const position = this.value() ? 'left-[22px]' : 'left-[4px]';
379
+ return `${base} ${position}`;
380
+ }, ...(ngDevMode ? [{ debugName: "thumbClasses" }] : /* istanbul ignore next */ []));
381
+ toggle() {
382
+ if (!this.disabled()) {
383
+ this.changed.emit(!this.value());
384
+ }
385
+ }
386
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Toggle, deps: [], target: i0.ɵɵFactoryTarget.Component });
387
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: Toggle, isStandalone: true, selector: "tm-toggle", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed" }, ngImport: i0, template: "<button\n type=\"button\"\n role=\"switch\"\n [attr.aria-checked]=\"value()\"\n [disabled]=\"disabled() || null\"\n [class]=\"trackClasses()\"\n (click)=\"toggle()\"\n>\n <span [class]=\"thumbClasses()\"></span>\n</button>\n" });
388
+ }
389
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Toggle, decorators: [{
390
+ type: Component,
391
+ args: [{ selector: 'tm-toggle', template: "<button\n type=\"button\"\n role=\"switch\"\n [attr.aria-checked]=\"value()\"\n [disabled]=\"disabled() || null\"\n [class]=\"trackClasses()\"\n (click)=\"toggle()\"\n>\n <span [class]=\"thumbClasses()\"></span>\n</button>\n" }]
392
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
393
+
394
+ class CheckboxButton {
395
+ checked = input(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
396
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
397
+ label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
398
+ id = input(`checkbox-${Math.random().toString(36).slice(2)}`, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
399
+ changed = output();
400
+ containerClasses = computed(() => {
401
+ const base = 'flex items-center gap-2';
402
+ const cursor = this.disabled() ? 'cursor-not-allowed opacity-50' : 'cursor-pointer';
403
+ return `${base} ${cursor}`;
404
+ }, ...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
405
+ boxClasses = computed(() => {
406
+ const base = 'w-5 h-5 rounded-sm border-2 flex items-center justify-center transition-all duration-200';
407
+ if (this.disabled()) {
408
+ return `${base} border-tm-subtle`;
409
+ }
410
+ return this.checked()
411
+ ? `${base} bg-tm-brand border-tm-brand text-tm-inverse`
412
+ : `${base} border-tm-default`;
413
+ }, ...(ngDevMode ? [{ debugName: "boxClasses" }] : /* istanbul ignore next */ []));
414
+ toggle() {
415
+ if (!this.disabled()) {
416
+ this.changed.emit(!this.checked());
417
+ }
418
+ }
419
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CheckboxButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
420
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CheckboxButton, isStandalone: true, selector: "tm-checkbox-button", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed" }, ngImport: i0, template: "<label [for]=\"id()\" [class]=\"containerClasses()\">\n <div class=\"relative\">\n <input\n type=\"checkbox\"\n [id]=\"id()\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n class=\"sr-only\"\n (change)=\"toggle()\"\n />\n <div [class]=\"boxClasses()\">\n @if(checked()) {\n <svg width=\"12\" height=\"10\" viewBox=\"0 0 12 10\" fill=\"none\">\n <path\n d=\"M1 5L4.5 8.5L11 1.5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n </div>\n </div>\n\n @if(label()) {\n <span [class]=\"'text-sm-regular ' + (disabled() ? 'text-tm-tertiary' : 'text-tm-primary')\">{{ label() }}</span>\n }\n</label>\n" });
421
+ }
422
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CheckboxButton, decorators: [{
423
+ type: Component,
424
+ args: [{ selector: 'tm-checkbox-button', template: "<label [for]=\"id()\" [class]=\"containerClasses()\">\n <div class=\"relative\">\n <input\n type=\"checkbox\"\n [id]=\"id()\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n class=\"sr-only\"\n (change)=\"toggle()\"\n />\n <div [class]=\"boxClasses()\">\n @if(checked()) {\n <svg width=\"12\" height=\"10\" viewBox=\"0 0 12 10\" fill=\"none\">\n <path\n d=\"M1 5L4.5 8.5L11 1.5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n </div>\n </div>\n\n @if(label()) {\n <span [class]=\"'text-sm-regular ' + (disabled() ? 'text-tm-tertiary' : 'text-tm-primary')\">{{ label() }}</span>\n }\n</label>\n" }]
425
+ }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
426
+
427
+ class RadioButton {
428
+ checked = input(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
429
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
430
+ label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
431
+ value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
432
+ name = input('radio-group', ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
433
+ id = input(`radio-${Math.random().toString(36).slice(2)}`, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
434
+ changed = output();
435
+ containerClasses = computed(() => {
436
+ const base = 'flex items-center gap-2';
437
+ const cursor = this.disabled() ? 'cursor-not-allowed opacity-50' : 'cursor-pointer';
438
+ return `${base} ${cursor}`;
439
+ }, ...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
440
+ circleClasses = computed(() => {
441
+ const base = 'w-5 h-5 rounded-full border-2 flex items-center justify-center transition-all duration-200';
442
+ if (this.disabled())
443
+ return `${base} border-tm-strong`;
444
+ if (this.checked())
445
+ return `${base} border-tm-brand`;
446
+ return `${base} border-tm-default`;
447
+ }, ...(ngDevMode ? [{ debugName: "circleClasses" }] : /* istanbul ignore next */ []));
448
+ innerClasses = 'w-6 h-6 relative flex items-center justify-center';
449
+ dotClasses = computed(() => {
450
+ const base = 'w-5 h-5 rounded-full absolute';
451
+ if (this.disabled())
452
+ return `${base} border-tm-subtle`;
453
+ if (this.checked())
454
+ return `${base} border-tm-brand`;
455
+ return `${base} border-tm-default`;
456
+ }, ...(ngDevMode ? [{ debugName: "dotClasses" }] : /* istanbul ignore next */ []));
457
+ select() {
458
+ if (!this.disabled()) {
459
+ this.changed.emit(this.value());
460
+ }
461
+ }
462
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RadioButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
463
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: RadioButton, isStandalone: true, selector: "tm-radio-button", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed" }, ngImport: i0, template: "<label [for]=\"id()\" [class]=\"containerClasses()\">\n <div class=\"relative\">\n <input\n type=\"radio\"\n [id]=\"id()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n class=\"sr-only\"\n (change)=\"select()\"\n />\n <div [class]=\"circleClasses()\">\n @if(checked()) {\n <div class=\"w-2.5 h-2.5 rounded-full bg-tm-brand\"></div>\n }\n </div>\n </div>\n\n @if(label()) {\n <span [class]=\"'text-sm-regular ' + (disabled() ? 'text-tm-tertiary' : 'text-tm-primary')\">{{ label() }}</span>\n }\n</label>\n" });
464
+ }
465
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RadioButton, decorators: [{
466
+ type: Component,
467
+ args: [{ selector: 'tm-radio-button', template: "<label [for]=\"id()\" [class]=\"containerClasses()\">\n <div class=\"relative\">\n <input\n type=\"radio\"\n [id]=\"id()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n class=\"sr-only\"\n (change)=\"select()\"\n />\n <div [class]=\"circleClasses()\">\n @if(checked()) {\n <div class=\"w-2.5 h-2.5 rounded-full bg-tm-brand\"></div>\n }\n </div>\n </div>\n\n @if(label()) {\n <span [class]=\"'text-sm-regular ' + (disabled() ? 'text-tm-tertiary' : 'text-tm-primary')\">{{ label() }}</span>\n }\n</label>\n" }]
468
+ }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
469
+
470
+ const AVATAR_SIZE_CLASSES = {
471
+ xs: 'w-7 h-7 text-xs', // 28px
472
+ sm: 'w-10 h-10 text-sm', // 40px
473
+ md: 'w-12 h-12 text-lg', // 48px
474
+ lg: 'w-15 h-15 text-xl', // 60px
475
+ xl: 'w-20 h-20 text-2xl', // 80px
476
+ };
477
+ const AVATAR_STATUS_CLASSES = {
478
+ online: 'bg-tm-green-500',
479
+ busy: 'bg-tm-yellow-500',
480
+ disconnect: 'bg-tm-gray-500',
481
+ };
482
+ // Posición y tamaño del indicador de status según el tamaño del avatar
483
+ const AVATAR_STATUS_POSITION = {
484
+ xs: 'w-2.5 h-2.5 bottom-0 right-0',
485
+ sm: 'w-3 h-3 bottom-0 right-0',
486
+ md: 'w-3.5 h-3.5 bottom-0 right-0',
487
+ lg: 'w-4 h-4 bottom-0.5 right-0.5',
488
+ xl: 'w-4 h-4 bottom-0.5 right-0.5',
489
+ };
490
+
491
+ class Avatar {
492
+ /** Imagen del avatar. Si no se provee, se muestran las iniciales. */
493
+ src = input('', ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
494
+ initials = input('', ...(ngDevMode ? [{ debugName: "initials" }] : /* istanbul ignore next */ []));
495
+ /** Texto alternativo para accesibilidad */
496
+ alt = input('Avatar', ...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
497
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
498
+ status = input(null, ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
499
+ showImage = computed(() => !!this.src(), ...(ngDevMode ? [{ debugName: "showImage" }] : /* istanbul ignore next */ []));
500
+ showInitials = computed(() => !this.src() && !!this.initials(), ...(ngDevMode ? [{ debugName: "showInitials" }] : /* istanbul ignore next */ []));
501
+ showStatus = computed(() => !!this.status(), ...(ngDevMode ? [{ debugName: "showStatus" }] : /* istanbul ignore next */ []));
502
+ avatarClasses = computed(() => [
503
+ 'relative inline-flex items-center justify-center',
504
+ 'rounded-full font-medium bg-tm-brand text-tm-inverse',
505
+ 'select-none shrink-0',
506
+ AVATAR_SIZE_CLASSES[this.size()],
507
+ ].join(' '), ...(ngDevMode ? [{ debugName: "avatarClasses" }] : /* istanbul ignore next */ []));
508
+ statusClasses = computed(() => [
509
+ 'absolute rounded-full border-[1.5px] border-white',
510
+ AVATAR_STATUS_CLASSES[this.status()],
511
+ AVATAR_STATUS_POSITION[this.size()],
512
+ ].join(' '), ...(ngDevMode ? [{ debugName: "statusClasses" }] : /* istanbul ignore next */ []));
513
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Avatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
514
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: Avatar, isStandalone: true, selector: "tm-avatar", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, initials: { classPropertyName: "initials", publicName: "initials", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [class]=\"avatarClasses()\">\n\n <!-- Imagen -->\n @if (showImage()) {\n <img\n [src]=\"src()\"\n [alt]=\"alt()\"\n class=\"w-full h-full rounded-full object-cover\"\n />\n }\n\n <!-- Iniciales -->\n @if (showInitials()) {\n <span class=\"leading-none\">{{ initials() }}</span>\n }\n\n <!-- Indicador de status -->\n @if (showStatus()) {\n <span\n [class]=\"statusClasses()\"\n [attr.aria-label]=\"status()!\"\n role=\"status\"\n ></span>\n }\n\n</div>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
515
+ }
516
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Avatar, decorators: [{
517
+ type: Component,
518
+ args: [{ selector: 'tm-avatar', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"avatarClasses()\">\n\n <!-- Imagen -->\n @if (showImage()) {\n <img\n [src]=\"src()\"\n [alt]=\"alt()\"\n class=\"w-full h-full rounded-full object-cover\"\n />\n }\n\n <!-- Iniciales -->\n @if (showInitials()) {\n <span class=\"leading-none\">{{ initials() }}</span>\n }\n\n <!-- Indicador de status -->\n @if (showStatus()) {\n <span\n [class]=\"statusClasses()\"\n [attr.aria-label]=\"status()!\"\n role=\"status\"\n ></span>\n }\n\n</div>\n" }]
519
+ }], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], initials: [{ type: i0.Input, args: [{ isSignal: true, alias: "initials", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }] } });
520
+
521
+ class CloseDialog {
522
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
523
+ ariaLabel = input('Cerrar', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
524
+ closed = output();
525
+ xIcon = X;
526
+ onClick() {
527
+ if (!this.disabled()) {
528
+ this.closed.emit();
529
+ }
530
+ }
531
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CloseDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
532
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: CloseDialog, isStandalone: true, selector: "tm-close-dialog", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, ngImport: i0, template: "<button\n type=\"button\"\n [attr.aria-label]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"onClick()\"\n class=\"\n inline-flex items-center justify-center\n w-9 h-9 rounded-full\n bg-transparent text-tm-gray-500\n transition-colors duration-200\n hover:bg-tm-subtle\n disabled:opacity-40 disabled:cursor-not-allowed\n cursor-pointer\n \"\n>\n <lucide-icon\n [img]=\"xIcon\"\n [size]=\"20\"\n [strokeWidth]=\"1.75\"\n />\n</button>\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
533
+ }
534
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CloseDialog, decorators: [{
535
+ type: Component,
536
+ args: [{ selector: 'tm-close-dialog', standalone: true, imports: [LucideAngularModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n type=\"button\"\n [attr.aria-label]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"onClick()\"\n class=\"\n inline-flex items-center justify-center\n w-9 h-9 rounded-full\n bg-transparent text-tm-gray-500\n transition-colors duration-200\n hover:bg-tm-subtle\n disabled:opacity-40 disabled:cursor-not-allowed\n cursor-pointer\n \"\n>\n <lucide-icon\n [img]=\"xIcon\"\n [size]=\"20\"\n [strokeWidth]=\"1.75\"\n />\n</button>\n" }]
537
+ }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
538
+
539
+ class CardButton {
540
+ count = input(0, ...(ngDevMode ? [{ debugName: "count" }] : /* istanbul ignore next */ []));
541
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
542
+ ariaLabel = input('Carrito de compras', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
543
+ clicked = output();
544
+ cartIcon = ShoppingCart;
545
+ /* Muestra el badge solo si hay items */
546
+ showBadge = computed(() => this.count() > 0, ...(ngDevMode ? [{ debugName: "showBadge" }] : /* istanbul ignore next */ []));
547
+ displayCount = computed(() => {
548
+ const c = this.count();
549
+ if (c > 9)
550
+ return '9+';
551
+ return c.toString();
552
+ }, ...(ngDevMode ? [{ debugName: "displayCount" }] : /* istanbul ignore next */ []));
553
+ onClick() {
554
+ if (!this.disabled()) {
555
+ this.clicked.emit();
556
+ }
557
+ }
558
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
559
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CardButton, isStandalone: true, selector: "tm-card-button", inputs: { count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button\n type=\"button\"\n [attr.aria-label]=\"ariaLabel() + (showBadge() ? ', ' + count() + ' items' : '')\"\n [disabled]=\"disabled()\"\n (click)=\"onClick()\"\n class=\"\n relative inline-flex items-center justify-center\n w-6 h-6\n bg-transparent text-tm-secondary\n transition-colors duration-200\n hover:text-tm-secondary\n disabled:opacity-40 disabled:cursor-not-allowed\n cursor-pointer text-tm-tertiary\n \"\n>\n <!-- Icono del carrito -->\n <lucide-icon\n [img]=\"cartIcon\"\n [size]=\"24\"\n [strokeWidth]=\"1.75\"\n />\n\n <!-- Badge con cantidad -->\n @if (showBadge()) {\n <span\n class=\"\n absolute -top-2.5 -right-2.5\n inline-flex items-center justify-center\n min-w-5 h-5 px-1\n rounded-full\n bg-tm-base-black text-tm-base-white\n text-[10px] font-medium leading-none\n select-none\n \"\n aria-hidden=\"true\"\n >\n {{ displayCount() }}\n </span>\n }\n</button>\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
560
+ }
561
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardButton, decorators: [{
562
+ type: Component,
563
+ args: [{ selector: 'tm-card-button', standalone: true, imports: [LucideAngularModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n type=\"button\"\n [attr.aria-label]=\"ariaLabel() + (showBadge() ? ', ' + count() + ' items' : '')\"\n [disabled]=\"disabled()\"\n (click)=\"onClick()\"\n class=\"\n relative inline-flex items-center justify-center\n w-6 h-6\n bg-transparent text-tm-secondary\n transition-colors duration-200\n hover:text-tm-secondary\n disabled:opacity-40 disabled:cursor-not-allowed\n cursor-pointer text-tm-tertiary\n \"\n>\n <!-- Icono del carrito -->\n <lucide-icon\n [img]=\"cartIcon\"\n [size]=\"24\"\n [strokeWidth]=\"1.75\"\n />\n\n <!-- Badge con cantidad -->\n @if (showBadge()) {\n <span\n class=\"\n absolute -top-2.5 -right-2.5\n inline-flex items-center justify-center\n min-w-5 h-5 px-1\n rounded-full\n bg-tm-base-black text-tm-base-white\n text-[10px] font-medium leading-none\n select-none\n \"\n aria-hidden=\"true\"\n >\n {{ displayCount() }}\n </span>\n }\n</button>\n" }]
564
+ }], propDecorators: { count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
565
+
566
+ class BtnTheme {
567
+ mode = input('light', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
568
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
569
+ /* Emite el nuevo modo luego del toggle */
570
+ modeChange = output();
571
+ sunIcon = Sun;
572
+ moonIcon = Moon;
573
+ isDark = computed(() => this.mode() === 'dark', ...(ngDevMode ? [{ debugName: "isDark" }] : /* istanbul ignore next */ []));
574
+ currentIcon = computed(() => (this.isDark() ? this.moonIcon : this.sunIcon), ...(ngDevMode ? [{ debugName: "currentIcon" }] : /* istanbul ignore next */ []));
575
+ ariaLabel = computed(() => this.isDark() ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
576
+ onClick() {
577
+ if (!this.disabled()) {
578
+ this.modeChange.emit(this.isDark() ? 'light' : 'dark');
579
+ }
580
+ }
581
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BtnTheme, deps: [], target: i0.ɵɵFactoryTarget.Component });
582
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: BtnTheme, isStandalone: true, selector: "tm-btn-theme", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modeChange: "modeChange" }, ngImport: i0, template: "<button\n type=\"button\"\n [attr.aria-label]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"onClick()\"\n class=\"\n inline-flex items-center justify-center\n w-10 h-10 p-2 rounded-full\n bg-transparent text-tm-secondary\n border border-tm-subtle\n transition-all duration-50 linear\n hover:border-tm-default\n hover:text-tm-primary\n disabled:opacity-40 disabled:cursor-not-allowed\n cursor-pointer\n \"\n>\n <lucide-icon\n [img]=\"currentIcon()\"\n [size]=\"20\"\n [strokeWidth]=\"1.75\"\n class=\"text-current transition-transform duration-50 linear\"\n />\n</button>\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
583
+ }
584
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BtnTheme, decorators: [{
585
+ type: Component,
586
+ args: [{ selector: 'tm-btn-theme', standalone: true, imports: [LucideAngularModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n type=\"button\"\n [attr.aria-label]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"onClick()\"\n class=\"\n inline-flex items-center justify-center\n w-10 h-10 p-2 rounded-full\n bg-transparent text-tm-secondary\n border border-tm-subtle\n transition-all duration-50 linear\n hover:border-tm-default\n hover:text-tm-primary\n disabled:opacity-40 disabled:cursor-not-allowed\n cursor-pointer\n \"\n>\n <lucide-icon\n [img]=\"currentIcon()\"\n [size]=\"20\"\n [strokeWidth]=\"1.75\"\n class=\"text-current transition-transform duration-50 linear\"\n />\n</button>\n" }]
587
+ }], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], modeChange: [{ type: i0.Output, args: ["modeChange"] }] } });
588
+
589
+ class MenuTriggerDirective {
590
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MenuTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
591
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: MenuTriggerDirective, isStandalone: true, selector: "[tmMenuTrigger]", ngImport: i0 });
592
+ }
593
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MenuTriggerDirective, decorators: [{
594
+ type: Directive,
595
+ args: [{
596
+ selector: '[tmMenuTrigger]',
597
+ standalone: true,
598
+ }]
599
+ }] });
600
+
601
+ class MenuComponent {
602
+ // ── Inputs
603
+ placement = input('bottom-end', ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
604
+ triggerOn = input('click', ...(ngDevMode ? [{ debugName: "triggerOn" }] : /* istanbul ignore next */ []));
605
+ opened = output();
606
+ closed = output();
607
+ // ── ContentChild
608
+ triggerTemplate;
609
+ // ── State
610
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
611
+ // ── CDK
612
+ overlay = inject(Overlay);
613
+ vcr = inject(ViewContainerRef);
614
+ el = inject(ElementRef);
615
+ overlayRef;
616
+ // ── Trigger handlers
617
+ onClickHost() {
618
+ const mode = this.triggerOn();
619
+ if (mode === 'click' || mode === 'both') {
620
+ this.isOpen() ? this.close() : this.open();
621
+ }
622
+ }
623
+ onMouseEnter() {
624
+ if (this.triggerOn() === 'hover' || this.triggerOn() === 'both') {
625
+ this.open();
626
+ }
627
+ }
628
+ onMouseLeave() {
629
+ if (this.triggerOn() === 'hover' || this.triggerOn() === 'both') {
630
+ this.close();
631
+ }
632
+ }
633
+ open() {
634
+ if (this.overlayRef?.hasAttached())
635
+ return;
636
+ const positionStrategy = this.overlay
637
+ .position()
638
+ .flexibleConnectedTo(this.el)
639
+ .withPositions([this.getPosition()]);
640
+ this.overlayRef = this.overlay.create({
641
+ positionStrategy,
642
+ hasBackdrop: this.triggerOn() !== 'hover',
643
+ backdropClass: 'cdk-overlay-transparent-backdrop',
644
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
645
+ });
646
+ this.overlayRef.backdropClick().subscribe(() => this.close());
647
+ const portal = new TemplatePortal(this.menuTemplate, this.vcr);
648
+ this.overlayRef.attach(portal);
649
+ this.isOpen.set(true);
650
+ this.opened.emit();
651
+ }
652
+ close() {
653
+ this.overlayRef?.detach();
654
+ this.isOpen.set(false);
655
+ this.closed.emit();
656
+ }
657
+ getPosition() {
658
+ const map = {
659
+ 'bottom-end': { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top' },
660
+ 'bottom-start': { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },
661
+ 'top-end': { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom' },
662
+ 'top-start': { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' },
663
+ };
664
+ return map[this.placement()];
665
+ }
666
+ ngOnDestroy() {
667
+ this.overlayRef?.dispose();
668
+ }
669
+ // referencia al template del menú
670
+ menuTemplate;
671
+ set setMenuTemplate(t) {
672
+ this.menuTemplate = t;
673
+ }
674
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
675
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MenuComponent, isStandalone: true, selector: "tm-menu", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, triggerOn: { classPropertyName: "triggerOn", publicName: "triggerOn", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed" }, host: { listeners: { "click": "onClickHost()", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" } }, queries: [{ propertyName: "triggerTemplate", first: true, predicate: MenuTriggerDirective, descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "setMenuTemplate", first: true, predicate: ["menuPanel"], descendants: true }], ngImport: i0, template: "@if (triggerTemplate) {\n <ng-container [ngTemplateOutlet]=\"triggerTemplate\" />\n}\n\n<ng-template #menuPanel>\n <div class=\"bg-tm-surface rounded-xl shadow-md flex flex-col min-w-48\">\n\n <!-- Header opcional (avatar, nombre, rol) -->\n <ng-content select=\"[menuHeader]\" />\n\n <!-- Items -->\n <div class=\"px-2 py-1 flex flex-col w-full\">\n <ng-content />\n </div>\n\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: OverlayModule }] });
676
+ }
677
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MenuComponent, decorators: [{
678
+ type: Component,
679
+ args: [{ selector: 'tm-menu', standalone: true, imports: [NgTemplateOutlet, OverlayModule], template: "@if (triggerTemplate) {\n <ng-container [ngTemplateOutlet]=\"triggerTemplate\" />\n}\n\n<ng-template #menuPanel>\n <div class=\"bg-tm-surface rounded-xl shadow-md flex flex-col min-w-48\">\n\n <!-- Header opcional (avatar, nombre, rol) -->\n <ng-content select=\"[menuHeader]\" />\n\n <!-- Items -->\n <div class=\"px-2 py-1 flex flex-col w-full\">\n <ng-content />\n </div>\n\n </div>\n</ng-template>\n" }]
680
+ }], propDecorators: { placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], triggerOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerOn", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], triggerTemplate: [{
681
+ type: ContentChild,
682
+ args: [MenuTriggerDirective, { read: TemplateRef }]
683
+ }], onClickHost: [{
684
+ type: HostListener,
685
+ args: ['click']
686
+ }], onMouseEnter: [{
687
+ type: HostListener,
688
+ args: ['mouseenter']
689
+ }], onMouseLeave: [{
690
+ type: HostListener,
691
+ args: ['mouseleave']
692
+ }], setMenuTemplate: [{
693
+ type: ViewChild,
694
+ args: ['menuPanel']
695
+ }] } });
696
+
697
+ class MenuItem {
698
+ label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
699
+ icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : /* istanbul ignore next */ []));
700
+ danger = input(false, ...(ngDevMode ? [{ debugName: "danger" }] : /* istanbul ignore next */ []));
701
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
702
+ selected = output();
703
+ onClick() {
704
+ if (!this.disabled()) {
705
+ this.selected.emit();
706
+ }
707
+ }
708
+ divider = input(false, ...(ngDevMode ? [{ debugName: "divider" }] : /* istanbul ignore next */ []));
709
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MenuItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
710
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MenuItem, isStandalone: true, selector: "tm-menu-item", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, danger: { classPropertyName: "danger", publicName: "danger", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, divider: { classPropertyName: "divider", publicName: "divider", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, ngImport: i0, template: "@if (divider()) {\n <div class=\"-mx-2 self-stretch h-px bg-tm-subtle my-1\"></div>\n}\n<tm-button\n type=\"ghost\"\n size=\"md\"\n [color]=\"danger() ? 'danger' : 'primary'\"\n [disabled]=\"disabled()\"\n [iconLeft]=\"icon()\"\n customClass=\"w-full justify-start\"\n (clicked)=\"onClick()\"\n>\n {{ label() }}\n</tm-button>\n", dependencies: [{ kind: "component", type: BtnPrimary, selector: "tm-button", inputs: ["color", "size", "type", "active", "disabled", "iconLeft", "iconRight", "rounded", "customClass"], outputs: ["clicked"] }] });
711
+ }
712
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MenuItem, decorators: [{
713
+ type: Component,
714
+ args: [{ selector: 'tm-menu-item', standalone: true, imports: [BtnPrimary], template: "@if (divider()) {\n <div class=\"-mx-2 self-stretch h-px bg-tm-subtle my-1\"></div>\n}\n<tm-button\n type=\"ghost\"\n size=\"md\"\n [color]=\"danger() ? 'danger' : 'primary'\"\n [disabled]=\"disabled()\"\n [iconLeft]=\"icon()\"\n customClass=\"w-full justify-start\"\n (clicked)=\"onClick()\"\n>\n {{ label() }}\n</tm-button>\n" }]
715
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], danger: [{ type: i0.Input, args: [{ isSignal: true, alias: "danger", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], selected: [{ type: i0.Output, args: ["selected"] }], divider: [{ type: i0.Input, args: [{ isSignal: true, alias: "divider", required: false }] }] } });
716
+
717
+ const TmMenu = [
718
+ MenuComponent,
719
+ MenuTriggerDirective,
720
+ MenuItem,
721
+ ];
722
+
723
+ const BASE = 'inline-flex items-center justify-center flex-shrink-0 ' + 'transition-all duration-200';
724
+ const ROUNDED = {
725
+ default: 'rounded-lg',
726
+ full: 'rounded-full',
727
+ };
728
+ // Cuadrado — mismo valor en width y height
729
+ const SIZES = {
730
+ lg: 'w-11 h-11', // 44px
731
+ md: 'w-10 h-10', // 40px
732
+ sm: 'w-9 h-9', // 36px
733
+ };
734
+ const ICON_SIZES = {
735
+ lg: 20,
736
+ md: 18,
737
+ sm: 16,
738
+ };
739
+ const VARIANTS = {
740
+ primary: {
741
+ filled: 'bg-tm-brand text-tm-inverse hover:bg-tm-brand-hover-default',
742
+ outlined: 'border border-tm-default text-tm-primary hover:bg-tm-brand-hover-subtle',
743
+ ghost: 'text-tm-primary hover:bg-tm-brand-hover-subtle',
744
+ },
745
+ danger: {
746
+ filled: 'bg-tm-red-500 text-tm-base-white hover:bg-tm-red-600',
747
+ outlined: 'border border-tm-default text-red-500 hover:bg-tm-red-500/10',
748
+ ghost: 'text-tm-red-500 hover:bg-tm-red-500/10',
749
+ },
750
+ success: {
751
+ filled: 'bg-tm-green-500 text-tm-base-white hover:bg-tm-green-600',
752
+ outlined: 'border border-tm-default text-tm-green-500 hover:bg-tm-green-500/10',
753
+ ghost: 'text-tm-green-500 hover:bg-tm-green-500/10',
754
+ },
755
+ warning: {
756
+ filled: 'bg-tm-yellow-500 text-tm-base-black hover:bg-tm-yellow-600',
757
+ outlined: 'border border-tm-default text-tm-yellow-500 hover:bg-tm-yellow-500/10',
758
+ ghost: 'text-tm-yellow-600 hover:bg-tm-yellow-500/10',
759
+ },
760
+ };
761
+ class BtnIcon {
762
+ icon = input.required(...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
763
+ color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
764
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
765
+ type = input('filled', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
766
+ rounded = input('default', ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
767
+ active = input(false, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
768
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
769
+ ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
770
+ clicked = output();
771
+ iconSize = computed(() => ICON_SIZES[this.size()], ...(ngDevMode ? [{ debugName: "iconSize" }] : /* istanbul ignore next */ []));
772
+ classes = computed(() => [
773
+ BASE,
774
+ SIZES[this.size()],
775
+ VARIANTS[this.color()][this.type()],
776
+ ROUNDED[this.rounded()],
777
+ this.active() ? 'brightness-90' : '',
778
+ this.disabled() ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer',
779
+ ]
780
+ .filter(Boolean)
781
+ .join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
782
+ onClick(event) {
783
+ if (!this.disabled())
784
+ this.clicked.emit(event);
785
+ }
786
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BtnIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
787
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: BtnIcon, isStandalone: true, selector: "tm-icon-button", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, host: { properties: { "attr.disabled": "disabled() || null" } }, ngImport: i0, template: "<button\n type=\"button\"\n [class]=\"classes()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n (click)=\"onClick($event)\"\n>\n <lucide-icon [img]=\"icon()\" [size]=\"iconSize()\" [strokeWidth]=\"1.75\" class=\"text-current\" />\n</button>\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
788
+ }
789
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BtnIcon, decorators: [{
790
+ type: Component,
791
+ args: [{ selector: 'tm-icon-button', standalone: true, imports: [LucideAngularModule], changeDetection: ChangeDetectionStrategy.OnPush, host: {
792
+ '[attr.disabled]': 'disabled() || null',
793
+ }, template: "<button\n type=\"button\"\n [class]=\"classes()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n (click)=\"onClick($event)\"\n>\n <lucide-icon [img]=\"icon()\" [size]=\"iconSize()\" [strokeWidth]=\"1.75\" class=\"text-current\" />\n</button>\n" }]
794
+ }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: true }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
795
+
796
+ const SIZE_WRAPPER = {
797
+ md: 'h-11 min-h-11 px-4 py-2 gap-2.5 text-sm',
798
+ sm: 'h-10 min-h-10 px-4 py-2 gap-2 text-xs',
799
+ };
800
+ const BASE_WRAPPER = 'inline-flex items-center rounded-lg border w-full transition-all duration-300 hover:shadow-md cursor-text';
801
+ const STATE_WRAPPER = {
802
+ default: 'border-tm-default text-tm-secondary hover:border-tm-strong',
803
+ active: 'border-tm-default text-tm-primary ring-2 ring-tm-default/20',
804
+ disabled: 'border-tm-subtle text-tm-secondary bg-tm-subtle cursor-not-allowed hover:shadow-none',
805
+ error: 'border-tm-red-500 text-tm-secondary',
806
+ };
807
+ class TmSelect {
808
+ el = inject(ElementRef);
809
+ overlay = inject(Overlay);
810
+ vcr = inject(ViewContainerRef);
811
+ overlayRef;
812
+ // ── Inputs
813
+ options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
814
+ placeholder = input('Seleccionar...', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
815
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
816
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
817
+ error = input('', ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
818
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
819
+ // ── Model
820
+ value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
821
+ // ── Output
822
+ changed = output();
823
+ // ── State
824
+ isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : /* istanbul ignore next */ []));
825
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
826
+ search = signal('', ...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
827
+ // ── Icons
828
+ chevronDown = ChevronDown;
829
+ xIcon = X;
830
+ checkIcon = CheckIcon;
831
+ dropdownPanel;
832
+ // ── Computed
833
+ currentState = computed(() => {
834
+ if (this.disabled())
835
+ return 'disabled';
836
+ if (this.error())
837
+ return 'error';
838
+ if (this.isOpen())
839
+ return 'active';
840
+ return 'default';
841
+ }, ...(ngDevMode ? [{ debugName: "currentState" }] : /* istanbul ignore next */ []));
842
+ wrapperClasses = computed(() => [BASE_WRAPPER, SIZE_WRAPPER[this.size()], STATE_WRAPPER[this.currentState()]].join(' '), ...(ngDevMode ? [{ debugName: "wrapperClasses" }] : /* istanbul ignore next */ []));
843
+ selectedOption = computed(() => this.options().find(o => o.value === this.value()) ?? null, ...(ngDevMode ? [{ debugName: "selectedOption" }] : /* istanbul ignore next */ []));
844
+ selectedLabel = computed(() => this.selectedOption()?.label ?? '', ...(ngDevMode ? [{ debugName: "selectedLabel" }] : /* istanbul ignore next */ []));
845
+ filteredOptions = computed(() => {
846
+ const term = this.search().toLowerCase();
847
+ return term
848
+ ? this.options().filter(o => o.label.toLowerCase().includes(term))
849
+ : this.options();
850
+ }, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
851
+ // ── CDK
852
+ open() {
853
+ if (this.overlayRef?.hasAttached() || this.disabled())
854
+ return;
855
+ const positionStrategy = this.overlay
856
+ .position()
857
+ .flexibleConnectedTo(this.el)
858
+ .withPositions([
859
+ { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },
860
+ { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' },
861
+ ]);
862
+ this.overlayRef = this.overlay.create({
863
+ positionStrategy,
864
+ hasBackdrop: true,
865
+ backdropClass: 'cdk-overlay-transparent-backdrop',
866
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
867
+ minWidth: this.el.nativeElement.getBoundingClientRect().width,
868
+ });
869
+ this.overlayRef.backdropClick().subscribe(() => this.close());
870
+ this.overlayRef.attach(new TemplatePortal(this.dropdownPanel, this.vcr));
871
+ this.isOpen.set(true);
872
+ }
873
+ close() {
874
+ this.overlayRef?.detach();
875
+ this.isOpen.set(false);
876
+ this.search.set('');
877
+ }
878
+ toggle() {
879
+ this.isOpen() ? this.close() : this.open();
880
+ }
881
+ selectOption(option) {
882
+ if (option.disabled)
883
+ return;
884
+ this.value.set(option.value);
885
+ this.changed.emit(option);
886
+ this.close();
887
+ }
888
+ clear(event) {
889
+ event.stopPropagation();
890
+ this.value.set(null);
891
+ this.changed.emit(null);
892
+ }
893
+ onInput(event) {
894
+ this.search.set(event.target.value);
895
+ if (!this.isOpen())
896
+ this.open();
897
+ }
898
+ ngOnDestroy() {
899
+ this.overlayRef?.dispose();
900
+ }
901
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TmSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
902
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: TmSelect, isStandalone: true, selector: "tm-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", 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 }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, 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", changed: "changed" }, host: { classAttribute: "block w-full" }, viewQueries: [{ propertyName: "dropdownPanel", first: true, predicate: ["dropdownPanel"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col gap-1.5 w-full\">\n @if (label()) {\n <label class=\"block text-sm font-medium text-tm-primary mb-1.5\">{{ label() }}</label>\n }\n\n <div [class]=\"wrapperClasses()\" (click)=\"toggle()\">\n <div class=\"flex items-center gap-2 min-w-0 flex-1\">\n @if (selectedOption()?.avatar) {\n <img [src]=\"selectedOption()!.avatar\" class=\"w-5 h-5 rounded-full object-cover shrink-0\" />\n } @else if (selectedOption()?.icon) {\n <lucide-icon\n [img]=\"selectedOption()!.icon!\"\n [size]=\"16\"\n class=\"shrink-0 text-tm-secondary\"\n />\n }\n\n <input\n class=\"flex-1 bg-transparent outline-none focus:outline-none border-0 text-tm-primary placeholder:text-tm-secondary min-w-0\"\n [class.cursor-not-allowed]=\"disabled()\"\n [class.cursor-pointer]=\"!disabled()\"\n [placeholder]=\"isOpen() ? 'Buscar...' : selectedLabel() || placeholder()\"\n [value]=\"isOpen() ? search() : ''\"\n [disabled]=\"disabled()\"\n (input)=\"onInput($event)\"\n (click)=\"$event.stopPropagation(); open()\"\n />\n </div>\n\n <div class=\"flex items-center gap-1 shrink-0\">\n @if (value() !== null && !disabled()) {\n <button\n (click)=\"clear($event)\"\n class=\"p-0.5 rounded text-tm-tertiary hover:text-tm-primary transition-colors\"\n >\n <lucide-icon [img]=\"xIcon\" [size]=\"14\" />\n </button>\n }\n <lucide-icon\n [img]=\"chevronDown\"\n [size]=\"16\"\n class=\"text-tm-tertiary transition-transform duration-200\"\n [class.rotate-180]=\"isOpen()\"\n />\n </div>\n </div>\n\n <ng-template #dropdownPanel>\n <div\n class=\"rounded-xl bg-tm-surface shadow-lg shadow-black/10 border border-tm-default py-1.5 mt-1 overflow-hidden\"\n >\n <div class=\"overflow-y-auto max-h-52\">\n @for (opt of filteredOptions(); track opt.value) {\n <div\n class=\"flex items-center gap-2.5 px-3 py-2 text-sm cursor-pointer transition-colors\"\n [class]=\"\n opt.disabled\n ? 'opacity-40 cursor-not-allowed'\n : value() === opt.value\n ? 'bg-tm-subtle text-tm-primary font-medium'\n : 'text-tm-primary hover:bg-tm-canvas'\n \"\n (click)=\"selectOption(opt)\"\n >\n @if (opt.avatar) {\n <img [src]=\"opt.avatar\" class=\"w-6 h-6 rounded-full object-cover shrink-0\" />\n } @else if (opt.icon) {\n <lucide-icon [img]=\"opt.icon\" [size]=\"16\" class=\"shrink-0 text-tm-secondary\" />\n }\n <span class=\"truncate flex-1\">{{ opt.label }}</span>\n @if (value() === opt.value) {\n <lucide-icon [img]=\"checkIcon\" [size]=\"14\" class=\"text-tm-brand shrink-0\" />\n }\n </div>\n }\n\n @if (filteredOptions().length === 0) {\n <div class=\"px-3 py-4 text-sm text-tm-tertiary text-center\">Sin resultados</div>\n }\n </div>\n </div>\n </ng-template>\n\n @if (error()) {\n <span class=\"text-xs text-tm-red-500\">{{ error() }}</span>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "ngmodule", type: OverlayModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
903
+ }
904
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TmSelect, decorators: [{
905
+ type: Component,
906
+ args: [{ selector: 'tm-select', standalone: true, host: { class: 'block w-full' }, imports: [FormsModule, LucideAngularModule, OverlayModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-1.5 w-full\">\n @if (label()) {\n <label class=\"block text-sm font-medium text-tm-primary mb-1.5\">{{ label() }}</label>\n }\n\n <div [class]=\"wrapperClasses()\" (click)=\"toggle()\">\n <div class=\"flex items-center gap-2 min-w-0 flex-1\">\n @if (selectedOption()?.avatar) {\n <img [src]=\"selectedOption()!.avatar\" class=\"w-5 h-5 rounded-full object-cover shrink-0\" />\n } @else if (selectedOption()?.icon) {\n <lucide-icon\n [img]=\"selectedOption()!.icon!\"\n [size]=\"16\"\n class=\"shrink-0 text-tm-secondary\"\n />\n }\n\n <input\n class=\"flex-1 bg-transparent outline-none focus:outline-none border-0 text-tm-primary placeholder:text-tm-secondary min-w-0\"\n [class.cursor-not-allowed]=\"disabled()\"\n [class.cursor-pointer]=\"!disabled()\"\n [placeholder]=\"isOpen() ? 'Buscar...' : selectedLabel() || placeholder()\"\n [value]=\"isOpen() ? search() : ''\"\n [disabled]=\"disabled()\"\n (input)=\"onInput($event)\"\n (click)=\"$event.stopPropagation(); open()\"\n />\n </div>\n\n <div class=\"flex items-center gap-1 shrink-0\">\n @if (value() !== null && !disabled()) {\n <button\n (click)=\"clear($event)\"\n class=\"p-0.5 rounded text-tm-tertiary hover:text-tm-primary transition-colors\"\n >\n <lucide-icon [img]=\"xIcon\" [size]=\"14\" />\n </button>\n }\n <lucide-icon\n [img]=\"chevronDown\"\n [size]=\"16\"\n class=\"text-tm-tertiary transition-transform duration-200\"\n [class.rotate-180]=\"isOpen()\"\n />\n </div>\n </div>\n\n <ng-template #dropdownPanel>\n <div\n class=\"rounded-xl bg-tm-surface shadow-lg shadow-black/10 border border-tm-default py-1.5 mt-1 overflow-hidden\"\n >\n <div class=\"overflow-y-auto max-h-52\">\n @for (opt of filteredOptions(); track opt.value) {\n <div\n class=\"flex items-center gap-2.5 px-3 py-2 text-sm cursor-pointer transition-colors\"\n [class]=\"\n opt.disabled\n ? 'opacity-40 cursor-not-allowed'\n : value() === opt.value\n ? 'bg-tm-subtle text-tm-primary font-medium'\n : 'text-tm-primary hover:bg-tm-canvas'\n \"\n (click)=\"selectOption(opt)\"\n >\n @if (opt.avatar) {\n <img [src]=\"opt.avatar\" class=\"w-6 h-6 rounded-full object-cover shrink-0\" />\n } @else if (opt.icon) {\n <lucide-icon [img]=\"opt.icon\" [size]=\"16\" class=\"shrink-0 text-tm-secondary\" />\n }\n <span class=\"truncate flex-1\">{{ opt.label }}</span>\n @if (value() === opt.value) {\n <lucide-icon [img]=\"checkIcon\" [size]=\"14\" class=\"text-tm-brand shrink-0\" />\n }\n </div>\n }\n\n @if (filteredOptions().length === 0) {\n <div class=\"px-3 py-4 text-sm text-tm-tertiary text-center\">Sin resultados</div>\n }\n </div>\n </div>\n </ng-template>\n\n @if (error()) {\n <span class=\"text-xs text-tm-red-500\">{{ error() }}</span>\n }\n</div>\n" }]
907
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], 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"] }], changed: [{ type: i0.Output, args: ["changed"] }], dropdownPanel: [{
908
+ type: ViewChild,
909
+ args: ['dropdownPanel']
910
+ }] } });
911
+
912
+ /*
913
+ * Public API Surface of tm-ui
914
+ */
915
+
916
+ /**
917
+ * Generated bundle index. Do not edit.
918
+ */
919
+
920
+ export { Avatar, BtnIcon, BtnPrimary, BtnTheme, CardButton, CheckboxButton, Chip, CloseDialog, InputTen, MenuComponent, MenuItem, MenuTriggerDirective, RadioButton, Snackbar, SnackbarHost, SnackbarService, TmMenu, TmSelect, Toggle, TwCart };
921
+ //# sourceMappingURL=ten-minds-ui-kit.mjs.map