@bimetal/whiteboard-angular-components 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,112 @@
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FocusTrapDirective } from '@bimetal/angular';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * The double-click edit dialog for a shape's text. Rendered with a host `*ngIf`;
7
+ * the draft resets per target on the shape-identity change. 1:1 with the React
8
+ * reference.
9
+ */
10
+ export class TextDialogComponent {
11
+ initial = '';
12
+ locale;
13
+ save = new EventEmitter();
14
+ close = new EventEmitter();
15
+ delete = new EventEmitter();
16
+ text = '';
17
+ lastInitial = null;
18
+ // v0.29 Tastatur: the shared FocusTrapDirective owns focus-on-open + Tab-cycle + Escape +
19
+ // restore (contract §3). Stable arrow so the template can bind [bmFocusTrapOnEscape].
20
+ onEscape = () => this.close.emit();
21
+ ngOnChanges() {
22
+ // Re-seed the draft whenever the dialog targets a different shape's text.
23
+ if (this.initial !== this.lastInitial) {
24
+ this.text = this.initial;
25
+ this.lastInitial = this.initial;
26
+ }
27
+ }
28
+ onInput(e) { this.text = e.target.value; }
29
+ stop(e) { e.stopPropagation(); }
30
+ static ɵfac = function TextDialogComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TextDialogComponent)(); };
31
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TextDialogComponent, selectors: [["bm-wb-text-dialog"]], hostAttrs: [2, "display", "contents"], inputs: { initial: "initial", locale: "locale" }, outputs: { save: "save", close: "close", delete: "delete" }, features: [i0.ɵɵNgOnChangesFeature], decls: 13, vars: 8, consts: [[1, "bm-wb__dialog-backdrop", 3, "pointerdown"], ["role", "dialog", "aria-modal", "true", "bmFocusTrap", "", 1, "bm-wb__dialog", 3, "pointerdown", "bmFocusTrapOnEscape"], [3, "input", "value"], [1, "bm-wb__dialog-actions"], ["type", "button", 1, "bm-wb__btn", 3, "click"], [2, "flex", "1"], ["type", "button", 1, "bm-wb__tool", "bm-wb__tool--active", 3, "click"]], template: function TextDialogComponent_Template(rf, ctx) { if (rf & 1) {
32
+ i0.ɵɵelementStart(0, "div", 0);
33
+ i0.ɵɵlistener("pointerdown", function TextDialogComponent_Template_div_pointerdown_0_listener() { return ctx.close.emit(); });
34
+ i0.ɵɵelementStart(1, "div", 1);
35
+ i0.ɵɵlistener("pointerdown", function TextDialogComponent_Template_div_pointerdown_1_listener($event) { return ctx.stop($event); });
36
+ i0.ɵɵelementStart(2, "strong");
37
+ i0.ɵɵtext(3);
38
+ i0.ɵɵelementEnd();
39
+ i0.ɵɵelementStart(4, "textarea", 2);
40
+ i0.ɵɵlistener("input", function TextDialogComponent_Template_textarea_input_4_listener($event) { return ctx.onInput($event); });
41
+ i0.ɵɵelementEnd();
42
+ i0.ɵɵelementStart(5, "div", 3)(6, "button", 4);
43
+ i0.ɵɵlistener("click", function TextDialogComponent_Template_button_click_6_listener() { return ctx.delete.emit(); });
44
+ i0.ɵɵtext(7);
45
+ i0.ɵɵelementEnd();
46
+ i0.ɵɵelement(8, "span", 5);
47
+ i0.ɵɵelementStart(9, "button", 4);
48
+ i0.ɵɵlistener("click", function TextDialogComponent_Template_button_click_9_listener() { return ctx.close.emit(); });
49
+ i0.ɵɵtext(10);
50
+ i0.ɵɵelementEnd();
51
+ i0.ɵɵelementStart(11, "button", 6);
52
+ i0.ɵɵlistener("click", function TextDialogComponent_Template_button_click_11_listener() { return ctx.save.emit(ctx.text); });
53
+ i0.ɵɵtext(12);
54
+ i0.ɵɵelementEnd()()()();
55
+ } if (rf & 2) {
56
+ i0.ɵɵadvance();
57
+ i0.ɵɵproperty("bmFocusTrapOnEscape", ctx.onEscape);
58
+ i0.ɵɵattribute("aria-label", ctx.locale.editShape);
59
+ i0.ɵɵadvance(2);
60
+ i0.ɵɵtextInterpolate(ctx.locale.editShape);
61
+ i0.ɵɵadvance();
62
+ i0.ɵɵproperty("value", ctx.text);
63
+ i0.ɵɵattribute("placeholder", ctx.locale.titlePlaceholder);
64
+ i0.ɵɵadvance(3);
65
+ i0.ɵɵtextInterpolate(ctx.locale.delete);
66
+ i0.ɵɵadvance(3);
67
+ i0.ɵɵtextInterpolate(ctx.locale.cancel);
68
+ i0.ɵɵadvance(2);
69
+ i0.ɵɵtextInterpolate(ctx.locale.save);
70
+ } }, dependencies: [CommonModule, FocusTrapDirective], encapsulation: 2, changeDetection: 0 });
71
+ }
72
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TextDialogComponent, [{
73
+ type: Component,
74
+ args: [{
75
+ selector: 'bm-wb-text-dialog',
76
+ standalone: true,
77
+ host: { style: 'display: contents' },
78
+ imports: [CommonModule, FocusTrapDirective],
79
+ changeDetection: ChangeDetectionStrategy.OnPush,
80
+ template: `
81
+ <div class="bm-wb__dialog-backdrop" (pointerdown)="close.emit()">
82
+ <div class="bm-wb__dialog" role="dialog" aria-modal="true" [attr.aria-label]="locale.editShape" (pointerdown)="stop($event)"
83
+ bmFocusTrap [bmFocusTrapOnEscape]="onEscape">
84
+ <strong>{{ locale.editShape }}</strong>
85
+ <textarea
86
+ [value]="text"
87
+ [attr.placeholder]="locale.titlePlaceholder"
88
+ (input)="onInput($event)"></textarea>
89
+ <div class="bm-wb__dialog-actions">
90
+ <button type="button" class="bm-wb__btn" (click)="delete.emit()">{{ locale.delete }}</button>
91
+ <span style="flex:1"></span>
92
+ <button type="button" class="bm-wb__btn" (click)="close.emit()">{{ locale.cancel }}</button>
93
+ <button type="button" class="bm-wb__tool bm-wb__tool--active" (click)="save.emit(text)">{{ locale.save }}</button>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ `,
98
+ }]
99
+ }], null, { initial: [{
100
+ type: Input
101
+ }], locale: [{
102
+ type: Input,
103
+ args: [{ required: true }]
104
+ }], save: [{
105
+ type: Output
106
+ }], close: [{
107
+ type: Output
108
+ }], delete: [{
109
+ type: Output
110
+ }] }); })();
111
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TextDialogComponent, { className: "TextDialogComponent", filePath: "components/textdialog.ts", lineNumber: 46 }); })();
112
+ //# sourceMappingURL=TextDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextDialog.js","sourceRoot":"","sources":["../../src/components/TextDialog.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAC3B,uBAAuB,GACnC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;;AAUtD;;;;GAIG;AA0BH,MAAM,OAAO,mBAAmB;IACrB,OAAO,GAAG,EAAE,CAAC;IACK,MAAM,CAAoB;IAC3C,IAAI,GAAG,IAAI,YAAY,EAAU,CAAC;IAClC,KAAK,GAAG,IAAI,YAAY,EAAQ,CAAC;IACjC,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE5C,IAAI,GAAG,EAAE,CAAC;IACF,WAAW,GAAkB,IAAI,CAAC;IAE1C,0FAA0F;IAC1F,sFAAsF;IAC7E,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAE5C,WAAW;QACT,0EAA0E;QAC1E,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;YAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC;QAAC,CAAC;IACvG,CAAC;IAED,OAAO,CAAC,CAAQ,IAAI,IAAI,CAAC,IAAI,GAAI,CAAC,CAAC,MAA8B,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1E,IAAI,CAAC,CAAQ,IAAI,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;6GApB5B,mBAAmB;6DAAnB,mBAAmB;YAlB5B,8BAAiE;YAA7B,yGAAe,gBAAY,IAAC;YAC9D,8BAC+C;YADiD,+GAAe,gBAAY,IAAC;YAE1H,8BAAQ;YAAA,YAAsB;YAAA,iBAAS;YACvC,mCAG4B;YAA1B,wGAAS,mBAAe,IAAC;YAAC,iBAAW;YAErC,AADF,8BAAmC,gBACgC;YAAxB,gGAAS,iBAAa,IAAC;YAAC,YAAmB;YAAA,iBAAS;YAC7F,0BAA4B;YAC5B,iCAAgE;YAAvB,gGAAS,gBAAY,IAAC;YAAC,aAAmB;YAAA,iBAAS;YAC5F,kCAAwF;YAA1B,iGAAS,uBAAe,IAAC;YAAC,aAAiB;YAG/G,AADE,AADE,AAD2G,iBAAS,EAC9G,EACF,EACF;;YAbU,cAAgC;YAAhC,kDAAgC;;YACpC,eAAsB;YAAtB,0CAAsB;YAE5B,cAAc;YAAd,gCAAc;;YAImD,eAAmB;YAAnB,uCAAmB;YAEpB,eAAmB;YAAnB,uCAAmB;YACK,eAAiB;YAAjB,qCAAiB;4BAfvG,YAAY,EAAE,kBAAkB;;iFAqB/B,mBAAmB;cAzB/B,SAAS;eAAC;gBACT,QAAQ,EAAE,mBAAmB;gBAC7B,UAAU,EAAE,IAAI;gBAChB,IAAI,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE;gBACpC,OAAO,EAAE,CAAC,YAAY,EAAE,kBAAkB,CAAC;gBAC3C,eAAe,EAAE,uBAAuB,CAAC,MAAM;gBAC/C,QAAQ,EAAE;;;;;;;;;;;;;;;;;GAiBT;aACF;gBAEU,OAAO;kBAAf,KAAK;YACqB,MAAM;kBAAhC,KAAK;mBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;YACf,IAAI;kBAAb,MAAM;YACG,KAAK;kBAAd,MAAM;YACG,MAAM;kBAAf,MAAM;;kFALI,mBAAmB"}
@@ -0,0 +1,27 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import type { ShapeView, ResizeHandle } from '@bimetal/whiteboard-headless';
3
+ import * as i0 from "@angular/core";
4
+ /** The resize-handle event carries both the corner intent and the raw pointer. */
5
+ export interface ResizeIntent {
6
+ handle: ResizeHandle;
7
+ event: PointerEvent;
8
+ }
9
+ /**
10
+ * The selection overlay for a SINGLE shape: a box at the shape's bounds (in board
11
+ * coords, inside the pan/zoom scene), rotated with the shape, carrying eight
12
+ * resize handles + a rotate knob. Each handle only emits a gesture intent — the
13
+ * controller owns the rotation-aware math. Locked shapes show no handles. 1:1 with
14
+ * the React reference.
15
+ */
16
+ export declare class TransformHandlesComponent {
17
+ view: ShapeView;
18
+ resize: EventEmitter<ResizeIntent>;
19
+ rotate: EventEmitter<PointerEvent>;
20
+ readonly handles: readonly ResizeHandle[];
21
+ get s(): import("@bimetal/whiteboard-data").Shape;
22
+ get boxStyle(): Record<string, string | undefined>;
23
+ onHandleDown(handle: ResizeHandle, event: PointerEvent): void;
24
+ static ɵfac: i0.ɵɵFactoryDeclaration<TransformHandlesComponent, never>;
25
+ static ɵcmp: i0.ɵɵComponentDeclaration<TransformHandlesComponent, "bm-wb-transform-handles", never, { "view": { "alias": "view"; "required": true; }; }, { "resize": "resize"; "rotate": "rotate"; }, never, never, true, never>;
26
+ }
27
+ //# sourceMappingURL=TransformHandles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransformHandles.d.ts","sourceRoot":"","sources":["../../src/components/TransformHandles.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAA2B,MAAM,eAAe,CAAC;AAEhG,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;;AAI5E,kFAAkF;AAClF,MAAM,WAAW,YAAY;IAAG,MAAM,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC;CAAE;AAE5E;;;;;;GAMG;AACH,qBAiBa,yBAAyB;IACT,IAAI,EAAG,SAAS,CAAC;IAClC,MAAM,6BAAoC;IAC1C,MAAM,6BAAoC;IAEpD,QAAQ,CAAC,OAAO,0BAAW;IAE3B,IAAI,CAAC,6CAA8B;IAEnC,IAAI,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CASjD;IAED,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY;yCApB3C,yBAAyB;2CAAzB,yBAAyB;CAuBrC"}
@@ -0,0 +1,83 @@
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/common";
5
+ function TransformHandlesComponent_div_2_Template(rf, ctx) { if (rf & 1) {
6
+ const _r1 = i0.ɵɵgetCurrentView();
7
+ i0.ɵɵelementStart(0, "div", 3);
8
+ i0.ɵɵlistener("pointerdown", function TransformHandlesComponent_div_2_Template_div_pointerdown_0_listener($event) { const h_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onHandleDown(h_r2, $event)); });
9
+ i0.ɵɵelementEnd();
10
+ } if (rf & 2) {
11
+ const h_r2 = ctx.$implicit;
12
+ i0.ɵɵclassMap("bm-wb__handle bm-wb__handle--" + h_r2);
13
+ i0.ɵɵattribute("data-handle", h_r2);
14
+ } }
15
+ const HANDLES = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];
16
+ /**
17
+ * The selection overlay for a SINGLE shape: a box at the shape's bounds (in board
18
+ * coords, inside the pan/zoom scene), rotated with the shape, carrying eight
19
+ * resize handles + a rotate knob. Each handle only emits a gesture intent — the
20
+ * controller owns the rotation-aware math. Locked shapes show no handles. 1:1 with
21
+ * the React reference.
22
+ */
23
+ export class TransformHandlesComponent {
24
+ view;
25
+ resize = new EventEmitter();
26
+ rotate = new EventEmitter();
27
+ handles = HANDLES;
28
+ get s() { return this.view.shape; }
29
+ get boxStyle() {
30
+ const s = this.s;
31
+ return {
32
+ left: `${s.x}px`,
33
+ top: `${s.y}px`,
34
+ width: `${s.width}px`,
35
+ height: `${s.height}px`,
36
+ transform: s.rotation ? `rotate(${s.rotation}deg)` : undefined,
37
+ };
38
+ }
39
+ onHandleDown(handle, event) {
40
+ this.resize.emit({ handle, event });
41
+ }
42
+ static ɵfac = function TransformHandlesComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TransformHandlesComponent)(); };
43
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TransformHandlesComponent, selectors: [["bm-wb-transform-handles"]], hostAttrs: [2, "display", "contents"], inputs: { view: "view" }, outputs: { resize: "resize", rotate: "rotate" }, decls: 3, vars: 2, consts: [["data-testid", "wb-handles", 1, "bm-wb__handles", 3, "ngStyle"], ["data-rotate", "", 1, "bm-wb__rotate", 3, "pointerdown"], [3, "class", "pointerdown", 4, "ngFor", "ngForOf"], [3, "pointerdown"]], template: function TransformHandlesComponent_Template(rf, ctx) { if (rf & 1) {
44
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1);
45
+ i0.ɵɵlistener("pointerdown", function TransformHandlesComponent_Template_div_pointerdown_1_listener($event) { return ctx.rotate.emit($event); });
46
+ i0.ɵɵelementEnd();
47
+ i0.ɵɵtemplate(2, TransformHandlesComponent_div_2_Template, 1, 3, "div", 2);
48
+ i0.ɵɵelementEnd();
49
+ } if (rf & 2) {
50
+ i0.ɵɵproperty("ngStyle", ctx.boxStyle);
51
+ i0.ɵɵadvance(2);
52
+ i0.ɵɵproperty("ngForOf", ctx.handles);
53
+ } }, dependencies: [CommonModule, i1.NgForOf, i1.NgStyle], encapsulation: 2, changeDetection: 0 });
54
+ }
55
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TransformHandlesComponent, [{
56
+ type: Component,
57
+ args: [{
58
+ selector: 'bm-wb-transform-handles',
59
+ standalone: true,
60
+ host: { style: 'display: contents' },
61
+ imports: [CommonModule],
62
+ changeDetection: ChangeDetectionStrategy.OnPush,
63
+ template: `
64
+ <div class="bm-wb__handles" [ngStyle]="boxStyle" data-testid="wb-handles">
65
+ <div class="bm-wb__rotate" data-rotate (pointerdown)="rotate.emit($event)"></div>
66
+ <div
67
+ *ngFor="let h of handles"
68
+ [class]="'bm-wb__handle bm-wb__handle--' + h"
69
+ [attr.data-handle]="h"
70
+ (pointerdown)="onHandleDown(h, $event)"></div>
71
+ </div>
72
+ `,
73
+ }]
74
+ }], null, { view: [{
75
+ type: Input,
76
+ args: [{ required: true }]
77
+ }], resize: [{
78
+ type: Output
79
+ }], rotate: [{
80
+ type: Output
81
+ }] }); })();
82
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TransformHandlesComponent, { className: "TransformHandlesComponent", filePath: "components/transformhandles.ts", lineNumber: 34 }); })();
83
+ //# sourceMappingURL=TransformHandles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransformHandles.js","sourceRoot":"","sources":["../../src/components/TransformHandles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;;;;;IAwBzC,8BAI0C;IAAxC,2NAAe,iCAAuB,KAAC;IAAC,iBAAM;;;IAF9C,qDAA6C;;;AAvBrD,MAAM,OAAO,GAA4B,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;AAKtF;;;;;;GAMG;AAkBH,MAAM,OAAO,yBAAyB;IACT,IAAI,CAAa;IAClC,MAAM,GAAG,IAAI,YAAY,EAAgB,CAAC;IAC1C,MAAM,GAAG,IAAI,YAAY,EAAgB,CAAC;IAE3C,OAAO,GAAG,OAAO,CAAC;IAE3B,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAEnC,IAAI,QAAQ;QACV,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QACjB,OAAO;YACL,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI;YAChB,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI;YACf,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI;YACrB,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,IAAI;YACvB,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,CAAC,SAAS;SAC/D,CAAC;IACJ,CAAC;IAED,YAAY,CAAC,MAAoB,EAAE,KAAmB;QACpD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACtC,CAAC;mHAtBU,yBAAyB;6DAAzB,yBAAyB;YAThC,AADF,8BAA0E,aACG;YAApC,qHAAe,uBAAmB,IAAC;YAAC,iBAAM;YACjF,0EAI0C;YAC5C,iBAAM;;YAPsB,sCAAoB;YAG9B,eAAU;YAAV,qCAAU;4BANpB,YAAY;;iFAaX,yBAAyB;cAjBrC,SAAS;eAAC;gBACT,QAAQ,EAAE,yBAAyB;gBACnC,UAAU,EAAE,IAAI;gBAChB,IAAI,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE;gBACpC,OAAO,EAAE,CAAC,YAAY,CAAC;gBACvB,eAAe,EAAE,uBAAuB,CAAC,MAAM;gBAC/C,QAAQ,EAAE;;;;;;;;;GAST;aACF;gBAE4B,IAAI;kBAA9B,KAAK;mBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;YACf,MAAM;kBAAf,MAAM;YACG,MAAM;kBAAf,MAAM;;kFAHI,yBAAyB"}
@@ -0,0 +1,164 @@
1
+ import { OnInit, OnDestroy, OnChanges, SimpleChanges, AfterViewInit, ElementRef } from '@angular/core';
2
+ import type { Point, WhiteboardControllerSnapshot, WhiteboardLocale, WhiteboardConfigInput, ShapeView, Tool, AlignEdge, DistributeAxis, StyleInput } from '@bimetal/whiteboard-headless';
3
+ import type { WhiteboardStore } from '@bimetal/whiteboard-data';
4
+ import { type ResizeIntent } from './TransformHandles.js';
5
+ import * as i0 from "@angular/core";
6
+ export interface WhiteboardProps {
7
+ store: WhiteboardStore;
8
+ canvasId: string;
9
+ config?: WhiteboardConfigInput;
10
+ darkMode?: boolean;
11
+ onError?: (err: unknown) => void;
12
+ }
13
+ interface ConnectorView {
14
+ id: string;
15
+ d: string;
16
+ stroke: string;
17
+ strokeWidth: number;
18
+ dash: string | undefined;
19
+ opacity: number;
20
+ markerEnd: string | null;
21
+ markerStart: string | null;
22
+ }
23
+ interface GuideLine {
24
+ axis: 'x' | 'y';
25
+ x1: number;
26
+ y1: number;
27
+ x2: number;
28
+ y2: number;
29
+ }
30
+ interface PinView {
31
+ id: string;
32
+ x: number;
33
+ y: number;
34
+ resolved: boolean;
35
+ text: string;
36
+ glyph: string;
37
+ }
38
+ interface LaserSeg {
39
+ x1: number;
40
+ y1: number;
41
+ x2: number;
42
+ y2: number;
43
+ opacity: number;
44
+ }
45
+ interface ThreadView {
46
+ id: string;
47
+ at: Point;
48
+ text: string;
49
+ resolved: boolean;
50
+ }
51
+ /**
52
+ * The Angular whiteboard — a thin, standalone-component binding over the canonical
53
+ * `@bimetal/whiteboard-headless` controller. Owns DOM only: it converts
54
+ * `clientX/Y → boardPoint` through the controller's viewport (`screenToBoard` —
55
+ * the binding's ONE piece of geometry), wires window pointer + wheel events, and
56
+ * renders the snapshot. Every interaction decision (tool FSM, create/drag/marquee,
57
+ * pan/zoom math, input policy) lives in the controller. 1:1 with the React
58
+ * reference.
59
+ */
60
+ export declare class WhiteboardComponent implements OnInit, AfterViewInit, OnDestroy, OnChanges {
61
+ store: WhiteboardStore;
62
+ canvasId: string;
63
+ config?: WhiteboardConfigInput;
64
+ darkMode: boolean;
65
+ /** Surfaces infrastructure errors (a domain rejection is an undo toast). */
66
+ onError?: (err: unknown) => void;
67
+ viewportRef?: ElementRef<HTMLDivElement>;
68
+ private binding;
69
+ private zone;
70
+ readonly tools: readonly {
71
+ id: Tool;
72
+ glyph: string;
73
+ }[];
74
+ readonly aligns: readonly {
75
+ edge: AlignEdge;
76
+ glyph: string;
77
+ }[];
78
+ readonly distributes: readonly {
79
+ axis: DistributeAxis;
80
+ glyph: string;
81
+ }[];
82
+ readonly arrowId: string;
83
+ readonly markerUrl: string;
84
+ get ctrl(): import("@bimetal/whiteboard-headless").WhiteboardController;
85
+ get snapshot(): WhiteboardControllerSnapshot;
86
+ get viewport(): import("@bimetal/whiteboard-headless").Viewport;
87
+ get activeTool(): Tool;
88
+ get cfg(): import("@bimetal/whiteboard-headless").WhiteboardConfig;
89
+ get locale(): WhiteboardLocale;
90
+ get zoomPct(): number;
91
+ get viewportClass(): string;
92
+ get sceneTransform(): string;
93
+ get viewportVars(): Record<string, string>;
94
+ private get selectedViews();
95
+ get hasSel(): boolean;
96
+ get canAlign(): boolean;
97
+ get canDistribute(): boolean;
98
+ get canGroup(): boolean;
99
+ get canUngroup(): boolean;
100
+ get transformView(): ShapeView | null;
101
+ get panelStyle(): import("@bimetal/whiteboard-data").ShapeStyle | null;
102
+ get undo(): import("@bimetal/headless-core").LastAction | null;
103
+ get dialogShape(): {
104
+ id: string;
105
+ text: string;
106
+ } | null;
107
+ get connectorViews(): ConnectorView[];
108
+ get connectorPreviewD(): string | null;
109
+ get drawPreviewPath(): string | null;
110
+ get guideLines(): GuideLine[];
111
+ get commentPins(): PinView[];
112
+ get laserSegments(): LaserSeg[] | null;
113
+ get draftAt(): Point | null;
114
+ get openThread(): ThreadView | null;
115
+ toolClass(id: string): string;
116
+ pinClass(p: PinView): string;
117
+ private boardOf;
118
+ private onMove;
119
+ private onUp;
120
+ private onCancel;
121
+ private onWheel;
122
+ ngOnInit(): void;
123
+ ngAfterViewInit(): void;
124
+ ngOnChanges(changes: SimpleChanges): void;
125
+ ngOnDestroy(): void;
126
+ onViewportPointerDown(e: PointerEvent): void;
127
+ onShapeDown(shapeId: string, e: PointerEvent): void;
128
+ onShapeDblClick(shapeId: string, e: MouseEvent): void;
129
+ onResizeIntent(shapeId: string, intent: ResizeIntent): void;
130
+ onRotate(shapeId: string, e: PointerEvent): void;
131
+ onKeydown(e: KeyboardEvent): void;
132
+ onTool(id: Tool): void;
133
+ onBringToFront(): void;
134
+ onSendToBack(): void;
135
+ onToggleLock(): void;
136
+ onGroup(): void;
137
+ onUngroup(): void;
138
+ onDuplicate(): void;
139
+ onDeleteSelection(): void;
140
+ onAlign(edge: AlignEdge): void;
141
+ onDistribute(axis: DistributeAxis): void;
142
+ onResetViewport(): void;
143
+ onUndo(): void;
144
+ onStyleInput(raw: StyleInput): void;
145
+ onPinClick(id: string, e: MouseEvent): void;
146
+ onCommitDraft(text: string): void;
147
+ onCancelDraft(): void;
148
+ onCloseThread(): void;
149
+ onCommitThread(id: string, text: string): void;
150
+ onResolveThread(id: string): void;
151
+ onDeleteThread(id: string): void;
152
+ onSaveShape(text: string): void;
153
+ onCloseDialog(): void;
154
+ onDeleteShape(id: string): void;
155
+ stop(e: Event): void;
156
+ trackShape(_i: number, v: ShapeView): string;
157
+ trackConnector(_i: number, c: ConnectorView): string;
158
+ trackPin(_i: number, p: PinView): string;
159
+ trackIndex(i: number): number;
160
+ static ɵfac: i0.ɵɵFactoryDeclaration<WhiteboardComponent, never>;
161
+ static ɵcmp: i0.ɵɵComponentDeclaration<WhiteboardComponent, "bm-whiteboard", never, { "store": { "alias": "store"; "required": true; }; "canvasId": { "alias": "canvasId"; "required": true; }; "config": { "alias": "config"; "required": false; }; "darkMode": { "alias": "darkMode"; "required": false; }; "onError": { "alias": "onError"; "required": false; }; }, {}, never, never, true, never>;
162
+ }
163
+ export {};
164
+ //# sourceMappingURL=Whiteboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Whiteboard.d.ts","sourceRoot":"","sources":["../../src/components/Whiteboard.ts"],"names":[],"mappings":"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"}