@libs-ui/services-grid-layout 0.2.357-20 → 0.2.357-21

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.
@@ -1,5 +1,5 @@
1
- import { OnDestroy } from '@angular/core';
2
- import { T_gridLayout_actionEvent, T_gridLayout_addEvent, T_gridLayout_changeEvent, T_gridLayout_node } from '../interfaces/grid-layout.interface';
1
+ import { AfterViewInit, OnDestroy, TemplateRef } from '@angular/core';
2
+ import { T_gridLayout_actionEvent, T_gridLayout_addEvent, T_gridLayout_changeEvent, T_gridLayout_dropEvent, T_gridLayout_dropGhost, T_gridLayout_node, T_gridLayout_toolbarContext, T_gridLayout_zoomPreset } from '../interfaces/grid-layout.interface';
3
3
  import * as i0 from "@angular/core";
4
4
  /**
5
5
  * Mặt phẳng kéo thả. Đệ quy: khối có `children` thì ruột nó lại là một mặt phẳng nữa.
@@ -7,7 +7,7 @@ import * as i0 from "@angular/core";
7
7
  * Nơi dùng KHÔNG dựng component này trực tiếp cho từng khối — chỉ đặt MỘT thẻ ở gốc và truyền
8
8
  * `nodeComponentType` qua `LibsUiGridLayoutService.init()`. Thư viện tự gắn component cho mọi khối.
9
9
  */
10
- export declare class LibsUiGridLayoutCanvasComponent implements OnDestroy {
10
+ export declare class LibsUiGridLayoutCanvasComponent implements AfterViewInit, OnDestroy {
11
11
  /**
12
12
  * @internal Chỉ mặt phẳng LỒNG dùng — thư viện tự truyền khi vẽ ruột container.
13
13
  *
@@ -17,6 +17,23 @@ export declare class LibsUiGridLayoutCanvasComponent implements OnDestroy {
17
17
  readonly node: import("@angular/core").InputSignal<T_gridLayout_node | undefined>;
18
18
  /** @internal Chỉ mặt phẳng LỒNG dùng — thư viện tự truyền. */
19
19
  readonly depth: import("@angular/core").InputSignal<number>;
20
+ /**
21
+ * Ẩn hẳn thanh công cụ mặc định (thêm-vào-trong · gộp/tách · xoá) của MỌI khối.
22
+ *
23
+ * Dùng khi sản phẩm gom các hành động đó vào chỗ khác — vd một nút ⋮ nằm trong chính nội dung
24
+ * khối. Ẩn rồi thì `outRemoveNode` · `outAddBlockInside` · `outToggleType` không còn nguồn phát
25
+ * từ thư viện; nơi dùng tự gọi `removeBlock` · `addBlock` · `toggleType` của service.
26
+ */
27
+ readonly hiddenToolbar: import("@angular/core").InputSignalWithTransform<boolean, boolean | undefined>;
28
+ /**
29
+ * Template tự vẽ thanh công cụ, thay cho bộ nút mặc định.
30
+ *
31
+ * Nhận context `{ $implicit: node, isContainer, canAddInside, canToggleType }` để nơi dùng vẽ đúng
32
+ * nút cho từng khối, rồi gọi ngược qua `outRemoveNode` · `outAddBlockInside` · `outToggleType`
33
+ * bằng chính các hàm trong context. Truyền cả `hiddenToolbar` và `templateToolbar` thì
34
+ * `hiddenToolbar` thắng — không vẽ gì.
35
+ */
36
+ readonly templateToolbar: import("@angular/core").InputSignal<TemplateRef<T_gridLayout_toolbarContext> | undefined>;
20
37
  /**
21
38
  * Bố cục vừa đổi do NGƯỜI DÙNG kéo hoặc đổi kích thước khối.
22
39
  *
@@ -36,12 +53,60 @@ export declare class LibsUiGridLayoutCanvasComponent implements OnDestroy {
36
53
  readonly outAddBlockInside: import("@angular/core").OutputEmitterRef<T_gridLayout_addEvent>;
37
54
  /** Người dùng bấm nút GỘP/TÁCH. Thư viện chưa làm gì — gọi `event.confirm()` để thực hiện. */
38
55
  readonly outToggleType: import("@angular/core").OutputEmitterRef<T_gridLayout_actionEvent>;
56
+ /** Bật tính năng thu phóng (zoom) canvas. Chỉ áp dụng cho canvas gốc (depth 0). */
57
+ readonly enableZoom: import("@angular/core").InputSignalWithTransform<boolean, boolean | undefined>;
58
+ /** Tỷ lệ thu phóng hiện tại (hỗ trợ two-way binding [(zoom)]="myZoom"). */
59
+ readonly zoom: import("@angular/core").ModelSignal<number | undefined>;
60
+ /** Giới hạn thu phóng tối thiểu. Mặc định 0.4 (40%). */
61
+ readonly zoomMin: import("@angular/core").InputSignal<number>;
62
+ /** Giới hạn thu phóng tối đa. Mặc định 1.5 (150%). */
63
+ readonly zoomMax: import("@angular/core").InputSignal<number>;
64
+ /** Bước nhảy thu phóng mỗi lần bấm +/- hoặc lăn chuột. Mặc định 0.05 (5%). */
65
+ readonly zoomStep: import("@angular/core").InputSignal<number>;
66
+ /** Chiều rộng chuẩn của canvas stage tính bằng px. Mặc định 1668. */
67
+ readonly stageWidth: import("@angular/core").InputSignal<number>;
68
+ /** Chiều cao tối thiểu của canvas stage tính bằng px. Mặc định 937. */
69
+ readonly stageMinHeight: import("@angular/core").InputSignal<number>;
70
+ /** Khóa lưu tỷ lệ thu phóng vào localStorage. Mặc định 'ocb_bi_canvas_zoom'. */
71
+ readonly storageKey: import("@angular/core").InputSignal<string | undefined>;
72
+ /** Hiển thị thanh dock điều khiển thu phóng nổi ở góc dưới phải. Mặc định true. */
73
+ readonly showZoomDock: import("@angular/core").InputSignalWithTransform<boolean, boolean | undefined>;
74
+ /** Tự động vừa màn hình khi tải trang lần đầu nếu khung nhìn nhỏ hơn stageWidth. Mặc định true. */
75
+ readonly autoFitOnLoad: import("@angular/core").InputSignalWithTransform<boolean, boolean | undefined>;
76
+ /** Phát ra khi tỷ lệ thu phóng thay đổi. */
77
+ readonly outZoomChange: import("@angular/core").OutputEmitterRef<number>;
78
+ /** Bật tính năng kéo thả thẻ từ bên ngoài vào canvas (mặc định true) */
79
+ readonly enableExternalDrop: import("@angular/core").InputSignalWithTransform<boolean, boolean | undefined>;
80
+ /** Luôn hiển thị đường kẻ lưới 24 cột */
81
+ readonly showGridLines: import("@angular/core").InputSignalWithTransform<boolean, boolean | undefined>;
82
+ /** Mã id của khối đang được chọn */
83
+ readonly selectedNodeId: import("@angular/core").ModelSignal<string | null | undefined>;
84
+ /** Phát ra khi thả một thẻ mới từ bên ngoài vào canvas */
85
+ readonly outDropNode: import("@angular/core").OutputEmitterRef<T_gridLayout_dropEvent>;
86
+ /** Phát ra khi người dùng click chọn một khối */
87
+ readonly outSelectNode: import("@angular/core").OutputEmitterRef<T_gridLayout_node>;
88
+ /** Phát ra khi người dùng bấm nút cấu hình trên thanh công cụ của khối */
89
+ readonly outConfigNode: import("@angular/core").OutputEmitterRef<T_gridLayout_actionEvent>;
39
90
  private readonly gridsterRef;
91
+ private readonly scrollAreaRef;
92
+ private readonly zoomDockRef;
40
93
  /** mỗi ô một chỗ gắn riêng — cùng thứ tự với `children()` */
41
94
  private readonly itemHosts;
95
+ /** Khung xem trước vị trí thả thẻ từ bên ngoài (snapped ghost preview) */
96
+ protected readonly dropGhost: import("@angular/core").WritableSignal<T_gridLayout_dropGhost | undefined>;
97
+ private activeHoveredEl?;
98
+ private rootGridsterEl?;
99
+ /** Menu chọn preset thu phóng đang mở hay đóng */
100
+ protected readonly isMenuOpen: import("@angular/core").WritableSignal<boolean>;
101
+ /** Các mốc thu phóng định sẵn */
102
+ protected readonly zoomPresets: Array<T_gridLayout_zoomPreset>;
42
103
  /** Sáu chấm của tay cầm kéo — chỉ để `@for` dựng đủ 6 thẻ, giá trị không dùng tới. */
43
104
  protected readonly dragBarDots: number[];
44
105
  private readonly service;
106
+ /** Chế độ thu phóng có đang hoạt động trên canvas này không (chỉ root canvas depth 0) */
107
+ protected readonly isZoomActive: import("@angular/core").Signal<boolean>;
108
+ protected readonly currentZoom: import("@angular/core").Signal<number>;
109
+ protected readonly zoomPercent: import("@angular/core").Signal<number>;
45
110
  /**
46
111
  * Node THẬT của mặt phẳng này.
47
112
  *
@@ -55,6 +120,13 @@ export declare class LibsUiGridLayoutCanvasComponent implements OnDestroy {
55
120
  */
56
121
  protected readonly currentNode: import("@angular/core").Signal<T_gridLayout_node>;
57
122
  protected readonly children: import("@angular/core").Signal<T_gridLayout_node[]>;
123
+ /**
124
+ * Bối cảnh cho `templateToolbar`, dựng sẵn theo từng khối.
125
+ *
126
+ * Dựng ở `computed` chứ không gọi hàm trên template: gọi hàm trong template chạy lại mỗi vòng
127
+ * dò thay đổi (rule `fe-coding-convention-templates` mục 6).
128
+ */
129
+ protected readonly toolbarContexts: import("@angular/core").Signal<T_gridLayout_toolbarContext[]>;
58
130
  protected readonly isNestedCanvas: import("@angular/core").Signal<boolean>;
59
131
  /** trần lồng container — khối đã chạm trần thì không cho chuyển thành container */
60
132
  protected readonly maxContainerDepth: import("@angular/core").Signal<number>;
@@ -70,11 +142,28 @@ export declare class LibsUiGridLayoutCanvasComponent implements OnDestroy {
70
142
  protected readonly isEditMode: import("@angular/core").Signal<boolean>;
71
143
  protected readonly gridOptions: import("@angular/core").Signal<import("angular-gridster2").GridsterConfig>;
72
144
  constructor();
145
+ ngAfterViewInit(): void;
73
146
  ngOnDestroy(): void;
74
147
  /** Vẽ lại lưới — gọi khi khung ngoài đổi kích thước hoặc cây vừa đổi diện rộng. */
75
148
  get FunctionControl(): {
76
149
  veLaiLuoi: () => void | undefined;
150
+ zoomIn: () => void;
151
+ zoomOut: () => void;
152
+ resetZoom: () => void;
153
+ fitToScreen: () => void;
154
+ setZoom: (val: number) => void;
77
155
  };
156
+ protected handlerZoomIn(): void;
157
+ protected handlerZoomOut(): void;
158
+ protected handlerResetZoom(): void;
159
+ protected handlerFitScreen(): void;
160
+ protected handlerToggleMenu(): void;
161
+ protected handlerSelectPreset(value: number): void;
162
+ protected isCurrentPreset(value: number): boolean;
163
+ private syncZoomOut;
164
+ protected handlerWheel(event: WheelEvent): void;
165
+ protected handlerDocumentKeyDown(event: KeyboardEvent): void;
166
+ protected handlerDocumentClick(event: MouseEvent): void;
78
167
  protected handlerTrackNode(_index: number, item: T_gridLayout_node): string;
79
168
  /**
80
169
  * 🔴 Chặn `mousedown` nổi lên lưới CHA khi thao tác trong lưới con.
@@ -94,6 +183,17 @@ export declare class LibsUiGridLayoutCanvasComponent implements OnDestroy {
94
183
  protected handlerRemove(event: Event, node: T_gridLayout_node): void;
95
184
  protected handlerAddInside(event: Event, node: T_gridLayout_node): void;
96
185
  protected handlerToggleType(event: Event, node: T_gridLayout_node): void;
186
+ /**
187
+ * Chặn cú bấm trong thanh công cụ nổi lên gridster.
188
+ *
189
+ * Chỉ `stopPropagation`, KHÔNG `preventDefault`: nút bên trong template của nơi dùng vẫn cần
190
+ * hành vi mặc định của mình (mở dropdown, focus…).
191
+ */
192
+ protected handlerStopEvent(event: Event): void;
193
+ /** Phát `outAddBlockInside` — dùng chung cho nút mặc định và `templateToolbar`. */
194
+ private emitAddInside;
195
+ /** Phát `outToggleType` — dùng chung cho nút mặc định và `templateToolbar`. */
196
+ private emitToggleType;
97
197
  /** khối này có phải container không (có khối con) */
98
198
  protected isContainer(item: T_gridLayout_node): boolean;
99
199
  /** container đã chạm trần lồng thì không cho thêm khối vào trong nữa */
@@ -102,6 +202,13 @@ export declare class LibsUiGridLayoutCanvasComponent implements OnDestroy {
102
202
  protected canToggleType(item: T_gridLayout_node): boolean;
103
203
  protected handlerBlockParentDrag(event: Event): void;
104
204
  protected handlerMouseDownTrongLuoi(event: Event): void;
205
+ protected handlerSelectNode(node: T_gridLayout_node, event?: MouseEvent): void;
206
+ protected handlerConfig(event: Event, node: T_gridLayout_node): void;
207
+ protected handlerDragOver(event: DragEvent): void;
208
+ protected handlerDragLeave(event: DragEvent): void;
209
+ protected handlerDrop(event: DragEvent): void;
210
+ private cleanupHoveredGroup;
211
+ private cleanupDragGrid;
105
212
  static ɵfac: i0.ɵɵFactoryDeclaration<LibsUiGridLayoutCanvasComponent, never>;
106
- static ɵcmp: i0.ɵɵComponentDeclaration<LibsUiGridLayoutCanvasComponent, "libs_ui-services-grid_layout-canvas", never, { "node": { "alias": "node"; "required": false; "isSignal": true; }; "depth": { "alias": "depth"; "required": false; "isSignal": true; }; }, { "outChange": "outChange"; "outRemoveNode": "outRemoveNode"; "outAddBlockInside": "outAddBlockInside"; "outToggleType": "outToggleType"; }, never, never, true, never>;
213
+ static ɵcmp: i0.ɵɵComponentDeclaration<LibsUiGridLayoutCanvasComponent, "libs_ui-services-grid_layout-canvas", never, { "node": { "alias": "node"; "required": false; "isSignal": true; }; "depth": { "alias": "depth"; "required": false; "isSignal": true; }; "hiddenToolbar": { "alias": "hiddenToolbar"; "required": false; "isSignal": true; }; "templateToolbar": { "alias": "templateToolbar"; "required": false; "isSignal": true; }; "enableZoom": { "alias": "enableZoom"; "required": false; "isSignal": true; }; "zoom": { "alias": "zoom"; "required": false; "isSignal": true; }; "zoomMin": { "alias": "zoomMin"; "required": false; "isSignal": true; }; "zoomMax": { "alias": "zoomMax"; "required": false; "isSignal": true; }; "zoomStep": { "alias": "zoomStep"; "required": false; "isSignal": true; }; "stageWidth": { "alias": "stageWidth"; "required": false; "isSignal": true; }; "stageMinHeight": { "alias": "stageMinHeight"; "required": false; "isSignal": true; }; "storageKey": { "alias": "storageKey"; "required": false; "isSignal": true; }; "showZoomDock": { "alias": "showZoomDock"; "required": false; "isSignal": true; }; "autoFitOnLoad": { "alias": "autoFitOnLoad"; "required": false; "isSignal": true; }; "enableExternalDrop": { "alias": "enableExternalDrop"; "required": false; "isSignal": true; }; "showGridLines": { "alias": "showGridLines"; "required": false; "isSignal": true; }; "selectedNodeId": { "alias": "selectedNodeId"; "required": false; "isSignal": true; }; }, { "outChange": "outChange"; "outRemoveNode": "outRemoveNode"; "outAddBlockInside": "outAddBlockInside"; "outToggleType": "outToggleType"; "zoom": "zoomChange"; "outZoomChange": "outZoomChange"; "selectedNodeId": "selectedNodeIdChange"; "outDropNode": "outDropNode"; "outSelectNode": "outSelectNode"; "outConfigNode": "outConfigNode"; }, never, never, true, never>;
107
214
  }
@@ -0,0 +1,31 @@
1
+ import { T_gridLayout_dropGhost, T_gridLayout_externalDragPayload, T_gridLayout_node } from '../interfaces/grid-layout.interface';
2
+ /**
3
+ * Checks whether the rectangular region [x, x + cols) x [y, y + rows)
4
+ * is completely vacant among existing items.
5
+ */
6
+ export declare const isRegionFree: (children: Array<T_gridLayout_node>, x: number, y: number, cols: number, rows: number, ignoredId?: string) => boolean;
7
+ /**
8
+ * Computes optimal (col, row) inside a group container.
9
+ * Snaps flush to adjacent card right edge if slot is vacant.
10
+ */
11
+ export declare const findSnapPositionInsideGroup: (children: Array<T_gridLayout_node>, rawCol: number, rawRow: number, innerCols: number, innerRows: number, totalCols?: number) => {
12
+ col: number;
13
+ row: number;
14
+ };
15
+ /**
16
+ * Resolves vertical collisions when inserting a new card at (newNode.x, newNode.y).
17
+ * Any existing card that horizontally overlaps and whose vertical span overlaps
18
+ * or is below the insertion point is pushed down so there is no overlap.
19
+ */
20
+ export declare const resolveCollisionsAndInsert: (children: Array<T_gridLayout_node>, newNode: T_gridLayout_node) => void;
21
+ export declare function parseDropPayload<T>(activePayload: T | undefined, dataTransfer: DataTransfer | null): T | undefined;
22
+ interface I_hoveredGroup {
23
+ groupNode: T_gridLayout_node;
24
+ groupGridster: HTMLElement;
25
+ }
26
+ export declare const findHoveredGroup: (elements: Element[], canvasContainer: HTMLElement, root: T_gridLayout_node) => I_hoveredGroup | undefined;
27
+ /**
28
+ * Calculates snapped spatial coordinates and pixel dimensions for drop ghost preview box.
29
+ */
30
+ export declare const calculateDropGhost: (event: DragEvent, canvasContainer: HTMLElement, root: T_gridLayout_node, payload: T_gridLayout_externalDragPayload, totalCols?: number) => T_gridLayout_dropGhost | undefined;
31
+ export {};