Librería de componentes UI transversales de eClass, construida en React, TypeScript y Chakra UI. Unifica los estilos y el comportamiento de los fronts de eClass (por ejemplo v8) siguiendo el sistema de diseño.
- Documentación y ejemplos de cada componente: https://ui-kit.eclass.com
- Paquete en npm:
@eclass/ui-kit
- Stack tecnológico
- Requisitos previos
- Instalación y uso
- Componentes
- Desarrollo local
- Scripts
- Estructura del proyecto
- Convenciones
- Publicación y versionado
- Documentación adicional
- Equipo
- Licencia
| Área | Tecnología |
|---|---|
| UI | React (desarrollo en 17.0.2, compatible desde 16.8 hasta 19) |
| Lenguaje | TypeScript 4.9 (strict), target ES2019 |
| Estilos | Chakra UI 1.8 + Emotion 11 + framer-motion 6 |
| Build | Vite 8 en modo librería (formatos ES y UMD) + tsc para los tipos .d.ts |
| Pruebas | Vitest 5 + Testing Library |
| Calidad | ESLint (standard + TypeScript) + Prettier + husky + lint-staged + commitlint |
| Publicación | GitHub Actions + semantic-release + npm Trusted Publishing |
| Otras deps. | date-fns, html-react-parser + dompurify, react-hot-toast, react-ripples |
- Node.js 24.22.0 (definido en
.nvmrc; con nvm:nvm use). - npm 11.13.0 (definido en
packageManagerdepackage.json). Es la misma versión que usa CI. - Acceso SSH a gitlab.com al grupo de eClass: los paquetes de tipos
@types/eclass__apiy@types/eclass__sequelize-modelsse instalan desde repositorios privados de GitLab. Sin ese accesonpm cifalla. - Solo para desarrollo: yalc, para probar la librería en un proyecto consumidor (ver Probar en un proyecto consumidor).
Instala la librería junto con sus peerDependencies, que no vienen incluidas en el bundle:
npm install @eclass/ui-kit @chakra-ui/react@^1.8.9 @emotion/react@^11.8.2 @emotion/styled@^11.8.1 framer-motion@^6.2.8| Peer dependency | Versión aceptada |
|---|---|
react |
^16.8, 17.x, ^18 o ^19 |
react-dom |
^16.8, 17.x, ^18 o ^19 |
@chakra-ui/react |
^1.8.9 |
@emotion/react |
^11.8.2 |
@emotion/styled |
^11.8.1 |
framer-motion |
^6.2.8 |
Envuelve la aplicación con ChakraProvider usando el tema de la librería y luego importa los
componentes desde @eclass/ui-kit:
import { ChakraProvider } from '@chakra-ui/react'
import { BtnPrimary, theme } from '@eclass/ui-kit'
export const App = () => (
<ChakraProvider theme={theme} resetCSS={false}>
<BtnPrimary onClick={() => console.log('Guardado')}>Guardar</BtnPrimary>
</ChakraProvider>
)Para usar los colores del tema en tus propios estilos, vars() devuelve la variable CSS
correspondiente:
import { Box } from '@chakra-ui/react'
import { vars } from '@eclass/ui-kit'
// var(--chakra-colors-main-deepSkyBlue)
const Destacado = () => <Box color={vars('colors-main-deepSkyBlue')}>Texto destacado</Box>La documentación interactiva, con ejemplos y código de cada variante, está en
https://ui-kit.eclass.com. Estos son los componentes que exporta la librería
(src/index.ts), ordenados según diseño atómico:
| Nivel | Componentes |
|---|---|
| Átomos | Label, Progress, Ripples, TinyAlert, Icons (set de íconos SVG) |
| Moléculas | Btn, BtnPrimary, BtnSecondary, BtnTertiary, BtnLink, NavBarButton, NewTooltip, UserWay, UserWayCookie |
| Organismos | Alert, FlashNotification, useFlashNotification, CalendarDropdown, EventsList, CourseList, CourseStatus, Eventos, Resources, ShareAndReviewModal, SimpleCourseBox, UserDropdown |
| Modales | Modal, ModalAlert, ModalAlertNew, ModalAlertButtons, ModalButtons, ModalContent, ModalMultiple, ModalSimple, ModalCard, ModalCardContent |
| Tema | theme, vars |
También se exportan los tipos ModalMultipleProps, AccesibleProfileMenuProps y
ProfileMenuItem, y las utilidades dataFake y maxWidthCoursesList de CourseList.
git clone git@github.com:eclass/ui-kit.git
cd ui-kit
nvm use
npm cinpm ci instala las dependencias exactas del package-lock.json (CI no regenera el lockfile) y,
mediante el script prepare, activa los hooks de husky y ts-patch.
El sitio de documentación y el Playground solo se montan si existe un archivo .env (ignorado por
git) en la raíz con:
VITE_REACT_DEPLOY_DOCUMENTATION=DOCUMENTATIONSin esa variable, src/main.tsx solo importa la librería y la página queda en blanco.
npm run docuLevanta el sitio de documentación en local, con todos los componentes.
npm run devLevanta el Playground (src/Playground.tsx), una página vacía para probar un componente aislado.
No se publica.
Antes de sacar una versión, se valida con yalc que los cambios se vean y funcionen bien en un proyecto que usa la librería (por ejemplo v8):
# En ui-kit: compilar y publicar en el almacén local de yalc
npm run build
npx yalc publish# En el proyecto consumidor: usar la versión local
npx yalc add @eclass/ui-kit
npm installDespués de cada cambio en ui-kit, recompilar y propagarlo a los proyectos que la usan:
npm run build
npx yalc pushAl terminar, en el proyecto consumidor volver a la versión de npm (y no commitear .yalc/ ni
yalc.lock):
npx yalc remove @eclass/ui-kit
npm installUna vez publicada la versión nueva en npm (ver Publicación y versionado),
se actualiza @eclass/ui-kit en cada proyecto que la utiliza.
| Script | Descripción |
|---|---|
npm run docu |
Sitio de documentación en local (Vite). |
npm run dev |
Playground (src/Playground.tsx) en local. |
npm run build |
Build de la librería en dist/: tsc + vite build (ES y UMD) + tipos + copia de los .d.ts de src. |
npm run deploy |
Build del sitio de documentación en dist/ (lo usa CI para GitHub Pages). |
npm run serve |
Sirve el último build con vite preview. |
npm run test |
Suite completa de Vitest con coverage (la corre CI). |
npm run test-local |
Vitest en modo watch. |
npm run lint |
Formatea src con Prettier y corrige con eslint --fix. |
npm run lint:check |
Revisa src con ESLint sin corregir (la corre CI). |
npm run format |
Solo Prettier sobre src. |
npm run eslint |
Solo eslint --fix sobre src. |
npm run ts-compile-check |
Revisión de tipos de todo el proyecto con tsc (la corre el pre-commit). |
La suite completa es pesada. En local, corre solo las pruebas de los archivos que tocaste:
npx vitest run src/molecules/Buttons/BtnPrimary.test.tsx.
ui-kit/
├── .github/workflows/nodejs.yml # CI: lint, pruebas, release y deploy de la documentación
├── .husky/ # Hooks de git (pre-commit y commit-msg)
├── __mocks__/ # Mocks de Vitest (dompurify, react-ripples)
├── src/
│ ├── atoms/ # Componentes básicos (Label, Progress, Icons, ...)
│ ├── molecules/ # Combinaciones de átomos (botones, tooltip, ...)
│ ├── organisms/ # Componentes complejos (modales, calendario, cursos, ...)
│ ├── theme/ # Tema de Chakra (colores, tipografía, estilos) y vars()
│ ├── services/ # Utilidades sin UI
│ ├── documentation/ # Sitio de documentación (páginas, rutas y componentes)
│ ├── test/vitest-setup.ts # Configuración global de Vitest
│ ├── Playground.tsx # Página para probar componentes en local
│ ├── main.tsx # Entrada de Vite (documentación o Playground)
│ └── index.ts # API pública de la librería
├── .releaserc.json # Configuración de semantic-release
├── vite.config.ts # Build de la librería y de la documentación
└── package.json
Cada componente vive en su propia carpeta (src/atoms/Label/Label.tsx) junto a sus pruebas. Cada
nivel tiene un index.ts y todo lo que el consumidor puede usar debe exportarse en
src/index.ts.
- Componentes funcionales con export nombrado (
export function BtnPrimary(...)), en PascalCase. Sin componentes de clase niexport default(salvo las páginas de la documentación). - Props tipadas con una interfaz
XProps, con sus valores por defecto en la desestructuración. - JSDoc en español en componentes, hooks y funciones nuevas, con
@exampleen los componentes. - Compatibilidad con el consumidor: solo APIs de React 16.8 (nada de
useId,useTransition, etc.) y JavaScript ES2019 (nada deat,toSorted, etc.). - Props nuevas siempre opcionales y con un valor por defecto que mantenga el comportamiento actual. Quitar o renombrar un export o una prop es un cambio incompatible.
- Textos visibles con valor por defecto en español y modificables por props.
- HTML recibido por props: sanitizar con
dompurifyantes de parsearlo conhtml-react-parser.
- Solo Chakra UI (
Box,Flex, props de estilo ysx). - Colores y tokens desde el tema con
vars('colors-...'), nunca hexadecimales sueltos. - Responsive con los valores por breakpoint de Chakra o con media queries dentro de
sx. - Imágenes y archivos estáticos no se versionan: se suben al CDN de eClass y se usan por URL. Los
íconos son componentes SVG en
src/atoms/Icons.
| Elemento | Convención | Ejemplo |
|---|---|---|
| Carpeta y componente | PascalCase | TinyAlert/TinyAlert.tsx |
| Interfaz de props | XProps |
ModalMultipleProps |
| Hooks | useX |
useFlashNotification |
| Pruebas | junto al archivo, X.test.tsx |
BtnTertiary.test.tsx |
| Página de docs | src/documentation/pages/<Nivel>/ |
pages/Organisms/Modals.tsx |
- Todo componente o funcionalidad nueva lleva pruebas y su página en la documentación en el mismo cambio.
- Se prueba lo que el componente promete al consumidor: lo que renderiza según sus props, sus
callbacks y su accesibilidad. Títulos de
describe/testen español. - Consultas accesibles de Testing Library (
getByRole,getByLabelText,getByText) e interacciones con@testing-library/user-event.
Se trabaja en una rama desde main con el prefijo según el tipo de cambio y se abre un pull
request en GitHub:
feat/<nombre> feature/<nombre> fix/<nombre> bugfix/<nombre>
Los PR se integran a main con squash, así que el título del PR queda como mensaje del commit
y debe cumplir el formato de commits.
Se usa Conventional Commits, validado por commitlint
(@commitlint/config-conventional) en el hook commit-msg:
type(scope): resumen en español
scopecorto y en minúsculas: el componente o dominio (modals,calendar,documentation).- Resumen de 72 caracteres como máximo.
- El hook
pre-commitcorrenpm run ts-compile-checky lint-staged (npm run lint): un error de tipos o de lint bloquea el commit.
El tipo del commit define la versión que publica semantic-release:
| Tipo | Uso | Versión |
|---|---|---|
feat |
Funcionalidad o componente nuevo | minor (1.64.0 → 1.65.0) |
fix |
Corrección de un error | patch (1.64.0 → 1.64.1) |
perf |
Mejora de rendimiento | patch |
revert |
Revierte un commit anterior | patch |
refactor, docs, test, style, build, ci, chore |
Cambios que no afectan a la librería publicada | sin versión |
Cualquiera con BREAKING CHANGE: en el cuerpo |
Cambio incompatible de la API pública | major (1.64.0 → 2.0.0) |
El pie BREAKING CHANGE: <qué se rompe> es obligatorio para una versión major: el ! en el
título no basta con el preset por defecto. Como obliga a actualizar a todos los consumidores, se
acuerda con el equipo antes.
La publicación es automática; nunca se edita a mano la versión de package.json ni el
CHANGELOG.md.
- Cada push y pull request ejecuta el job
testde GitHub Actions:npm ci,npm run lint:checkynpm run test. - Al integrar en
main, el jobreleasecompila la librería (npm run build) y ejecuta semantic-release, que:- analiza los commits desde el último tag y calcula la versión según la tabla de commits;
- publica
@eclass/ui-kiten el registro público de npm; - actualiza
CHANGELOG.mdy la versión enpackage.jsoncon un commitchore(release): x.y.z [skip ci]; - crea el tag y el release en GitHub.
- Después del release, los jobs
build-pagesydeploy-pagesgeneran el sitio de documentación (npm run deploy) y lo publican en GitHub Pages (https://ui-kit.eclass.com).
Si ningún commit desde el último release genera versión (por ejemplo, solo docs o chore), no
se publica nada.
La publicación usa Trusted Publishing de npm: el job
de release pide un token OIDC de corta duración (id-token: write) y no se usa NPM_TOKEN. El
trusted publisher del paquete en npm está configurado para la organización eclass, el
repositorio ui-kit y el workflow nodejs.yml, sin environment. Si se renombra el workflow o se
mueve el repositorio, hay que actualizar esa configuración en npm o la publicación falla.
- Sitio de documentación de componentes
- Sistema de diseño de eClass
- Cómo documentar un componente
- CHANGELOG
- Chakra UI v1
- Trusted Publishing de npm y semantic-release en GitHub Actions
Mantenido por el equipo de desarrollo de eClass.
- Jonathan Garrido (@Jonathangarrido)
- Javiera Munita (@JaviMunita)
- Josefin Ferrada (@josefin-ferrada)
Contribuidores anteriores
- Daniel Camilo Montoya
- Sebastián González Riffo
- Alvaro Alvarez
MIT, la misma con la que se publica el paquete en npm.