@salesql/sql_components_vue3
v3.25.0
Published
Librería de componentes Vue 3 (SalesQL)
Readme
@salesql/sql_components_vue3
Librería de componentes Vue 3 (TypeScript) para SalesQL.
Estilos con SCSS (variables centralizadas en colors.scss).
Visor de componentes y playground con Histoire.
🚀 Requisitos
⚠️ Node: Vite 7 requiere Node ≥ 20.19 (recomendado 22.12.0).
Con Node 18 fallará concrypto.hash is not a function.
| Tool / lib | Versión recomendada | | ---------------------- | ---------------------- | | Node | 22.12.0 (o ≥20.19) | | pnpm | 10.17.0 | | Vue | 3.5.22 | | Vite | 7.1.7 | | @vitejs/plugin-vue | 6.0.1 | | TypeScript | 5.9.2 | | vue-tsc | 2.2.12 | | Histoire | 1.0.0-alpha.3 | | Sass (dart-sass) | 1.93.2 | | Changesets | 2.29.7 |
Preparación de entorno
# Node
nvm install 22.12.0
nvm use 22.12.0
node -v # v22.12.0
# Instalar dependencias del monorepo
pnpm install
# (Primera vez con Vite/Histoire)
pnpm approve-builds # marca @parcel/watcher y confirma📂 Estructura
salesql-components-library-vue3/
├─ package.json # raíz del monorepo
├─ pnpm-workspace.yaml
├─ tsconfig.base.json
└─ components/ # paquete de la librería
├─ package.json
├─ tsconfig.json # solo src/*
├─ tsconfig.build.json # build de la lib
├─ tsconfig.node.json # configs: vite/histoire
├─ vite.config.ts
├─ histoire.config.ts
├─ src/
│ ├─ index.ts # exporta componentes (+ importa estilos base)
│ ├─ env.d.ts
│ ├─ stories.setup.ts
│ ├─ assets/css/
│ │ ├─ base.scss
│ │ ├─ colors.scss
│ │ └─ spacing.scss
│ ├─ constants/sql-components.ts
│ └─ components/
│ ├─ SqlButton.vue
│ ├─ SqlButton.story.vue
│ ├─ SqlSpinner.vue
│ └─ SqlSpinner.story.vue
└─ dist/ # salida de build📦 Scripts principales
Desde la raíz:
pnpm build # build de la librería (regenera también los docs LLM)
pnpm dev:stories # arranca Histoire
pnpm docs:generate # regenera llms.txt + llms-full.txt (docs para agentes)
pnpm typecheck # chequeo estricto de tipos
pnpm changeset # crear un changeset (la release la hace CI: ver PUBLISHING.md del repo)
pnpm reset # limpiar node_modules + reinstalar + aprobar builds🔎 Histoire (visualización y testeo)
Para arrancar el entorno de historias:
pnpm dev:stories- Abre http://localhost:6006
- Historias junto al componente, ej:
SqlButton.story.vue - Usa
<Story>/<Variant>/<Controls>para mostrar variantes e interactuar
📥 Uso en apps consumidoras
pnpm add @salesql/sql_components_vue3Ejemplo:
<script setup lang="ts">
import { SqlButton } from '@salesql/sql_components_vue3';
</script>
<template>
<SqlButton class="sql-button--primary sql-button--large"> Guardar </SqlButton>
</template>Los estilos de los componentes viajan scoped en dist/style.css (importalo una
vez en tu app). El reset de documento (base.scss) no va en ese bundle: se
publica aparte como dist/reset.css, opt-in (SALESQL-3454).
🔤 Fuente de iconos — REQUERIDA en la app consumidora
Los componentes que dibujan un icono emiten
<i class="material-symbols-filled">{ligadura}</i>. La librería no envía ni la
fuente ni esa clase: un component library no debe imponer una baseline global
(mismo criterio que SALESQL-3454). La app tiene que aportar las dos, o cada
glifo se pinta como su propia ligadura — un close literal en vez de ✕.
- Cargar la fuente en
index.html:
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,0..1,0"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0..1,0"
/>- Definir la clase global:
.material-symbols-filled {
font-family: 'Material Symbols Rounded';
font-weight: normal;
font-style: normal;
font-size: 20px;
line-height: 20px;
font-variation-settings:
'FILL' 1,
'wght' 400,
'GRAD' 0,
'opsz' 20;
}Los componentes dimensionan su propio glifo (sus reglas scoped le ganan al 20px por defecto), así que la clase sólo tiene que aportar familia y relleno.
Hasta SALESQL-3968 la librería marcaba
.material-icons, una familia que ninguna app de SalesQL linkea — y el playground de Histoire la cargaba, así que el bug sólo se veía del lado consumidor. El playground ahora carga exactamente lo mismo que la app.
🔤 Tipografía (Mulish) — REQUERIDA en la app consumidora
typography.scss declara 'Mulish', 'Muli', -apple-system, …, pero la librería
no envía la fuente, por el mismo criterio. La app la carga; frontend-app ya lo
hace en su index.html:
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&display=swap"
/>Sin ella, el stack cae en la fuente del sistema, que a igual tamaño y peso compone
el texto un ~5% más ancho que Mulish. El playground de Histoire la carga desde
src/assets/css/typeface.dev.scss (sólo dev). Hasta SALESQL-3298 no la cargaba, y
cada texto se veía más grande que en el diseño aunque el CSS fuera idéntico.
🤖 Docs para agentes de IA (LLM)
El paquete publica documentación en markdown plano, pensada para que los agentes de IA de los repos consumidores (frontend-app, etc.) entiendan la librería sin scrapear el HTML de Histoire:
llms-full.txt— todos los componentes en detalle (props, eventos, a11y, uso).llms.txt— índice liviano (formato llms.txt) que apunta al anterior.
Ambos se autogeneran desde los bloques <docs lang="md"> de las *.story.vue (la
única fuente de verdad) y viajan dentro del paquete npm:
pnpm docs:generate # regenera llms.txt + llms-full.txt (corre solo en `pnpm build`)Como viajan en el paquete, un agente en un repo consumidor los lee version-locked a lo que tiene instalado, sin red ni token de GitHub:
node_modules/@salesql/sql_components_vue3/llms-full.txtEnganche recomendado en el repo consumidor (su AGENTS.md / CLAUDE.md):
Para usar `@salesql/sql_components_vue3`, leé primero
`node_modules/@salesql/sql_components_vue3/llms-full.txt` — props, eventos y uso de cada componente.¿Querés docs más ricas? Agregá/mejorá el bloque
<docs>de la story del componente:llms-full.txtse regenera solo en el próximo build.
🛠️ Añadir un nuevo componente (Checklist)
Convención de nombres: archivos PascalCase (
SqlX.vue,SqlX.story.vue).
1. Crear el componente
components/src/components/SqlX.vue:
<script setup lang="ts">
// lógica/props
</script>
<template>
<div class="sql-x">
<slot />
</div>
</template>
<style lang="scss" scoped>
@use '../assets/css/colors.scss' as colors;
@use '../assets/css/spacing.scss' as s;
.sql-x {
color: colors.$primary-main;
padding: s.spacing(2);
}
</style>2. Crear la historia
components/src/components/SqlX.story.vue:
<script setup lang="ts">
import SqlX from './SqlX.vue';
</script>
<template>
<Story title="SqlX/Básico">
<Variant title="Default">
<SqlX>Contenido</SqlX>
</Variant>
<Variant title="Playground">
<Controls :data="{ text: { type: 'text', default: 'Hola' } }">
<template #default="{ state }">
<SqlX>{{ state.text }}</SqlX>
</template>
</Controls>
</Variant>
</Story>
</template>3. Exportarlo
En components/src/index.ts:
export { default as SqlButton } from './components/SqlButton.vue';
export { default as SqlSpinner } from './components/SqlSpinner.vue';
export { default as SqlX } from './components/SqlX.vue';El entry público no importa
base.scss: ese reset es opt-in y se compila adist/reset.css(SALESQL-3454). El playground de Histoire lo carga por su cuenta desdesrc/stories.setup.ts.
4. Probar con Histoire
pnpm dev:stories5. Chequear y build
pnpm typecheck
pnpm build6. Versionado y publicación
Los cambios se registran con pnpm changeset; la versión y la publicación las hace CI (ver PUBLISHING.md del repo).
🔧 Convenciones
- Archivos: PascalCase para
.vuey.story.vue. - Estilos:
@use '../assets/css/colors.scss' as colors;. - Spacing:
spacing.scssconmap.get(...). - Enums/constantes:
export const SQL_SPINNER_SIZES = { SMALL: 'small', MEDIUM: 'medium', LARGE: 'large', } as const; export type SqlSpinnerSize = (typeof SQL_SPINNER_SIZES)[keyof typeof SQL_SPINNER_SIZES];
🐛 Troubleshooting
crypto.hash is not a function/ “Vite requires Node 20.19+ or 22.12+”
→ Actualiza Node a 22.12.0 y reinstala dependencias.VSCode marca “Cannot find module 'vue'”
→ Asegúrate de quevueestá en peerDependencies y devDependencies encomponents/package.json.
Reinicia TS server.pnpm pide aprobar
@parcel/watcher
→pnpm approve-builds(marca@parcel/watcher).
Para global:pnpm approve-builds --global.
