shared-lib-angular 1.0.36 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/shared-lib-angular.mjs +307 -446
- package/fesm2022/shared-lib-angular.mjs.map +1 -1
- package/index.d.ts +74 -114
- package/package.json +1 -1
- package/src/assets/icons/material-symbols.css +20 -0
- package/src/lib/styles/_tokens.scss +70 -4
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { OnInit, OnDestroy } from '@angular/core';
|
|
3
3
|
import { AuthConfig, OAuthService } from 'angular-oauth2-oidc';
|
|
4
4
|
import * as rxjs from 'rxjs';
|
|
5
5
|
import { Observable } from 'rxjs';
|
|
@@ -10,14 +10,14 @@ import { HttpClient } from '@angular/common/http';
|
|
|
10
10
|
* Versión actual de la librería @dinafi/frmk
|
|
11
11
|
* Sincronizada con package.json
|
|
12
12
|
*/
|
|
13
|
-
declare const VERSION = "
|
|
13
|
+
declare const VERSION = "2.0.1";
|
|
14
14
|
/**
|
|
15
15
|
* Información completa de la versión
|
|
16
16
|
*/
|
|
17
17
|
declare const VERSION_INFO: {
|
|
18
|
-
readonly version: "
|
|
18
|
+
readonly version: "2.0.1";
|
|
19
19
|
readonly name: "shared-lib-angular";
|
|
20
|
-
readonly buildDate: "2026-02-
|
|
20
|
+
readonly buildDate: "2026-02-05T20:39:22.686Z";
|
|
21
21
|
readonly angular: "^20.0.0";
|
|
22
22
|
};
|
|
23
23
|
|
|
@@ -196,8 +196,9 @@ interface MenuHierarchyRequest {
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
/**
|
|
199
|
-
* Configuración de la librería que debe ser proporcionada por la aplicación consumidora
|
|
199
|
+
* Configuración de la librería que debe ser proporcionada por la aplicación consumidora.
|
|
200
200
|
* Estos valores son críticos y deben ser configurados al inicializar la librería
|
|
201
|
+
* mediante `FrmkConfigStore.initialize()` en el APP_INITIALIZER.
|
|
201
202
|
*/
|
|
202
203
|
interface FrmkLibraryConfig {
|
|
203
204
|
/**
|
|
@@ -251,120 +252,76 @@ interface FrmkLibraryConfig {
|
|
|
251
252
|
* Configuración por defecto de la librería
|
|
252
253
|
*/
|
|
253
254
|
declare const DEFAULT_LIBRARY_CONFIG: Partial<FrmkLibraryConfig>;
|
|
255
|
+
|
|
254
256
|
/**
|
|
255
|
-
*
|
|
257
|
+
* Store centralizado de configuración del framework.
|
|
256
258
|
*
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
* providers: [
|
|
260
|
-
* {
|
|
261
|
-
* provide: FRMK_LIBRARY_CONFIG,
|
|
262
|
-
* useValue: {
|
|
263
|
-
* configServerHost: 'config-server.miempresa.com',
|
|
264
|
-
* frontendId: 'mi-aplicacion-frontend',
|
|
265
|
-
* production: environment.production
|
|
266
|
-
* }
|
|
267
|
-
* }
|
|
268
|
-
* ]
|
|
269
|
-
*/
|
|
270
|
-
declare const FRMK_LIBRARY_CONFIG: InjectionToken<FrmkLibraryConfig>;
|
|
271
|
-
/**
|
|
272
|
-
* Función helper para crear la configuración de la librería
|
|
259
|
+
* Reemplaza las variables globales mutables (`currentAppConfig`, `libraryConfig`)
|
|
260
|
+
* con un servicio inyectable basado en signals de Angular.
|
|
273
261
|
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
262
|
+
* Ciclo de vida:
|
|
263
|
+
* 1. `initialize(config)` — llamado en APP_INITIALIZER con FrmkLibraryConfig
|
|
264
|
+
* 2. `applyServerConfig(data)` — llamado por ConfigService tras obtener datos del Config Server
|
|
277
265
|
*
|
|
278
|
-
*
|
|
279
|
-
* providers: [
|
|
280
|
-
* provideFrmkConfig({
|
|
281
|
-
* configServerHost: environment.configServerHost,
|
|
282
|
-
* frontendId: 'mi-aplicacion'
|
|
283
|
-
* })
|
|
284
|
-
* ]
|
|
285
|
-
* };
|
|
286
|
-
*/
|
|
287
|
-
declare function provideFrmkConfig(config: FrmkLibraryConfig): {
|
|
288
|
-
provide: InjectionToken<FrmkLibraryConfig>;
|
|
289
|
-
useValue: {
|
|
290
|
-
/**
|
|
291
|
-
* URL del servidor de configuración (Config Server)
|
|
292
|
-
* Ejemplo: 'config-server.example.com' o 'localhost:8080'
|
|
293
|
-
*/
|
|
294
|
-
configServerHost: string;
|
|
295
|
-
/**
|
|
296
|
-
* Identificador del frontend en el Config Server
|
|
297
|
-
* Este valor identifica la aplicación para obtener su configuración específica
|
|
298
|
-
* Ejemplo: 'mi-aplicacion-frontend'
|
|
299
|
-
*/
|
|
300
|
-
frontendId: string;
|
|
301
|
-
configServicePath?: string;
|
|
302
|
-
realm?: string;
|
|
303
|
-
production?: boolean;
|
|
304
|
-
requireHttps?: boolean;
|
|
305
|
-
showDebugInformation?: boolean;
|
|
306
|
-
loginConfig?: Partial<LoginConfig>;
|
|
307
|
-
dashboardConfig?: Partial<DashboardConfig>;
|
|
308
|
-
};
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Inicializa la configuración de la librería con los valores proporcionados por la aplicación
|
|
313
|
-
* Esta función debe ser llamada antes de usar cualquier servicio de la librería
|
|
266
|
+
* Todas las propiedades computadas lanzan error si se leen antes de `initialize()`.
|
|
314
267
|
*
|
|
315
|
-
* @
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*/
|
|
322
|
-
declare function getLibraryConfig(): FrmkLibraryConfig;
|
|
323
|
-
/**
|
|
324
|
-
* Verifica si la librería ha sido configurada
|
|
325
|
-
*/
|
|
326
|
-
declare function isLibraryConfigured(): boolean;
|
|
327
|
-
/**
|
|
328
|
-
* Obtiene la configuración del componente Login
|
|
329
|
-
* Combina los valores por defecto con los configurados en la librería
|
|
330
|
-
*/
|
|
331
|
-
declare function getLoginConfig(): LoginConfig;
|
|
332
|
-
/**
|
|
333
|
-
* Obtiene la configuración del componente Dashboard
|
|
334
|
-
* Combina los valores por defecto con los configurados en la librería
|
|
335
|
-
*/
|
|
336
|
-
declare function getDashboardConfig(): DashboardConfig;
|
|
337
|
-
declare function getDefaultAppConfig(): AppConfiguration;
|
|
338
|
-
declare function mapConfigServerResponse(configServerData: ConfigServerResponse): Partial<AppConfiguration>;
|
|
339
|
-
/**
|
|
340
|
-
* Función para establecer la configuración actual con datos del config server
|
|
341
|
-
* Esta función debe ser llamada desde el ConfigService después de cargar la configuración
|
|
342
|
-
*/
|
|
343
|
-
declare function setCurrentAppConfig(configServerData?: ConfigServerResponse): void;
|
|
344
|
-
/**
|
|
345
|
-
* Función para obtener la configuración actual
|
|
346
|
-
* Si no se ha establecido una configuración, devuelve la configuración por defecto
|
|
347
|
-
*/
|
|
348
|
-
declare function getCurrentAppConfig(): AppConfiguration;
|
|
349
|
-
declare function getAppConfig(): AppConfiguration;
|
|
350
|
-
declare function getAppConfigWithServerData(configServerData?: ConfigServerResponse): AppConfiguration;
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Función para obtener la configuración de autenticación actual
|
|
354
|
-
* Esta función se evalúa cada vez que se llama, por lo que siempre tendrá la configuración más reciente
|
|
268
|
+
* @example
|
|
269
|
+
* // En APP_INITIALIZER:
|
|
270
|
+
* const store = inject(FrmkConfigStore);
|
|
271
|
+
* store.initialize(myLibraryConfig);
|
|
272
|
+
* await configService.loadConfig(); // internamente llama store.applyServerConfig()
|
|
273
|
+
* authService.initializeAuth(store.authConfig());
|
|
355
274
|
*/
|
|
356
|
-
declare
|
|
357
|
-
|
|
275
|
+
declare class FrmkConfigStore {
|
|
276
|
+
private readonly _libraryConfig;
|
|
277
|
+
private readonly _serverConfig;
|
|
278
|
+
/** Indica si la librería ha sido inicializada con `initialize()`. */
|
|
279
|
+
readonly isConfigured: i0.Signal<boolean>;
|
|
280
|
+
/** Configuración de la librería (merged con defaults). Lanza si no inicializada. */
|
|
281
|
+
readonly libraryConfig: i0.Signal<FrmkLibraryConfig>;
|
|
282
|
+
/** Configuración del componente Login (defaults + libraryConfig.loginConfig). */
|
|
283
|
+
readonly loginConfig: i0.Signal<LoginConfig>;
|
|
284
|
+
/** Configuración del componente Dashboard (defaults + libraryConfig.dashboardConfig). */
|
|
285
|
+
readonly dashboardConfig: i0.Signal<DashboardConfig>;
|
|
286
|
+
/**
|
|
287
|
+
* Configuración completa de la aplicación.
|
|
288
|
+
* Si hay datos del Config Server se aplican; en caso contrario se usan solo los defaults + libraryConfig.
|
|
289
|
+
*/
|
|
290
|
+
readonly appConfig: i0.Signal<AppConfiguration>;
|
|
291
|
+
/** AuthConfig de angular-oauth2-oidc derivada de appConfig. */
|
|
292
|
+
readonly authConfig: i0.Signal<AuthConfig>;
|
|
293
|
+
/**
|
|
294
|
+
* Inicializa la librería con la configuración proporcionada por la app consumidora.
|
|
295
|
+
* Debe llamarse UNA vez dentro del APP_INITIALIZER, antes de cualquier otro uso.
|
|
296
|
+
*
|
|
297
|
+
* @param config Configuración de la librería (se fusiona con DEFAULT_LIBRARY_CONFIG)
|
|
298
|
+
*/
|
|
299
|
+
initialize(config: FrmkLibraryConfig): void;
|
|
300
|
+
/**
|
|
301
|
+
* Aplica los datos devueltos por el Config Server.
|
|
302
|
+
* Llamado por `ConfigService.loadConfig()` después de la petición HTTP.
|
|
303
|
+
*
|
|
304
|
+
* @param data Respuesta del Config Server (o undefined si falló la carga)
|
|
305
|
+
*/
|
|
306
|
+
applyServerConfig(data?: ConfigServerResponse): void;
|
|
307
|
+
private createDefaultAppConfig;
|
|
308
|
+
private mapConfigServerResponse;
|
|
309
|
+
private mergeConfigurations;
|
|
310
|
+
private buildDynamicUrls;
|
|
311
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FrmkConfigStore, never>;
|
|
312
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<FrmkConfigStore>;
|
|
313
|
+
}
|
|
358
314
|
|
|
359
315
|
declare class AuthService {
|
|
360
316
|
private readonly oauthService;
|
|
361
317
|
private readonly router;
|
|
318
|
+
private readonly store;
|
|
362
319
|
private readonly isAuthenticatedSubject$;
|
|
363
320
|
isAuthenticated$: rxjs.Observable<boolean>;
|
|
364
321
|
private readonly isDoneLoadingSubject$;
|
|
365
322
|
isDoneLoading$: rxjs.Observable<boolean>;
|
|
366
323
|
private isInitialLogin;
|
|
367
|
-
constructor(oauthService: OAuthService, router: Router);
|
|
324
|
+
constructor(oauthService: OAuthService, router: Router, store: FrmkConfigStore);
|
|
368
325
|
/**
|
|
369
326
|
* Limpia tokens expirados al iniciar la aplicación
|
|
370
327
|
* Solo limpia si NO estamos en un callback OAuth
|
|
@@ -424,11 +381,10 @@ declare class AuthService {
|
|
|
424
381
|
|
|
425
382
|
declare class ConfigService {
|
|
426
383
|
private readonly http;
|
|
384
|
+
private readonly store;
|
|
427
385
|
private configServerData;
|
|
428
|
-
private finalAppConfig;
|
|
429
386
|
private isLoaded;
|
|
430
|
-
|
|
431
|
-
constructor(http: HttpClient);
|
|
387
|
+
constructor(http: HttpClient, store: FrmkConfigStore);
|
|
432
388
|
/**
|
|
433
389
|
* Carga la configuración desde el config-server
|
|
434
390
|
*/
|
|
@@ -518,12 +474,14 @@ declare class LoginComponent implements OnInit, OnDestroy {
|
|
|
518
474
|
/**
|
|
519
475
|
* Configuration object to customize the login component appearance and behavior
|
|
520
476
|
*/
|
|
521
|
-
config: Partial<LoginConfig
|
|
477
|
+
readonly config: i0.InputSignal<Partial<LoginConfig>>;
|
|
478
|
+
private readonly store;
|
|
522
479
|
isLoggingIn: boolean;
|
|
523
480
|
statusMessage: string;
|
|
524
481
|
private authSubscription?;
|
|
525
482
|
private isProcessingCallback;
|
|
526
|
-
|
|
483
|
+
/** Configuración merged: defaults ← libraryConfig.loginConfig ← @Input config */
|
|
484
|
+
readonly mergedConfig: i0.Signal<LoginConfig>;
|
|
527
485
|
constructor(authService: AuthService);
|
|
528
486
|
ngOnInit(): void;
|
|
529
487
|
ngOnDestroy(): void;
|
|
@@ -542,13 +500,14 @@ declare class LoginComponent implements OnInit, OnDestroy {
|
|
|
542
500
|
goToDashboard(): void;
|
|
543
501
|
private navigateToRedirect;
|
|
544
502
|
static ɵfac: i0.ɵɵFactoryDeclaration<LoginComponent, never>;
|
|
545
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<LoginComponent, "lib-login", never, { "config": { "alias": "config"; "required": false; }; }, {}, never, never, true, never>;
|
|
503
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<LoginComponent, "lib-login", never, { "config": { "alias": "config"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
546
504
|
}
|
|
547
505
|
|
|
548
506
|
declare class DashboardComponent implements OnInit {
|
|
549
507
|
authService: AuthService;
|
|
550
508
|
private readonly authorizationService;
|
|
551
|
-
config: Partial<DashboardConfig
|
|
509
|
+
readonly config: i0.InputSignal<Partial<DashboardConfig>>;
|
|
510
|
+
private readonly store;
|
|
552
511
|
userInfo: any;
|
|
553
512
|
userRoles: string[];
|
|
554
513
|
menuHierarchy: MenuHierarchyItem[];
|
|
@@ -557,7 +516,8 @@ declare class DashboardComponent implements OnInit {
|
|
|
557
516
|
openMenuItems: Set<string>;
|
|
558
517
|
isUserPanelOpen: boolean;
|
|
559
518
|
isMobileMenuOpen: boolean;
|
|
560
|
-
|
|
519
|
+
/** Configuración merged: defaults ← libraryConfig.dashboardConfig ← @Input config */
|
|
520
|
+
readonly mergedConfig: i0.Signal<DashboardConfig>;
|
|
561
521
|
constructor(authService: AuthService, authorizationService: AuthorizationService);
|
|
562
522
|
ngOnInit(): void;
|
|
563
523
|
getConfig<K extends keyof DashboardConfig>(key: K): DashboardConfig[K];
|
|
@@ -592,8 +552,8 @@ declare class DashboardComponent implements OnInit {
|
|
|
592
552
|
toggleMobileMenu(): void;
|
|
593
553
|
closeMobileMenu(): void;
|
|
594
554
|
static ɵfac: i0.ɵɵFactoryDeclaration<DashboardComponent, never>;
|
|
595
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<DashboardComponent, "lib-dashboard", never, { "config": { "alias": "config"; "required": false; }; }, {}, never, never, true, never>;
|
|
555
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DashboardComponent, "lib-dashboard", never, { "config": { "alias": "config"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
596
556
|
}
|
|
597
557
|
|
|
598
|
-
export { AuthService, AuthorizationService, ConfigService, DEFAULT_DASHBOARD_CONFIG, DEFAULT_LIBRARY_CONFIG, DEFAULT_LOGIN_CONFIG, DashboardComponent,
|
|
558
|
+
export { AuthService, AuthorizationService, ConfigService, DEFAULT_DASHBOARD_CONFIG, DEFAULT_LIBRARY_CONFIG, DEFAULT_LOGIN_CONFIG, DashboardComponent, FrmkConfigStore, LoginComponent, VERSION, VERSION_INFO, authGuard };
|
|
599
559
|
export type { AppConfiguration, AuthorizationRequest, AuthorizationResponse, ConfigServerResponse, DashboardConfig, FrmkLibraryConfig, LoginConfig, MenuHierarchyItem, MenuHierarchyRequest };
|
package/package.json
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
src: url('/assets/icons/MaterialSymbolsOutlined.ttf') format('truetype');
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/* Clase principal para iconos outlined */
|
|
10
11
|
.material-symbols-outlined {
|
|
11
12
|
font-family: 'Material Symbols Outlined';
|
|
12
13
|
font-weight: normal;
|
|
@@ -23,3 +24,22 @@
|
|
|
23
24
|
font-feature-settings: 'liga';
|
|
24
25
|
-webkit-font-smoothing: antialiased;
|
|
25
26
|
}
|
|
27
|
+
|
|
28
|
+
/* Alias: material-symbols-rounded usa la misma fuente Outlined */
|
|
29
|
+
/* Esto permite compatibilidad con código que use 'rounded' */
|
|
30
|
+
.material-symbols-rounded {
|
|
31
|
+
font-family: 'Material Symbols Outlined';
|
|
32
|
+
font-weight: normal;
|
|
33
|
+
font-style: normal;
|
|
34
|
+
font-size: 24px;
|
|
35
|
+
line-height: 1;
|
|
36
|
+
letter-spacing: normal;
|
|
37
|
+
text-transform: none;
|
|
38
|
+
display: inline-block;
|
|
39
|
+
white-space: nowrap;
|
|
40
|
+
word-wrap: normal;
|
|
41
|
+
direction: ltr;
|
|
42
|
+
-webkit-font-feature-settings: 'liga';
|
|
43
|
+
font-feature-settings: 'liga';
|
|
44
|
+
-webkit-font-smoothing: antialiased;
|
|
45
|
+
}
|
|
@@ -3,6 +3,65 @@
|
|
|
3
3
|
// Variables CSS reutilizables
|
|
4
4
|
// ========================================
|
|
5
5
|
|
|
6
|
+
// === FUENTES INSTITUCIONALES ===
|
|
7
|
+
// Bembo Std - Para titulares importantes
|
|
8
|
+
@font-face {
|
|
9
|
+
font-family: 'Bembo Std';
|
|
10
|
+
src: url('/assets/fonts/Bembo/BemboStd.otf') format('opentype');
|
|
11
|
+
font-weight: 400;
|
|
12
|
+
font-style: normal;
|
|
13
|
+
font-display: swap;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@font-face {
|
|
17
|
+
font-family: 'Bembo Std';
|
|
18
|
+
src: url('/assets/fonts/Bembo/BemboStd-Bold.otf') format('opentype');
|
|
19
|
+
font-weight: 700;
|
|
20
|
+
font-style: normal;
|
|
21
|
+
font-display: swap;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@font-face {
|
|
25
|
+
font-family: 'Bembo Std';
|
|
26
|
+
src: url('/assets/fonts/Bembo/BemboStd-SemiboldItalic.otf') format('opentype');
|
|
27
|
+
font-weight: 600;
|
|
28
|
+
font-style: italic;
|
|
29
|
+
font-display: swap;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Museo Sans - Para cuerpos de texto
|
|
33
|
+
@font-face {
|
|
34
|
+
font-family: 'Museo Sans';
|
|
35
|
+
src: url('/assets/fonts/MuseoSans/Museo_Sans_500.otf') format('opentype');
|
|
36
|
+
font-weight: 400;
|
|
37
|
+
font-style: normal;
|
|
38
|
+
font-display: swap;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@font-face {
|
|
42
|
+
font-family: 'Museo Sans';
|
|
43
|
+
src: url('/assets/fonts/MuseoSans/Museo_Sans_500.otf') format('opentype');
|
|
44
|
+
font-weight: 500;
|
|
45
|
+
font-style: normal;
|
|
46
|
+
font-display: swap;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@font-face {
|
|
50
|
+
font-family: 'Museo Sans';
|
|
51
|
+
src: url('/assets/fonts/MuseoSans/Museo_Sans_500_Italic.otf') format('opentype');
|
|
52
|
+
font-weight: 500;
|
|
53
|
+
font-style: italic;
|
|
54
|
+
font-display: swap;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@font-face {
|
|
58
|
+
font-family: 'Museo Sans';
|
|
59
|
+
src: url('/assets/fonts/MuseoSans/Museo_Sans_Rounded_500.otf') format('opentype');
|
|
60
|
+
font-weight: 500;
|
|
61
|
+
font-style: normal;
|
|
62
|
+
font-display: swap;
|
|
63
|
+
}
|
|
64
|
+
|
|
6
65
|
// === COLORES ===
|
|
7
66
|
:root {
|
|
8
67
|
// Colores primarios
|
|
@@ -46,10 +105,17 @@
|
|
|
46
105
|
|
|
47
106
|
// === TIPOGRAFÍA ===
|
|
48
107
|
:root {
|
|
49
|
-
// Familia de fuentes
|
|
50
|
-
|
|
51
|
-
--font-family-
|
|
52
|
-
|
|
108
|
+
// Familia de fuentes institucionales
|
|
109
|
+
// Bembo Std - Para titulares importantes
|
|
110
|
+
--font-family-headings: 'Bembo Std', Georgia, 'Times New Roman', serif;
|
|
111
|
+
// Museo Sans - Para cuerpos de texto
|
|
112
|
+
--font-family-body: 'Museo Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
113
|
+
// Monoespaciada para código
|
|
114
|
+
--font-family-mono: 'Consolas', 'Monaco', 'Courier New', monospace;
|
|
115
|
+
|
|
116
|
+
// Alias para compatibilidad
|
|
117
|
+
--font-family-primary: var(--font-family-body);
|
|
118
|
+
--font-family-secondary: var(--font-family-headings);
|
|
53
119
|
|
|
54
120
|
// Tamaños de fuente
|
|
55
121
|
--font-size-xs: 0.75rem; // 12px
|