Skip to main content

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

EntregaDescripción
UppKonvaModuleDeclara 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)

PaqueteVersió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: true en el package.json de 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) desde model; 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 mode del modelo, active del host y qué UI mostrar.

Documentación

RecursoUbicació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 hostsrc/doc/docs/implementation.md
Demosrc/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.