npm package: @lesterarte/sefin-ui
Description: Sefin Design System - A comprehensive Angular UI library based on Atomic Design and design tokens
Author: Sefin
Latest version: 0.0.95

# @lesterarte/sefin-ui

Una librería de sistema de diseño Angular completa basada en principios de Atomic Design y design tokens de la Secretaría de Finanzas.

## Resumen

`@lesterarte/sefin-ui` es una librería UI Angular lista para producción diseñada para aplicaciones empresariales a gran escala. Proporciona:

- **Design Tokens**: Variables CSS y constantes TypeScript para temas consistentes
- **Estructura Atomic Design**: Componentes organizados (atoms, molecules, organisms)
- **Múltiples Temas**: Temas light, dark y brand (colores de Secretaría de Finanzas)
- **Integración con Angular Material**: Tema Material personalizado basado en design tokens
- **Componentes Type-Safe**: Soporte completo de TypeScript
- **Testing Completo**: Tests unitarios con Jest
- **Documentación Storybook**: Documentación visual de componentes con cambio de temas
  - 📖 [Ver Storybook en línea](https://sefin.github.io/sefin-ui/)

## Estructura del Proyecto

```
sefin-ui/
├── src/
│   ├── atoms/          # Bloques básicos (Button, Icon, Input)
│   ├── molecules/      # Componentes compuestos (FormField, Dropdown, Card)
│   ├── organisms/      # Bloques UI complejos (Header, LoginForm, Toolbar)
│   ├── tokens/         # Design tokens (colors, spacing, typography, etc.)
│   ├── themes/         # Configuraciones de temas (light, dark, brand)
│   ├── utils/          # Utilidades (ThemeLoader)
│   ├── shared/         # Tipos e interfaces compartidos
│   ├── styles/         # Estilos globales y resets
│   └── public-api.ts   # Exportaciones de la API pública
├── .storybook/         # Configuración de Storybook
├── ng-package.json     # Configuración de build
└── package.json        # Configuración del paquete
```

## Instalación

### Construir la Librería

```bash
npm run build
```

Esto creará el paquete distribuible en `dist/`.

### Publicar en NPM

1. Actualiza la versión en `package.json`
2. Construye la librería: `npm run build`
3. Navega a dist: `cd dist`
4. Publica: `npm publish --access public`

### Instalar en Tu Aplicación

```bash
npm install @lesterarte/sefin-ui
```

## Uso

> 📖 **Guía Completa**: Para una guía detallada de cómo usar la librería, consulta [GUIA_CONSUMO.md](./GUIA_CONSUMO.md)

### Inicio Rápido

### 1. Importar Estilos

En tu `styles.scss` o `angular.json`:

```scss
@import "@lesterarte/sefin-ui/styles";
```

O en `angular.json`:

```json
{
  "styles": ["node_modules/@lesterarte/sefin-ui/styles/index.scss"]
}
```

### 2. Cargar Tema

En tu `app.component.ts`:

```typescript
import { Component, OnInit } from "@angular/core";
import { ThemeLoader } from "@lesterarte/sefin-ui";

@Component({
  selector: "app-root",
  // ...
})
export class AppComponent implements OnInit {
  ngOnInit(): void {
    // Cargar tema brand (colores de Secretaría de Finanzas)
    ThemeLoader.loadTheme("brand");

    // O cargar tema light
    // ThemeLoader.loadTheme('light');

    // O cargar tema dark
    // ThemeLoader.loadTheme('dark');
  }
}
```

### 3. Usar Componentes

Todos los componentes son standalone y se pueden importar directamente:

```typescript
import { Component } from "@angular/core";
import { ButtonComponent, CardComponent } from "@lesterarte/sefin-ui";

@Component({
  selector: "app-example",
  standalone: true,
  imports: [ButtonComponent, CardComponent],
  template: `
    <sefin-card variant="elevated">
      <h2>Hola Mundo</h2>
      <sefin-button variant="primary" (clicked)="handleClick()"> Haz Clic </sefin-button>
    </sefin-card>
  `,
})
export class ExampleComponent {
  handleClick() {
    console.log("¡Botón clickeado!");
  }
}
```

## Componentes Disponibles

### Atoms

- **Button**: `sefin-button` - Múltiples variantes (primary, secondary, outline, ghost, danger) y tamaños
- **Icon**: `sefin-icon` - Componente contenedor de iconos
- **Input**: `sefin-input` - Input de formulario con soporte ControlValueAccessor

### Molecules

- **FormField**: `sefin-form-field` - Campo de formulario completo con label, input, hint y error
- **Dropdown**: `sefin-dropdown` - Componente de selección dropdown
- **Card**: `sefin-card` - Contenedor de tarjeta con variantes (default, elevated, outlined)

### Organisms

- **Header**: `sefin-header` - Encabezado de aplicación con logo, título y menú de usuario
- **LoginForm**: `sefin-login-form` - Componente de formulario de login completo
- **Toolbar**: `sefin-toolbar` - Barra de herramientas con título y botones de acción

## Design Tokens

### Paleta de Colores - Secretaría de Finanzas

- **Dark Gray**: `#383838`
- **Light Gray**: `#cecece`
- **Light Blue**: `#55C3D8`
- **White**: `#ffffff`

### Usando Variables CSS

Todos los design tokens están disponibles como variables CSS:

```scss
.mi-componente {
  color: var(--sefin-color-primary);
  padding: var(--sefin-spacing-md);
  border-radius: var(--sefin-radius-md);
  font-size: var(--sefin-font-size-base);
  box-shadow: var(--sefin-shadow-md);
}
```

### Usando Constantes TypeScript

```typescript
import { COLOR_TOKENS, SPACING_TOKENS } from "@lesterarte/sefin-ui";

const primaryColor = COLOR_TOKENS.brand.lightBlue;
const mediumSpacing = SPACING_TOKENS.md;
```

## Temas

### Temas Disponibles

- **brand**: Tema con colores exactos de Secretaría de Finanzas (por defecto)
- **light**: Tema claro
- **dark**: Tema oscuro

### Cambiar Temas

```typescript
import { ThemeLoader } from "@lesterarte/sefin-ui";

// Cambiar a tema brand
ThemeLoader.loadTheme("brand");

// Cambiar a tema dark
ThemeLoader.loadTheme("dark");
```

## Tipografía

La librería usa la fuente **Pluto** de Secretaría de Finanzas según las guías de marca:

- **Pluto-Light** (300) - Para texto ligero
- **Pluto-Regular** (400) - Para texto normal y body
- **Pluto-Bold** (700) - Para títulos y encabezados

### ⚠️ Importante: Incluir Archivos de Fuente

La librería define las declaraciones `@font-face` para Pluto, pero **debes proporcionar los archivos de fuente en tu aplicación consumidora**.

#### Opción 1: Archivos locales (Recomendado)

1. **Copia los archivos de fuente** a tu proyecto en la carpeta `src/assets/fonts/`:

   ```
   src/
   └── assets/
       └── fonts/
           ├── Pluto-Regular.woff2
           ├── Pluto-Regular.woff
           ├── Pluto-Bold.woff2
           ├── Pluto-Bold.woff
           ├── Pluto-Light.woff2
           └── Pluto-Light.woff
   ```

2. **Configura Angular** para copiar los assets en `angular.json`:

   ```json
   {
     "assets": [
       "src/favicon.ico",
       "src/assets",
       {
         "glob": "**/*",
         "input": "src/assets/fonts",
         "output": "/assets/fonts"
       }
     ]
   }
   ```

3. **Los estilos de la librería buscarán automáticamente** los archivos en `./assets/fonts/`

#### Opción 2: CDN o fuente externa

Si prefieres usar una fuente desde CDN o servidor externo, puedes sobrescribir las rutas en tu `styles.scss`:

```scss
@font-face {
  font-family: "Pluto";
  src: url("https://tu-cdn.com/fonts/Pluto-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Pluto";
  src: url("https://tu-cdn.com/fonts/Pluto-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
```

#### Formatos de fuente soportados

La librería busca los archivos en este orden de prioridad:

1. `.woff2` (recomendado - mejor compresión)
2. `.woff` (fallback)
3. `.ttf` (fallback)

**Nota:** Si no incluyes los archivos de fuente, el navegador usará las fuentes de fallback del sistema (Arial, Roboto, etc.).

## Desarrollo

### Ejecutar Tests

```bash
npm test
```

### Ejecutar Tests en Modo Watch

```bash
npm run test:watch
```

### Generar Reporte de Cobertura

```bash
npm run test:coverage
```

### Ejecutar Storybook

```bash
npm run storybook
```

Esto iniciará Storybook en `http://localhost:6006` con:

- Documentación de componentes
- Playground interactivo de componentes
- Cambio de temas
- Testing de accesibilidad

### Ver Storybook en Línea

📖 **Documentación en vivo**: Puedes ver la documentación completa de Storybook en GitHub Pages:

👉 **[Ver Storybook en GitHub Pages](https://sefin.github.io/sefin-ui/)**

La documentación incluye:

- Todos los componentes disponibles
- Ejemplos interactivos
- Guías de uso
- Cambio de temas en tiempo real
- Testing de accesibilidad

### Construir la Librería

```bash
npm run build
```

## Versionado

Este proyecto sigue [Semantic Versioning](https://semver.org/):

- **MAJOR**: Cambios que rompen compatibilidad
- **MINOR**: Nuevas características (compatibles hacia atrás)
- **PATCH**: Correcciones de bugs (compatibles hacia atrás)

## Flujo de Publicación

1. Actualiza la versión en `package.json`
2. Actualiza CHANGELOG.md
3. Construye la librería: `npm run build`
4. Prueba el build localmente
5. Publica: `cd dist && npm publish --access public`

## Mejores Prácticas

### Para Mantenedores de la Librería

1. **Siempre prueba antes de publicar**: Ejecuta tests y Storybook
2. **Actualiza documentación**: Mantén README y stories de Storybook actualizados
3. **Sigue Atomic Design**: Mantén los componentes organizados por jerarquía
4. **Usa design tokens**: Nunca hardcodees colores, spacing, etc.
5. **Escribe tests**: Mantén alta cobertura de tests

### Para Consumidores

1. **Importa solo lo que necesites**: Usa imports amigables con tree-shaking
2. **Carga el tema temprano**: Inicializa el tema en AppComponent
3. **Usa variables CSS**: Prefiere variables CSS sobre constantes TypeScript en estilos
4. **Sigue las APIs de componentes**: Usa los componentes como están documentados
5. **Extiende, no modifiques**: Crea componentes wrapper para personalización

## Solución de Problemas

### Warning del Linter: "Component is used but not imported"

Si ves un warning del linter de Angular que indica que un componente está siendo usado pero no importado, **este es un falso positivo conocido**.

#### ¿Por qué ocurre?

Aunque el componente está correctamente exportado desde la librería, el linter de Angular no puede detectar su uso en templates HTML cuando se trata de:

- Componentes standalone
- Selectores personalizados (como `sefin-button`, `sefin-card`, etc.)

#### Estado de la Librería

✅ **Componente correctamente exportado**  
✅ **Tipos TypeScript bien definidos**  
✅ **Metadata del componente correcta**

No hay nada que corregir en la librería. Esta es una limitación conocida del linter de Angular con componentes standalone y selectores personalizados.

#### Solución en el Proyecto Consumidor

1. **Mantener el archivo `.eslintrc.json` en el proyecto consumidor** con la configuración adecuada
2. **El código funciona correctamente** a pesar del warning
3. **Puedes ignorar el warning** de forma segura, ya que es un falso positivo

#### Recomendación

- Documentar en el README del proyecto consumidor que este warning es un falso positivo conocido
- El código funciona correctamente a pesar del warning
- Mantener la configuración del linter en el proyecto consumidor

## Soporte

Para problemas, preguntas o contribuciones, por favor abre un issue en el repositorio.

## Licencia

MIT