@libs-ui/services-grid-layout 0.2.357-25 → 0.2.357-27

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,4 +1,5 @@
1
1
  import { AfterViewInit, OnDestroy, TemplateRef } from '@angular/core';
2
+ import { IScrollOverlayOptions } from '@libs-ui/components-scroll-overlay';
2
3
  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
4
  import * as i0 from "@angular/core";
4
5
  /**
@@ -89,7 +90,48 @@ export declare class LibsUiGridLayoutCanvasComponent implements AfterViewInit, O
89
90
  readonly outConfigNode: import("@angular/core").OutputEmitterRef<T_gridLayout_actionEvent>;
90
91
  private readonly gridsterRef;
91
92
  private readonly scrollAreaRef;
93
+ /**
94
+ * Cầm BẤT CỨ ĐÂU trên khối để kéo, thay cho dải kéo ba chấm.
95
+ *
96
+ * 🔴 Mặc định `false` — giữ nguyên luật đã chốt 28/08/2026 cho mọi sản phẩm: *"phải hover vào vùng
97
+ * màu xanh thì mới kéo thả được cho đồng nhất"*. Nơi dùng nào muốn kiểu "cầm vào thẻ là kéo" thì tự
98
+ * bật, không đổi hành vi của màn khác.
99
+ *
100
+ * Bật lên thì dải kéo biến mất và gridster chuyển sang `ignoreContent: false` — cho kéo từ mọi chỗ
101
+ * TRỪ phần tử mang `ignoreContentClass`. Nhờ vậy khối con nằm trong khối ghép vẫn không nhấc nhầm
102
+ * khối ghép: vỏ khối con đã mang sẵn class chặn đó.
103
+ */
104
+ readonly dragFromAnywhere: import("@angular/core").InputSignal<boolean>;
105
+ /**
106
+ * Nơi dùng đã đẩy vùng cuộn DỌC vào thẳng `<gridster>` (bằng CSS của chính nó).
107
+ *
108
+ * 🔴 Bật cờ này là trả `angular-gridster2` về đúng giả định gốc của nó — `dragMove` đọc
109
+ * `gridster.el.scrollTop`, `scroll()` đo `gridsterElement.offsetHeight` — nên thư viện KHÔNG bắc
110
+ * cầu `scrollTop` sang khung bọc nữa, và vòng tự cuộn khi kéo cũng cuộn thẳng vào gridster.
111
+ *
112
+ * 🔴 PHẢI là input, KHÔNG dò bằng `getComputedStyle`: thanh cuộn nổi của libs-ui mới là thứ đặt
113
+ * `overflow` lên phần tử, mà nó chạy SAU `ngAfterViewInit` — dò lúc đó luôn ra "không cuộn" và cầu
114
+ * nối vẫn cắm vào, nuốt sạch đoạn cuộn thật (đo 15/09/2026: `g.scrollTop = 300` xong đọc lại vẫn 0).
115
+ */
116
+ readonly gridsterOwnsScroll: import("@angular/core").InputSignal<boolean>;
117
+ /**
118
+ * Vẽ thanh cuộn nổi của libs-ui cho mặt phẳng LỒNG (ruột khối ghép).
119
+ *
120
+ * 🔴 Vùng cuộn của mặt phẳng lồng phải giấu thanh cuộn mặc định của trình duyệt — nó dày, xám, và
121
+ * ăn mất bề rộng của lưới con nên 24 cột hẹp lại mỗi khi nội dung vừa đủ tràn. Hệ quả là người
122
+ * dùng cuộn được nhưng KHÔNG THẤY có gì để cuộn: thẻ con nằm dưới đáy trông như biến mất (người
123
+ * dùng chỉ ra 16/09/2026). Bật cờ này để thư viện gắn thanh cuộn nổi — nhìn thấy được mà không
124
+ * chiếm chỗ.
125
+ */
126
+ readonly nestedScrollbar: import("@angular/core").InputSignal<boolean>;
92
127
  private readonly zoomDockRef;
128
+ /** Gỡ cầu nối scroll đã cắm lên phần tử `<gridster>` — xem `bridgeScrollToGridster`. */
129
+ private removeScrollBridge;
130
+ /** Gỡ vòng tự cuộn khi kéo — xem `startDragAutoScroll`. */
131
+ private stopDragAutoScroll;
132
+ /** Khoảng cách tới mép vùng cuộn (px) bắt đầu tự cuộn, và bước cuộn mỗi khung hình. */
133
+ private readonly dragScrollEdge;
134
+ private readonly dragScrollStep;
93
135
  /** mỗi ô một chỗ gắn riêng — cùng thứ tự với `children()` */
94
136
  private readonly itemHosts;
95
137
  /**
@@ -137,6 +179,13 @@ export declare class LibsUiGridLayoutCanvasComponent implements AfterViewInit, O
137
179
  */
138
180
  protected readonly toolbarContexts: import("@angular/core").Signal<T_gridLayout_toolbarContext[]>;
139
181
  protected readonly isNestedCanvas: import("@angular/core").Signal<boolean>;
182
+ /** Chỉ mặt phẳng LỒNG mới vẽ thanh cuộn nổi — mặt phẳng gốc do nơi dùng tự lo. */
183
+ protected readonly showNestedScrollbar: import("@angular/core").Signal<boolean>;
184
+ /**
185
+ * Chỉ cuộn DỌC: bề rộng khối con luôn bị gridster kẹp trong số cột của lưới nên không có gì để
186
+ * cuộn ngang.
187
+ */
188
+ protected readonly nestedScrollOverlayOptions: IScrollOverlayOptions;
140
189
  /**
141
190
  * Khe nhìn thấy giữa các khối CẤP GỐC. Mặt phẳng lồng trả 0 — khối con là các dòng của cùng một
142
191
  * thẻ, tách chúng ra làm chúng trông như thẻ rời.
@@ -168,6 +217,40 @@ export declare class LibsUiGridLayoutCanvasComponent implements AfterViewInit, O
168
217
  setZoom: (val: number) => void;
169
218
  scrollArea: () => HTMLElement | undefined;
170
219
  };
220
+ /**
221
+ * Bắc CẦU NỐI để `<gridster>` báo cáo scroll của KHUNG CUỘN, thay vì scroll của chính nó.
222
+ *
223
+ * 🔴 Vì sao cần: gridster đổi vị trí chuột thành ô lưới bằng
224
+ * `e.clientY + (el.scrollTop - el.offsetTop)` (xem `calculateItemPositionWithoutScale` và
225
+ * `this.offsetTop = this.gridster.el.scrollTop - this.gridster.el.offsetTop` trong
226
+ * `angular-gridster2@18`). Công thức chỉ đúng khi CHÍNH `<gridster>` là phần tử cuộn — đúng như
227
+ * comment đã ghi ở template cho `offsetParent`. Ở nhánh THU PHÓNG, việc cuộn nằm ở `#scrollArea`
228
+ * còn `<gridster>` giữ đủ cỡ sân khấu bên trong một tầng `transform: scale`, nên
229
+ * `el.scrollTop` luôn bằng 0: mọi px người dùng cuộn đều vô hình với thư viện. Hệ quả đo được
230
+ * 15/09/2026 trên mặt phẳng cấp trang: tự cuộn lúc kéo không chạy, và nếu nơi dùng tự cuộn thì thẻ
231
+ * đứng im trong khi mặt phẳng trôi.
232
+ *
233
+ * 🔴 CHỈ vá `scrollTop`/`scrollLeft`. CẤM đụng `offsetWidth`/`offsetHeight`: `setGridSize()` của
234
+ * gridster đọc hai cái đó để tính `curColWidth`, đè vào là vỡ bề rộng cột của mọi lưới.
235
+ *
236
+ * 🔴 Chia cho mức phóng: `offsetTop` là px BỐ CỤC, còn `scrollTop` của khung cuộn là px đã nhân
237
+ * thu phóng. Không quy đổi thì ở mức phóng khác 100% khối trôi nhanh hơn hoặc chậm hơn con trỏ.
238
+ */
239
+ /** Phần tử thật sự cuộn theo chiều dọc — `<gridster>` nếu nơi dùng đã đẩy cuộn vào trong nó. */
240
+ private vungCuonDoc;
241
+ private bridgeScrollToGridster;
242
+ /**
243
+ * Tự cuộn mặt phẳng khi người dùng kéo khối tới sát mép.
244
+ *
245
+ * 🔴 Tự cuộn sẵn có của gridster (`scrollSensitivity`) không dùng được ở nhánh thu phóng: hàm
246
+ * `scroll()` của nó đo bằng `gridsterElement.offsetHeight`, mà `<gridster>` cao bằng CẢ sân khấu
247
+ * nên con trỏ không bao giờ "tới sát mép" theo con mắt của nó.
248
+ *
249
+ * 🔴 Chỉ cuộn khi thư viện ĐANG kéo thật (`.gridster-item-moving`) — không có chốt này thì một cú
250
+ * bấm bình thường gần mép cũng làm mặt phẳng trôi.
251
+ */
252
+ protected handlerScrollAreaPointerDown(): void;
253
+ private startDragAutoScroll;
171
254
  protected handlerZoomIn(): void;
172
255
  protected handlerZoomOut(): void;
173
256
  protected handlerResetZoom(): void;
@@ -234,5 +317,5 @@ export declare class LibsUiGridLayoutCanvasComponent implements AfterViewInit, O
234
317
  private cleanupHoveredGroup;
235
318
  private cleanupDragGrid;
236
319
  static ɵfac: i0.ɵɵFactoryDeclaration<LibsUiGridLayoutCanvasComponent, never>;
237
- 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>;
320
+ 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; }; "dragFromAnywhere": { "alias": "dragFromAnywhere"; "required": false; "isSignal": true; }; "gridsterOwnsScroll": { "alias": "gridsterOwnsScroll"; "required": false; "isSignal": true; }; "nestedScrollbar": { "alias": "nestedScrollbar"; "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>;
238
321
  }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Cầu nối cho phép một phần tử BÁO CÁO scroll của phần tử khác.
3
+ *
4
+ * 🔴 Vì sao tồn tại: `angular-gridster2` đổi vị trí chuột thành ô lưới bằng
5
+ * `e.clientY + (el.scrollTop - el.offsetTop)` — công thức chỉ đúng khi CHÍNH `<gridster>` là phần tử
6
+ * cuộn. Ở mặt phẳng có THU PHÓNG, việc cuộn nằm ở khung bọc còn `<gridster>` giữ đủ cỡ sân khấu bên
7
+ * trong một tầng `transform: scale`, nên `el.scrollTop` luôn bằng 0: mọi px người dùng cuộn đều vô
8
+ * hình với thư viện. Hệ quả đo được 15/09/2026: tự cuộn lúc kéo không chạy, và nếu nơi dùng tự cuộn
9
+ * thì khối đứng im trong khi mặt phẳng trôi.
10
+ *
11
+ * 🔴 CHỈ vá `scrollTop`/`scrollLeft`. CẤM đụng `offsetWidth`/`offsetHeight`: `setGridSize()` của
12
+ * gridster đọc hai cái đó để tính bề rộng cột, đè vào là vỡ lưới.
13
+ */
14
+ /**
15
+ * Cắm cầu nối, trả về hàm gỡ.
16
+ *
17
+ * `zoom` là hàm chứ không phải số: mức phóng đổi bất cứ lúc nào, đọc lại mỗi lần truy cập mới đúng.
18
+ * Chia cho mức phóng vì `offsetTop` là px BỐ CỤC còn scroll của khung bọc đã nhân thu phóng — không
19
+ * quy đổi thì ở mức khác 100% khối trôi nhanh hơn hoặc chậm hơn con trỏ.
20
+ */
21
+ export declare const bridgeScrollBetweenElements: (target: HTMLElement, source: HTMLElement, zoom: () => number) => (() => void);
22
+ /**
23
+ * Bước cuộn cho một trục khi con trỏ đang ở sát mép vùng cuộn.
24
+ *
25
+ * Trả `0` khi con trỏ còn ở giữa. Mép DƯỚI/PHẢI được soát trước: con trỏ ra ngoài hẳn khung thì
26
+ * `pos` vượt `max`, phải cuộn xuôi chứ không phải ngược.
27
+ */
28
+ export declare const edgeScrollStep: (options: {
29
+ pos: number;
30
+ min: number;
31
+ max: number;
32
+ edge: number;
33
+ step: number;
34
+ }) => number;