@mimi-ng/cli 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/dist/init/css.js +17 -0
- package/dist/init/index.js +7 -5
- package/dist/init/items.js +9 -0
- package/dist/registry.json +222 -1
- package/dist/templates/components/avatar/avatar.ts +1 -1
- package/dist/templates/components/avatar/avatar.variants.ts +4 -4
- package/dist/templates/components/badge/badge.ts +41 -6
- package/dist/templates/components/badge/badge.variants.ts +105 -11
- package/dist/templates/components/button/button.ts +74 -7
- package/dist/templates/components/button/button.variants.ts +145 -21
- package/dist/templates/components/card/card.ts +8 -5
- package/dist/templates/components/checkbox/checkbox.ts +3 -3
- package/dist/templates/components/confirm/confirm-texts.ts +46 -0
- package/dist/templates/components/confirm/confirm.ts +190 -0
- package/dist/templates/components/confirm/index.ts +2 -0
- package/dist/templates/components/context-menu/context-menu.ts +378 -0
- package/dist/templates/components/context-menu/index.ts +14 -0
- package/dist/templates/components/dialog/dialog-texts.ts +41 -0
- package/dist/templates/components/dialog/dialog.ts +701 -0
- package/dist/templates/components/dialog/index.ts +18 -0
- package/dist/templates/components/dropdown-menu/dropdown-menu.ts +252 -0
- package/dist/templates/components/dropdown-menu/index.ts +14 -0
- package/dist/templates/components/form-field/form-error.ts +1 -1
- package/dist/templates/components/form-field/form-field.ts +3 -2
- package/dist/templates/components/input/input.variants.ts +6 -4
- package/dist/templates/components/menu/index.ts +15 -0
- package/dist/templates/components/menu/menu.ts +656 -0
- package/dist/templates/components/pagination/index.ts +2 -0
- package/dist/templates/components/pagination/pagination-page-size.ts +74 -0
- package/dist/templates/components/pagination/pagination-texts.ts +69 -0
- package/dist/templates/components/pagination/pagination.ts +443 -0
- package/dist/templates/components/popover/index.ts +12 -0
- package/dist/templates/components/popover/popover.ts +399 -0
- package/dist/templates/components/select/index.ts +12 -0
- package/dist/templates/components/select/select-texts.ts +62 -0
- package/dist/templates/components/select/select.ts +1085 -0
- package/dist/templates/components/separator/separator.variants.ts +10 -7
- package/dist/templates/components/skeleton/skeleton.ts +4 -1
- package/dist/templates/components/switch/switch.ts +6 -6
- package/dist/templates/components/tabs/index.ts +2 -0
- package/dist/templates/components/tabs/tabs.ts +426 -0
- package/dist/templates/components/textarea/textarea.variants.ts +14 -11
- package/dist/templates/components/toast/index.ts +3 -0
- package/dist/templates/components/toast/toast-config.ts +45 -0
- package/dist/templates/components/toast/toast-texts.ts +46 -0
- package/dist/templates/components/toast/toast.ts +1000 -0
- package/dist/templates/components/toolbar/index.ts +1 -0
- package/dist/templates/components/toolbar/toolbar.ts +377 -0
- package/dist/templates/components/tooltip/index.ts +7 -0
- package/dist/templates/components/tooltip/tooltip.ts +407 -0
- package/dist/templates/theme/provider.ts +62 -6
- package/dist/templates/theme/theme-base.css +307 -9
- package/dist/templates/theme/types.ts +278 -4
- package/dist/templates/utils/cn.ts +15 -1
- package/dist/templates/utils/control-styles.ts +2 -2
- package/dist/templates/utils/overlay.ts +140 -0
- package/dist/ui/index.js +80 -8
- package/dist/ui/schema.json +44 -0
- package/dist/utils/write-files.js +156 -59
- package/package.json +1 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Preset tipado del tema (spec 6.3). Cada propiedad se convierte en una variable --mimi-*
|
|
3
|
-
* de theme-base.css. Los derivados con color-mix (primary-hover, ring-soft, switch-off
|
|
4
|
-
* no están aquí: se recalculan solos a partir de los
|
|
3
|
+
* de theme-base.css. Los derivados con color-mix (primary-hover, ring-soft, switch-off y los
|
|
4
|
+
* <tono>-soft, <tono>-hover y <tono>-ring) no están aquí: se recalculan solos a partir de los
|
|
5
|
+
* colores.
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
/** Colores. `colors` se aplica en claro y `darkColors` en oscuro. */
|
|
@@ -25,9 +26,29 @@ export interface MimiColorTokens {
|
|
|
25
26
|
border?: string;
|
|
26
27
|
input?: string;
|
|
27
28
|
inputBackground?: string;
|
|
29
|
+
/** Borde de un campo con el puntero encima (por defecto, mezcla de foreground e input). */
|
|
30
|
+
inputHover?: string;
|
|
28
31
|
ring?: string;
|
|
29
32
|
/** Fondo que oscurece la página detrás de paneles y diálogos. */
|
|
30
33
|
overlay?: string;
|
|
34
|
+
success?: string;
|
|
35
|
+
successForeground?: string;
|
|
36
|
+
/** Texto sobre el fondo suave de success. */
|
|
37
|
+
successSoftForeground?: string;
|
|
38
|
+
warning?: string;
|
|
39
|
+
warningForeground?: string;
|
|
40
|
+
warningSoftForeground?: string;
|
|
41
|
+
info?: string;
|
|
42
|
+
infoForeground?: string;
|
|
43
|
+
infoSoftForeground?: string;
|
|
44
|
+
destructiveSoftForeground?: string;
|
|
45
|
+
/** Cuánto tono lleva cada fondo suave (-soft), en porcentaje: '12%'. */
|
|
46
|
+
softMix?: string;
|
|
47
|
+
tooltip?: string;
|
|
48
|
+
tooltipForeground?: string;
|
|
49
|
+
/** Fondo translúcido de las píldoras flotantes (mimi-toolbar, Pagination). */
|
|
50
|
+
glass?: string;
|
|
51
|
+
glassBorder?: string;
|
|
31
52
|
}
|
|
32
53
|
|
|
33
54
|
/** Sombras (`box-shadow` completo). `shadows` en claro y `darkShadows` en oscuro. */
|
|
@@ -41,12 +62,28 @@ export interface MimiShadowTokens {
|
|
|
41
62
|
neutralHover?: string;
|
|
42
63
|
/** Pulgar del Switch. */
|
|
43
64
|
thumb?: string;
|
|
65
|
+
success?: string;
|
|
66
|
+
successHover?: string;
|
|
67
|
+
warning?: string;
|
|
68
|
+
warningHover?: string;
|
|
69
|
+
info?: string;
|
|
70
|
+
infoHover?: string;
|
|
71
|
+
/** Menús, diálogos, toasts y píldoras flotantes. */
|
|
72
|
+
popover?: string;
|
|
73
|
+
/** Glow (opción glow): van a --mimi-glow y --mimi-glow-<tono>, sin el prefijo shadow-. */
|
|
74
|
+
glow?: string;
|
|
75
|
+
glowPrimary?: string;
|
|
76
|
+
glowSuccess?: string;
|
|
77
|
+
glowWarning?: string;
|
|
78
|
+
glowInfo?: string;
|
|
79
|
+
glowDestructive?: string;
|
|
44
80
|
}
|
|
45
81
|
|
|
46
82
|
/** Radios fijos. Si no se definen, sm y card se calculan a partir de `radius`. */
|
|
47
83
|
export interface MimiRadiusTokens {
|
|
48
84
|
sm?: string;
|
|
49
85
|
card?: string;
|
|
86
|
+
/** @deprecated Usa components.badge.radius (la misma variable). Sigue hasta la 1.0. */
|
|
50
87
|
badge?: string;
|
|
51
88
|
}
|
|
52
89
|
|
|
@@ -71,9 +108,41 @@ export interface MimiControlSizeTokens {
|
|
|
71
108
|
heightLg?: string;
|
|
72
109
|
}
|
|
73
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Tokens compartidos por todos los controles (spec 13, nivel 2). Las alturas van a
|
|
113
|
+
* --mimi-control-height*; el resto, sin prefijo: focusRing → --mimi-focus-ring.
|
|
114
|
+
*/
|
|
115
|
+
export interface MimiSharedTokens extends MimiControlSizeTokens {
|
|
116
|
+
/** Halo de foco en campos y botones (box-shadow). */
|
|
117
|
+
focusRing?: string;
|
|
118
|
+
/** Contorno de foco con teclado (outline). */
|
|
119
|
+
focusOutline?: string;
|
|
120
|
+
focusOffset?: string;
|
|
121
|
+
disabledOpacity?: string | number;
|
|
122
|
+
iconSize?: string;
|
|
123
|
+
iconSizeSm?: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Efectos que no son movimiento ni controles: desenfoques (y, más adelante, los de Mimi
|
|
128
|
+
* Effects). Iguales en claro y oscuro.
|
|
129
|
+
*/
|
|
130
|
+
export interface MimiEffectTokens {
|
|
131
|
+
/** Desenfoque del fondo detrás de Dialog y Sheet. */
|
|
132
|
+
overlayBlur?: string;
|
|
133
|
+
/** Desenfoque de las píldoras translúcidas. */
|
|
134
|
+
glassBlur?: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
74
137
|
/** Tokens por componente. Cada componente los lee con la cascada de la spec 6.2. */
|
|
75
138
|
export interface MimiControlTokens extends MimiControlSizeTokens {
|
|
76
139
|
radius?: string;
|
|
140
|
+
/** Padding horizontal del tamaño default: --mimi-<prefijo>-px. */
|
|
141
|
+
px?: string;
|
|
142
|
+
/**
|
|
143
|
+
* @deprecated Nombre de la 0.1.0 (--mimi-<prefijo>-padding-x): usa `px`. Sigue funcionando
|
|
144
|
+
* hasta la 1.0 (spec 12).
|
|
145
|
+
*/
|
|
77
146
|
paddingX?: string;
|
|
78
147
|
fontSize?: string;
|
|
79
148
|
borderWidth?: string;
|
|
@@ -82,11 +151,19 @@ export interface MimiControlTokens extends MimiControlSizeTokens {
|
|
|
82
151
|
|
|
83
152
|
/** paddingX y fontSize se aplican al tamaño default; sm y lg usan los valores del diseño. */
|
|
84
153
|
export interface MimiButtonTokens extends MimiControlTokens {
|
|
154
|
+
/** Espacio entre ícono y texto del tamaño default. */
|
|
155
|
+
gap?: string;
|
|
156
|
+
/** Escala al presionar; si no, --mimi-press-scale. Con movimiento reducido vale 1. */
|
|
157
|
+
pressScale?: string | number;
|
|
85
158
|
fontWeight?: string | number;
|
|
86
159
|
letterSpacing?: string;
|
|
87
160
|
}
|
|
88
161
|
|
|
89
162
|
export interface MimiInputTokens extends MimiControlTokens {
|
|
163
|
+
/**
|
|
164
|
+
* @deprecated Es un color: cámbialo en el CSS con --mimi-input-placeholder (spec 6.2). Sigue
|
|
165
|
+
* funcionando hasta la 1.0.
|
|
166
|
+
*/
|
|
90
167
|
placeholderColor?: string;
|
|
91
168
|
disabledOpacity?: string | number;
|
|
92
169
|
}
|
|
@@ -95,16 +172,212 @@ export interface MimiCardTokens {
|
|
|
95
172
|
radius?: string;
|
|
96
173
|
borderWidth?: string;
|
|
97
174
|
shadow?: string;
|
|
175
|
+
/** Padding exterior de las partes (1.5rem); los paddingHeader/Content/Footer lo detallan. */
|
|
176
|
+
padding?: string;
|
|
98
177
|
paddingHeader?: string;
|
|
99
178
|
paddingContent?: string;
|
|
100
179
|
paddingFooter?: string;
|
|
101
180
|
}
|
|
102
181
|
|
|
182
|
+
export interface MimiAvatarTokens {
|
|
183
|
+
size?: string;
|
|
184
|
+
sizeSm?: string;
|
|
185
|
+
sizeLg?: string;
|
|
186
|
+
radius?: string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface MimiSwitchTokens {
|
|
190
|
+
/** Ancho de la pista. El pulgar se desplaza ancho − alto. */
|
|
191
|
+
width?: string;
|
|
192
|
+
/** Alto de la pista. El pulgar mide alto − 4px. */
|
|
193
|
+
height?: string;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface MimiCheckboxTokens {
|
|
197
|
+
size?: string;
|
|
198
|
+
radius?: string;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** FormField (prefijo field). */
|
|
202
|
+
export interface MimiFieldTokens {
|
|
203
|
+
gap?: string;
|
|
204
|
+
labelSize?: string;
|
|
205
|
+
labelWeight?: string | number;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface MimiSeparatorTokens {
|
|
209
|
+
/** Grosor de la línea. */
|
|
210
|
+
size?: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface MimiSkeletonTokens {
|
|
214
|
+
radius?: string;
|
|
215
|
+
/** Duración del pulso: '1.6s'. */
|
|
216
|
+
duration?: string;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export interface MimiBadgeTokens {
|
|
220
|
+
height?: string;
|
|
221
|
+
px?: string;
|
|
222
|
+
fontSize?: string;
|
|
223
|
+
fontWeight?: string | number;
|
|
224
|
+
/** --mimi-badge-radius (el mismo que radii.badge de la 0.1.0). */
|
|
225
|
+
radius?: string;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** Textarea: si no se definen, usa los de Input y después los compartidos. */
|
|
229
|
+
export interface MimiTextareaTokens {
|
|
230
|
+
radius?: string;
|
|
231
|
+
minHeight?: string;
|
|
232
|
+
lineHeight?: string;
|
|
233
|
+
py?: string;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Popover. Fondo, borde y sombra van en el CSS (`--mimi-popover-bg`, `-border`, `-shadow`). */
|
|
237
|
+
export interface MimiPopoverTokens {
|
|
238
|
+
radius?: string;
|
|
239
|
+
/** Padding del panel (16px). */
|
|
240
|
+
padding?: string;
|
|
241
|
+
/** Lado de la flecha (10px). */
|
|
242
|
+
arrow?: string;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Tooltip. Fondo y texto van en el CSS (`--mimi-tooltip-bg`, `--mimi-tooltip-fg`). */
|
|
246
|
+
export interface MimiTooltipTokens {
|
|
247
|
+
radius?: string;
|
|
248
|
+
fontSize?: string;
|
|
249
|
+
/** Lado de la flecha (8px). */
|
|
250
|
+
arrow?: string;
|
|
251
|
+
/** Retraso al abrir (300ms). `mimiTooltipDelay` lo cambia en un tooltip. */
|
|
252
|
+
delay?: string;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Dropdown Menu y Context Menu. Fondo, borde, sombra, hover, atajo y tono de peligro van en el CSS
|
|
257
|
+
* (`--mimi-menu-bg`, `-border`, `-shadow`, `-item-hover`, `-shortcut`, `-danger`, `-danger-hover`).
|
|
258
|
+
*/
|
|
259
|
+
export interface MimiMenuTokens {
|
|
260
|
+
radius?: string;
|
|
261
|
+
/** Ancho del panel (240px). */
|
|
262
|
+
width?: string;
|
|
263
|
+
/** Alto de cada ítem (32px). */
|
|
264
|
+
itemHeight?: string;
|
|
265
|
+
itemRadius?: string;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Select. Fondos, borde, sombra y opción activa van en el CSS (`--mimi-select-trigger-bg`,
|
|
270
|
+
* `-border`, `-menu-bg`, `-menu-shadow`, `-option-hover`).
|
|
271
|
+
*/
|
|
272
|
+
export interface MimiSelectTokens {
|
|
273
|
+
/** Radio del disparador y del panel. */
|
|
274
|
+
radius?: string;
|
|
275
|
+
/** Alto del disparador (el de los controles). */
|
|
276
|
+
height?: string;
|
|
277
|
+
/** Alto de cada opción (34px). */
|
|
278
|
+
optionHeight?: string;
|
|
279
|
+
optionRadius?: string;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Dialog. El fondo oscurecido, el fondo del panel y la sombra van en el CSS
|
|
284
|
+
* (`--mimi-dialog-overlay`, `-bg`, `-shadow`).
|
|
285
|
+
*/
|
|
286
|
+
export interface MimiDialogTokens {
|
|
287
|
+
radius?: string;
|
|
288
|
+
/** Ancho del panel (420px). */
|
|
289
|
+
width?: string;
|
|
290
|
+
/** Relleno a los lados del encabezado, el cuerpo y el pie (24px). */
|
|
291
|
+
padding?: string;
|
|
292
|
+
/** Tamaño de la X (32px). */
|
|
293
|
+
closeSize?: string;
|
|
294
|
+
/** Desenfoque del fondo (el global `effects.overlayBlur`). */
|
|
295
|
+
overlayBlur?: string;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Confirm. Los colores del círculo del tono danger van en el CSS (`--mimi-confirm-icon-bg`,
|
|
300
|
+
* `-icon-fg`).
|
|
301
|
+
*/
|
|
302
|
+
export interface MimiConfirmTokens {
|
|
303
|
+
/** Ancho del panel (380px). */
|
|
304
|
+
width?: string;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Toast. El fondo, el borde y la sombra van en el CSS (`--mimi-toast-bg`, `-border`, `-shadow`).
|
|
309
|
+
*/
|
|
310
|
+
export interface MimiToastTokens {
|
|
311
|
+
radius?: string;
|
|
312
|
+
/** Ancho de la pila (340px). */
|
|
313
|
+
width?: string;
|
|
314
|
+
/** Separación de la pila con el borde de la pantalla (16px). */
|
|
315
|
+
offset?: string;
|
|
316
|
+
/** Cuánto asoma cada toast de atrás con la pila colapsada (12px). */
|
|
317
|
+
stackGap?: string;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Tabs. Los colores (pestañas, indicador y píldora) van en el CSS (`--mimi-tabs-fg`,
|
|
322
|
+
* `-active-fg`, `-indicator`, `-pill-bg`, `-pill-active`).
|
|
323
|
+
*/
|
|
324
|
+
export interface MimiTabsTokens {
|
|
325
|
+
/** Alto de las pestañas subrayadas (44px). */
|
|
326
|
+
height?: string;
|
|
327
|
+
/** Curva del indicador (`cubic-bezier(.3, 1.35, .5, 1)`). */
|
|
328
|
+
spring?: string;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* mimi-toolbar. Fondo, borde, sombra, disco activo, anillo y presionado van en el CSS
|
|
333
|
+
* (`--mimi-toolbar-bg`, `-border`, `-shadow`, `-active-bg`, `-active-fg`, `-ring`, `-pressed-bg`).
|
|
334
|
+
*/
|
|
335
|
+
export interface MimiToolbarTokens {
|
|
336
|
+
/** Tamaño de cada botón (40px). */
|
|
337
|
+
itemSize?: string;
|
|
338
|
+
/** Desenfoque del fondo (el global `effects.glassBlur`). */
|
|
339
|
+
blur?: string;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Pagination. Fondo, borde, sombra flotante y error van en el CSS (`--mimi-pagination-bg`,
|
|
344
|
+
* `-border`, `-shadow`, `-error`).
|
|
345
|
+
*/
|
|
346
|
+
export interface MimiPaginationTokens {
|
|
347
|
+
/** Tamaño de ← y → y alto del selector (el alto de control: sm 32px, md 40px). */
|
|
348
|
+
itemSize?: string;
|
|
349
|
+
/** Ancho del campo de página (sm 44px, md 52px). */
|
|
350
|
+
inputWidth?: string;
|
|
351
|
+
/** Desenfoque del fondo (el global `effects.glassBlur`). */
|
|
352
|
+
blur?: string;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Tokens por componente (spec 13). Solo los que no dependen del modo: los colores de los
|
|
357
|
+
* componentes (`--mimi-<prefijo>-bg`, `-fg`, `-border`…) se cambian en el CSS (spec 6.2).
|
|
358
|
+
*/
|
|
103
359
|
export interface MimiComponentTokens {
|
|
104
360
|
button?: MimiButtonTokens;
|
|
105
361
|
input?: MimiInputTokens;
|
|
106
362
|
card?: MimiCardTokens;
|
|
107
|
-
|
|
363
|
+
avatar?: MimiAvatarTokens;
|
|
364
|
+
switch?: MimiSwitchTokens;
|
|
365
|
+
checkbox?: MimiCheckboxTokens;
|
|
366
|
+
formField?: MimiFieldTokens;
|
|
367
|
+
separator?: MimiSeparatorTokens;
|
|
368
|
+
skeleton?: MimiSkeletonTokens;
|
|
369
|
+
badge?: MimiBadgeTokens;
|
|
370
|
+
textarea?: MimiTextareaTokens;
|
|
371
|
+
popover?: MimiPopoverTokens;
|
|
372
|
+
tooltip?: MimiTooltipTokens;
|
|
373
|
+
menu?: MimiMenuTokens;
|
|
374
|
+
select?: MimiSelectTokens;
|
|
375
|
+
dialog?: MimiDialogTokens;
|
|
376
|
+
confirm?: MimiConfirmTokens;
|
|
377
|
+
toast?: MimiToastTokens;
|
|
378
|
+
tabs?: MimiTabsTokens;
|
|
379
|
+
toolbar?: MimiToolbarTokens;
|
|
380
|
+
pagination?: MimiPaginationTokens;
|
|
108
381
|
}
|
|
109
382
|
|
|
110
383
|
export interface MimiThemePreset {
|
|
@@ -119,6 +392,7 @@ export interface MimiThemePreset {
|
|
|
119
392
|
darkShadows?: MimiShadowTokens;
|
|
120
393
|
fonts?: MimiFontTokens;
|
|
121
394
|
motion?: MimiMotionTokens;
|
|
122
|
-
|
|
395
|
+
effects?: MimiEffectTokens;
|
|
396
|
+
controls?: MimiSharedTokens;
|
|
123
397
|
components?: MimiComponentTokens;
|
|
124
398
|
}
|
|
@@ -5,7 +5,7 @@ import { extendTailwindMerge } from 'tailwind-merge';
|
|
|
5
5
|
* tailwind-merge solo reconoce tallas (sm, md, lg…) en las escalas de sombra y radio.
|
|
6
6
|
* Sin registrar los tokens de Mimi, `shadow-card` se tomaría como color de sombra y
|
|
7
7
|
* `rounded-card` no se fusionaría con otros `rounded-*`; lo mismo `animate-mimi-pulse` con
|
|
8
|
-
* `animate-none
|
|
8
|
+
* `animate-none` y `backdrop-blur-glass` con otros `backdrop-blur-*`. Los colores no hace falta registrarlos: la escala de color acepta cualquier
|
|
9
9
|
* nombre.
|
|
10
10
|
*/
|
|
11
11
|
const twMerge = extendTailwindMerge({
|
|
@@ -20,8 +20,22 @@ const twMerge = extendTailwindMerge({
|
|
|
20
20
|
'neutral',
|
|
21
21
|
'neutral-hover',
|
|
22
22
|
'thumb',
|
|
23
|
+
'success',
|
|
24
|
+
'success-hover',
|
|
25
|
+
'warning',
|
|
26
|
+
'warning-hover',
|
|
27
|
+
'info',
|
|
28
|
+
'info-hover',
|
|
29
|
+
'popover',
|
|
30
|
+
'glow',
|
|
31
|
+
'glow-primary',
|
|
32
|
+
'glow-success',
|
|
33
|
+
'glow-warning',
|
|
34
|
+
'glow-info',
|
|
35
|
+
'glow-destructive',
|
|
23
36
|
],
|
|
24
37
|
radius: ['card', 'badge'],
|
|
38
|
+
blur: ['glass', 'overlay'],
|
|
25
39
|
animate: ['mimi-pulse'],
|
|
26
40
|
},
|
|
27
41
|
classGroups: {
|
|
@@ -19,9 +19,9 @@ export const fieldFocusStyles =
|
|
|
19
19
|
export const controlDisabledStyles =
|
|
20
20
|
'disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50';
|
|
21
21
|
|
|
22
|
-
/** Inválido: borde destructive fijo y halo destructive-
|
|
22
|
+
/** Inválido: borde destructive fijo y halo destructive-ring solo al enfocar. */
|
|
23
23
|
export const controlInvalidStyles =
|
|
24
|
-
'aria-invalid:border-destructive aria-invalid:focus-visible:border-destructive aria-invalid:focus-visible:ring-destructive-
|
|
24
|
+
'aria-invalid:border-destructive aria-invalid:focus-visible:border-destructive aria-invalid:focus-visible:ring-destructive-ring';
|
|
25
25
|
|
|
26
26
|
/** Transición y escala al hacer clic. Solo botones. */
|
|
27
27
|
export const controlPressStyles = 'mimi-transition active:scale-(--mimi-press-scale)';
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { ConnectedPosition } from '@angular/cdk/overlay';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Posición, flecha y animación compartidas por los overlays de Mimi (Popover, Tooltip…). Usa
|
|
5
|
+
* tipos de @angular/cdk/overlay: impórtalo siempre con su archivo concreto
|
|
6
|
+
* (`@/components/ui/utils/overlay`), nunca desde el índice de utils, que no lo reexporta para no
|
|
7
|
+
* arrastrar el CDK a quien no lo usa.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type MimiOverlaySide = 'top' | 'right' | 'bottom' | 'left';
|
|
11
|
+
export type MimiOverlayAlign = 'start' | 'center' | 'end';
|
|
12
|
+
|
|
13
|
+
/** Distancia mínima de un overlay al borde de la pantalla (no está en el diseño: spec 13, plan D6). */
|
|
14
|
+
export const MIMI_VIEWPORT_MARGIN = 8;
|
|
15
|
+
|
|
16
|
+
const OPPOSITE: Record<MimiOverlaySide, MimiOverlaySide> = {
|
|
17
|
+
top: 'bottom',
|
|
18
|
+
bottom: 'top',
|
|
19
|
+
left: 'right',
|
|
20
|
+
right: 'left',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function connectedPosition(
|
|
24
|
+
side: MimiOverlaySide,
|
|
25
|
+
align: MimiOverlayAlign,
|
|
26
|
+
offset: number,
|
|
27
|
+
): ConnectedPosition {
|
|
28
|
+
if (side === 'top' || side === 'bottom') {
|
|
29
|
+
return side === 'bottom'
|
|
30
|
+
? { originX: align, originY: 'bottom', overlayX: align, overlayY: 'top', offsetY: offset }
|
|
31
|
+
: { originX: align, originY: 'top', overlayX: align, overlayY: 'bottom', offsetY: -offset };
|
|
32
|
+
}
|
|
33
|
+
const y = align === 'start' ? 'top' : align === 'end' ? 'bottom' : 'center';
|
|
34
|
+
return side === 'right'
|
|
35
|
+
? { originX: 'end', originY: y, overlayX: 'start', overlayY: y, offsetX: offset }
|
|
36
|
+
: { originX: 'start', originY: y, overlayX: 'end', overlayY: y, offsetX: -offset };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Posiciones para el CDK, en orden de preferencia: el lado y la alineación pedidos, el lado
|
|
41
|
+
* opuesto y, por último, los otros dos lados centrados. `offset` es la separación con el trigger.
|
|
42
|
+
*/
|
|
43
|
+
export function mimiConnectedPositions(
|
|
44
|
+
side: MimiOverlaySide,
|
|
45
|
+
align: MimiOverlayAlign,
|
|
46
|
+
offset: number,
|
|
47
|
+
): ConnectedPosition[] {
|
|
48
|
+
const others: MimiOverlaySide[] =
|
|
49
|
+
side === 'top' || side === 'bottom' ? ['right', 'left'] : ['bottom', 'top'];
|
|
50
|
+
return [
|
|
51
|
+
connectedPosition(side, align, offset),
|
|
52
|
+
connectedPosition(OPPOSITE[side], align, offset),
|
|
53
|
+
...others.map((other) => connectedPosition(other, 'center', offset)),
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Posiciones para abrir en un punto (el puntero, en Context Menu): la esquina superior izquierda
|
|
59
|
+
* del panel en el punto; si no cabe, se voltea a la izquierda del punto, hacia arriba o ambas.
|
|
60
|
+
*/
|
|
61
|
+
export function mimiPointPositions(): ConnectedPosition[] {
|
|
62
|
+
return [
|
|
63
|
+
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'top' },
|
|
64
|
+
{ originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top' },
|
|
65
|
+
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' },
|
|
66
|
+
{ originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'bottom' },
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Lado en el que quedó el overlay, según la posición que eligió el CDK. */
|
|
71
|
+
export function mimiPlacedSide({
|
|
72
|
+
originX,
|
|
73
|
+
originY,
|
|
74
|
+
overlayX,
|
|
75
|
+
overlayY,
|
|
76
|
+
}: ConnectedPosition): MimiOverlaySide {
|
|
77
|
+
if (originY === 'bottom' && overlayY === 'top') return 'bottom';
|
|
78
|
+
if (originY === 'top' && overlayY === 'bottom') return 'top';
|
|
79
|
+
return originX === 'end' && overlayX === 'start' ? 'right' : 'left';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Dónde va la flecha para que apunte al centro del trigger: distancia desde el borde del panel
|
|
84
|
+
* (izquierdo arriba/abajo, superior a los lados), dentro del panel. null si aún no hay medidas.
|
|
85
|
+
*/
|
|
86
|
+
export function mimiArrowOffset(
|
|
87
|
+
trigger: DOMRect,
|
|
88
|
+
panel: DOMRect,
|
|
89
|
+
side: MimiOverlaySide,
|
|
90
|
+
): string | null {
|
|
91
|
+
if (panel.width === 0 || panel.height === 0) return null;
|
|
92
|
+
const vertical = side === 'top' || side === 'bottom';
|
|
93
|
+
const offset = vertical
|
|
94
|
+
? trigger.left + trigger.width / 2 - panel.left
|
|
95
|
+
: trigger.top + trigger.height / 2 - panel.top;
|
|
96
|
+
const size = vertical ? panel.width : panel.height;
|
|
97
|
+
return `${Math.min(Math.max(offset, 0), size)}px`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Entrada y salida de los overlays, para el `styles` del componente. Valores de
|
|
102
|
+
* --mimi-transition (spec 6.6): 0.15s cubic-bezier(.2,.8,.2,1), escala desde --mimi-press-scale.
|
|
103
|
+
* Sin animación con movimiento reducido. El panel lleva `data-mimi-overlay-panel` y `data-state`.
|
|
104
|
+
*/
|
|
105
|
+
export const MIMI_OVERLAY_ANIMATION = `
|
|
106
|
+
@keyframes mimi-overlay-in {
|
|
107
|
+
from {
|
|
108
|
+
opacity: 0;
|
|
109
|
+
scale: var(--mimi-press-scale);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
@keyframes mimi-overlay-out {
|
|
113
|
+
to {
|
|
114
|
+
opacity: 0;
|
|
115
|
+
scale: var(--mimi-press-scale);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
[data-mimi-overlay-panel][data-state='open'] {
|
|
119
|
+
animation: mimi-overlay-in 0.15s cubic-bezier(0.2, 0.8, 0.2, 1);
|
|
120
|
+
}
|
|
121
|
+
[data-mimi-overlay-panel][data-state='closed'] {
|
|
122
|
+
animation: mimi-overlay-out 0.15s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
|
|
123
|
+
}
|
|
124
|
+
@media (prefers-reduced-motion: reduce) {
|
|
125
|
+
[data-mimi-overlay-panel] {
|
|
126
|
+
animation: none !important;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
`;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Se resuelve cuando terminan las animaciones del elemento (la de salida). Sin animaciones
|
|
133
|
+
* (movimiento reducido, o un entorno sin Web Animations), enseguida.
|
|
134
|
+
*/
|
|
135
|
+
export function mimiWaitForExit(element: HTMLElement | undefined): Promise<void> {
|
|
136
|
+
const animations = element?.getAnimations?.() ?? [];
|
|
137
|
+
return Promise.allSettled(animations.map((animation) => animation.finished)).then(
|
|
138
|
+
() => undefined,
|
|
139
|
+
);
|
|
140
|
+
}
|