Package README
@unpispas/upp-konva
Biblioteca Angular para planos de sala (restauración y similares): el lienzo Konva vive solo dentro del paquete. Tu aplicación pasa un modelo en centímetros y recibe eventos tipados; no debe importar Konva directamente.
Qué incluye el paquete
| Entrega | Descripción |
|---|---|
UppKonvaModule | Declara el stage y el host interno del plano; exporta solo UppKonvaComponent. |
UppKonvaComponent (upp-konva) | Integración pública: enlaza UppKonvaModel con el stage interno. Expone (onChange), (onSelect), [active], [theme] (preset). |
Modelo público (lib/model/) | UppKonvaModel, UppKonvaArea, UppKonvaShape (base), UppKonvaGroup, DTO UppKonvaAreaSource / UppKonvaShapeSource, catálogo de tipos (UppKonvaShapeKind, mode, theme, etc.), RxJS (onGrouped$, onSourceChanged$, onSelected$, onUpdated$). |
| Stage (interno) | Implementación Konva, adaptadores wire, serialización de documento y preferencias de plano. No forman parte del contrato del integrador en el barrel principal. |
No forma parte del contrato soportado para apps: importar upp-floor-plan-stage ni rutas internas bajo stage/internal/.
Demo de laboratorio: módulo @unpispas/upp-konva-demo en libs/upp-konva/demo/ (no se emite en el bundle ng-packagr por defecto).
Documentación narrativa: páginas Markdown junto al código (src/lib/**/doc/, demo/doc/), sincronizadas a src/doc/docs/ con node libs/upp-konva/scripts/sync-doc-narrative.mjs (también vía nx run upp-konva:build / upp-konva:doc). El sitio Docusaurus vive en src/doc/. Tras cambios: npx nx run upp-konva:doc; la guía corporativa enlaza el hub y sirve /upp-konva/ tras upp-guide:build.
Dependencias
Peer (obligatorias en la app consumidora)
| Paquete | Versión (orientativa) |
|---|---|
@angular/core | ^18 |
@angular/common | ^18 |
konva | ^9.3 |
rxjs | ^7.8 |
Notas
- Sin dependencias de otras librerías
@unpispas/*: el mapeo desde tu dominio (catálogo, API, etc.) es responsabilidad de la feature. sideEffects: trueen elpackage.jsonde la librería: los empaquetadores no deben eliminar el registro de pintores Konva del paquete; si se tree-shakea, muchas figuras quedan solo con el rectángulo de hit invisible.
Manual rápido de integración
1. Instalar e importar el módulo
npx nx build upp-konva
import { NgModule } from '@angular/core';
import { UppKonvaModule } from '@unpispas/upp-konva';
@NgModule({
imports: [UppKonvaModule],
})
export class MiPlanoModule {}
(Evitá llamar tu NgModule exactamente UppKonvaModule sin alias de import.)
2. Contrato de integración
upp-konva + UppKonvaModel: filas con kind, área viva UppKonvaArea, area.source, streams RxJS, exportModel / importModel / exportToPng en el modelo. El selector upp-konva-floor-plan y el modelo de escena interno no se publican en el barrel ni se exportan desde el módulo.
La guía detallada está en Docusaurus: integrator.md.
3. Ejemplo mínimo
import { Component } from '@angular/core';
import {
UppKonvaModel,
type UppKonvaAreaSource,
} from '@unpispas/upp-konva';
@Component({
selector: 'app-plano',
template: `
<upp-konva
[model]="canvas"
[active]="true"
(onChange)="onEstructural()"
(onSelect)="onSel($event)"
/>
`,
})
export class PlanoComponent {
readonly initial: UppKonvaAreaSource = {
width: 800,
height: 600,
name: 'Sala',
shapes: [
{
id: 't1',
kind: 'TABLE',
x: 200,
y: 200,
width: 120,
height: 80,
rotation: 0,
data: { shape: 'SQUARE', chairs: 4 },
label: 'M1',
},
],
};
readonly canvas = new UppKonvaModel(this.initial);
onEstructural(): void {
// Lista de figuras cambió (alta/baja/reemplazo estructural): persistir si aplica
void this.canvas.exportModel();
}
onSel(_shapes: readonly unknown[]): void {
// Selección en el lienzo (instancias vivas del área)
}
}
4. Persistencia JSON
- Con
UppKonvaModel:canvas.exportModel()/canvas.importModel(json). - El integrador opera con el DTO público (
UppKonvaAreaSource/UppKonvaShapeSource) desdemodel; el wire interno de stage no forma parte del contrato público principal.
5. Clics en barra y taburetes (vista)
En onSelected$ de una figura bar, el payload puede incluir stool: null si el clic fue en el cuerpo de la barra, o un número (índice global del taburete) si fue en un taburete. Los taburetes solo se dibujan si en data del DTO indicás recuentos por lado (stoolLeft, stoolFront, stoolRight); si omitís esos campos, no hay taburetes.
Unidades y permisos
- Geometría en centímetros y grados de rotación donde aplique.
- RBAC / usuarios: fuera de alcance; la app decide
modedel modelo,activedel host y qué UI mostrar.
Documentación
| Recurso | Ubicación |
|---|---|
| Guía del integrador (Docusaurus) | src/doc/docs/integrator.md |
| Modelo público (TypeDoc + intro) | src/doc/docs/public-model-api.md y src/doc/docs/model-api/ (generado) |
| Notas de implementación del host | src/doc/docs/implementation.md |
| Demo | src/doc/docs/demo.md |
Especificaciones internas (español): src/lib/stage/presentation/upp-floor-plan-presentation.mdc, src/lib/stage/canvas/upp-floor-plan.mdc.
Licencia
Parte del monorepo Unpispas; uso y distribución según la licencia del repositorio.