@kaufmann-lab/ui 0.1.2 → 0.1.8
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.
- package/fesm2022/kaufmann-lab-ui.mjs +1358 -612
- package/fesm2022/kaufmann-lab-ui.mjs.map +1 -1
- package/package.json +2 -1
- package/src/tokens/base.css +20 -0
- package/types/kaufmann-lab-ui.d.ts +264 -69
|
@@ -1,321 +1,710 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, inject, computed, effect, Component, booleanAttribute, model, output, numberAttribute, contentChildren, signal, DestroyRef, viewChild, forwardRef,
|
|
2
|
+
import { input, inject, computed, effect, Component, booleanAttribute, model, output, numberAttribute, contentChildren, signal, DestroyRef, viewChild, forwardRef, ViewContainerRef, HostListener, TemplateRef, contentChild, ElementRef, ChangeDetectionStrategy, afterRenderEffect, afterNextRender, Injectable } from '@angular/core';
|
|
3
3
|
import { DOCUMENT, NgTemplateOutlet } from '@angular/common';
|
|
4
4
|
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
|
|
5
|
+
import { Overlay } from '@angular/cdk/overlay';
|
|
6
|
+
import { TemplatePortal } from '@angular/cdk/portal';
|
|
5
7
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* `kf-icon-alert-triangle`, etc.) — `Icon` lo referencia con `<use>`.
|
|
11
|
-
*
|
|
12
|
-
* Los paths vienen de Lucide (https://lucide.dev, licencia ISC), la
|
|
13
|
-
* librería de iconos de trazo cuyo set de nombres coincide exactamente con
|
|
14
|
-
* el que pide el design system (chevron-right, alert-triangle, bar-chart…).
|
|
15
|
-
* Se embeben acá en vez de agregar `lucide` como dependencia del paquete
|
|
16
|
-
* para no sumar peso/versión externa a algo que consumen todos los
|
|
17
|
-
* frontends del ecosistema — son 59 <path>/<circle>/<rect> estáticos, no
|
|
18
|
-
* lógica que necesite actualizarse seguido.
|
|
19
|
-
*
|
|
20
|
-
* Mapeo de 4 nombres de la spec que no existen tal cual en Lucide (renombres
|
|
21
|
-
* entre versiones de esa librería, o conceptos vecinos):
|
|
22
|
-
* tool -> wrench
|
|
23
|
-
* sort -> arrow-up-down (control de orden bidireccional simple)
|
|
24
|
-
* cart -> shopping-cart
|
|
25
|
-
* chevron-left-bar -> panel-left (icono de "colapsar panel lateral")
|
|
26
|
-
*
|
|
27
|
-
* Se inyecta UNA sola vez en el DOM (ver `Icon`), sin importar cuántos
|
|
28
|
-
* `<kf-icon>` distintos haya en la página — todos referencian el mismo
|
|
29
|
-
* sprite vía `<use href="#kf-icon-...">`.
|
|
30
|
-
*/
|
|
31
|
-
const KF_ICON_SPRITE = `<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
|
|
32
|
-
<symbol id="kf-icon-activity" viewBox="0 0 24 24">
|
|
8
|
+
/** Símbolo de trazo "activity" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
9
|
+
const activity = {
|
|
10
|
+
viewBox: '0 0 24 24',
|
|
11
|
+
markup: `
|
|
33
12
|
<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2" />
|
|
34
|
-
|
|
35
|
-
|
|
13
|
+
`,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/** Símbolo de trazo "alert-circle" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
17
|
+
const alertCircle = {
|
|
18
|
+
viewBox: '0 0 24 24',
|
|
19
|
+
markup: `
|
|
36
20
|
<circle cx="12" cy="12" r="10" />
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
21
|
+
<line x1="12" x2="12" y1="8" y2="12" />
|
|
22
|
+
<line x1="12" x2="12.01" y1="16" y2="16" />
|
|
23
|
+
`,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** Símbolo de trazo "alert-octagon" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
27
|
+
const alertOctagon = {
|
|
28
|
+
viewBox: '0 0 24 24',
|
|
29
|
+
markup: `
|
|
41
30
|
<path d="M12 16h.01" />
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
31
|
+
<path d="M12 8v4" />
|
|
32
|
+
<path d="M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z" />
|
|
33
|
+
`,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** Símbolo de trazo "alert-triangle" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
37
|
+
const alertTriangle = {
|
|
38
|
+
viewBox: '0 0 24 24',
|
|
39
|
+
markup: `
|
|
46
40
|
<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" />
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
41
|
+
<path d="M12 9v4" />
|
|
42
|
+
<path d="M12 17h.01" />
|
|
43
|
+
`,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/** Símbolo de trazo "award" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
47
|
+
const award = {
|
|
48
|
+
viewBox: '0 0 24 24',
|
|
49
|
+
markup: `
|
|
51
50
|
<path d="m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526" />
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
<circle cx="12" cy="8" r="6" />
|
|
52
|
+
`,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/** Símbolo de trazo "bar-chart" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
56
|
+
const barChart = {
|
|
57
|
+
viewBox: '0 0 24 24',
|
|
58
|
+
markup: `
|
|
55
59
|
<path d="M5 21v-6" />
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
<path d="M12 21V9" />
|
|
61
|
+
<path d="M19 21V3" />
|
|
62
|
+
`,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** Símbolo de trazo "bell" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
66
|
+
const bell = {
|
|
67
|
+
viewBox: '0 0 24 24',
|
|
68
|
+
markup: `
|
|
60
69
|
<path d="M10.268 21a2 2 0 0 0 3.464 0" />
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
70
|
+
<path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" />
|
|
71
|
+
`,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/** Símbolo de trazo "bus" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
75
|
+
const bus = {
|
|
76
|
+
viewBox: '0 0 24 24',
|
|
77
|
+
markup: `
|
|
64
78
|
<path d="M8 6v6" />
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
<path d="M15 6v6" />
|
|
80
|
+
<path d="M2 12h19.6" />
|
|
81
|
+
<path d="M18 18h3s.5-1.7.8-2.8c.1-.4.2-.8.2-1.2 0-.4-.1-.8-.2-1.2l-1.4-5C20.1 6.8 19.1 6 18 6H4a2 2 0 0 0-2 2v10h3" />
|
|
82
|
+
<circle cx="7" cy="18" r="2" />
|
|
83
|
+
<path d="M9 18h5" />
|
|
84
|
+
<circle cx="16" cy="18" r="2" />
|
|
85
|
+
`,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/** Símbolo de trazo "calculator" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
89
|
+
const calculator = {
|
|
90
|
+
viewBox: '0 0 24 24',
|
|
91
|
+
markup: `
|
|
73
92
|
<rect width="16" height="20" x="4" y="2" rx="2" />
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
93
|
+
<line x1="8" x2="16" y1="6" y2="6" />
|
|
94
|
+
<line x1="16" x2="16" y1="14" y2="18" />
|
|
95
|
+
<path d="M16 10h.01" />
|
|
96
|
+
<path d="M12 10h.01" />
|
|
97
|
+
<path d="M8 10h.01" />
|
|
98
|
+
<path d="M12 14h.01" />
|
|
99
|
+
<path d="M8 14h.01" />
|
|
100
|
+
<path d="M12 18h.01" />
|
|
101
|
+
<path d="M8 18h.01" />
|
|
102
|
+
`,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/** Símbolo de trazo "calendar" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
106
|
+
const calendar = {
|
|
107
|
+
viewBox: '0 0 24 24',
|
|
108
|
+
markup: `
|
|
85
109
|
<path d="M8 2v3" />
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
110
|
+
<path d="M16 2v3" />
|
|
111
|
+
<rect x="3" y="3" width="18" height="18" rx="2" />
|
|
112
|
+
<path d="M3 9h18" />
|
|
113
|
+
`,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/** Símbolo de trazo "car" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
117
|
+
const car = {
|
|
118
|
+
viewBox: '0 0 24 24',
|
|
119
|
+
markup: `
|
|
91
120
|
<path d="M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2" />
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
121
|
+
<circle cx="7" cy="17" r="2" />
|
|
122
|
+
<path d="M9 17h6" />
|
|
123
|
+
<circle cx="17" cy="17" r="2" />
|
|
124
|
+
`,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/** Símbolo de trazo "cart" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
128
|
+
const cart = {
|
|
129
|
+
viewBox: '0 0 24 24',
|
|
130
|
+
markup: `
|
|
97
131
|
<circle cx="8" cy="21" r="1" />
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
132
|
+
<circle cx="19" cy="21" r="1" />
|
|
133
|
+
<path d="M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12" />
|
|
134
|
+
`,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/** Símbolo de trazo "check" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
138
|
+
const check = {
|
|
139
|
+
viewBox: '0 0 24 24',
|
|
140
|
+
markup: `
|
|
102
141
|
<path d="M20 6 9 17l-5-5" />
|
|
103
|
-
|
|
104
|
-
|
|
142
|
+
`,
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/** Símbolo de trazo "check-circle" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
146
|
+
const checkCircle = {
|
|
147
|
+
viewBox: '0 0 24 24',
|
|
148
|
+
markup: `
|
|
105
149
|
<path d="M21.801 10A10 10 0 1 1 17 3.335" />
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
150
|
+
<path d="m9 11 3 3L22 4" />
|
|
151
|
+
`,
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/** Símbolo de trazo "check-square" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
155
|
+
const checkSquare = {
|
|
156
|
+
viewBox: '0 0 24 24',
|
|
157
|
+
markup: `
|
|
109
158
|
<rect width="18" height="18" x="3" y="3" rx="2" />
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
159
|
+
<path d="m9 12 2 2 4-4" />
|
|
160
|
+
`,
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/** Símbolo de trazo "chevron-down" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
164
|
+
const chevronDown = {
|
|
165
|
+
viewBox: '0 0 24 24',
|
|
166
|
+
markup: `
|
|
113
167
|
<path d="m6 9 6 6 6-6" />
|
|
114
|
-
|
|
115
|
-
|
|
168
|
+
`,
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/** Símbolo de trazo "chevron-left" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
172
|
+
const chevronLeft = {
|
|
173
|
+
viewBox: '0 0 24 24',
|
|
174
|
+
markup: `
|
|
116
175
|
<path d="m15 18-6-6 6-6" />
|
|
117
|
-
|
|
118
|
-
|
|
176
|
+
`,
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/** Símbolo de trazo "chevron-left-bar" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
180
|
+
const chevronLeftBar = {
|
|
181
|
+
viewBox: '0 0 24 24',
|
|
182
|
+
markup: `
|
|
119
183
|
<rect width="18" height="18" x="3" y="3" rx="2" />
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
184
|
+
<path d="M9 3v18" />
|
|
185
|
+
`,
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
/** Símbolo de trazo "chevron-right" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
189
|
+
const chevronRight = {
|
|
190
|
+
viewBox: '0 0 24 24',
|
|
191
|
+
markup: `
|
|
123
192
|
<path d="m9 18 6-6-6-6" />
|
|
124
|
-
|
|
125
|
-
|
|
193
|
+
`,
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
/** Símbolo de trazo "clipboard" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
197
|
+
const clipboard = {
|
|
198
|
+
viewBox: '0 0 24 24',
|
|
199
|
+
markup: `
|
|
126
200
|
<rect width="8" height="4" x="8" y="2" rx="1" ry="1" />
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
201
|
+
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" />
|
|
202
|
+
`,
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
/** Símbolo de trazo "clock" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
206
|
+
const clock = {
|
|
207
|
+
viewBox: '0 0 24 24',
|
|
208
|
+
markup: `
|
|
130
209
|
<circle cx="12" cy="12" r="10" />
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
210
|
+
<path d="M12 6v6l4 2" />
|
|
211
|
+
`,
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
/** Símbolo de trazo "credit-card" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
215
|
+
const creditCard = {
|
|
216
|
+
viewBox: '0 0 24 24',
|
|
217
|
+
markup: `
|
|
134
218
|
<rect width="20" height="14" x="2" y="5" rx="2" />
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
219
|
+
<line x1="2" x2="22" y1="10" y2="10" />
|
|
220
|
+
`,
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
/** Símbolo de trazo "download" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
224
|
+
const download = {
|
|
225
|
+
viewBox: '0 0 24 24',
|
|
226
|
+
markup: `
|
|
138
227
|
<path d="M12 15V3" />
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
228
|
+
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
229
|
+
<path d="m7 10 5 5 5-5" />
|
|
230
|
+
`,
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
/** Símbolo de trazo "edit" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
234
|
+
const edit = {
|
|
235
|
+
viewBox: '0 0 24 24',
|
|
236
|
+
markup: `
|
|
143
237
|
<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" />
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
238
|
+
<path d="m15 5 4 4" />
|
|
239
|
+
`,
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/** Símbolo de trazo "external-link" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
243
|
+
const externalLink = {
|
|
244
|
+
viewBox: '0 0 24 24',
|
|
245
|
+
markup: `
|
|
147
246
|
<path d="M15 3h6v6" />
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
247
|
+
<path d="M10 14 21 3" />
|
|
248
|
+
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
|
|
249
|
+
`,
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
/** Símbolo de trazo "eye" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
253
|
+
const eye = {
|
|
254
|
+
viewBox: '0 0 24 24',
|
|
255
|
+
markup: `
|
|
152
256
|
<path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" />
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
257
|
+
<circle cx="12" cy="12" r="3" />
|
|
258
|
+
`,
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
/** Símbolo de trazo "eye-off" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
262
|
+
const eyeOff = {
|
|
263
|
+
viewBox: '0 0 24 24',
|
|
264
|
+
markup: `
|
|
156
265
|
<path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49" />
|
|
157
266
|
<path d="M14.084 14.158a3 3 0 0 1-4.242-4.242" />
|
|
158
267
|
<path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143" />
|
|
159
268
|
<path d="m2 2 20 20" />
|
|
160
|
-
|
|
161
|
-
|
|
269
|
+
`,
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
/** Símbolo de trazo "file" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
273
|
+
const file = {
|
|
274
|
+
viewBox: '0 0 24 24',
|
|
275
|
+
markup: `
|
|
162
276
|
<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" />
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
277
|
+
<path d="M14 2v5a1 1 0 0 0 1 1h5" />
|
|
278
|
+
`,
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
/** Símbolo de trazo "filter" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
282
|
+
const filter = {
|
|
283
|
+
viewBox: '0 0 24 24',
|
|
284
|
+
markup: `
|
|
166
285
|
<path d="M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z" />
|
|
167
|
-
|
|
168
|
-
|
|
286
|
+
`,
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
/** Símbolo de trazo "gauge" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
290
|
+
const gauge = {
|
|
291
|
+
viewBox: '0 0 24 24',
|
|
292
|
+
markup: `
|
|
169
293
|
<path d="m12 14 4-4" />
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
294
|
+
<path d="M3.34 19a10 10 0 1 1 17.32 0" />
|
|
295
|
+
`,
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/** Símbolo de trazo "gift" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
299
|
+
const gift = {
|
|
300
|
+
viewBox: '0 0 24 24',
|
|
301
|
+
markup: `
|
|
173
302
|
<path d="M12 7v14" />
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
303
|
+
<path d="M20 11v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8" />
|
|
304
|
+
<path d="M7.5 7a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5 1 1 0 0 1 0 5" />
|
|
305
|
+
<rect x="3" y="7" width="18" height="4" rx="1" />
|
|
306
|
+
`,
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
/** Símbolo de trazo "grid" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
310
|
+
const grid = {
|
|
311
|
+
viewBox: '0 0 24 24',
|
|
312
|
+
markup: `
|
|
179
313
|
<rect width="18" height="18" x="3" y="3" rx="2" />
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
314
|
+
<path d="M3 9h18" />
|
|
315
|
+
<path d="M3 15h18" />
|
|
316
|
+
<path d="M9 3v18" />
|
|
317
|
+
<path d="M15 3v18" />
|
|
318
|
+
`,
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
/** Símbolo de trazo "history" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
322
|
+
const history = {
|
|
323
|
+
viewBox: '0 0 24 24',
|
|
324
|
+
markup: `
|
|
186
325
|
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" />
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
326
|
+
<path d="M3 3v5h5" />
|
|
327
|
+
<path d="M12 7v5l4 2" />
|
|
328
|
+
`,
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
/** Símbolo de trazo "inbox" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
332
|
+
const inbox = {
|
|
333
|
+
viewBox: '0 0 24 24',
|
|
334
|
+
markup: `
|
|
191
335
|
<polyline points="22 12 16 12 14 15 10 15 8 12 2 12" />
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
336
|
+
<path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" />
|
|
337
|
+
`,
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
/** Símbolo de trazo "layers" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
341
|
+
const layers = {
|
|
342
|
+
viewBox: '0 0 24 24',
|
|
343
|
+
markup: `
|
|
195
344
|
<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z" />
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
345
|
+
<path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12" />
|
|
346
|
+
<path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17" />
|
|
347
|
+
`,
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
/** Símbolo de trazo "list" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
351
|
+
const list = {
|
|
352
|
+
viewBox: '0 0 24 24',
|
|
353
|
+
markup: `
|
|
200
354
|
<path d="M3 5h.01" />
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
355
|
+
<path d="M3 12h.01" />
|
|
356
|
+
<path d="M3 19h.01" />
|
|
357
|
+
<path d="M8 5h13" />
|
|
358
|
+
<path d="M8 12h13" />
|
|
359
|
+
<path d="M8 19h13" />
|
|
360
|
+
`,
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
/** Símbolo de trazo "map" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
364
|
+
const map = {
|
|
365
|
+
viewBox: '0 0 24 24',
|
|
366
|
+
markup: `
|
|
208
367
|
<path d="M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z" />
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
368
|
+
<path d="M15 5.764v15" />
|
|
369
|
+
<path d="M9 3.236v15" />
|
|
370
|
+
`,
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
/** Símbolo de trazo "map-pin" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
374
|
+
const mapPin = {
|
|
375
|
+
viewBox: '0 0 24 24',
|
|
376
|
+
markup: `
|
|
213
377
|
<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" />
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
378
|
+
<circle cx="12" cy="10" r="3" />
|
|
379
|
+
`,
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
/** Símbolo de trazo "menu" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
383
|
+
const menu = {
|
|
384
|
+
viewBox: '0 0 24 24',
|
|
385
|
+
markup: `
|
|
217
386
|
<path d="M4 5h16" />
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
387
|
+
<path d="M4 12h16" />
|
|
388
|
+
<path d="M4 19h16" />
|
|
389
|
+
`,
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
/** Símbolo de trazo "mic" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
393
|
+
const mic = {
|
|
394
|
+
viewBox: '0 0 24 24',
|
|
395
|
+
markup: `
|
|
222
396
|
<path d="M12 19v3" />
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
397
|
+
<path d="M19 10v2a7 7 0 0 1-14 0v-2" />
|
|
398
|
+
<rect x="9" y="2" width="6" height="13" rx="3" />
|
|
399
|
+
`,
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
/** Símbolo de trazo "mic-off" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
403
|
+
const micOff = {
|
|
404
|
+
viewBox: '0 0 24 24',
|
|
405
|
+
markup: `
|
|
227
406
|
<path d="M12 19v3" />
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
407
|
+
<path d="M15 9.34V5a3 3 0 0 0-5.68-1.33" />
|
|
408
|
+
<path d="M16.95 16.95A7 7 0 0 1 5 12v-2" />
|
|
409
|
+
<path d="M18.89 13.23A7 7 0 0 0 19 12v-2" />
|
|
410
|
+
<path d="m2 2 20 20" />
|
|
411
|
+
<path d="M9 9v3a3 3 0 0 0 5.12 2.12" />
|
|
412
|
+
`,
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
/** Símbolo de trazo "more-vertical" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
416
|
+
const moreVertical = {
|
|
417
|
+
viewBox: '0 0 24 24',
|
|
418
|
+
markup: `
|
|
235
419
|
<circle cx="12" cy="12" r="1" />
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
420
|
+
<circle cx="12" cy="5" r="1" />
|
|
421
|
+
<circle cx="12" cy="19" r="1" />
|
|
422
|
+
`,
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
/** Símbolo de trazo "pause" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
426
|
+
const pause = {
|
|
427
|
+
viewBox: '0 0 24 24',
|
|
428
|
+
markup: `
|
|
240
429
|
<rect x="14" y="3" width="5" height="18" rx="1" />
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
430
|
+
<rect x="5" y="3" width="5" height="18" rx="1" />
|
|
431
|
+
`,
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
/** Símbolo de trazo "phone" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
435
|
+
const phone = {
|
|
436
|
+
viewBox: '0 0 24 24',
|
|
437
|
+
markup: `
|
|
244
438
|
<path d="M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384" />
|
|
245
|
-
|
|
246
|
-
|
|
439
|
+
`,
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
/** Símbolo de trazo "play" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
443
|
+
const play = {
|
|
444
|
+
viewBox: '0 0 24 24',
|
|
445
|
+
markup: `
|
|
247
446
|
<path d="M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z" />
|
|
248
|
-
|
|
249
|
-
|
|
447
|
+
`,
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
/** Símbolo de trazo "plus" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
451
|
+
const plus = {
|
|
452
|
+
viewBox: '0 0 24 24',
|
|
453
|
+
markup: `
|
|
250
454
|
<path d="M5 12h14" />
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
455
|
+
<path d="M12 5v14" />
|
|
456
|
+
`,
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
/** Símbolo de trazo "search" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
460
|
+
const search = {
|
|
461
|
+
viewBox: '0 0 24 24',
|
|
462
|
+
markup: `
|
|
254
463
|
<path d="m21 21-4.34-4.34" />
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
464
|
+
<circle cx="11" cy="11" r="8" />
|
|
465
|
+
`,
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
/** Símbolo de trazo "settings" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
469
|
+
const settings = {
|
|
470
|
+
viewBox: '0 0 24 24',
|
|
471
|
+
markup: `
|
|
258
472
|
<path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" />
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
473
|
+
<circle cx="12" cy="12" r="3" />
|
|
474
|
+
`,
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
/** Símbolo de trazo "shield-check" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
478
|
+
const shieldCheck = {
|
|
479
|
+
viewBox: '0 0 24 24',
|
|
480
|
+
markup: `
|
|
262
481
|
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
482
|
+
<path d="m9 12 2 2 4-4" />
|
|
483
|
+
`,
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
/** Símbolo de trazo "sort" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
487
|
+
const sort = {
|
|
488
|
+
viewBox: '0 0 24 24',
|
|
489
|
+
markup: `
|
|
266
490
|
<path d="m21 16-4 4-4-4" />
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
491
|
+
<path d="M17 20V4" />
|
|
492
|
+
<path d="m3 8 4-4 4 4" />
|
|
493
|
+
<path d="M7 4v16" />
|
|
494
|
+
`,
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
/** Símbolo de trazo "star" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
498
|
+
const star = {
|
|
499
|
+
viewBox: '0 0 24 24',
|
|
500
|
+
markup: `
|
|
272
501
|
<path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z" />
|
|
273
|
-
|
|
274
|
-
|
|
502
|
+
`,
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
/** Símbolo de trazo "ticket" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
506
|
+
const ticket = {
|
|
507
|
+
viewBox: '0 0 24 24',
|
|
508
|
+
markup: `
|
|
275
509
|
<path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z" />
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
510
|
+
<path d="M13 5v2" />
|
|
511
|
+
<path d="M13 17v2" />
|
|
512
|
+
<path d="M13 11v2" />
|
|
513
|
+
`,
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
/** Símbolo de trazo "tool" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
517
|
+
const tool = {
|
|
518
|
+
viewBox: '0 0 24 24',
|
|
519
|
+
markup: `
|
|
281
520
|
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z" />
|
|
282
|
-
|
|
283
|
-
|
|
521
|
+
`,
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
/** Símbolo de trazo "trash" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
525
|
+
const trash = {
|
|
526
|
+
viewBox: '0 0 24 24',
|
|
527
|
+
markup: `
|
|
284
528
|
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" />
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
529
|
+
<path d="M3 6h18" />
|
|
530
|
+
<path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
|
531
|
+
`,
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
/** Símbolo de trazo "truck" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
535
|
+
const truck = {
|
|
536
|
+
viewBox: '0 0 24 24',
|
|
537
|
+
markup: `
|
|
289
538
|
<path d="M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2" />
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
539
|
+
<path d="M15 18H9" />
|
|
540
|
+
<path d="M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14" />
|
|
541
|
+
<circle cx="17" cy="18" r="2" />
|
|
542
|
+
<circle cx="7" cy="18" r="2" />
|
|
543
|
+
`,
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
/** Símbolo de trazo "upload-cloud" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
547
|
+
const uploadCloud = {
|
|
548
|
+
viewBox: '0 0 24 24',
|
|
549
|
+
markup: `
|
|
296
550
|
<path d="M12 13v8" />
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
551
|
+
<path d="M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242" />
|
|
552
|
+
<path d="m8 17 4-4 4 4" />
|
|
553
|
+
`,
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
/** Símbolo de trazo "user" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
557
|
+
const user = {
|
|
558
|
+
viewBox: '0 0 24 24',
|
|
559
|
+
markup: `
|
|
301
560
|
<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
561
|
+
<circle cx="12" cy="7" r="4" />
|
|
562
|
+
`,
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
/** Símbolo de trazo "user-search" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
566
|
+
const userSearch = {
|
|
567
|
+
viewBox: '0 0 24 24',
|
|
568
|
+
markup: `
|
|
305
569
|
<circle cx="10" cy="7" r="4" />
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
570
|
+
<path d="M10.3 15H7a4 4 0 0 0-4 4v2" />
|
|
571
|
+
<circle cx="17" cy="17" r="3" />
|
|
572
|
+
<path d="m21 21-1.9-1.9" />
|
|
573
|
+
`,
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
/** Símbolo de trazo "video" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
577
|
+
const video = {
|
|
578
|
+
viewBox: '0 0 24 24',
|
|
579
|
+
markup: `
|
|
311
580
|
<path d="m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5" />
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
581
|
+
<rect x="2" y="6" width="14" height="12" rx="2" />
|
|
582
|
+
`,
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
/** Símbolo de trazo "x" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */
|
|
586
|
+
const x = {
|
|
587
|
+
viewBox: '0 0 24 24',
|
|
588
|
+
markup: `
|
|
315
589
|
<path d="M18 6 6 18" />
|
|
316
|
-
|
|
317
|
-
|
|
590
|
+
<path d="m6 6 12 12" />
|
|
591
|
+
`,
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Registro tipado de todos los símbolos de ícono. `Record<IconName,
|
|
596
|
+
* IconDefinition>` obliga al compilador a exigir una entrada por cada
|
|
597
|
+
* nombre de `IconName` — agregar un nombre acá sin su archivo en
|
|
598
|
+
* `icons/`, o viceversa, es un error de TypeScript, no un ícono roto
|
|
599
|
+
* en runtime (que era el riesgo real del sprite como string único).
|
|
600
|
+
*
|
|
601
|
+
* Agregar un ícono nuevo es: crear `icons/nombre-del-icono.ts` (copiar
|
|
602
|
+
* el patrón de cualquier archivo vecino), agregarlo a `IconName` en
|
|
603
|
+
* `icon-name.ts`, e importarlo/registrarlo acá.
|
|
604
|
+
*/
|
|
605
|
+
const ICON_DEFINITIONS = {
|
|
606
|
+
activity: activity,
|
|
607
|
+
'alert-circle': alertCircle,
|
|
608
|
+
'alert-octagon': alertOctagon,
|
|
609
|
+
'alert-triangle': alertTriangle,
|
|
610
|
+
award: award,
|
|
611
|
+
'bar-chart': barChart,
|
|
612
|
+
bell: bell,
|
|
613
|
+
bus: bus,
|
|
614
|
+
calculator: calculator,
|
|
615
|
+
calendar: calendar,
|
|
616
|
+
car: car,
|
|
617
|
+
cart: cart,
|
|
618
|
+
check: check,
|
|
619
|
+
'check-circle': checkCircle,
|
|
620
|
+
'check-square': checkSquare,
|
|
621
|
+
'chevron-down': chevronDown,
|
|
622
|
+
'chevron-left': chevronLeft,
|
|
623
|
+
'chevron-left-bar': chevronLeftBar,
|
|
624
|
+
'chevron-right': chevronRight,
|
|
625
|
+
clipboard: clipboard,
|
|
626
|
+
clock: clock,
|
|
627
|
+
'credit-card': creditCard,
|
|
628
|
+
download: download,
|
|
629
|
+
edit: edit,
|
|
630
|
+
'external-link': externalLink,
|
|
631
|
+
eye: eye,
|
|
632
|
+
'eye-off': eyeOff,
|
|
633
|
+
file: file,
|
|
634
|
+
filter: filter,
|
|
635
|
+
gauge: gauge,
|
|
636
|
+
gift: gift,
|
|
637
|
+
grid: grid,
|
|
638
|
+
history: history,
|
|
639
|
+
inbox: inbox,
|
|
640
|
+
layers: layers,
|
|
641
|
+
list: list,
|
|
642
|
+
map: map,
|
|
643
|
+
'map-pin': mapPin,
|
|
644
|
+
menu: menu,
|
|
645
|
+
mic: mic,
|
|
646
|
+
'mic-off': micOff,
|
|
647
|
+
'more-vertical': moreVertical,
|
|
648
|
+
pause: pause,
|
|
649
|
+
phone: phone,
|
|
650
|
+
play: play,
|
|
651
|
+
plus: plus,
|
|
652
|
+
search: search,
|
|
653
|
+
settings: settings,
|
|
654
|
+
'shield-check': shieldCheck,
|
|
655
|
+
sort: sort,
|
|
656
|
+
star: star,
|
|
657
|
+
ticket: ticket,
|
|
658
|
+
tool: tool,
|
|
659
|
+
trash: trash,
|
|
660
|
+
truck: truck,
|
|
661
|
+
'upload-cloud': uploadCloud,
|
|
662
|
+
user: user,
|
|
663
|
+
'user-search': userSearch,
|
|
664
|
+
video: video,
|
|
665
|
+
x: x,
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Sprite SVG con los 60 íconos de trazo del design system (página 5:
|
|
670
|
+
* "Set de 59 iconos de trazo (1.9px, grilla 24×24)", más `eye-off` como
|
|
671
|
+
* extensión propia). Cada ícono es un `<symbol>` con su nombre real de la
|
|
672
|
+
* spec como id (`kf-icon-check`, `kf-icon-alert-triangle`, etc.) — `Icon`
|
|
673
|
+
* lo referencia con `<use>`.
|
|
674
|
+
*
|
|
675
|
+
* Los paths vienen de Lucide (https://lucide.dev, licencia ISC), la
|
|
676
|
+
* librería de iconos de trazo cuyo set de nombres coincide exactamente con
|
|
677
|
+
* el que pide el design system (chevron-right, alert-triangle, bar-chart…).
|
|
678
|
+
* Se embeben acá en vez de agregar `lucide` como dependencia del paquete
|
|
679
|
+
* para no sumar peso/versión externa a algo que consumen todos los
|
|
680
|
+
* frontends del ecosistema — son símbolos estáticos, no lógica que
|
|
681
|
+
* necesite actualizarse seguido.
|
|
682
|
+
*
|
|
683
|
+
* Mapeo de 4 nombres de la spec que no existen tal cual en Lucide (renombres
|
|
684
|
+
* entre versiones de esa librería, o conceptos vecinos):
|
|
685
|
+
* tool -> wrench
|
|
686
|
+
* sort -> arrow-up-down (control de orden bidireccional simple)
|
|
687
|
+
* cart -> shopping-cart
|
|
688
|
+
* chevron-left-bar -> panel-left (icono de "colapsar panel lateral")
|
|
689
|
+
*
|
|
690
|
+
* El sprite ya no es un string único de mano: se construye acá a partir de
|
|
691
|
+
* `ICON_DEFINITIONS` (ver `icons/index.ts`), el registro tipado donde cada
|
|
692
|
+
* ícono vive en su propio archivo bajo `icons/`. Esto es responsabilidad de
|
|
693
|
+
* ensamblado pura — los datos de cada glyph viven en otro lado.
|
|
694
|
+
*
|
|
695
|
+
* Se inyecta UNA sola vez en el DOM (ver `Icon`), sin importar cuántos
|
|
696
|
+
* `<kf-icon>` distintos haya en la página — todos referencian el mismo
|
|
697
|
+
* sprite vía `<use href="#kf-icon-...">`.
|
|
698
|
+
*/
|
|
699
|
+
const KF_ICON_SPRITE = buildIconSprite();
|
|
700
|
+
function buildIconSprite() {
|
|
701
|
+
const symbols = Object.entries(ICON_DEFINITIONS)
|
|
702
|
+
.map(([name, { viewBox, markup }]) => `<symbol id="kf-icon-${name}" viewBox="${viewBox}">${markup}</symbol>`)
|
|
703
|
+
.join('\n ');
|
|
704
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
|
|
705
|
+
${symbols}
|
|
318
706
|
</svg>`;
|
|
707
|
+
}
|
|
319
708
|
|
|
320
709
|
/** Marca el sprite ya inyectado, para no depender de una bandera de módulo
|
|
321
710
|
* — una bandera compartida entre instancias de test (o entre múltiples
|
|
@@ -324,7 +713,7 @@ const KF_ICON_SPRITE = `<svg xmlns="http://www.w3.org/2000/svg" style="display:
|
|
|
324
713
|
* nunca se inyecta. Comprobar el propio DOM es la fuente de verdad real. */
|
|
325
714
|
const SPRITE_ROOT_ID = 'kf-icon-sprite-root';
|
|
326
715
|
/**
|
|
327
|
-
* Ícono de trazo del design system —
|
|
716
|
+
* Ícono de trazo del design system — 60 glyphs (59 de la página 5 + `eye-off`), grilla 24×24,
|
|
328
717
|
* grosor de trazo 1.9px. Referencia un sprite SVG embebido (ver
|
|
329
718
|
* `icon-sprite.ts`) vía `<use>`, así que no hay peso de red adicional por
|
|
330
719
|
* cada instancia: el sprite se inyecta al DOM una única vez, la primera
|
|
@@ -462,6 +851,55 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
462
851
|
}, styles: [":host{display:inline-flex;align-items:center;gap:var(--kf-space-xs);padding:var(--kf-space-xs) var(--kf-space-sm);border-radius:var(--kf-radius-pill);background:var(--kf-color-warning-soft);border:1px solid var(--kf-color-warning);color:var(--kf-color-warning-strong);font-size:.75rem;font-weight:700;letter-spacing:.02em;text-transform:uppercase;line-height:1}:host(.kf-admin-badge--inline){background:transparent;border-color:#e2b93b80;color:var(--kf-color-warning)}\n"] }]
|
|
463
852
|
}], propDecorators: { inline: [{ type: i0.Input, args: [{ isSignal: true, alias: "inline", required: false }] }] } });
|
|
464
853
|
|
|
854
|
+
/**
|
|
855
|
+
* Indicador de carga indeterminado: inline, dentro de un botón, o como único
|
|
856
|
+
* contenido de una sección mientras llega la data.
|
|
857
|
+
*
|
|
858
|
+
* Cuando se conoce la forma del contenido que viene, preferir `kf-skeleton`
|
|
859
|
+
* (dibuja la silueta). El spinner es para "algo está pasando" sin forma
|
|
860
|
+
* conocida — guardar, enviar, reintentar.
|
|
861
|
+
*
|
|
862
|
+
* Lleva `role="status"`, así que el lector de pantalla anuncia el `label`
|
|
863
|
+
* cuando aparece. Sin `label` cae en un texto accesible por defecto.
|
|
864
|
+
*
|
|
865
|
+
* <kf-spinner />
|
|
866
|
+
* <kf-spinner size="sm" label="Cargando…" />
|
|
867
|
+
* <kf-spinner onDark />
|
|
868
|
+
*/
|
|
869
|
+
class Spinner {
|
|
870
|
+
size = input('md', /* @ts-ignore */
|
|
871
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
872
|
+
/** Texto al lado del anillo. Vacío deja solo el anillo (y el texto para lectores). */
|
|
873
|
+
label = input('', /* @ts-ignore */
|
|
874
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
875
|
+
/** Invierte los colores para fondos oscuros. */
|
|
876
|
+
onDark = input(false, { ...(ngDevMode ? { debugName: "onDark" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
877
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Spinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
878
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Spinner, isStandalone: true, selector: "kf-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, onDark: { classPropertyName: "onDark", publicName: "onDark", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
879
|
+
<span class="kf-spinner" [class.kf-spinner--on-dark]="onDark()" role="status">
|
|
880
|
+
<span class="kf-spinner__ring" [class]="'kf-spinner__ring--' + size()"></span>
|
|
881
|
+
@if (label()) {
|
|
882
|
+
<span class="kf-spinner__label">{{ label() }}</span>
|
|
883
|
+
} @else {
|
|
884
|
+
<span class="kf-spinner__sr">Cargando</span>
|
|
885
|
+
}
|
|
886
|
+
</span>
|
|
887
|
+
`, isInline: true, styles: [":host{display:inline-block}.kf-spinner{display:inline-flex;align-items:center;gap:var(--kf-space-sm);font-family:var(--kf-font-body)}.kf-spinner__ring{display:inline-block;flex:none;border-radius:var(--kf-radius-pill);border:2px solid var(--kf-color-border);border-top-color:var(--kf-color-primary);animation:kf-spinner-turn .7s linear infinite}.kf-spinner__ring--sm{width:16px;height:16px}.kf-spinner__ring--md{width:24px;height:24px;border-width:3px}.kf-spinner__ring--lg{width:32px;height:32px;border-width:3px}.kf-spinner__label{font-size:.875rem;color:var(--kf-color-text-muted)}.kf-spinner--on-dark .kf-spinner__ring{border-color:#ffffff47;border-top-color:var(--kf-color-white)}.kf-spinner--on-dark .kf-spinner__label{color:var(--kf-color-white)}@keyframes kf-spinner-turn{to{transform:rotate(360deg)}}.kf-spinner__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@media(prefers-reduced-motion:reduce){.kf-spinner__ring{animation-duration:2s}}\n"] });
|
|
888
|
+
}
|
|
889
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Spinner, decorators: [{
|
|
890
|
+
type: Component,
|
|
891
|
+
args: [{ selector: 'kf-spinner', template: `
|
|
892
|
+
<span class="kf-spinner" [class.kf-spinner--on-dark]="onDark()" role="status">
|
|
893
|
+
<span class="kf-spinner__ring" [class]="'kf-spinner__ring--' + size()"></span>
|
|
894
|
+
@if (label()) {
|
|
895
|
+
<span class="kf-spinner__label">{{ label() }}</span>
|
|
896
|
+
} @else {
|
|
897
|
+
<span class="kf-spinner__sr">Cargando</span>
|
|
898
|
+
}
|
|
899
|
+
</span>
|
|
900
|
+
`, styles: [":host{display:inline-block}.kf-spinner{display:inline-flex;align-items:center;gap:var(--kf-space-sm);font-family:var(--kf-font-body)}.kf-spinner__ring{display:inline-block;flex:none;border-radius:var(--kf-radius-pill);border:2px solid var(--kf-color-border);border-top-color:var(--kf-color-primary);animation:kf-spinner-turn .7s linear infinite}.kf-spinner__ring--sm{width:16px;height:16px}.kf-spinner__ring--md{width:24px;height:24px;border-width:3px}.kf-spinner__ring--lg{width:32px;height:32px;border-width:3px}.kf-spinner__label{font-size:.875rem;color:var(--kf-color-text-muted)}.kf-spinner--on-dark .kf-spinner__ring{border-color:#ffffff47;border-top-color:var(--kf-color-white)}.kf-spinner--on-dark .kf-spinner__label{color:var(--kf-color-white)}@keyframes kf-spinner-turn{to{transform:rotate(360deg)}}.kf-spinner__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@media(prefers-reduced-motion:reduce){.kf-spinner__ring{animation-duration:2s}}\n"] }]
|
|
901
|
+
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], onDark: [{ type: i0.Input, args: [{ isSignal: true, alias: "onDark", required: false }] }] } });
|
|
902
|
+
|
|
465
903
|
/**
|
|
466
904
|
* Wraps a native `<button>`, so keyboard handling, focus and form submission
|
|
467
905
|
* keep working. The cost of the wrapper is forwarding `disabled` and `type` by
|
|
@@ -477,10 +915,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
477
915
|
*
|
|
478
916
|
* `(click)` is not forwarded — it bubbles from the inner button to the host.
|
|
479
917
|
*
|
|
918
|
+
* `loading` replaces the projected content with `kf-spinner` and forces
|
|
919
|
+
* `disabled` — for the common "Ingresando…"/"Enviando…" submit pattern,
|
|
920
|
+
* which before this prop existed as plain text swaps with no visual
|
|
921
|
+
* indicator (see `web-portal-latam-frontend`'s login submit buttons).
|
|
922
|
+
*
|
|
480
923
|
* <kf-button (click)="save()">Save</kf-button>
|
|
481
924
|
* <kf-button variant="ghost" disabled>Cancel</kf-button>
|
|
482
925
|
* <kf-button variant="danger" (click)="remove()">Delete</kf-button>
|
|
483
926
|
* <kf-button size="sm" icon="calendar" block>Reservar hora</kf-button>
|
|
927
|
+
* <kf-button type="submit" [loading]="submitting()">Ingresar</kf-button>
|
|
484
928
|
*/
|
|
485
929
|
class Button {
|
|
486
930
|
variant = input('primary', /* @ts-ignore */
|
|
@@ -496,11 +940,19 @@ class Button {
|
|
|
496
940
|
...(ngDevMode ? [undefined, { debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
497
941
|
/** Stretches the button to the full width of its container. */
|
|
498
942
|
block = input(false, { ...(ngDevMode ? { debugName: "block" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
943
|
+
/** Replaces the projected content with `kf-spinner` and forces `disabled`. */
|
|
944
|
+
loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
945
|
+
/** `ghost`/`outline` have no solid background — the default spinner ring already reads fine there. */
|
|
946
|
+
hasSolidFill = computed(() => {
|
|
947
|
+
const variant = this.variant();
|
|
948
|
+
return variant !== 'ghost' && variant !== 'outline';
|
|
949
|
+
}, /* @ts-ignore */
|
|
950
|
+
...(ngDevMode ? [{ debugName: "hasSolidFill" }] : /* istanbul ignore next */ []));
|
|
499
951
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Button, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
500
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Button, isStandalone: true, selector: "kf-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.block": "block() ? '' : null" } }, ngImport: i0, template: `
|
|
952
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Button, isStandalone: true, selector: "kf-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.block": "block() ? '' : null" } }, ngImport: i0, template: `
|
|
501
953
|
<button
|
|
502
954
|
[type]="type()"
|
|
503
|
-
[disabled]="disabled()"
|
|
955
|
+
[disabled]="disabled() || loading()"
|
|
504
956
|
[class.kf-button--secondary]="variant() === 'secondary'"
|
|
505
957
|
[class.kf-button--ghost]="variant() === 'ghost'"
|
|
506
958
|
[class.kf-button--outline]="variant() === 'outline'"
|
|
@@ -508,19 +960,27 @@ class Button {
|
|
|
508
960
|
[class.kf-button--sm]="size() === 'sm'"
|
|
509
961
|
[class.kf-button--lg]="size() === 'lg'"
|
|
510
962
|
>
|
|
511
|
-
@if (
|
|
512
|
-
<kf-
|
|
963
|
+
@if (loading()) {
|
|
964
|
+
<kf-spinner size="sm" [onDark]="hasSolidFill()" />
|
|
965
|
+
} @else {
|
|
966
|
+
@if (icon(); as iconName) {
|
|
967
|
+
<kf-icon
|
|
968
|
+
class="kf-button__icon"
|
|
969
|
+
[name]="iconName"
|
|
970
|
+
[size]="size() === 'lg' ? 'md' : 'sm'"
|
|
971
|
+
/>
|
|
972
|
+
}
|
|
973
|
+
<ng-content />
|
|
513
974
|
}
|
|
514
|
-
<ng-content />
|
|
515
975
|
</button>
|
|
516
|
-
`, isInline: true, styles: [":host{display:inline-block}:host([block]){display:block}button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);width:100%;font:inherit;font-weight:600;padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-primary);border-radius:var(--kf-radius-sm);background:var(--kf-color-primary);color:var(--kf-color-white);cursor:pointer;transition:background .14s,border-color .14s,color .14s}button:hover:not(:disabled){background:var(--kf-color-primary-hover);border-color:var(--kf-color-primary-hover)}button:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}button:disabled{opacity:.5;cursor:not-allowed}button.kf-button--secondary{border-color:var(--kf-color-secondary);background:var(--kf-color-secondary)}button.kf-button--secondary:hover:not(:disabled){background:var(--kf-color-secondary-hover);border-color:var(--kf-color-secondary-hover)}button.kf-button--ghost{background:transparent;border-color:transparent;color:var(--kf-color-primary)}button.kf-button--ghost:hover:not(:disabled){background:var(--kf-color-primary-soft)}button.kf-button--outline{background:transparent;border-color:var(--kf-color-border-strong);color:var(--kf-color-text)}button.kf-button--outline:hover:not(:disabled){background:var(--kf-color-surface);border-color:var(--kf-color-text-muted)}button.kf-button--danger{border-color:var(--kf-color-error);background:var(--kf-color-error)}button.kf-button--danger:hover:not(:disabled){background:var(--kf-color-error-hover);border-color:var(--kf-color-error-hover)}button.kf-button--sm{padding:6px var(--kf-space-sm);font-size:.85rem}button.kf-button--lg{padding:var(--kf-space-sm) var(--kf-space-lg);font-size:1.05rem}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size"] }] });
|
|
976
|
+
`, isInline: true, styles: [":host{display:inline-block}:host([block]){display:block}button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);width:100%;font:inherit;font-weight:600;padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-primary);border-radius:var(--kf-radius-sm);background:var(--kf-color-primary);color:var(--kf-color-white);cursor:pointer;transition:background .14s,border-color .14s,color .14s}button:hover:not(:disabled){background:var(--kf-color-primary-hover);border-color:var(--kf-color-primary-hover)}button:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}button:disabled{opacity:.5;cursor:not-allowed}button.kf-button--secondary{border-color:var(--kf-color-secondary);background:var(--kf-color-secondary)}button.kf-button--secondary:hover:not(:disabled){background:var(--kf-color-secondary-hover);border-color:var(--kf-color-secondary-hover)}button.kf-button--ghost{background:transparent;border-color:transparent;color:var(--kf-color-primary)}button.kf-button--ghost:hover:not(:disabled){background:var(--kf-color-primary-soft)}button.kf-button--outline{background:transparent;border-color:var(--kf-color-border-strong);color:var(--kf-color-text)}button.kf-button--outline:hover:not(:disabled){background:var(--kf-color-surface);border-color:var(--kf-color-text-muted)}button.kf-button--danger{border-color:var(--kf-color-error);background:var(--kf-color-error)}button.kf-button--danger:hover:not(:disabled){background:var(--kf-color-error-hover);border-color:var(--kf-color-error-hover)}button.kf-button--sm{padding:6px var(--kf-space-sm);font-size:.85rem}button.kf-button--lg{padding:var(--kf-space-sm) var(--kf-space-lg);font-size:1.05rem}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size"] }, { kind: "component", type: Spinner, selector: "kf-spinner", inputs: ["size", "label", "onDark"] }] });
|
|
517
977
|
}
|
|
518
978
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Button, decorators: [{
|
|
519
979
|
type: Component,
|
|
520
|
-
args: [{ selector: 'kf-button', imports: [Icon], template: `
|
|
980
|
+
args: [{ selector: 'kf-button', imports: [Icon, Spinner], template: `
|
|
521
981
|
<button
|
|
522
982
|
[type]="type()"
|
|
523
|
-
[disabled]="disabled()"
|
|
983
|
+
[disabled]="disabled() || loading()"
|
|
524
984
|
[class.kf-button--secondary]="variant() === 'secondary'"
|
|
525
985
|
[class.kf-button--ghost]="variant() === 'ghost'"
|
|
526
986
|
[class.kf-button--outline]="variant() === 'outline'"
|
|
@@ -528,15 +988,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
528
988
|
[class.kf-button--sm]="size() === 'sm'"
|
|
529
989
|
[class.kf-button--lg]="size() === 'lg'"
|
|
530
990
|
>
|
|
531
|
-
@if (
|
|
532
|
-
<kf-
|
|
991
|
+
@if (loading()) {
|
|
992
|
+
<kf-spinner size="sm" [onDark]="hasSolidFill()" />
|
|
993
|
+
} @else {
|
|
994
|
+
@if (icon(); as iconName) {
|
|
995
|
+
<kf-icon
|
|
996
|
+
class="kf-button__icon"
|
|
997
|
+
[name]="iconName"
|
|
998
|
+
[size]="size() === 'lg' ? 'md' : 'sm'"
|
|
999
|
+
/>
|
|
1000
|
+
}
|
|
1001
|
+
<ng-content />
|
|
533
1002
|
}
|
|
534
|
-
<ng-content />
|
|
535
1003
|
</button>
|
|
536
1004
|
`, host: {
|
|
537
1005
|
'[attr.block]': "block() ? '' : null",
|
|
538
1006
|
}, styles: [":host{display:inline-block}:host([block]){display:block}button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);width:100%;font:inherit;font-weight:600;padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-primary);border-radius:var(--kf-radius-sm);background:var(--kf-color-primary);color:var(--kf-color-white);cursor:pointer;transition:background .14s,border-color .14s,color .14s}button:hover:not(:disabled){background:var(--kf-color-primary-hover);border-color:var(--kf-color-primary-hover)}button:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}button:disabled{opacity:.5;cursor:not-allowed}button.kf-button--secondary{border-color:var(--kf-color-secondary);background:var(--kf-color-secondary)}button.kf-button--secondary:hover:not(:disabled){background:var(--kf-color-secondary-hover);border-color:var(--kf-color-secondary-hover)}button.kf-button--ghost{background:transparent;border-color:transparent;color:var(--kf-color-primary)}button.kf-button--ghost:hover:not(:disabled){background:var(--kf-color-primary-soft)}button.kf-button--outline{background:transparent;border-color:var(--kf-color-border-strong);color:var(--kf-color-text)}button.kf-button--outline:hover:not(:disabled){background:var(--kf-color-surface);border-color:var(--kf-color-text-muted)}button.kf-button--danger{border-color:var(--kf-color-error);background:var(--kf-color-error)}button.kf-button--danger:hover:not(:disabled){background:var(--kf-color-error-hover);border-color:var(--kf-color-error-hover)}button.kf-button--sm{padding:6px var(--kf-space-sm);font-size:.85rem}button.kf-button--lg{padding:var(--kf-space-sm) var(--kf-space-lg);font-size:1.05rem}\n"] }]
|
|
539
|
-
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], block: [{ type: i0.Input, args: [{ isSignal: true, alias: "block", required: false }] }] } });
|
|
1007
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], block: [{ type: i0.Input, args: [{ isSignal: true, alias: "block", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }] } });
|
|
540
1008
|
|
|
541
1009
|
/**
|
|
542
1010
|
* Banner contextual que vive dentro del flujo: validaciones, avisos de
|
|
@@ -955,11 +1423,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
955
1423
|
*/
|
|
956
1424
|
class CarouselSlide {
|
|
957
1425
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselSlide, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
958
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.0", type: CarouselSlide, isStandalone: true, selector: "kf-carousel-slide", ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{display:block;flex:0 0 100%;width:100%}\n"] });
|
|
1426
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.0", type: CarouselSlide, isStandalone: true, selector: "kf-carousel-slide", ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{display:block;flex:0 0 100%;width:100%;height:100%}\n"] });
|
|
959
1427
|
}
|
|
960
1428
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselSlide, decorators: [{
|
|
961
1429
|
type: Component,
|
|
962
|
-
args: [{ selector: 'kf-carousel-slide', template: `<ng-content />`, styles: [":host{display:block;flex:0 0 100%;width:100%}\n"] }]
|
|
1430
|
+
args: [{ selector: 'kf-carousel-slide', template: `<ng-content />`, styles: [":host{display:block;flex:0 0 100%;width:100%;height:100%}\n"] }]
|
|
963
1431
|
}] });
|
|
964
1432
|
/**
|
|
965
1433
|
* Carrusel de slides con flechas, dots y autoplay opcional.
|
|
@@ -1056,43 +1524,44 @@ class Carousel {
|
|
|
1056
1524
|
</div>
|
|
1057
1525
|
|
|
1058
1526
|
@if (slides().length > 1) {
|
|
1059
|
-
<
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1527
|
+
<div class="kf-carousel__controls">
|
|
1528
|
+
<div class="kf-carousel__dots" role="tablist">
|
|
1529
|
+
@for (slide of slides(); track slide; let i = $index) {
|
|
1530
|
+
<button
|
|
1531
|
+
type="button"
|
|
1532
|
+
role="tab"
|
|
1533
|
+
class="kf-carousel__dot"
|
|
1534
|
+
[class.kf-carousel__dot--active]="i === activeIndex()"
|
|
1535
|
+
[attr.aria-selected]="i === activeIndex()"
|
|
1536
|
+
[attr.aria-label]="'Ir al slide ' + (i + 1)"
|
|
1537
|
+
(click)="goTo(i)"
|
|
1538
|
+
></button>
|
|
1539
|
+
}
|
|
1540
|
+
</div>
|
|
1541
|
+
<button
|
|
1542
|
+
type="button"
|
|
1543
|
+
class="kf-carousel__arrow"
|
|
1544
|
+
aria-label="Slide anterior"
|
|
1545
|
+
(click)="previous()"
|
|
1546
|
+
>
|
|
1547
|
+
<kf-icon name="chevron-left" size="sm" />
|
|
1548
|
+
</button>
|
|
1549
|
+
<button
|
|
1550
|
+
type="button"
|
|
1551
|
+
class="kf-carousel__arrow"
|
|
1552
|
+
aria-label="Slide siguiente"
|
|
1553
|
+
(click)="next()"
|
|
1554
|
+
>
|
|
1555
|
+
<kf-icon name="chevron-right" size="sm" />
|
|
1556
|
+
</button>
|
|
1088
1557
|
</div>
|
|
1089
1558
|
}
|
|
1090
1559
|
</div>
|
|
1091
|
-
`, isInline: true, styles: [":host{display:block;font-family:var(--kf-font-body)}.kf-carousel{position:relative}.kf-carousel__viewport{overflow:hidden;border-radius:var(--kf-radius-md)}.kf-carousel__track{display:flex;transition:transform .32s ease}.kf-
|
|
1560
|
+
`, isInline: true, styles: [":host{display:block;height:100%;font-family:var(--kf-font-body)}.kf-carousel{position:relative;height:100%}.kf-carousel__viewport{height:100%;overflow:hidden;border-radius:var(--kf-radius-md)}.kf-carousel__track{display:flex;height:100%;transition:transform .32s ease}.kf-carousel__controls{position:absolute;z-index:2;right:var(--kf-space-sm);bottom:var(--kf-space-sm);display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-carousel__arrow{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border:1px solid rgb(255 255 255 / 22%);border-radius:var(--kf-radius-pill);background:#ffffff1f;color:#fff;cursor:pointer;transition:background .14s}.kf-carousel__arrow:hover{background:#ffffff3d}.kf-carousel__arrow:focus-visible{outline:none;box-shadow:0 0 0 2px #fff9}.kf-carousel__dots{display:flex;gap:var(--kf-space-xs)}.kf-carousel__dot{width:7px;height:7px;padding:0;border:none;border-radius:var(--kf-radius-pill);background:#ffffff59;cursor:pointer;transition:background .14s,width .14s}.kf-carousel__dot:focus-visible{outline:none;box-shadow:0 0 0 2px #fff9}.kf-carousel__dot--active{width:1.125rem;border-radius:var(--kf-radius-xs);background:#fff}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size"] }] });
|
|
1092
1561
|
}
|
|
1093
1562
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Carousel, decorators: [{
|
|
1094
1563
|
type: Component,
|
|
1095
|
-
args: [{ selector: 'kf-carousel', template: `
|
|
1564
|
+
args: [{ selector: 'kf-carousel', imports: [Icon], template: `
|
|
1096
1565
|
<div
|
|
1097
1566
|
class="kf-carousel"
|
|
1098
1567
|
(mouseenter)="pauseAutoplay()"
|
|
@@ -1110,39 +1579,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
1110
1579
|
</div>
|
|
1111
1580
|
|
|
1112
1581
|
@if (slides().length > 1) {
|
|
1113
|
-
<
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1582
|
+
<div class="kf-carousel__controls">
|
|
1583
|
+
<div class="kf-carousel__dots" role="tablist">
|
|
1584
|
+
@for (slide of slides(); track slide; let i = $index) {
|
|
1585
|
+
<button
|
|
1586
|
+
type="button"
|
|
1587
|
+
role="tab"
|
|
1588
|
+
class="kf-carousel__dot"
|
|
1589
|
+
[class.kf-carousel__dot--active]="i === activeIndex()"
|
|
1590
|
+
[attr.aria-selected]="i === activeIndex()"
|
|
1591
|
+
[attr.aria-label]="'Ir al slide ' + (i + 1)"
|
|
1592
|
+
(click)="goTo(i)"
|
|
1593
|
+
></button>
|
|
1594
|
+
}
|
|
1595
|
+
</div>
|
|
1596
|
+
<button
|
|
1597
|
+
type="button"
|
|
1598
|
+
class="kf-carousel__arrow"
|
|
1599
|
+
aria-label="Slide anterior"
|
|
1600
|
+
(click)="previous()"
|
|
1601
|
+
>
|
|
1602
|
+
<kf-icon name="chevron-left" size="sm" />
|
|
1603
|
+
</button>
|
|
1604
|
+
<button
|
|
1605
|
+
type="button"
|
|
1606
|
+
class="kf-carousel__arrow"
|
|
1607
|
+
aria-label="Slide siguiente"
|
|
1608
|
+
(click)="next()"
|
|
1609
|
+
>
|
|
1610
|
+
<kf-icon name="chevron-right" size="sm" />
|
|
1611
|
+
</button>
|
|
1142
1612
|
</div>
|
|
1143
1613
|
}
|
|
1144
1614
|
</div>
|
|
1145
|
-
`, styles: [":host{display:block;font-family:var(--kf-font-body)}.kf-carousel{position:relative}.kf-carousel__viewport{overflow:hidden;border-radius:var(--kf-radius-md)}.kf-carousel__track{display:flex;transition:transform .32s ease}.kf-
|
|
1615
|
+
`, styles: [":host{display:block;height:100%;font-family:var(--kf-font-body)}.kf-carousel{position:relative;height:100%}.kf-carousel__viewport{height:100%;overflow:hidden;border-radius:var(--kf-radius-md)}.kf-carousel__track{display:flex;height:100%;transition:transform .32s ease}.kf-carousel__controls{position:absolute;z-index:2;right:var(--kf-space-sm);bottom:var(--kf-space-sm);display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-carousel__arrow{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border:1px solid rgb(255 255 255 / 22%);border-radius:var(--kf-radius-pill);background:#ffffff1f;color:#fff;cursor:pointer;transition:background .14s}.kf-carousel__arrow:hover{background:#ffffff3d}.kf-carousel__arrow:focus-visible{outline:none;box-shadow:0 0 0 2px #fff9}.kf-carousel__dots{display:flex;gap:var(--kf-space-xs)}.kf-carousel__dot{width:7px;height:7px;padding:0;border:none;border-radius:var(--kf-radius-pill);background:#ffffff59;cursor:pointer;transition:background .14s,width .14s}.kf-carousel__dot:focus-visible{outline:none;box-shadow:0 0 0 2px #fff9}.kf-carousel__dot--active{width:1.125rem;border-radius:var(--kf-radius-xs);background:#fff}\n"] }]
|
|
1146
1616
|
}], propDecorators: { autoplay: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoplay", required: false }] }], interval: [{ type: i0.Input, args: [{ isSignal: true, alias: "interval", required: false }] }], indexChange: [{ type: i0.Output, args: ["indexChange"] }], slides: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => CarouselSlide), { isSignal: true }] }] } });
|
|
1147
1617
|
|
|
1148
1618
|
/**
|
|
@@ -1310,6 +1780,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
1310
1780
|
}, styles: [":host{display:inline-flex;align-items:center;gap:var(--kf-space-xs);padding:var(--kf-space-xs) var(--kf-space-sm);border-radius:var(--kf-radius-pill);border:1px solid transparent;font:inherit;font-size:.875em;line-height:1;color:var(--kf-color-text);background:var(--kf-color-surface);border-color:var(--kf-color-border);white-space:nowrap}:host(.kf-chip--ok){background:var(--kf-color-success-soft);border-color:var(--kf-color-success-soft);color:var(--kf-color-text)}:host(.kf-chip--warn){background:var(--kf-color-warning-soft);border-color:var(--kf-color-warning-soft);color:var(--kf-color-text)}:host(.kf-chip--error){background:var(--kf-color-error-soft);border-color:var(--kf-color-error-soft);color:var(--kf-color-text)}:host(.kf-chip--neutral){background:var(--kf-color-surface);border-color:var(--kf-color-border);color:var(--kf-color-text)}.kf-chip__dot{inline-size:.5em;block-size:.5em;border-radius:var(--kf-radius-pill);flex:none;background:var(--kf-color-text-muted)}.kf-chip__label{display:inline-block}.kf-chip__dot--ok{background:var(--kf-color-success)}.kf-chip__dot--warn{background:var(--kf-color-warning)}.kf-chip__dot--error{background:var(--kf-color-error)}.kf-chip__dot--neutral{background:var(--kf-color-text-muted)}\n"] }]
|
|
1311
1781
|
}], propDecorators: { tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }] } });
|
|
1312
1782
|
|
|
1783
|
+
/**
|
|
1784
|
+
* Separador visual simple entre bloques de contenido. `orientation`
|
|
1785
|
+
* controla si es una línea horizontal (para separar secciones apiladas) o
|
|
1786
|
+
* vertical (para separar elementos en una fila, ej. acciones en una toolbar,
|
|
1787
|
+
* o las columnas de metadata en `kf-company-selector`).
|
|
1788
|
+
*
|
|
1789
|
+
* En `vertical`, el divisor necesita una altura del contexto donde vive —
|
|
1790
|
+
* `:host { align-self: stretch }` lo hace ocupar la altura del contenedor
|
|
1791
|
+
* flex/grid padre sin que el consumidor tenga que fijarla a mano. `flex:
|
|
1792
|
+
* none` evita que el propio divisor se achique a 0 dentro de ese contenedor
|
|
1793
|
+
* flex cuando hay contenido hermano compitiendo por espacio.
|
|
1794
|
+
*
|
|
1795
|
+
* <kf-divider />
|
|
1796
|
+
* <kf-divider orientation="vertical" />
|
|
1797
|
+
*/
|
|
1798
|
+
class Divider {
|
|
1799
|
+
orientation = input('horizontal', /* @ts-ignore */
|
|
1800
|
+
...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
1801
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Divider, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1802
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: Divider, isStandalone: true, selector: "kf-divider", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "separator" }, properties: { "attr.orientation": "orientation()", "attr.aria-orientation": "orientation()" } }, ngImport: i0, template: '', isInline: true, styles: [":host{display:block;flex:none;border:none;background:var(--kf-color-border)}:host,:host([orientation=\"horizontal\"]){width:100%;height:1px}:host([orientation=\"vertical\"]){align-self:stretch;width:1px;height:auto}\n"] });
|
|
1803
|
+
}
|
|
1804
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Divider, decorators: [{
|
|
1805
|
+
type: Component,
|
|
1806
|
+
args: [{ selector: 'kf-divider', template: '', host: {
|
|
1807
|
+
role: 'separator',
|
|
1808
|
+
'[attr.orientation]': 'orientation()',
|
|
1809
|
+
'[attr.aria-orientation]': 'orientation()',
|
|
1810
|
+
}, styles: [":host{display:block;flex:none;border:none;background:var(--kf-color-border)}:host,:host([orientation=\"horizontal\"]){width:100%;height:1px}:host([orientation=\"vertical\"]){align-self:stretch;width:1px;height:auto}\n"] }]
|
|
1811
|
+
}], propDecorators: { orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }] } });
|
|
1812
|
+
|
|
1313
1813
|
/**
|
|
1314
1814
|
* Label superior compartido por todos los campos de formulario del design
|
|
1315
1815
|
* system (páginas 11-12: Text Field, Select, Multiselect) — uppercase,
|
|
@@ -1358,23 +1858,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
1358
1858
|
`, styles: [":host{display:contents}.kf-field-label{font-family:var(--kf-font-title);font-size:.75rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-field-label__required{color:var(--kf-color-error);margin-inline-start:2px}\n"] }]
|
|
1359
1859
|
}], propDecorators: { for: [{ type: i0.Input, args: [{ isSignal: true, alias: "for", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }] } });
|
|
1360
1860
|
|
|
1361
|
-
let nextId$
|
|
1861
|
+
let nextId$1 = 0;
|
|
1362
1862
|
/**
|
|
1363
1863
|
* Dropdown de selección simple con panel propio — NUNCA usa el `<select>`
|
|
1364
1864
|
* nativo del navegador. Un `<select>` real siempre delega el popup de
|
|
1365
1865
|
* opciones al sistema operativo, y ningún CSS puede controlar cómo se ve
|
|
1366
|
-
* ese popup
|
|
1367
|
-
*
|
|
1368
|
-
*
|
|
1866
|
+
* ese popup.
|
|
1867
|
+
*
|
|
1868
|
+
* Hasta la `0.1.5` existía además `kf-select-menu`, un segundo componente
|
|
1869
|
+
* prácticamente idéntico (mismo trigger, mismo panel, mismo CSS) que solo
|
|
1870
|
+
* se diferenciaba en aceptar `options` únicamente como `{ value, label }[]`
|
|
1871
|
+
* (sin el atajo `string[]` que `Select` ya tenía). Se fusionaron en este
|
|
1872
|
+
* componente en la `0.2.0` — mantener dos componentes con la misma
|
|
1873
|
+
* interacción y el mismo aspecto visual, cuya única diferencia real era la
|
|
1874
|
+
* forma de un input, no se sostenía como dos piezas separadas del catálogo.
|
|
1369
1875
|
*
|
|
1370
|
-
*
|
|
1371
|
-
*
|
|
1372
|
-
* solo de estilo (label uppercase, fondo gris que pasa a blanco al foco,
|
|
1373
|
-
* a tono con `Input`) y que acepta `options` como `string[]` además de
|
|
1374
|
-
* `{ value, label }[]`.
|
|
1876
|
+
* El panel flotante se conecta al trigger vía `@angular/cdk/overlay` — el
|
|
1877
|
+
* mismo mecanismo que `Dropdown` (ver `../dropdown/Dropdown.ts`).
|
|
1375
1878
|
*
|
|
1376
1879
|
* <kf-select label="Sede" [options]="['Lima', 'Arequipa', 'Trujillo']" placeholder="Selecciona…" />
|
|
1377
1880
|
* <kf-select [options]="[{ value: 'pe', label: 'Perú' }]" (valueChange)="onCountry($event)" />
|
|
1881
|
+
*
|
|
1882
|
+
* Pendiente: el prop `icon` de otros componentes del design system requiere
|
|
1883
|
+
* un componente Icon / sprite SVG que esta librería todavía no tiene — este
|
|
1884
|
+
* componente no usa iconos, así que no aplica acá.
|
|
1378
1885
|
*/
|
|
1379
1886
|
class Select {
|
|
1380
1887
|
label = input(/* @ts-ignore */
|
|
@@ -1387,7 +1894,7 @@ class Select {
|
|
|
1387
1894
|
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
1388
1895
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1389
1896
|
valueChange = output();
|
|
1390
|
-
instanceId = `kf-select-${nextId$
|
|
1897
|
+
instanceId = `kf-select-${nextId$1++}`;
|
|
1391
1898
|
triggerId = `${this.instanceId}-trigger`;
|
|
1392
1899
|
listboxId = `${this.instanceId}-listbox`;
|
|
1393
1900
|
isOpen = signal(false, /* @ts-ignore */
|
|
@@ -1397,7 +1904,34 @@ class Select {
|
|
|
1397
1904
|
...(ngDevMode ? [{ debugName: "normalizedOptions" }] : /* istanbul ignore next */ []));
|
|
1398
1905
|
selectedOption = computed(() => this.normalizedOptions().find((option) => option.value === this.value()), /* @ts-ignore */
|
|
1399
1906
|
...(ngDevMode ? [{ debugName: "selectedOption" }] : /* istanbul ignore next */ []));
|
|
1400
|
-
|
|
1907
|
+
triggerRef = viewChild.required('trigger', /* @ts-ignore */
|
|
1908
|
+
...(ngDevMode ? [{ debugName: "triggerRef" }] : /* istanbul ignore next */ []));
|
|
1909
|
+
panelTemplate = viewChild.required('panelTemplate', /* @ts-ignore */
|
|
1910
|
+
...(ngDevMode ? [{ debugName: "panelTemplate" }] : /* istanbul ignore next */ []));
|
|
1911
|
+
overlayService = inject(Overlay);
|
|
1912
|
+
viewContainerRef = inject(ViewContainerRef);
|
|
1913
|
+
destroyRef = inject(DestroyRef);
|
|
1914
|
+
overlayRef = null;
|
|
1915
|
+
constructor() {
|
|
1916
|
+
effect(() => {
|
|
1917
|
+
if (this.isOpen()) {
|
|
1918
|
+
this.attach();
|
|
1919
|
+
}
|
|
1920
|
+
else {
|
|
1921
|
+
this.detach();
|
|
1922
|
+
}
|
|
1923
|
+
});
|
|
1924
|
+
this.destroyRef.onDestroy(() => this.overlayRef?.dispose());
|
|
1925
|
+
}
|
|
1926
|
+
/**
|
|
1927
|
+
* Respaldo de `overlayRef.keydownEvents()`: ese observable del CDK solo ve
|
|
1928
|
+
* teclas presionadas con el foco DENTRO del pane del overlay. Si el foco
|
|
1929
|
+
* sigue en el trigger (o en cualquier otro lado de la página) mientras el
|
|
1930
|
+
* panel está abierto, `keydownEvents()` nunca dispara.
|
|
1931
|
+
*/
|
|
1932
|
+
onDocumentEscape() {
|
|
1933
|
+
this.isOpen.set(false);
|
|
1934
|
+
}
|
|
1401
1935
|
toggle() {
|
|
1402
1936
|
if (this.disabled()) {
|
|
1403
1937
|
return;
|
|
@@ -1410,16 +1944,53 @@ class Select {
|
|
|
1410
1944
|
this.valueChange.emit(option.value);
|
|
1411
1945
|
}
|
|
1412
1946
|
}
|
|
1413
|
-
|
|
1414
|
-
if (this.
|
|
1415
|
-
|
|
1947
|
+
attach() {
|
|
1948
|
+
if (this.overlayRef?.hasAttached()) {
|
|
1949
|
+
return;
|
|
1416
1950
|
}
|
|
1951
|
+
const overlayRef = this.getOrCreateOverlayRef();
|
|
1952
|
+
// Se remide el ancho del trigger en cada apertura, no solo la primera —
|
|
1953
|
+
// ver la misma nota en SelectMenu: cachear el ancho en la creación del
|
|
1954
|
+
// overlay lo deja desincronizado si el trigger cambia de tamaño entre
|
|
1955
|
+
// una apertura y la siguiente.
|
|
1956
|
+
overlayRef.updateSize({ width: this.triggerRef().nativeElement.getBoundingClientRect().width });
|
|
1957
|
+
const portal = new TemplatePortal(this.panelTemplate(), this.viewContainerRef);
|
|
1958
|
+
overlayRef.attach(portal);
|
|
1959
|
+
overlayRef.outsidePointerEvents().subscribe(() => this.isOpen.set(false));
|
|
1960
|
+
overlayRef.keydownEvents().subscribe((event) => {
|
|
1961
|
+
if (event.key === 'Escape') {
|
|
1962
|
+
this.isOpen.set(false);
|
|
1963
|
+
}
|
|
1964
|
+
});
|
|
1417
1965
|
}
|
|
1418
|
-
|
|
1419
|
-
this.
|
|
1966
|
+
detach() {
|
|
1967
|
+
this.overlayRef?.detach();
|
|
1968
|
+
}
|
|
1969
|
+
getOrCreateOverlayRef() {
|
|
1970
|
+
if (this.overlayRef) {
|
|
1971
|
+
return this.overlayRef;
|
|
1972
|
+
}
|
|
1973
|
+
const positionStrategy = this.overlayService
|
|
1974
|
+
.position()
|
|
1975
|
+
.flexibleConnectedTo(this.triggerRef())
|
|
1976
|
+
.withPositions([
|
|
1977
|
+
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
1978
|
+
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
1979
|
+
{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
|
|
1980
|
+
{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },
|
|
1981
|
+
])
|
|
1982
|
+
.withViewportMargin(8)
|
|
1983
|
+
.withPush(true);
|
|
1984
|
+
this.overlayRef = this.overlayService.create({
|
|
1985
|
+
positionStrategy,
|
|
1986
|
+
scrollStrategy: this.overlayService.scrollStrategies.reposition(),
|
|
1987
|
+
width: this.triggerRef().nativeElement.getBoundingClientRect().width,
|
|
1988
|
+
maxWidth: '90vw',
|
|
1989
|
+
});
|
|
1990
|
+
return this.overlayRef;
|
|
1420
1991
|
}
|
|
1421
1992
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Select, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1422
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Select, isStandalone: true, selector: "kf-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:
|
|
1993
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Select, isStandalone: true, selector: "kf-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:keydown.escape": "onDocumentEscape()" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "panelTemplate", first: true, predicate: ["panelTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
1423
1994
|
@if (label()) {
|
|
1424
1995
|
<kf-field-label [for]="triggerId">{{ label() }}</kf-field-label>
|
|
1425
1996
|
}
|
|
@@ -1444,7 +2015,7 @@ class Select {
|
|
|
1444
2015
|
aria-hidden="true"
|
|
1445
2016
|
></span>
|
|
1446
2017
|
</button>
|
|
1447
|
-
|
|
2018
|
+
<ng-template #panelTemplate>
|
|
1448
2019
|
<ul
|
|
1449
2020
|
class="kf-select__panel"
|
|
1450
2021
|
[id]="listboxId"
|
|
@@ -1468,8 +2039,8 @@ class Select {
|
|
|
1468
2039
|
<li class="kf-select__empty">Sin opciones disponibles</li>
|
|
1469
2040
|
}
|
|
1470
2041
|
</ul>
|
|
1471
|
-
|
|
1472
|
-
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:var(--kf-space-xs);
|
|
2042
|
+
</ng-template>
|
|
2043
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:var(--kf-space-xs);width:240px;font-family:var(--kf-font-body)}.kf-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-select__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-select__trigger:focus-visible{outline:none;border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-select__trigger--disabled{opacity:.5;cursor:not-allowed}.kf-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-select__caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-select__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-select__panel{box-sizing:border-box;width:100%;margin:0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.kf-select__option{padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-select__option:hover{background:var(--kf-color-primary-soft)}.kf-select__option--selected{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);font-weight:600}.kf-select__empty{padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"], dependencies: [{ kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required"] }] });
|
|
1473
2044
|
}
|
|
1474
2045
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Select, decorators: [{
|
|
1475
2046
|
type: Component,
|
|
@@ -1498,7 +2069,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
1498
2069
|
aria-hidden="true"
|
|
1499
2070
|
></span>
|
|
1500
2071
|
</button>
|
|
1501
|
-
|
|
2072
|
+
<ng-template #panelTemplate>
|
|
1502
2073
|
<ul
|
|
1503
2074
|
class="kf-select__panel"
|
|
1504
2075
|
[id]="listboxId"
|
|
@@ -1522,12 +2093,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
1522
2093
|
<li class="kf-select__empty">Sin opciones disponibles</li>
|
|
1523
2094
|
}
|
|
1524
2095
|
</ul>
|
|
1525
|
-
|
|
1526
|
-
`, styles: [":host{display:flex;flex-direction:column;gap:var(--kf-space-xs);
|
|
1527
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }],
|
|
1528
|
-
type: HostListener,
|
|
1529
|
-
args: ['document:click', ['$event']]
|
|
1530
|
-
}], onEscape: [{
|
|
2096
|
+
</ng-template>
|
|
2097
|
+
`, styles: [":host{display:flex;flex-direction:column;gap:var(--kf-space-xs);width:240px;font-family:var(--kf-font-body)}.kf-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-select__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-select__trigger:focus-visible{outline:none;border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-select__trigger--disabled{opacity:.5;cursor:not-allowed}.kf-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-select__caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-select__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-select__panel{box-sizing:border-box;width:100%;margin:0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.kf-select__option{padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-select__option:hover{background:var(--kf-color-primary-soft)}.kf-select__option--selected{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);font-weight:600}.kf-select__empty{padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"] }]
|
|
2098
|
+
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], triggerRef: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], panelTemplate: [{ type: i0.ViewChild, args: ['panelTemplate', { isSignal: true }] }], onDocumentEscape: [{
|
|
1531
2099
|
type: HostListener,
|
|
1532
2100
|
args: ['document:keydown.escape']
|
|
1533
2101
|
}] } });
|
|
@@ -1571,19 +2139,22 @@ class CompanySelector {
|
|
|
1571
2139
|
/>
|
|
1572
2140
|
@if (meta().length) {
|
|
1573
2141
|
<div class="kf-company-selector__meta">
|
|
1574
|
-
@for (item of meta(); track item.label) {
|
|
2142
|
+
@for (item of meta(); track item.label; let last = $last) {
|
|
1575
2143
|
<div class="kf-company-selector__meta-item">
|
|
1576
2144
|
<span class="kf-company-selector__meta-label">{{ item.label }}</span>
|
|
1577
2145
|
<span class="kf-company-selector__meta-value">{{ item.value }}</span>
|
|
1578
2146
|
</div>
|
|
2147
|
+
@if (!last) {
|
|
2148
|
+
<kf-divider orientation="vertical" />
|
|
2149
|
+
}
|
|
1579
2150
|
}
|
|
1580
2151
|
</div>
|
|
1581
2152
|
}
|
|
1582
|
-
`, isInline: true, styles: [":host{display:flex;align-items:center;gap:var(--kf-space-lg);flex-wrap:wrap;padding:var(--kf-space-md);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);background:var(--kf-color-white);font-family:var(--kf-font-body)}.kf-company-selector__select{flex:1 1 260px;min-width:0}.kf-company-selector__meta{display:flex;gap:var(--kf-space-lg);flex-wrap:wrap}.kf-company-selector__meta-item{display:flex;flex-direction:column;gap:2px}.kf-company-selector__meta-label{font-family:var(--kf-font-title);font-size:.72rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-company-selector__meta-value{font-family:var(--kf-font-mono);font-size:.875rem;color:var(--kf-color-ink)}\n"], dependencies: [{ kind: "component", type: Select, selector: "kf-select", inputs: ["label", "options", "value", "placeholder", "disabled"], outputs: ["valueChange"] }] });
|
|
2153
|
+
`, isInline: true, styles: [":host{display:flex;align-items:center;gap:var(--kf-space-lg);flex-wrap:wrap;padding:var(--kf-space-md);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);background:var(--kf-color-white);font-family:var(--kf-font-body)}.kf-company-selector__select{flex:1 1 260px;min-width:0}.kf-company-selector__meta{display:flex;gap:var(--kf-space-lg);flex-wrap:wrap}.kf-company-selector__meta-item{display:flex;flex-direction:column;gap:2px}.kf-company-selector__meta-label{font-family:var(--kf-font-title);font-size:.72rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-company-selector__meta-value{font-family:var(--kf-font-mono);font-size:.875rem;color:var(--kf-color-ink)}\n"], dependencies: [{ kind: "component", type: Divider, selector: "kf-divider", inputs: ["orientation"] }, { kind: "component", type: Select, selector: "kf-select", inputs: ["label", "options", "value", "placeholder", "disabled"], outputs: ["valueChange"] }] });
|
|
1583
2154
|
}
|
|
1584
2155
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CompanySelector, decorators: [{
|
|
1585
2156
|
type: Component,
|
|
1586
|
-
args: [{ selector: 'kf-company-selector', imports: [Select], template: `
|
|
2157
|
+
args: [{ selector: 'kf-company-selector', imports: [Divider, Select], template: `
|
|
1587
2158
|
<kf-select
|
|
1588
2159
|
class="kf-company-selector__select"
|
|
1589
2160
|
[label]="label()"
|
|
@@ -1593,11 +2164,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
1593
2164
|
/>
|
|
1594
2165
|
@if (meta().length) {
|
|
1595
2166
|
<div class="kf-company-selector__meta">
|
|
1596
|
-
@for (item of meta(); track item.label) {
|
|
2167
|
+
@for (item of meta(); track item.label; let last = $last) {
|
|
1597
2168
|
<div class="kf-company-selector__meta-item">
|
|
1598
2169
|
<span class="kf-company-selector__meta-label">{{ item.label }}</span>
|
|
1599
2170
|
<span class="kf-company-selector__meta-value">{{ item.value }}</span>
|
|
1600
2171
|
</div>
|
|
2172
|
+
@if (!last) {
|
|
2173
|
+
<kf-divider orientation="vertical" />
|
|
2174
|
+
}
|
|
1601
2175
|
}
|
|
1602
2176
|
</div>
|
|
1603
2177
|
}
|
|
@@ -1760,55 +2334,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
1760
2334
|
`, styles: [":host{display:block}.kf-skeleton{display:block;background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-skeleton-shimmer 1.4s ease infinite}.kf-skeleton--text{height:14px;border-radius:var(--kf-radius-xs)}.kf-skeleton--rect{height:80px;border-radius:var(--kf-radius-sm)}.kf-skeleton--circle{aspect-ratio:1 / 1;border-radius:var(--kf-radius-pill)}@keyframes kf-skeleton-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-skeleton{animation:none;background:var(--kf-color-border)}}\n"] }]
|
|
1761
2335
|
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }] } });
|
|
1762
2336
|
|
|
1763
|
-
/**
|
|
1764
|
-
* Indicador de carga indeterminado: inline, dentro de un botón, o como único
|
|
1765
|
-
* contenido de una sección mientras llega la data.
|
|
1766
|
-
*
|
|
1767
|
-
* Cuando se conoce la forma del contenido que viene, preferir `kf-skeleton`
|
|
1768
|
-
* (dibuja la silueta). El spinner es para "algo está pasando" sin forma
|
|
1769
|
-
* conocida — guardar, enviar, reintentar.
|
|
1770
|
-
*
|
|
1771
|
-
* Lleva `role="status"`, así que el lector de pantalla anuncia el `label`
|
|
1772
|
-
* cuando aparece. Sin `label` cae en un texto accesible por defecto.
|
|
1773
|
-
*
|
|
1774
|
-
* <kf-spinner />
|
|
1775
|
-
* <kf-spinner size="sm" label="Cargando…" />
|
|
1776
|
-
* <kf-spinner onDark />
|
|
1777
|
-
*/
|
|
1778
|
-
class Spinner {
|
|
1779
|
-
size = input('md', /* @ts-ignore */
|
|
1780
|
-
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
1781
|
-
/** Texto al lado del anillo. Vacío deja solo el anillo (y el texto para lectores). */
|
|
1782
|
-
label = input('', /* @ts-ignore */
|
|
1783
|
-
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1784
|
-
/** Invierte los colores para fondos oscuros. */
|
|
1785
|
-
onDark = input(false, { ...(ngDevMode ? { debugName: "onDark" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1786
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Spinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1787
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Spinner, isStandalone: true, selector: "kf-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, onDark: { classPropertyName: "onDark", publicName: "onDark", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1788
|
-
<span class="kf-spinner" [class.kf-spinner--on-dark]="onDark()" role="status">
|
|
1789
|
-
<span class="kf-spinner__ring" [class]="'kf-spinner__ring--' + size()"></span>
|
|
1790
|
-
@if (label()) {
|
|
1791
|
-
<span class="kf-spinner__label">{{ label() }}</span>
|
|
1792
|
-
} @else {
|
|
1793
|
-
<span class="kf-spinner__sr">Cargando</span>
|
|
1794
|
-
}
|
|
1795
|
-
</span>
|
|
1796
|
-
`, isInline: true, styles: [":host{display:inline-block}.kf-spinner{display:inline-flex;align-items:center;gap:var(--kf-space-sm);font-family:var(--kf-font-body)}.kf-spinner__ring{display:inline-block;flex:none;border-radius:var(--kf-radius-pill);border:2px solid var(--kf-color-border);border-top-color:var(--kf-color-primary);animation:kf-spinner-turn .7s linear infinite}.kf-spinner__ring--sm{width:16px;height:16px}.kf-spinner__ring--md{width:24px;height:24px;border-width:3px}.kf-spinner__ring--lg{width:32px;height:32px;border-width:3px}.kf-spinner__label{font-size:.875rem;color:var(--kf-color-text-muted)}.kf-spinner--on-dark .kf-spinner__ring{border-color:#ffffff47;border-top-color:var(--kf-color-white)}.kf-spinner--on-dark .kf-spinner__label{color:var(--kf-color-white)}@keyframes kf-spinner-turn{to{transform:rotate(360deg)}}.kf-spinner__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@media(prefers-reduced-motion:reduce){.kf-spinner__ring{animation-duration:2s}}\n"] });
|
|
1797
|
-
}
|
|
1798
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Spinner, decorators: [{
|
|
1799
|
-
type: Component,
|
|
1800
|
-
args: [{ selector: 'kf-spinner', template: `
|
|
1801
|
-
<span class="kf-spinner" [class.kf-spinner--on-dark]="onDark()" role="status">
|
|
1802
|
-
<span class="kf-spinner__ring" [class]="'kf-spinner__ring--' + size()"></span>
|
|
1803
|
-
@if (label()) {
|
|
1804
|
-
<span class="kf-spinner__label">{{ label() }}</span>
|
|
1805
|
-
} @else {
|
|
1806
|
-
<span class="kf-spinner__sr">Cargando</span>
|
|
1807
|
-
}
|
|
1808
|
-
</span>
|
|
1809
|
-
`, styles: [":host{display:inline-block}.kf-spinner{display:inline-flex;align-items:center;gap:var(--kf-space-sm);font-family:var(--kf-font-body)}.kf-spinner__ring{display:inline-block;flex:none;border-radius:var(--kf-radius-pill);border:2px solid var(--kf-color-border);border-top-color:var(--kf-color-primary);animation:kf-spinner-turn .7s linear infinite}.kf-spinner__ring--sm{width:16px;height:16px}.kf-spinner__ring--md{width:24px;height:24px;border-width:3px}.kf-spinner__ring--lg{width:32px;height:32px;border-width:3px}.kf-spinner__label{font-size:.875rem;color:var(--kf-color-text-muted)}.kf-spinner--on-dark .kf-spinner__ring{border-color:#ffffff47;border-top-color:var(--kf-color-white)}.kf-spinner--on-dark .kf-spinner__label{color:var(--kf-color-white)}@keyframes kf-spinner-turn{to{transform:rotate(360deg)}}.kf-spinner__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@media(prefers-reduced-motion:reduce){.kf-spinner__ring{animation-duration:2s}}\n"] }]
|
|
1810
|
-
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], onDark: [{ type: i0.Input, args: [{ isSignal: true, alias: "onDark", required: false }] }] } });
|
|
1811
|
-
|
|
1812
2337
|
/**
|
|
1813
2338
|
* Wrapper de los cuatro estados que toda sección tiene: cargando, con datos,
|
|
1814
2339
|
* vacía y con error. Un componente en vez de tres `@if` sueltos, porque es
|
|
@@ -2358,16 +2883,239 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
2358
2883
|
</div>
|
|
2359
2884
|
}
|
|
2360
2885
|
</div>
|
|
2361
|
-
}
|
|
2362
|
-
|
|
2363
|
-
@if (rows().length > 0) {
|
|
2364
|
-
<div class="kf-data-table__footer">
|
|
2365
|
-
<ng-content select="[footer]" />
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2888
|
+
@if (rows().length > 0) {
|
|
2889
|
+
<div class="kf-data-table__footer">
|
|
2890
|
+
<ng-content select="[footer]" />
|
|
2891
|
+
</div>
|
|
2892
|
+
}
|
|
2893
|
+
</div>
|
|
2894
|
+
`, styles: [":host{display:block;font-family:var(--kf-font-body)}.kf-data-table{background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-sm);overflow:hidden}.kf-data-table--flush{border:none;box-shadow:none;border-radius:0}.kf-data-table__toolbar{display:flex;justify-content:flex-end;padding:var(--kf-space-sm) var(--kf-space-md);border-bottom:1px solid var(--kf-color-border)}.kf-data-table__view-toggle{display:inline-flex;gap:2px;padding:2px;background:var(--kf-color-surface);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm)}.kf-data-table__view-option{font:inherit;font-size:.875em;padding:var(--kf-space-xs) var(--kf-space-sm);border:none;background:transparent;color:var(--kf-color-text-muted);border-radius:var(--kf-radius-xs);cursor:pointer;transition:background .14s,color .14s}.kf-data-table__view-option:hover:not(.kf-data-table__view-option--active){color:var(--kf-color-text)}.kf-data-table__view-option--active{background:var(--kf-color-white);color:var(--kf-color-ink);box-shadow:var(--kf-shadow-xs)}.kf-data-table__view-option:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-data-table__scroll{overflow-x:auto}.kf-data-table__table{width:100%;border-collapse:collapse;text-align:left}.kf-data-table__table th,.kf-data-table__table td{padding:var(--kf-space-sm) var(--kf-space-md);border-bottom:1px solid var(--kf-color-border);white-space:nowrap}.kf-data-table__table th{font-family:var(--kf-font-title);font-size:.8125em;text-transform:uppercase;letter-spacing:.02em;color:var(--kf-color-text-muted);background:var(--kf-color-surface)}.kf-data-table__table td{color:var(--kf-color-text)}.kf-data-table__table tbody tr:last-child td{border-bottom:none}.kf-data-table__row{cursor:pointer;transition:background .14s}.kf-data-table__row:hover{background:var(--kf-color-primary-soft)}.kf-data-table__cell--right{text-align:right}.kf-data-table__empty{padding:var(--kf-space-md)}.kf-data-table__footer{padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-data-table__footer:empty{display:none}.kf-data-table__cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:var(--kf-space-md);padding:var(--kf-space-md)}.kf-data-table__card{display:flex;flex-direction:column;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);overflow:hidden;transition:border-color .14s,box-shadow .14s}.kf-data-table__card--interactive{cursor:pointer}.kf-data-table__card:hover{border-color:var(--kf-color-border-strong);box-shadow:var(--kf-shadow-xs)}.kf-data-table__card--interactive:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-data-table__card-header{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-md)}.kf-data-table__card-media{flex:none}.kf-data-table__card-media img,.kf-data-table__thumb{display:block;width:48px;height:48px;border-radius:var(--kf-radius-xs);object-fit:cover;background:var(--kf-color-surface)}.kf-data-table__card-heading{display:flex;flex-direction:column;gap:var(--kf-space-xs);min-width:0}.kf-data-table__card-title{font-family:var(--kf-font-title);font-weight:600;color:var(--kf-color-ink);overflow-wrap:anywhere}.kf-data-table__card-statuses,.kf-data-table__card-actions{display:flex;flex-wrap:wrap;gap:var(--kf-space-xs)}.kf-data-table__card-fields{display:flex;flex-direction:column;gap:var(--kf-space-xs);padding:var(--kf-space-md)}.kf-data-table__card-header+.kf-data-table__card-fields{padding-top:0}.kf-data-table__card-field{display:flex;justify-content:space-between;gap:var(--kf-space-sm)}.kf-data-table__card-actions{justify-content:flex-end;margin-top:auto;padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border);background:var(--kf-color-surface)}.kf-data-table__thumb{width:32px;height:32px}.kf-data-table__card-label{font-family:var(--kf-font-title);font-size:.8125em;text-transform:uppercase;letter-spacing:.02em;color:var(--kf-color-text-muted)}.kf-data-table__card-value{color:var(--kf-color-text);text-align:right}\n"] }]
|
|
2895
|
+
}], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], rowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowKey", required: false }] }], flush: [{ type: i0.Input, args: [{ isSignal: true, alias: "flush", required: false }] }], cardable: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardable", required: false }] }], defaultView: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultView", required: false }] }], render: [{ type: i0.Input, args: [{ isSignal: true, alias: "render", required: false }] }], cellTemplates: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellTemplates", required: false }] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }] } });
|
|
2896
|
+
|
|
2897
|
+
/**
|
|
2898
|
+
* Ítem de acción dentro de un `kf-dropdown-panel`. Es un `<button>` nativo
|
|
2899
|
+
* por dentro (no un `<a>`): las acciones de un menú de este tipo disparan
|
|
2900
|
+
* comportamiento en la pantalla actual (cerrar sesión, ejecutar un
|
|
2901
|
+
* comando), no navegan a otra URL.
|
|
2902
|
+
*
|
|
2903
|
+
* <kf-dropdown-item (click)="onLogout()" tone="error">Cerrar sesión</kf-dropdown-item>
|
|
2904
|
+
*/
|
|
2905
|
+
class DropdownItem {
|
|
2906
|
+
tone = input('neutral', /* @ts-ignore */
|
|
2907
|
+
...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
|
|
2908
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DropdownItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2909
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: DropdownItem, isStandalone: true, selector: "kf-dropdown-item", inputs: { tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
2910
|
+
<button
|
|
2911
|
+
type="button"
|
|
2912
|
+
class="kf-dropdown-item"
|
|
2913
|
+
[class.kf-dropdown-item--error]="tone() === 'error'"
|
|
2914
|
+
role="menuitem"
|
|
2915
|
+
>
|
|
2916
|
+
<ng-content />
|
|
2917
|
+
</button>
|
|
2918
|
+
`, isInline: true, styles: [":host{display:block}.kf-dropdown-item{display:block;width:100%;padding:var(--kf-space-sm) var(--kf-space-md);border:none;background:transparent;font:inherit;text-align:left;color:var(--kf-color-text);cursor:pointer}.kf-dropdown-item:hover{background:var(--kf-color-surface)}.kf-dropdown-item:focus-visible{outline:none;box-shadow:inset var(--kf-shadow-focus)}.kf-dropdown-item--error{color:var(--kf-color-error-strong)}.kf-dropdown-item--error:hover{background:var(--kf-color-error-soft)}\n"] });
|
|
2919
|
+
}
|
|
2920
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DropdownItem, decorators: [{
|
|
2921
|
+
type: Component,
|
|
2922
|
+
args: [{ selector: 'kf-dropdown-item', template: `
|
|
2923
|
+
<button
|
|
2924
|
+
type="button"
|
|
2925
|
+
class="kf-dropdown-item"
|
|
2926
|
+
[class.kf-dropdown-item--error]="tone() === 'error'"
|
|
2927
|
+
role="menuitem"
|
|
2928
|
+
>
|
|
2929
|
+
<ng-content />
|
|
2930
|
+
</button>
|
|
2931
|
+
`, styles: [":host{display:block}.kf-dropdown-item{display:block;width:100%;padding:var(--kf-space-sm) var(--kf-space-md);border:none;background:transparent;font:inherit;text-align:left;color:var(--kf-color-text);cursor:pointer}.kf-dropdown-item:hover{background:var(--kf-color-surface)}.kf-dropdown-item:focus-visible{outline:none;box-shadow:inset var(--kf-shadow-focus)}.kf-dropdown-item--error{color:var(--kf-color-error-strong)}.kf-dropdown-item--error:hover{background:var(--kf-color-error-soft)}\n"] }]
|
|
2932
|
+
}], propDecorators: { tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }] } });
|
|
2933
|
+
/**
|
|
2934
|
+
* Contenido del panel flotante de un `kf-dropdown`. Es solo una plantilla
|
|
2935
|
+
* (`<ng-template>` por dentro, capturada vía `TemplateRef`) — `Dropdown` la
|
|
2936
|
+
* conecta al overlay real cuando `open` pasa a `true`, no la renderiza en su
|
|
2937
|
+
* propio lugar del DOM. Esto es lo que permite que el panel aparezca pegado
|
|
2938
|
+
* al host de `Dropdown` sin importar dónde esté ese host en la página.
|
|
2939
|
+
*
|
|
2940
|
+
* <kf-dropdown [(open)]="menuOpen">
|
|
2941
|
+
* <kf-dropdown-panel>
|
|
2942
|
+
* <kf-dropdown-item (click)="onLogout()">Cerrar sesión</kf-dropdown-item>
|
|
2943
|
+
* </kf-dropdown-panel>
|
|
2944
|
+
* </kf-dropdown>
|
|
2945
|
+
*/
|
|
2946
|
+
class DropdownPanel {
|
|
2947
|
+
templateRef = viewChild.required(TemplateRef, /* @ts-ignore */
|
|
2948
|
+
...(ngDevMode ? [{ debugName: "templateRef" }] : /* istanbul ignore next */ []));
|
|
2949
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DropdownPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2950
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: DropdownPanel, isStandalone: true, selector: "kf-dropdown-panel", viewQueries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
2951
|
+
<ng-template>
|
|
2952
|
+
<div class="kf-dropdown-panel">
|
|
2953
|
+
<div class="kf-dropdown-panel__inner" role="menu">
|
|
2954
|
+
<ng-content />
|
|
2955
|
+
</div>
|
|
2956
|
+
</div>
|
|
2957
|
+
</ng-template>
|
|
2958
|
+
`, isInline: true, styles: [".kf-dropdown-panel{min-width:220px;max-width:100%;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-lg);font-family:var(--kf-font-body);animation:kf-dropdown-panel-enter .14s ease-out}.kf-dropdown-panel__inner{padding:var(--kf-space-xs) 0;overflow:hidden;border-radius:inherit}@media(prefers-reduced-motion:reduce){.kf-dropdown-panel{animation:none}}@keyframes kf-dropdown-panel-enter{0%{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] });
|
|
2959
|
+
}
|
|
2960
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DropdownPanel, decorators: [{
|
|
2961
|
+
type: Component,
|
|
2962
|
+
args: [{ selector: 'kf-dropdown-panel', template: `
|
|
2963
|
+
<ng-template>
|
|
2964
|
+
<div class="kf-dropdown-panel">
|
|
2965
|
+
<div class="kf-dropdown-panel__inner" role="menu">
|
|
2966
|
+
<ng-content />
|
|
2366
2967
|
</div>
|
|
2367
|
-
|
|
2368
|
-
</
|
|
2369
|
-
`, styles: ["
|
|
2370
|
-
}], propDecorators: {
|
|
2968
|
+
</div>
|
|
2969
|
+
</ng-template>
|
|
2970
|
+
`, styles: [".kf-dropdown-panel{min-width:220px;max-width:100%;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-lg);font-family:var(--kf-font-body);animation:kf-dropdown-panel-enter .14s ease-out}.kf-dropdown-panel__inner{padding:var(--kf-space-xs) 0;overflow:hidden;border-radius:inherit}@media(prefers-reduced-motion:reduce){.kf-dropdown-panel{animation:none}}@keyframes kf-dropdown-panel-enter{0%{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] }]
|
|
2971
|
+
}], propDecorators: { templateRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
2972
|
+
/**
|
|
2973
|
+
* Menú de acciones flotante, conectado a un elemento disparador vía
|
|
2974
|
+
* `@angular/cdk/overlay` — la misma pieza que usa Angular Material para
|
|
2975
|
+
* `mat-menu`/`mat-select`. Resuelve el patrón que antes se reimplementaba a
|
|
2976
|
+
* mano en cada consumidor (ver el session-menu de `web-portal-latam-frontend`,
|
|
2977
|
+
* ~80 líneas de HTML/TS/SCSS para toggle + click-afuera + Escape + animación
|
|
2978
|
+
* de entrada, acopladas a una clase interna no pública de `PortalHeader`).
|
|
2979
|
+
*
|
|
2980
|
+
* Se apoya en el CDK en vez de un `position: absolute` casero (como sí hace
|
|
2981
|
+
* `SelectMenu`, que puede permitírselo porque su trigger vive siempre dentro
|
|
2982
|
+
* del propio componente) porque acá el disparador real puede vivir en OTRO
|
|
2983
|
+
* componente por completo — ej. el avatar dentro de `kf-portal-header` — y
|
|
2984
|
+
* el panel tiene que aparecer pegado a ESE elemento sin importar dónde el
|
|
2985
|
+
* consumidor ubique al `Dropdown` en su HTML. El Overlay CDK calcula esa
|
|
2986
|
+
* posición (con fallback si no entra en pantalla) en vez de que cada
|
|
2987
|
+
* consumidor lo recalcule a mano.
|
|
2988
|
+
*
|
|
2989
|
+
* `open` es two-way, igual que `Alert`/`Modal`: el consumidor decide qué
|
|
2990
|
+
* dispara la apertura (puede ser un `(click)` en un botón propio, o un
|
|
2991
|
+
* evento de otro componente como `PortalHeader.sessionClick`) — `Dropdown`
|
|
2992
|
+
* en sí no renderiza ningún trigger, su propio host es el punto de anclaje
|
|
2993
|
+
* visual del panel.
|
|
2994
|
+
*
|
|
2995
|
+
* <kf-dropdown [(open)]="menuOpen">
|
|
2996
|
+
* <kf-dropdown-panel>
|
|
2997
|
+
* <div class="mi-header">Sesión iniciada como {{ email() }}</div>
|
|
2998
|
+
* <kf-dropdown-item (click)="onLogout()" tone="error">Cerrar sesión</kf-dropdown-item>
|
|
2999
|
+
* </kf-dropdown-panel>
|
|
3000
|
+
* </kf-dropdown>
|
|
3001
|
+
*/
|
|
3002
|
+
class Dropdown {
|
|
3003
|
+
/** Visibilidad del panel, two-way: `[(open)]="menuOpen"`. */
|
|
3004
|
+
open = model(false, /* @ts-ignore */
|
|
3005
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
3006
|
+
/**
|
|
3007
|
+
* Elemento al que se conecta el overlay, si es distinto del propio host
|
|
3008
|
+
* de `Dropdown`. Sin esto, `Dropdown` asume que ÉL MISMO es visualmente
|
|
3009
|
+
* el disparador (caso normal: el consumidor arma su propio botón como
|
|
3010
|
+
* contenido, y `Dropdown` envuelve ese contenido). Cuando el disparador
|
|
3011
|
+
* real vive dentro de OTRO componente que no se puede envolver sin
|
|
3012
|
+
* ensanchar el área de click a algo más grande que el botón (ej. el
|
|
3013
|
+
* avatar de sesión dentro de `PortalHeader`, que convive con logo y
|
|
3014
|
+
* navegación en el mismo host), `anchor` permite apuntar el overlay a la
|
|
3015
|
+
* referencia real de ese componente en vez de al host vacío de
|
|
3016
|
+
* `Dropdown`.
|
|
3017
|
+
*
|
|
3018
|
+
* <kf-dropdown [(open)]="menuOpen" [anchor]="headerRef()">
|
|
3019
|
+
*/
|
|
3020
|
+
anchor = input(/* @ts-ignore */
|
|
3021
|
+
...(ngDevMode ? [undefined, { debugName: "anchor" }] : /* istanbul ignore next */ []));
|
|
3022
|
+
panel = contentChild(DropdownPanel, /* @ts-ignore */
|
|
3023
|
+
...(ngDevMode ? [{ debugName: "panel" }] : /* istanbul ignore next */ []));
|
|
3024
|
+
overlayService = inject(Overlay);
|
|
3025
|
+
host = inject((ElementRef));
|
|
3026
|
+
viewContainerRef = inject(ViewContainerRef);
|
|
3027
|
+
destroyRef = inject(DestroyRef);
|
|
3028
|
+
overlayRef = null;
|
|
3029
|
+
constructor() {
|
|
3030
|
+
effect(() => {
|
|
3031
|
+
if (this.open()) {
|
|
3032
|
+
this.attach();
|
|
3033
|
+
}
|
|
3034
|
+
else {
|
|
3035
|
+
this.detach();
|
|
3036
|
+
}
|
|
3037
|
+
});
|
|
3038
|
+
this.destroyRef.onDestroy(() => this.overlayRef?.dispose());
|
|
3039
|
+
}
|
|
3040
|
+
/**
|
|
3041
|
+
* Respaldo de `overlayRef.keydownEvents()`: ese observable del CDK solo
|
|
3042
|
+
* ve teclas presionadas con el foco DENTRO del pane del overlay. Si el
|
|
3043
|
+
* usuario abre el menú y presiona Escape con el foco en otro lado de la
|
|
3044
|
+
* página (caso común — el foco puede seguir en el botón disparador, que
|
|
3045
|
+
* vive fuera del overlay), `keydownEvents()` nunca dispara. Este listener
|
|
3046
|
+
* a nivel de documento cubre ese caso; el de `keydownEvents()` sigue
|
|
3047
|
+
* activo para cuando el foco sí está dentro del panel.
|
|
3048
|
+
*/
|
|
3049
|
+
onDocumentEscape() {
|
|
3050
|
+
this.open.set(false);
|
|
3051
|
+
}
|
|
3052
|
+
attach() {
|
|
3053
|
+
const panel = this.panel();
|
|
3054
|
+
if (!panel || this.overlayRef?.hasAttached()) {
|
|
3055
|
+
return;
|
|
3056
|
+
}
|
|
3057
|
+
const overlayRef = this.getOrCreateOverlayRef();
|
|
3058
|
+
const portal = new TemplatePortal(panel.templateRef(), this.viewContainerRef);
|
|
3059
|
+
overlayRef.attach(portal);
|
|
3060
|
+
overlayRef.outsidePointerEvents().subscribe(() => this.open.set(false));
|
|
3061
|
+
overlayRef.keydownEvents().subscribe((event) => {
|
|
3062
|
+
if (event.key === 'Escape') {
|
|
3063
|
+
this.open.set(false);
|
|
3064
|
+
}
|
|
3065
|
+
});
|
|
3066
|
+
}
|
|
3067
|
+
detach() {
|
|
3068
|
+
this.overlayRef?.detach();
|
|
3069
|
+
}
|
|
3070
|
+
getOrCreateOverlayRef() {
|
|
3071
|
+
if (this.overlayRef) {
|
|
3072
|
+
return this.overlayRef;
|
|
3073
|
+
}
|
|
3074
|
+
const positionStrategy = this.overlayService
|
|
3075
|
+
.position()
|
|
3076
|
+
.flexibleConnectedTo(this.anchor() ?? this.host)
|
|
3077
|
+
// 4 posiciones, no 2: además de abajo/arriba (alineado al borde
|
|
3078
|
+
// derecho del anchor, el caso común), agrega el mismo par alineado al
|
|
3079
|
+
// borde IZQUIERDO. Con solo el par "end" — como estaba antes — un
|
|
3080
|
+
// trigger cerca del borde derecho de la pantalla no tenía ningún
|
|
3081
|
+
// fallback horizontal: el panel se salía del viewport en vez de
|
|
3082
|
+
// reacomodarse hacia la izquierda. El CDK prueba cada posición en
|
|
3083
|
+
// orden y usa la primera que entra completa en el viewport.
|
|
3084
|
+
.withPositions([
|
|
3085
|
+
{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
|
|
3086
|
+
{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },
|
|
3087
|
+
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
3088
|
+
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
3089
|
+
])
|
|
3090
|
+
// Margen de seguridad contra los bordes del viewport — sin esto, el
|
|
3091
|
+
// CDK puede considerar una posición "válida" aunque quede pegada al
|
|
3092
|
+
// borde con 0px de aire.
|
|
3093
|
+
.withViewportMargin(8)
|
|
3094
|
+
// Si ninguna de las 4 posiciones entra completa (viewport muy
|
|
3095
|
+
// angosto), la última se ajusta con push en vez de desbordarse fuera
|
|
3096
|
+
// de pantalla sin control.
|
|
3097
|
+
.withPush(true);
|
|
3098
|
+
this.overlayRef = this.overlayService.create({
|
|
3099
|
+
positionStrategy,
|
|
3100
|
+
scrollStrategy: this.overlayService.scrollStrategies.reposition(),
|
|
3101
|
+
// Sin esto, el panel puede quedar más angosto que su propio
|
|
3102
|
+
// `min-width` en pantallas chicas si el CDK decide recortar — fija un
|
|
3103
|
+
// techo razonable en vez de dejarlo crecer sin límite ni encogerse
|
|
3104
|
+
// por debajo de lo legible.
|
|
3105
|
+
maxWidth: '90vw',
|
|
3106
|
+
});
|
|
3107
|
+
return this.overlayRef;
|
|
3108
|
+
}
|
|
3109
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Dropdown, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3110
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: Dropdown, isStandalone: true, selector: "kf-dropdown", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { listeners: { "document:keydown.escape": "onDocumentEscape()" } }, queries: [{ propertyName: "panel", first: true, predicate: DropdownPanel, descendants: true, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{display:inline-block}\n"] });
|
|
3111
|
+
}
|
|
3112
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Dropdown, decorators: [{
|
|
3113
|
+
type: Component,
|
|
3114
|
+
args: [{ selector: 'kf-dropdown', template: `<ng-content />`, styles: [":host{display:inline-block}\n"] }]
|
|
3115
|
+
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], anchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchor", required: false }] }], panel: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownPanel), { isSignal: true }] }], onDocumentEscape: [{
|
|
3116
|
+
type: HostListener,
|
|
3117
|
+
args: ['document:keydown.escape']
|
|
3118
|
+
}] } });
|
|
2371
3119
|
|
|
2372
3120
|
/**
|
|
2373
3121
|
* Bloque promocional sobre fondo oscuro de marca (página 37) — campañas,
|
|
@@ -2950,6 +3698,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
2950
3698
|
`, styles: [":host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-input__field{display:flex;align-items:center;gap:var(--kf-space-sm);padding:0 var(--kf-space-sm);background:var(--kf-color-surface);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);transition:background .14s,border-color .14s,box-shadow .14s}.kf-input__field--focused{background:var(--kf-color-white);border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-input__field--invalid{border-color:var(--kf-color-error)}.kf-input__field--invalid.kf-input__field--focused{box-shadow:0 0 0 3px #eb575738}.kf-input__field--disabled{opacity:.5}.kf-input__icon{color:var(--kf-color-text-muted)}.kf-input__field--invalid .kf-input__icon{color:var(--kf-color-error)}.kf-input__control{flex:1;min-width:0;border:none;outline:none;background:transparent;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) 0}.kf-input__control::placeholder{color:var(--kf-color-text-muted)}.kf-input__control:disabled{cursor:not-allowed}.kf-input__suffix{flex:none;color:var(--kf-color-text-muted);font-size:.875rem}.kf-input__toggle{flex:none;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:var(--kf-space-xs);margin:0 calc(var(--kf-space-xs) * -1);color:var(--kf-color-text-muted);cursor:pointer;border-radius:var(--kf-radius-xs);transition:color .14s}.kf-input__toggle:hover{color:var(--kf-color-text)}.kf-input__toggle:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-input__hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-input__error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}\n"] }]
|
|
2951
3699
|
}], propDecorators: { nativeInput: [{ type: i0.ViewChild, args: ['nativeInput', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], toggleable: [{ type: i0.Input, args: [{ isSignal: true, alias: "toggleable", required: false }] }] } });
|
|
2952
3700
|
|
|
3701
|
+
/**
|
|
3702
|
+
* Acción de bajo énfasis con apariencia de texto — "¿Olvidaste tu
|
|
3703
|
+
* contraseña?", "Volver a iniciar sesión". Antes de este componente,
|
|
3704
|
+
* `web-portal-latam-frontend` reimplementaba esto dos veces (`.login__forgot`
|
|
3705
|
+
* como `<a href="#">` con `preventDefault()`, `.login__back` como
|
|
3706
|
+
* `<button>`), cada una con su propio `:focus-visible` copiado literal.
|
|
3707
|
+
*
|
|
3708
|
+
* Es siempre un `<button type="button">` por dentro, nunca un `<a>`: ninguno
|
|
3709
|
+
* de los dos casos reales navega a otra URL, ambos disparan una acción en la
|
|
3710
|
+
* misma pantalla (cambiar de vista, someter un flujo). Si en el futuro un
|
|
3711
|
+
* consumidor necesita navegación real con href, esa es una discusión de API
|
|
3712
|
+
* distinta (`kf-link` con `[routerLink]`/`href`), no se fuerza acá sin caso
|
|
3713
|
+
* de uso confirmado.
|
|
3714
|
+
*
|
|
3715
|
+
* `variant="default"` (color primario, subrayado en hover) es para la
|
|
3716
|
+
* acción de mayor jerarquía relativa de la pantalla (ej. "¿Olvidaste tu
|
|
3717
|
+
* contraseña?"); `variant="muted"` (gris que pasa a primario en hover) es
|
|
3718
|
+
* para acciones de retroceso/salida (ej. "← Volver a iniciar sesión").
|
|
3719
|
+
*
|
|
3720
|
+
* <kf-link (click)="onForgotPassword()">¿Olvidaste tu contraseña?</kf-link>
|
|
3721
|
+
* <kf-link variant="muted" (click)="onBack()">← Volver a iniciar sesión</kf-link>
|
|
3722
|
+
*/
|
|
3723
|
+
class Link {
|
|
3724
|
+
variant = input('default', /* @ts-ignore */
|
|
3725
|
+
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
3726
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
3727
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Link, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3728
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: Link, isStandalone: true, selector: "kf-link", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
3729
|
+
<button
|
|
3730
|
+
type="button"
|
|
3731
|
+
class="kf-link"
|
|
3732
|
+
[class.kf-link--muted]="variant() === 'muted'"
|
|
3733
|
+
[disabled]="disabled()"
|
|
3734
|
+
>
|
|
3735
|
+
<ng-content />
|
|
3736
|
+
</button>
|
|
3737
|
+
`, isInline: true, styles: [":host{display:inline-block}.kf-link{padding:0;border:none;background:transparent;font:inherit;font-weight:500;color:var(--kf-color-primary);text-decoration:none;cursor:pointer}.kf-link:hover:not(:disabled){text-decoration:underline}.kf-link:focus-visible{outline:2px solid var(--kf-color-primary);outline-offset:2px;border-radius:var(--kf-radius-xs)}.kf-link:disabled{opacity:.5;cursor:not-allowed}.kf-link--muted{color:var(--kf-color-text-muted)}.kf-link--muted:hover:not(:disabled){color:var(--kf-color-primary);text-decoration:none}\n"] });
|
|
3738
|
+
}
|
|
3739
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Link, decorators: [{
|
|
3740
|
+
type: Component,
|
|
3741
|
+
args: [{ selector: 'kf-link', template: `
|
|
3742
|
+
<button
|
|
3743
|
+
type="button"
|
|
3744
|
+
class="kf-link"
|
|
3745
|
+
[class.kf-link--muted]="variant() === 'muted'"
|
|
3746
|
+
[disabled]="disabled()"
|
|
3747
|
+
>
|
|
3748
|
+
<ng-content />
|
|
3749
|
+
</button>
|
|
3750
|
+
`, styles: [":host{display:inline-block}.kf-link{padding:0;border:none;background:transparent;font:inherit;font-weight:500;color:var(--kf-color-primary);text-decoration:none;cursor:pointer}.kf-link:hover:not(:disabled){text-decoration:underline}.kf-link:focus-visible{outline:2px solid var(--kf-color-primary);outline-offset:2px;border-radius:var(--kf-radius-xs)}.kf-link:disabled{opacity:.5;cursor:not-allowed}.kf-link--muted{color:var(--kf-color-text-muted)}.kf-link--muted:hover:not(:disabled){color:var(--kf-color-primary);text-decoration:none}\n"] }]
|
|
3751
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
3752
|
+
|
|
2953
3753
|
/**
|
|
2954
3754
|
* Card de estadística/KPI: label, valor grande, ícono opcional en la esquina
|
|
2955
3755
|
* superior derecha, badge de esquina opcional (pegado al valor) y una nota
|
|
@@ -3201,7 +4001,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
3201
4001
|
args: ['click', ['$event']]
|
|
3202
4002
|
}] } });
|
|
3203
4003
|
|
|
3204
|
-
let nextId
|
|
4004
|
+
let nextId = 0;
|
|
3205
4005
|
/**
|
|
3206
4006
|
* Dropdown de selección múltiple con checkboxes internos, siguiendo el mismo
|
|
3207
4007
|
* patrón de panel flotante que `SelectMenu` (panel con `position: absolute`
|
|
@@ -3238,7 +4038,7 @@ class MultiSelect {
|
|
|
3238
4038
|
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
3239
4039
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
3240
4040
|
valuesChange = output();
|
|
3241
|
-
instanceId = `kf-multi-select-${nextId
|
|
4041
|
+
instanceId = `kf-multi-select-${nextId++}`;
|
|
3242
4042
|
triggerId = `${this.instanceId}-trigger`;
|
|
3243
4043
|
listboxId = `${this.instanceId}-listbox`;
|
|
3244
4044
|
isOpen = signal(false, /* @ts-ignore */
|
|
@@ -3374,7 +4174,7 @@ class MultiSelect {
|
|
|
3374
4174
|
}
|
|
3375
4175
|
</ul>
|
|
3376
4176
|
}
|
|
3377
|
-
`, isInline: true, styles: [":host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font:inherit;
|
|
4177
|
+
`, isInline: true, styles: [":host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font:inherit;width:240px}.kf-multi-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;font-family:var(--kf-font-body);padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);color:var(--kf-color-text);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-multi-select__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-multi-select__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-multi-select__trigger:disabled{opacity:.5;cursor:not-allowed}.kf-multi-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;text-align:left}.kf-multi-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-multi-select__count{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 5px;border-radius:var(--kf-radius-pill);background:var(--kf-color-primary);color:var(--kf-color-white);font-size:.72rem;font-weight:700}.kf-multi-select__caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-multi-select__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-multi-select__panel{position:absolute;top:100%;left:0;right:0;z-index:10;margin:var(--kf-space-xs) 0 0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.kf-multi-select__option{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-multi-select__option:hover{background:var(--kf-color-primary-soft)}.kf-multi-select__option--selected{color:var(--kf-color-primary);font-weight:600}.kf-multi-select__checkbox{display:inline-flex;flex-shrink:0;width:var(--kf-space-md);height:var(--kf-space-md);border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-xs);background:var(--kf-color-white);transition:background .14s,border-color .14s;position:relative}.kf-multi-select__checkbox--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--checked:after{content:\"\";position:absolute;left:4px;top:1px;width:4px;height:8px;border:solid var(--kf-color-white);border-width:0 2px 2px 0;transform:rotate(45deg)}.kf-multi-select__checkbox--indeterminate{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--indeterminate:after{content:\"\";position:absolute;left:3px;top:6px;width:8px;height:2px;background:var(--kf-color-white);border:none;transform:none}.kf-multi-select__option-label{overflow:hidden;text-overflow:ellipsis}.kf-multi-select__empty{padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"], dependencies: [{ kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required"] }] });
|
|
3378
4178
|
}
|
|
3379
4179
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MultiSelect, decorators: [{
|
|
3380
4180
|
type: Component,
|
|
@@ -3456,7 +4256,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
3456
4256
|
}
|
|
3457
4257
|
</ul>
|
|
3458
4258
|
}
|
|
3459
|
-
`, styles: [":host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font:inherit;
|
|
4259
|
+
`, styles: [":host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font:inherit;width:240px}.kf-multi-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;font-family:var(--kf-font-body);padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);color:var(--kf-color-text);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-multi-select__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-multi-select__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-multi-select__trigger:disabled{opacity:.5;cursor:not-allowed}.kf-multi-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;text-align:left}.kf-multi-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-multi-select__count{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 5px;border-radius:var(--kf-radius-pill);background:var(--kf-color-primary);color:var(--kf-color-white);font-size:.72rem;font-weight:700}.kf-multi-select__caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-multi-select__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-multi-select__panel{position:absolute;top:100%;left:0;right:0;z-index:10;margin:var(--kf-space-xs) 0 0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.kf-multi-select__option{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-multi-select__option:hover{background:var(--kf-color-primary-soft)}.kf-multi-select__option--selected{color:var(--kf-color-primary);font-weight:600}.kf-multi-select__checkbox{display:inline-flex;flex-shrink:0;width:var(--kf-space-md);height:var(--kf-space-md);border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-xs);background:var(--kf-color-white);transition:background .14s,border-color .14s;position:relative}.kf-multi-select__checkbox--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--checked:after{content:\"\";position:absolute;left:4px;top:1px;width:4px;height:8px;border:solid var(--kf-color-white);border-width:0 2px 2px 0;transform:rotate(45deg)}.kf-multi-select__checkbox--indeterminate{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--indeterminate:after{content:\"\";position:absolute;left:3px;top:6px;width:8px;height:2px;background:var(--kf-color-white);border:none;transform:none}.kf-multi-select__option-label{overflow:hidden;text-overflow:ellipsis}.kf-multi-select__empty{padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"] }]
|
|
3460
4260
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], values: [{ type: i0.Input, args: [{ isSignal: true, alias: "values", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valuesChange: [{ type: i0.Output, args: ["valuesChange"] }], onDocumentClick: [{
|
|
3461
4261
|
type: HostListener,
|
|
3462
4262
|
args: ['document:click', ['$event']]
|
|
@@ -3715,15 +4515,16 @@ class Panel {
|
|
|
3715
4515
|
</a>
|
|
3716
4516
|
}
|
|
3717
4517
|
</div>
|
|
4518
|
+
<kf-divider />
|
|
3718
4519
|
<div class="kf-panel__body">
|
|
3719
4520
|
<ng-content />
|
|
3720
4521
|
</div>
|
|
3721
4522
|
</kf-card>
|
|
3722
|
-
`, isInline: true, styles: [":host{display:block}.kf-panel__head{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);margin-bottom:var(--kf-space-sm)}.kf-panel__title{font-family:var(--kf-font-title);font-size:1.05rem;font-weight:700;color:var(--kf-color-ink)}.kf-panel__action{display:inline-flex;align-items:center;gap:2px;flex:none;font-size:.8125rem;font-weight:600;color:var(--kf-color-primary);text-decoration:none}.kf-panel__action:hover{text-decoration:underline}.kf-panel__body{display:flex;flex-direction:column;gap:var(--kf-space-sm)}\n"], dependencies: [{ kind: "component", type: Card, selector: "kf-card", inputs: ["flush"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size"] }] });
|
|
4523
|
+
`, isInline: true, styles: [":host{display:block}.kf-panel__head{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);margin-bottom:var(--kf-space-sm)}.kf-panel__title{font-family:var(--kf-font-title);font-size:1.05rem;font-weight:700;color:var(--kf-color-ink)}.kf-panel__action{display:inline-flex;align-items:center;gap:2px;flex:none;font-size:.8125rem;font-weight:600;color:var(--kf-color-primary);text-decoration:none}.kf-panel__action:hover{text-decoration:underline}.kf-panel__body{display:flex;flex-direction:column;gap:var(--kf-space-sm);margin-top:var(--kf-space-sm)}\n"], dependencies: [{ kind: "component", type: Card, selector: "kf-card", inputs: ["flush"] }, { kind: "component", type: Divider, selector: "kf-divider", inputs: ["orientation"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size"] }] });
|
|
3723
4524
|
}
|
|
3724
4525
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Panel, decorators: [{
|
|
3725
4526
|
type: Component,
|
|
3726
|
-
args: [{ selector: 'kf-panel', imports: [Card, Icon], template: `
|
|
4527
|
+
args: [{ selector: 'kf-panel', imports: [Card, Divider, Icon], template: `
|
|
3727
4528
|
<kf-card>
|
|
3728
4529
|
<div class="kf-panel__head">
|
|
3729
4530
|
<span class="kf-panel__title">{{ title() }}</span>
|
|
@@ -3734,11 +4535,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
3734
4535
|
</a>
|
|
3735
4536
|
}
|
|
3736
4537
|
</div>
|
|
4538
|
+
<kf-divider />
|
|
3737
4539
|
<div class="kf-panel__body">
|
|
3738
4540
|
<ng-content />
|
|
3739
4541
|
</div>
|
|
3740
4542
|
</kf-card>
|
|
3741
|
-
`, styles: [":host{display:block}.kf-panel__head{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);margin-bottom:var(--kf-space-sm)}.kf-panel__title{font-family:var(--kf-font-title);font-size:1.05rem;font-weight:700;color:var(--kf-color-ink)}.kf-panel__action{display:inline-flex;align-items:center;gap:2px;flex:none;font-size:.8125rem;font-weight:600;color:var(--kf-color-primary);text-decoration:none}.kf-panel__action:hover{text-decoration:underline}.kf-panel__body{display:flex;flex-direction:column;gap:var(--kf-space-sm)}\n"] }]
|
|
4543
|
+
`, styles: [":host{display:block}.kf-panel__head{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);margin-bottom:var(--kf-space-sm)}.kf-panel__title{font-family:var(--kf-font-title);font-size:1.05rem;font-weight:700;color:var(--kf-color-ink)}.kf-panel__action{display:inline-flex;align-items:center;gap:2px;flex:none;font-size:.8125rem;font-weight:600;color:var(--kf-color-primary);text-decoration:none}.kf-panel__action:hover{text-decoration:underline}.kf-panel__body{display:flex;flex-direction:column;gap:var(--kf-space-sm);margin-top:var(--kf-space-sm)}\n"] }]
|
|
3742
4544
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], actionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionLabel", required: false }] }], actionHref: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionHref", required: false }] }] } });
|
|
3743
4545
|
|
|
3744
4546
|
/**
|
|
@@ -3926,10 +4728,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
3926
4728
|
* `<ng-content select="[actions]">` para no acoplar el componente a un set
|
|
3927
4729
|
* fijo de botones.
|
|
3928
4730
|
*
|
|
3929
|
-
* `size
|
|
3930
|
-
*
|
|
3931
|
-
*
|
|
3932
|
-
*
|
|
4731
|
+
* `size` sigue la misma escala `'sm'|'md'|'lg'` que `Button`/`Icon`/`Spinner`
|
|
4732
|
+
* (`md` es el default): `sm` reduce tipografía y espaciado para usarse
|
|
4733
|
+
* dentro de cards ya compactas, `lg` los agranda para encabezar un bloque
|
|
4734
|
+
* más prominente. Antes de la `0.2.0`, `size` solo aceptaba `'sm'` —
|
|
4735
|
+
* placeholder incompleto de esta misma escala; los valores de `lg` son una
|
|
4736
|
+
* extrapolación proporcional de la escala existente (sin un caso de uso
|
|
4737
|
+
* real todavía que los valide, a diferencia de `sm`, que sí viene de un
|
|
4738
|
+
* patrón real de uso dentro de cards). `solid` rellena el chip de ícono con
|
|
4739
|
+
* el color primario sólido en vez del tratamiento "soft" (fondo tenue) —
|
|
4740
|
+
* pensado para superficies que ya tienen un tinte de color propio, donde el
|
|
4741
|
+
* chip "soft" perdería contraste.
|
|
3933
4742
|
*
|
|
3934
4743
|
* <kf-section-header icon="settings" title="Preferencias"
|
|
3935
4744
|
* subtitle="Configuración general de la cuenta">
|
|
@@ -3937,6 +4746,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
3937
4746
|
* </kf-section-header>
|
|
3938
4747
|
*
|
|
3939
4748
|
* <kf-section-header title="Detalle" size="sm" [solid]="true" />
|
|
4749
|
+
* <kf-section-header title="Resumen de flota" size="lg" />
|
|
3940
4750
|
*/
|
|
3941
4751
|
class SectionHeader {
|
|
3942
4752
|
icon = input(/* @ts-ignore */
|
|
@@ -3945,14 +4755,24 @@ class SectionHeader {
|
|
|
3945
4755
|
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
3946
4756
|
subtitle = input(/* @ts-ignore */
|
|
3947
4757
|
...(ngDevMode ? [undefined, { debugName: "subtitle" }] : /* istanbul ignore next */ []));
|
|
3948
|
-
size = input(/* @ts-ignore */
|
|
3949
|
-
...(ngDevMode ? [
|
|
4758
|
+
size = input('md', /* @ts-ignore */
|
|
4759
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
3950
4760
|
solid = input(false, { ...(ngDevMode ? { debugName: "solid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
4761
|
+
iconSize = computed(() => {
|
|
4762
|
+
if (this.size() === 'sm') {
|
|
4763
|
+
return 'sm';
|
|
4764
|
+
}
|
|
4765
|
+
if (this.size() === 'lg') {
|
|
4766
|
+
return 'lg';
|
|
4767
|
+
}
|
|
4768
|
+
return 'md';
|
|
4769
|
+
}, /* @ts-ignore */
|
|
4770
|
+
...(ngDevMode ? [{ debugName: "iconSize" }] : /* istanbul ignore next */ []));
|
|
3951
4771
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SectionHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3952
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: SectionHeader, isStandalone: true, selector: "kf-section-header", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, solid: { classPropertyName: "solid", publicName: "solid", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.kf-section-header--sm": "size() === 'sm'" } }, ngImport: i0, template: `
|
|
4772
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: SectionHeader, isStandalone: true, selector: "kf-section-header", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, solid: { classPropertyName: "solid", publicName: "solid", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.kf-section-header--sm": "size() === 'sm'", "class.kf-section-header--lg": "size() === 'lg'" } }, ngImport: i0, template: `
|
|
3953
4773
|
@if (icon(); as iconName) {
|
|
3954
4774
|
<span class="kf-section-header__icon" [class.kf-section-header__icon--solid]="solid()">
|
|
3955
|
-
<kf-icon [name]="iconName" [size]="
|
|
4775
|
+
<kf-icon [name]="iconName" [size]="iconSize()" />
|
|
3956
4776
|
</span>
|
|
3957
4777
|
}
|
|
3958
4778
|
|
|
@@ -3966,14 +4786,14 @@ class SectionHeader {
|
|
|
3966
4786
|
<span class="kf-section-header__actions">
|
|
3967
4787
|
<ng-content select="[actions]" />
|
|
3968
4788
|
</span>
|
|
3969
|
-
`, isInline: true, styles: [":host{display:flex;align-items:center;gap:var(--kf-space-sm);font-family:var(--kf-font-body)}:host(.kf-section-header--sm){gap:var(--kf-space-xs)}.kf-section-header__icon{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:2.5rem;block-size:2.5rem;border-radius:var(--kf-radius-sm);background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}:host(.kf-section-header--sm) .kf-section-header__icon{inline-size:1.75rem;block-size:1.75rem;border-radius:var(--kf-radius-xs)}.kf-section-header__icon--solid{background:var(--kf-color-primary);color:var(--kf-color-white)}.kf-section-header__text{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}.kf-section-header__title{font-family:var(--kf-font-title);font-size:1rem;font-weight:700;color:var(--kf-color-ink);line-height:1.3}:host(.kf-section-header--sm) .kf-section-header__title{font-size:.875rem}.kf-section-header__subtitle{font-size:.8125rem;color:var(--kf-color-text-muted);line-height:1.3}:host(.kf-section-header--sm) .kf-section-header__subtitle{font-size:.75rem}.kf-section-header__actions{flex:none;display:flex;align-items:center;gap:var(--kf-space-sm)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size"] }] });
|
|
4789
|
+
`, isInline: true, styles: [":host{display:flex;align-items:center;gap:var(--kf-space-sm);font-family:var(--kf-font-body)}:host(.kf-section-header--sm){gap:var(--kf-space-xs)}:host(.kf-section-header--lg){gap:var(--kf-space-md)}.kf-section-header__icon{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:2.5rem;block-size:2.5rem;border-radius:var(--kf-radius-sm);background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}:host(.kf-section-header--sm) .kf-section-header__icon{inline-size:1.75rem;block-size:1.75rem;border-radius:var(--kf-radius-xs)}:host(.kf-section-header--lg) .kf-section-header__icon{inline-size:3.25rem;block-size:3.25rem;border-radius:var(--kf-radius-md)}.kf-section-header__icon--solid{background:var(--kf-color-primary);color:var(--kf-color-white)}.kf-section-header__text{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}.kf-section-header__title{font-family:var(--kf-font-title);font-size:1rem;font-weight:700;color:var(--kf-color-ink);line-height:1.3}:host(.kf-section-header--sm) .kf-section-header__title{font-size:.875rem}:host(.kf-section-header--lg) .kf-section-header__title{font-size:1.25rem}.kf-section-header__subtitle{font-size:.8125rem;color:var(--kf-color-text-muted);line-height:1.3}:host(.kf-section-header--sm) .kf-section-header__subtitle{font-size:.75rem}:host(.kf-section-header--lg) .kf-section-header__subtitle{font-size:.9375rem}.kf-section-header__actions{flex:none;display:flex;align-items:center;gap:var(--kf-space-sm)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size"] }] });
|
|
3970
4790
|
}
|
|
3971
4791
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SectionHeader, decorators: [{
|
|
3972
4792
|
type: Component,
|
|
3973
4793
|
args: [{ selector: 'kf-section-header', imports: [Icon], template: `
|
|
3974
4794
|
@if (icon(); as iconName) {
|
|
3975
4795
|
<span class="kf-section-header__icon" [class.kf-section-header__icon--solid]="solid()">
|
|
3976
|
-
<kf-icon [name]="iconName" [size]="
|
|
4796
|
+
<kf-icon [name]="iconName" [size]="iconSize()" />
|
|
3977
4797
|
</span>
|
|
3978
4798
|
}
|
|
3979
4799
|
|
|
@@ -3989,7 +4809,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
3989
4809
|
</span>
|
|
3990
4810
|
`, host: {
|
|
3991
4811
|
'[class.kf-section-header--sm]': "size() === 'sm'",
|
|
3992
|
-
|
|
4812
|
+
'[class.kf-section-header--lg]': "size() === 'lg'",
|
|
4813
|
+
}, styles: [":host{display:flex;align-items:center;gap:var(--kf-space-sm);font-family:var(--kf-font-body)}:host(.kf-section-header--sm){gap:var(--kf-space-xs)}:host(.kf-section-header--lg){gap:var(--kf-space-md)}.kf-section-header__icon{display:inline-flex;align-items:center;justify-content:center;flex:none;inline-size:2.5rem;block-size:2.5rem;border-radius:var(--kf-radius-sm);background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}:host(.kf-section-header--sm) .kf-section-header__icon{inline-size:1.75rem;block-size:1.75rem;border-radius:var(--kf-radius-xs)}:host(.kf-section-header--lg) .kf-section-header__icon{inline-size:3.25rem;block-size:3.25rem;border-radius:var(--kf-radius-md)}.kf-section-header__icon--solid{background:var(--kf-color-primary);color:var(--kf-color-white)}.kf-section-header__text{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}.kf-section-header__title{font-family:var(--kf-font-title);font-size:1rem;font-weight:700;color:var(--kf-color-ink);line-height:1.3}:host(.kf-section-header--sm) .kf-section-header__title{font-size:.875rem}:host(.kf-section-header--lg) .kf-section-header__title{font-size:1.25rem}.kf-section-header__subtitle{font-size:.8125rem;color:var(--kf-color-text-muted);line-height:1.3}:host(.kf-section-header--sm) .kf-section-header__subtitle{font-size:.75rem}:host(.kf-section-header--lg) .kf-section-header__subtitle{font-size:.9375rem}.kf-section-header__actions{flex:none;display:flex;align-items:center;gap:var(--kf-space-sm)}\n"] }]
|
|
3993
4814
|
}], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], solid: [{ type: i0.Input, args: [{ isSignal: true, alias: "solid", required: false }] }] } });
|
|
3994
4815
|
|
|
3995
4816
|
/**
|
|
@@ -4063,184 +4884,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
4063
4884
|
`, styles: [":host{display:inline-block}.kf-segmented__track{position:relative;display:grid;grid-template-columns:repeat(var(--kf-segmented-count),1fr);gap:2px;padding:2px;background:var(--kf-color-surface);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md)}.kf-segmented__thumb{position:absolute;top:2px;left:2px;width:calc((100% - 4px) / var(--kf-segmented-count));height:calc(100% - 4px);background:var(--kf-color-white);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-xs);transform:translate(calc(var(--kf-segmented-index, 0) * 100%));transition:transform .2s ease}.kf-segmented__option{position:relative;z-index:1;font:inherit;padding:var(--kf-space-xs) var(--kf-space-md);border:none;background:transparent;color:var(--kf-color-text-muted);border-radius:var(--kf-radius-sm);cursor:pointer;transition:color .14s}.kf-segmented__option:hover:not(.kf-segmented__option--active){color:var(--kf-color-text)}.kf-segmented__option--active{color:var(--kf-color-ink)}.kf-segmented__option:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}\n"] }]
|
|
4064
4885
|
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
4065
4886
|
|
|
4066
|
-
let nextId = 0;
|
|
4067
|
-
/**
|
|
4068
|
-
* Dropdown de selección simple pero con panel propio (no usa `<select>` nativo),
|
|
4069
|
-
* para cuando se necesita más control visual que un `<select>` estándar permite.
|
|
4070
|
-
*
|
|
4071
|
-
* El panel flotante se implementa con `position: absolute` sobre el host
|
|
4072
|
-
* (sin Angular CDK Overlay, que no es dependencia del proyecto). Se abre y
|
|
4073
|
-
* cierra por click en el disparador, y se cierra al hacer click afuera o al
|
|
4074
|
-
* presionar Escape.
|
|
4075
|
-
*
|
|
4076
|
-
* <kf-select-menu
|
|
4077
|
-
* label="País"
|
|
4078
|
-
* [options]="countries"
|
|
4079
|
-
* [value]="selectedCountry()"
|
|
4080
|
-
* (valueChange)="selectedCountry.set($event)"
|
|
4081
|
-
* />
|
|
4082
|
-
*
|
|
4083
|
-
* Pendiente: el prop `icon` de otros componentes del design system requiere
|
|
4084
|
-
* un componente Icon / sprite SVG que esta librería todavía no tiene — este
|
|
4085
|
-
* componente no usa iconos, así que no aplica acá.
|
|
4086
|
-
*/
|
|
4087
|
-
class SelectMenu {
|
|
4088
|
-
label = input(/* @ts-ignore */
|
|
4089
|
-
...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
|
|
4090
|
-
options = input([], /* @ts-ignore */
|
|
4091
|
-
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
4092
|
-
value = input(/* @ts-ignore */
|
|
4093
|
-
...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
|
|
4094
|
-
placeholder = input('Seleccionar', /* @ts-ignore */
|
|
4095
|
-
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
4096
|
-
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
4097
|
-
valueChange = output();
|
|
4098
|
-
instanceId = `kf-select-menu-${nextId++}`;
|
|
4099
|
-
triggerId = `${this.instanceId}-trigger`;
|
|
4100
|
-
listboxId = `${this.instanceId}-listbox`;
|
|
4101
|
-
isOpen = signal(false, /* @ts-ignore */
|
|
4102
|
-
...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
4103
|
-
selectedOption = computed(() => this.options().find((option) => option.value === this.value()), /* @ts-ignore */
|
|
4104
|
-
...(ngDevMode ? [{ debugName: "selectedOption" }] : /* istanbul ignore next */ []));
|
|
4105
|
-
host = inject((ElementRef));
|
|
4106
|
-
toggle() {
|
|
4107
|
-
if (this.disabled()) {
|
|
4108
|
-
return;
|
|
4109
|
-
}
|
|
4110
|
-
this.isOpen.update((open) => !open);
|
|
4111
|
-
}
|
|
4112
|
-
select(option) {
|
|
4113
|
-
this.isOpen.set(false);
|
|
4114
|
-
if (option.value !== this.value()) {
|
|
4115
|
-
this.valueChange.emit(option.value);
|
|
4116
|
-
}
|
|
4117
|
-
}
|
|
4118
|
-
onDocumentClick(event) {
|
|
4119
|
-
if (this.isOpen() && !this.host.nativeElement.contains(event.target)) {
|
|
4120
|
-
this.isOpen.set(false);
|
|
4121
|
-
}
|
|
4122
|
-
}
|
|
4123
|
-
onEscape() {
|
|
4124
|
-
this.isOpen.set(false);
|
|
4125
|
-
}
|
|
4126
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SelectMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4127
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: SelectMenu, isStandalone: true, selector: "kf-select-menu", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: `
|
|
4128
|
-
@if (label()) {
|
|
4129
|
-
<kf-field-label [for]="triggerId">{{ label() }}</kf-field-label>
|
|
4130
|
-
}
|
|
4131
|
-
<button
|
|
4132
|
-
#trigger
|
|
4133
|
-
type="button"
|
|
4134
|
-
[id]="triggerId"
|
|
4135
|
-
class="kf-select-menu__trigger"
|
|
4136
|
-
[disabled]="disabled()"
|
|
4137
|
-
[attr.aria-haspopup]="'listbox'"
|
|
4138
|
-
[attr.aria-expanded]="isOpen()"
|
|
4139
|
-
[attr.aria-controls]="isOpen() ? listboxId : null"
|
|
4140
|
-
(click)="toggle()"
|
|
4141
|
-
>
|
|
4142
|
-
<span
|
|
4143
|
-
class="kf-select-menu__value"
|
|
4144
|
-
[class.kf-select-menu__value--placeholder]="!selectedOption()"
|
|
4145
|
-
>
|
|
4146
|
-
{{ selectedOption()?.label ?? placeholder() }}
|
|
4147
|
-
</span>
|
|
4148
|
-
<span
|
|
4149
|
-
class="kf-select-menu__caret"
|
|
4150
|
-
[class.kf-select-menu__caret--open]="isOpen()"
|
|
4151
|
-
aria-hidden="true"
|
|
4152
|
-
></span>
|
|
4153
|
-
</button>
|
|
4154
|
-
@if (isOpen()) {
|
|
4155
|
-
<ul
|
|
4156
|
-
class="kf-select-menu__panel"
|
|
4157
|
-
[id]="listboxId"
|
|
4158
|
-
role="listbox"
|
|
4159
|
-
[attr.aria-labelledby]="triggerId"
|
|
4160
|
-
>
|
|
4161
|
-
@for (option of options(); track option.value) {
|
|
4162
|
-
<li
|
|
4163
|
-
class="kf-select-menu__option"
|
|
4164
|
-
[class.kf-select-menu__option--selected]="option.value === value()"
|
|
4165
|
-
role="option"
|
|
4166
|
-
tabindex="0"
|
|
4167
|
-
[attr.aria-selected]="option.value === value()"
|
|
4168
|
-
(click)="select(option)"
|
|
4169
|
-
(keydown.enter)="select(option)"
|
|
4170
|
-
(keydown.space)="$event.preventDefault(); select(option)"
|
|
4171
|
-
>
|
|
4172
|
-
{{ option.label }}
|
|
4173
|
-
</li>
|
|
4174
|
-
} @empty {
|
|
4175
|
-
<li class="kf-select-menu__empty">Sin opciones disponibles</li>
|
|
4176
|
-
}
|
|
4177
|
-
</ul>
|
|
4178
|
-
}
|
|
4179
|
-
`, isInline: true, styles: [":host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font:inherit;min-width:200px}.kf-select-menu__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;font-family:var(--kf-font-body);padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);color:var(--kf-color-text);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-select-menu__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-select-menu__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-select-menu__trigger:disabled{opacity:.5;cursor:not-allowed}.kf-select-menu__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select-menu__value--placeholder{color:var(--kf-color-text-muted)}.kf-select-menu__caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-select-menu__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-select-menu__panel{position:absolute;top:100%;left:0;right:0;z-index:10;margin:var(--kf-space-xs) 0 0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.kf-select-menu__option{padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-select-menu__option:hover{background:var(--kf-color-primary-soft)}.kf-select-menu__option--selected{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);font-weight:600}.kf-select-menu__empty{padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"], dependencies: [{ kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required"] }] });
|
|
4180
|
-
}
|
|
4181
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SelectMenu, decorators: [{
|
|
4182
|
-
type: Component,
|
|
4183
|
-
args: [{ selector: 'kf-select-menu', imports: [FieldLabel], template: `
|
|
4184
|
-
@if (label()) {
|
|
4185
|
-
<kf-field-label [for]="triggerId">{{ label() }}</kf-field-label>
|
|
4186
|
-
}
|
|
4187
|
-
<button
|
|
4188
|
-
#trigger
|
|
4189
|
-
type="button"
|
|
4190
|
-
[id]="triggerId"
|
|
4191
|
-
class="kf-select-menu__trigger"
|
|
4192
|
-
[disabled]="disabled()"
|
|
4193
|
-
[attr.aria-haspopup]="'listbox'"
|
|
4194
|
-
[attr.aria-expanded]="isOpen()"
|
|
4195
|
-
[attr.aria-controls]="isOpen() ? listboxId : null"
|
|
4196
|
-
(click)="toggle()"
|
|
4197
|
-
>
|
|
4198
|
-
<span
|
|
4199
|
-
class="kf-select-menu__value"
|
|
4200
|
-
[class.kf-select-menu__value--placeholder]="!selectedOption()"
|
|
4201
|
-
>
|
|
4202
|
-
{{ selectedOption()?.label ?? placeholder() }}
|
|
4203
|
-
</span>
|
|
4204
|
-
<span
|
|
4205
|
-
class="kf-select-menu__caret"
|
|
4206
|
-
[class.kf-select-menu__caret--open]="isOpen()"
|
|
4207
|
-
aria-hidden="true"
|
|
4208
|
-
></span>
|
|
4209
|
-
</button>
|
|
4210
|
-
@if (isOpen()) {
|
|
4211
|
-
<ul
|
|
4212
|
-
class="kf-select-menu__panel"
|
|
4213
|
-
[id]="listboxId"
|
|
4214
|
-
role="listbox"
|
|
4215
|
-
[attr.aria-labelledby]="triggerId"
|
|
4216
|
-
>
|
|
4217
|
-
@for (option of options(); track option.value) {
|
|
4218
|
-
<li
|
|
4219
|
-
class="kf-select-menu__option"
|
|
4220
|
-
[class.kf-select-menu__option--selected]="option.value === value()"
|
|
4221
|
-
role="option"
|
|
4222
|
-
tabindex="0"
|
|
4223
|
-
[attr.aria-selected]="option.value === value()"
|
|
4224
|
-
(click)="select(option)"
|
|
4225
|
-
(keydown.enter)="select(option)"
|
|
4226
|
-
(keydown.space)="$event.preventDefault(); select(option)"
|
|
4227
|
-
>
|
|
4228
|
-
{{ option.label }}
|
|
4229
|
-
</li>
|
|
4230
|
-
} @empty {
|
|
4231
|
-
<li class="kf-select-menu__empty">Sin opciones disponibles</li>
|
|
4232
|
-
}
|
|
4233
|
-
</ul>
|
|
4234
|
-
}
|
|
4235
|
-
`, styles: [":host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font:inherit;min-width:200px}.kf-select-menu__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;font-family:var(--kf-font-body);padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);color:var(--kf-color-text);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-select-menu__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-select-menu__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-select-menu__trigger:disabled{opacity:.5;cursor:not-allowed}.kf-select-menu__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select-menu__value--placeholder{color:var(--kf-color-text-muted)}.kf-select-menu__caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-select-menu__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-select-menu__panel{position:absolute;top:100%;left:0;right:0;z-index:10;margin:var(--kf-space-xs) 0 0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.kf-select-menu__option{padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-select-menu__option:hover{background:var(--kf-color-primary-soft)}.kf-select-menu__option--selected{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);font-weight:600}.kf-select-menu__empty{padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"] }]
|
|
4236
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], onDocumentClick: [{
|
|
4237
|
-
type: HostListener,
|
|
4238
|
-
args: ['document:click', ['$event']]
|
|
4239
|
-
}], onEscape: [{
|
|
4240
|
-
type: HostListener,
|
|
4241
|
-
args: ['document:keydown.escape']
|
|
4242
|
-
}] } });
|
|
4243
|
-
|
|
4244
4887
|
/**
|
|
4245
4888
|
* Indicador numérico compacto (página 34): label + valor grande, con un
|
|
4246
4889
|
* ícono a la derecha del label — más chico y sin badge de esquina que
|
|
@@ -4509,6 +5152,109 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
4509
5152
|
`, styles: [":host{display:block;font-family:var(--kf-font-body)}.kf-tabs{position:relative;display:flex;align-items:stretch;gap:var(--kf-space-md);border-bottom:1px solid var(--kf-color-border)}.kf-tabs__tab{display:inline-flex;align-items:center;gap:var(--kf-space-xs);font:inherit;font-size:.9rem;color:var(--kf-color-text-muted);background:transparent;border:none;padding:var(--kf-space-sm) 0;cursor:pointer;transition:color .14s}.kf-tabs__tab:hover:not(.kf-tabs__tab--active){color:var(--kf-color-text)}.kf-tabs__tab:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus);border-radius:var(--kf-radius-xs)}.kf-tabs__tab--active{color:var(--kf-color-primary);font-size:1rem;font-weight:700}.kf-tabs__indicator{position:absolute;bottom:-1px;left:0;height:2px;background:var(--kf-color-primary);border-radius:2px 2px 0 0;pointer-events:none;transition:transform .28s cubic-bezier(.32,.72,0,1),width .28s cubic-bezier(.32,.72,0,1),opacity .14s}@media(prefers-reduced-motion:reduce){.kf-tabs__indicator{transition:opacity .14s}}\n"] }]
|
|
4510
5153
|
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], track: [{ type: i0.ViewChild, args: ['track', { isSignal: true }] }] } });
|
|
4511
5154
|
|
|
5155
|
+
/**
|
|
5156
|
+
* Tipografía unificada — separa la etiqueta semántica (`as`, qué es el
|
|
5157
|
+
* texto para el DOM/accesibilidad) del estilo visual (`variant`, cómo se
|
|
5158
|
+
* ve). Antes de este componente, cada pantalla que consume la librería
|
|
5159
|
+
* definía su propio `h1`/`p` con `font-size` suelto para el mismo rol
|
|
5160
|
+
* (título de página, subtítulo, texto secundario) — auditoría sobre
|
|
5161
|
+
* `web-portal-latam-frontend` encontró 9 tamaños distintos entre login y
|
|
5162
|
+
* home sin ningún paso de escala en común. `variant` resuelve eso contra
|
|
5163
|
+
* la escala de `tokens/base.css` (`--kf-font-size-*`).
|
|
5164
|
+
*
|
|
5165
|
+
* `tone` sigue la misma convención cerrada que `Alert`/`Badge`/`Chip`: sin
|
|
5166
|
+
* escape hatch de color libre. Si un caso necesita un color que `tone` no
|
|
5167
|
+
* cubre, es una discusión de design system, no una prop nueva acá.
|
|
5168
|
+
*
|
|
5169
|
+
* <kf-text as="h1" variant="title-lg">Bienvenido de nuevo</kf-text>
|
|
5170
|
+
* <kf-text as="p" variant="body-muted">Ingresá con tu cuenta corporativa.</kf-text>
|
|
5171
|
+
* <kf-text as="span" variant="caption" tone="error">Campo obligatorio</kf-text>
|
|
5172
|
+
*/
|
|
5173
|
+
class Text {
|
|
5174
|
+
/** Etiqueta semántica real que se renderiza — nunca es solo un `div`. */
|
|
5175
|
+
as = input('p', /* @ts-ignore */
|
|
5176
|
+
...(ngDevMode ? [{ debugName: "as" }] : /* istanbul ignore next */ []));
|
|
5177
|
+
variant = input('body', /* @ts-ignore */
|
|
5178
|
+
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
5179
|
+
tone = input('neutral', /* @ts-ignore */
|
|
5180
|
+
...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
|
|
5181
|
+
/**
|
|
5182
|
+
* Copia de `as` para uso dentro del template: `as` es palabra reservada
|
|
5183
|
+
* en las expresiones de Angular (`@if (x; as y)`), así que `@switch (as())`
|
|
5184
|
+
* no parsea — NG5002. La prop pública sigue llamándose `as` (es solo un
|
|
5185
|
+
* atributo HTML ahí, `<kf-text as="h1">`, no una expresión).
|
|
5186
|
+
*/
|
|
5187
|
+
tag = computed(() => this.as(), /* @ts-ignore */
|
|
5188
|
+
...(ngDevMode ? [{ debugName: "tag" }] : /* istanbul ignore next */ []));
|
|
5189
|
+
hostClass() {
|
|
5190
|
+
const classes = [`kf-text--${this.variant()}`];
|
|
5191
|
+
if (this.tone() !== 'neutral') {
|
|
5192
|
+
classes.push(`kf-text--${this.tone()}`);
|
|
5193
|
+
}
|
|
5194
|
+
return classes.join(' ');
|
|
5195
|
+
}
|
|
5196
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Text, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5197
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Text, isStandalone: true, selector: "kf-text", inputs: { as: { classPropertyName: "as", publicName: "as", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
5198
|
+
<!--
|
|
5199
|
+
Una sola proyección compartida (ng-template + ngTemplateOutlet) en vez
|
|
5200
|
+
de un <ng-content> por cada rama del @switch: Angular solo conecta la
|
|
5201
|
+
proyección real del consumidor a la PRIMERA instancia de <ng-content>
|
|
5202
|
+
que encuentra en el árbol de compilación — con un <ng-content> por
|
|
5203
|
+
rama, todas menos una quedan vacías en runtime (bug detectado por
|
|
5204
|
+
Text.spec.ts, no algo documentado a simple vista en los docs de Angular).
|
|
5205
|
+
-->
|
|
5206
|
+
<ng-template #projected><ng-content /></ng-template>
|
|
5207
|
+
@switch (tag()) {
|
|
5208
|
+
@case ('h1') {
|
|
5209
|
+
<h1 [class]="hostClass()"><ng-container [ngTemplateOutlet]="projected" /></h1>
|
|
5210
|
+
}
|
|
5211
|
+
@case ('h2') {
|
|
5212
|
+
<h2 [class]="hostClass()"><ng-container [ngTemplateOutlet]="projected" /></h2>
|
|
5213
|
+
}
|
|
5214
|
+
@case ('h3') {
|
|
5215
|
+
<h3 [class]="hostClass()"><ng-container [ngTemplateOutlet]="projected" /></h3>
|
|
5216
|
+
}
|
|
5217
|
+
@case ('span') {
|
|
5218
|
+
<span [class]="hostClass()"><ng-container [ngTemplateOutlet]="projected" /></span>
|
|
5219
|
+
}
|
|
5220
|
+
@default {
|
|
5221
|
+
<p [class]="hostClass()"><ng-container [ngTemplateOutlet]="projected" /></p>
|
|
5222
|
+
}
|
|
5223
|
+
}
|
|
5224
|
+
`, isInline: true, styles: [":host{display:contents}h1,h2,h3,p,span{margin:0;font-family:var(--kf-font-body);color:var(--kf-color-text)}.kf-text--title-lg{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-lg);font-weight:var(--kf-font-weight-title);color:var(--kf-color-ink)}.kf-text--title-md{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-md);font-weight:var(--kf-font-weight-title);color:var(--kf-color-ink)}.kf-text--title-sm{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-sm);font-weight:var(--kf-font-weight-title);color:var(--kf-color-ink)}.kf-text--body{font-size:var(--kf-font-size-body);font-weight:var(--kf-font-weight-body)}.kf-text--body-muted{font-size:var(--kf-font-size-body);font-weight:var(--kf-font-weight-body);color:var(--kf-color-text-muted)}.kf-text--caption{font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-body);color:var(--kf-color-text-muted)}.kf-text--ok{color:var(--kf-color-success-strong)}.kf-text--warn{color:var(--kf-color-warning-strong)}.kf-text--error{color:var(--kf-color-error-strong)}.kf-text--info{color:var(--kf-color-info-strong)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
5225
|
+
}
|
|
5226
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Text, decorators: [{
|
|
5227
|
+
type: Component,
|
|
5228
|
+
args: [{ selector: 'kf-text', imports: [NgTemplateOutlet], template: `
|
|
5229
|
+
<!--
|
|
5230
|
+
Una sola proyección compartida (ng-template + ngTemplateOutlet) en vez
|
|
5231
|
+
de un <ng-content> por cada rama del @switch: Angular solo conecta la
|
|
5232
|
+
proyección real del consumidor a la PRIMERA instancia de <ng-content>
|
|
5233
|
+
que encuentra en el árbol de compilación — con un <ng-content> por
|
|
5234
|
+
rama, todas menos una quedan vacías en runtime (bug detectado por
|
|
5235
|
+
Text.spec.ts, no algo documentado a simple vista en los docs de Angular).
|
|
5236
|
+
-->
|
|
5237
|
+
<ng-template #projected><ng-content /></ng-template>
|
|
5238
|
+
@switch (tag()) {
|
|
5239
|
+
@case ('h1') {
|
|
5240
|
+
<h1 [class]="hostClass()"><ng-container [ngTemplateOutlet]="projected" /></h1>
|
|
5241
|
+
}
|
|
5242
|
+
@case ('h2') {
|
|
5243
|
+
<h2 [class]="hostClass()"><ng-container [ngTemplateOutlet]="projected" /></h2>
|
|
5244
|
+
}
|
|
5245
|
+
@case ('h3') {
|
|
5246
|
+
<h3 [class]="hostClass()"><ng-container [ngTemplateOutlet]="projected" /></h3>
|
|
5247
|
+
}
|
|
5248
|
+
@case ('span') {
|
|
5249
|
+
<span [class]="hostClass()"><ng-container [ngTemplateOutlet]="projected" /></span>
|
|
5250
|
+
}
|
|
5251
|
+
@default {
|
|
5252
|
+
<p [class]="hostClass()"><ng-container [ngTemplateOutlet]="projected" /></p>
|
|
5253
|
+
}
|
|
5254
|
+
}
|
|
5255
|
+
`, styles: [":host{display:contents}h1,h2,h3,p,span{margin:0;font-family:var(--kf-font-body);color:var(--kf-color-text)}.kf-text--title-lg{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-lg);font-weight:var(--kf-font-weight-title);color:var(--kf-color-ink)}.kf-text--title-md{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-md);font-weight:var(--kf-font-weight-title);color:var(--kf-color-ink)}.kf-text--title-sm{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-sm);font-weight:var(--kf-font-weight-title);color:var(--kf-color-ink)}.kf-text--body{font-size:var(--kf-font-size-body);font-weight:var(--kf-font-weight-body)}.kf-text--body-muted{font-size:var(--kf-font-size-body);font-weight:var(--kf-font-weight-body);color:var(--kf-color-text-muted)}.kf-text--caption{font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-body);color:var(--kf-color-text-muted)}.kf-text--ok{color:var(--kf-color-success-strong)}.kf-text--warn{color:var(--kf-color-warning-strong)}.kf-text--error{color:var(--kf-color-error-strong)}.kf-text--info{color:var(--kf-color-info-strong)}\n"] }]
|
|
5256
|
+
}], propDecorators: { as: [{ type: i0.Input, args: [{ isSignal: true, alias: "as", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }] } });
|
|
5257
|
+
|
|
4512
5258
|
/** Fixed icon per tone (page 20 of the design system) — not configurable per call. */
|
|
4513
5259
|
const TOAST_ICON = {
|
|
4514
5260
|
success: 'check-circle',
|
|
@@ -4858,5 +5604,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
4858
5604
|
* Generated bundle index. Do not edit.
|
|
4859
5605
|
*/
|
|
4860
5606
|
|
|
4861
|
-
export { ActionTile, AdminBadge, Alert, Avatar, Badge, Breadcrumb, Button, Card, Carousel, CarouselSlide, Checkbox, Chip, CompanySelector, ContentSlot, ContentState, DataTable, EmptyState, FeatureCard, Field, FieldLabel, FilterChips, FolderTabs, Icon, Input, MetricCard, Modal, MultiSelect, PageHeader, Pagination, Panel, PortalHeader, ReserveBlock, SectionHeader, Segmented, Select,
|
|
5607
|
+
export { ActionTile, AdminBadge, Alert, Avatar, Badge, Breadcrumb, Button, Card, Carousel, CarouselSlide, Checkbox, Chip, CompanySelector, ContentSlot, ContentState, DataTable, Divider, Dropdown, DropdownItem, DropdownPanel, EmptyState, FeatureCard, Field, FieldLabel, FilterChips, FolderTabs, Icon, Input, Link, MetricCard, Modal, MultiSelect, PageHeader, Pagination, Panel, PortalHeader, ReserveBlock, SectionHeader, Segmented, Select, Skeleton, Spinner, StatTile, StatusPill, Tabs, Text, ToastHost, ToastService, VehicleHeader, ViewToggle };
|
|
4862
5608
|
//# sourceMappingURL=kaufmann-lab-ui.mjs.map
|