@grafloria/element 0.4.54 → 0.4.56

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.
@@ -790,6 +790,54 @@ export function createDashboardHandle(ctx) {
790
790
  * looked like. Undo reopens the page (its grid re-binds on the history event)
791
791
  * and then the widget comes back into it.
792
792
  */
793
+ /**
794
+ * A CONTAINER CROSSES BOARDS by hand (tile first, 4b-ii): a section carried
795
+ * into a page, a tab container into a section. The membership commands
796
+ * move it; this moves what the kit keeps beside the membership — the
797
+ * authored entry from the old board's list to the new one's, and which
798
+ * board the container is filed under — as a register/unregister pair, the
799
+ * way the tear-out plan files a group it creates. `toJSON()` reads the
800
+ * membership, so the document is right either way; the registry is what
801
+ * `addWidget` and the page-closing rule read.
802
+ */
803
+ ctx.moveContainerCommands = (containerId, fromBoardId, toBoardId) => {
804
+ if (!ctx.boardGroups.has(containerId))
805
+ return [];
806
+ const spec = specById.get(containerId);
807
+ const fromArr = ctx.boardWidgets.get(fromBoardId);
808
+ const toArr = ctx.boardWidgets.get(toBoardId);
809
+ const prevFiled = viewOfWidget.get(containerId);
810
+ let slot = -1;
811
+ const moved = {
812
+ register: () => {
813
+ viewOfWidget.set(containerId, toBoardId);
814
+ if (spec && fromArr) {
815
+ const i = fromArr.findIndex((w) => w.id === containerId);
816
+ if (i >= 0) {
817
+ slot = i;
818
+ fromArr.splice(i, 1);
819
+ }
820
+ }
821
+ if (spec && toArr && !toArr.some((w) => w.id === containerId))
822
+ toArr.push(spec);
823
+ },
824
+ unregister: () => {
825
+ if (prevFiled !== undefined)
826
+ viewOfWidget.set(containerId, prevFiled);
827
+ else
828
+ viewOfWidget.delete(containerId);
829
+ if (spec && toArr) {
830
+ const i = toArr.findIndex((w) => w.id === containerId);
831
+ if (i >= 0)
832
+ toArr.splice(i, 1);
833
+ }
834
+ if (spec && fromArr && !fromArr.some((w) => w.id === containerId)) {
835
+ fromArr.splice(slot < 0 ? fromArr.length : Math.min(slot, fromArr.length), 0, spec);
836
+ }
837
+ },
838
+ };
839
+ return [new RegisterWidgetCommand(moved, 'register')];
840
+ };
793
841
  ctx.closePageIfEmptied = (boardId, leaving) => {
794
842
  var _a, _b, _c, _d, _e, _f;
795
843
  const model = (_a = ctx.apiRef) === null || _a === void 0 ? void 0 : _a.getModel();
@@ -2303,7 +2351,7 @@ export function dashboard(options) {
2303
2351
  if (e.type === 'commit')
2304
2352
  reportChanged();
2305
2353
  (_b = (_a = options.binder) === null || _a === void 0 ? void 0 : _a.onGesture) === null || _b === void 0 ? void 0 : _b.call(_a, e);
2306
- }, onSelect: (id) => { var _a; return (_a = options.onSelect) === null || _a === void 0 ? void 0 : _a.call(options, id, v.id); } }), captionHooks(v.id)), { onMemberLeaving: (memberId) => { var _a, _b; return (_b = (_a = ctx.closePageIfEmptied) === null || _a === void 0 ? void 0 : _a.call(ctx, v.id, memberId)) !== null && _b !== void 0 ? _b : []; } }), (ctx.tabDrop ? { tabDrop: ctx.tabDrop } : {}));
2354
+ }, onSelect: (id) => { var _a; return (_a = options.onSelect) === null || _a === void 0 ? void 0 : _a.call(options, id, v.id); } }), captionHooks(v.id)), { onMemberLeaving: (memberId) => { var _a, _b; return (_b = (_a = ctx.closePageIfEmptied) === null || _a === void 0 ? void 0 : _a.call(ctx, v.id, memberId)) !== null && _b !== void 0 ? _b : []; }, onMemberMoving: (memberId, from, to) => { var _a, _b; return (_b = (_a = ctx.moveContainerCommands) === null || _a === void 0 ? void 0 : _a.call(ctx, memberId, from, to)) !== null && _b !== void 0 ? _b : []; } }), (ctx.tabDrop ? { tabDrop: ctx.tabDrop } : {}));
2307
2355
  if (viewLayout === 'split') {
2308
2356
  return bindDashboardSplit(a, g, Object.assign(Object.assign(Object.assign({}, common), { columns: (_h = v.columns) !== null && _h !== void 0 ? _h : columns, baseRowHeight: rowHeight, designHeight: viewH(v) }), (v.tree !== undefined ? { tree: v.tree } : {})));
2309
2357
  }
@@ -2321,7 +2369,7 @@ export function dashboard(options) {
2321
2369
  if (e.type === 'commit')
2322
2370
  reportChanged();
2323
2371
  (_b = (_a = options.binder) === null || _a === void 0 ? void 0 : _a.onGesture) === null || _b === void 0 ? void 0 : _b.call(_a, e);
2324
- }, onSelect: (id) => { var _a, _b; return (_a = options.onSelect) === null || _a === void 0 ? void 0 : _a.call(options, id, (_b = ctx.viewOfBoard.get(w.id)) !== null && _b !== void 0 ? _b : ctx.active); } }), captionHooks((_h = ctx.viewOfBoard.get(w.id)) !== null && _h !== void 0 ? _h : ctx.active)), { onMemberLeaving: (memberId) => { var _a, _b; return (_b = (_a = ctx.closePageIfEmptied) === null || _a === void 0 ? void 0 : _a.call(ctx, w.id, memberId)) !== null && _b !== void 0 ? _b : []; } }), (ctx.tabDrop ? { tabDrop: ctx.tabDrop } : {}));
2372
+ }, onSelect: (id) => { var _a, _b; return (_a = options.onSelect) === null || _a === void 0 ? void 0 : _a.call(options, id, (_b = ctx.viewOfBoard.get(w.id)) !== null && _b !== void 0 ? _b : ctx.active); } }), captionHooks((_h = ctx.viewOfBoard.get(w.id)) !== null && _h !== void 0 ? _h : ctx.active)), { onMemberLeaving: (memberId) => { var _a, _b; return (_b = (_a = ctx.closePageIfEmptied) === null || _a === void 0 ? void 0 : _a.call(ctx, w.id, memberId)) !== null && _b !== void 0 ? _b : []; }, onMemberMoving: (memberId, from, to) => { var _a, _b; return (_b = (_a = ctx.moveContainerCommands) === null || _a === void 0 ? void 0 : _a.call(ctx, memberId, from, to)) !== null && _b !== void 0 ? _b : []; } }), (ctx.tabDrop ? { tabDrop: ctx.tabDrop } : {}));
2325
2373
  if (((_j = ctx.layoutOf.get(w.id)) !== null && _j !== void 0 ? _j : w.layout) === 'split') {
2326
2374
  // A splitter tree covering the pane; the pane's frame is the parent's
2327
2375
  // slab, so no design height of its own.
@@ -0,0 +1,15 @@
1
+ /** Which edges of a tile a press takes, and the cursor that says so (tile first, step 4b-i: out of the binder). */
2
+ /** A press this close (CSS px) to a tile's border takes that edge for a resize. */
3
+ export declare const EDGE_GRIP = 7;
4
+ export interface ResizeEdges {
5
+ n: boolean;
6
+ e: boolean;
7
+ s: boolean;
8
+ w: boolean;
9
+ }
10
+ export declare const NO_EDGES: ResizeEdges;
11
+ /** Which of a host's edges a client point is within EDGE_GRIP of (none when outside). */
12
+ export declare function edgesNear(host: Element, cx: number, cy: number): ResizeEdges;
13
+ export declare const anyEdge: (E: ResizeEdges) => boolean;
14
+ /** The resize cursor for a set of edges ('' when none). */
15
+ export declare function cursorFor(E: ResizeEdges): string;
@@ -0,0 +1,30 @@
1
+ /** Which edges of a tile a press takes, and the cursor that says so (tile first, step 4b-i: out of the binder). */
2
+ /** A press this close (CSS px) to a tile's border takes that edge for a resize. */
3
+ export const EDGE_GRIP = 7;
4
+ export const NO_EDGES = { n: false, e: false, s: false, w: false };
5
+ /** Which of a host's edges a client point is within EDGE_GRIP of (none when outside). */
6
+ export function edgesNear(host, cx, cy) {
7
+ const r = host.getBoundingClientRect();
8
+ if (cx < r.left - 2 || cx > r.right + 2 || cy < r.top - 2 || cy > r.bottom + 2)
9
+ return NO_EDGES;
10
+ return {
11
+ n: cy - r.top <= EDGE_GRIP,
12
+ s: r.bottom - cy <= EDGE_GRIP,
13
+ w: cx - r.left <= EDGE_GRIP,
14
+ e: r.right - cx <= EDGE_GRIP,
15
+ };
16
+ }
17
+ export const anyEdge = (E) => E.n || E.e || E.s || E.w;
18
+ /** The resize cursor for a set of edges ('' when none). */
19
+ export function cursorFor(E) {
20
+ const v = E.n || E.s;
21
+ const h = E.e || E.w;
22
+ if (v && h)
23
+ return (E.n && E.w) || (E.s && E.e) ? 'nwse-resize' : 'nesw-resize';
24
+ if (v)
25
+ return 'ns-resize';
26
+ if (h)
27
+ return 'ew-resize';
28
+ return '';
29
+ }
30
+ //# sourceMappingURL=edges.js.map
@@ -53,6 +53,10 @@ import { Command, type DiagramModel, type GridColumnLayout, type GroupModel, typ
53
53
  import { type ToolPointerEvent } from '@grafloria/renderer';
54
54
  import { type CellRect, type WorldRect } from './grid-mapping.js';
55
55
  import { type BesideSide } from './zones.js';
56
+ import { type ResizeEdges } from './edges.js';
57
+ import { type DragHandleOption } from './grip.js';
58
+ export { EDGE_GRIP, anyEdge, type ResizeEdges } from './edges.js';
59
+ export { GRIP_CLASS, DRAG_HANDLE_CLASS, CAPTION_BAND, normalizeDragHandle, dragHandleSelector, gripOf, syncGrip, gripHostOf, pressOnDragHandle, type DragGripOptions, type DragHandleOption } from './grip.js';
56
60
  export { SequenceCommand, SetGroupCellCommand } from './commit.js';
57
61
  /** The slice of a DiagramInstance the binder needs (structural, test-friendly). */
58
62
  export interface DashboardGridApi {
@@ -199,6 +203,12 @@ export interface DashboardGridOptions {
199
203
  * it in the same batch — a tab page emptied by the move closes.
200
204
  */
201
205
  onMemberLeaving?: (memberId: string) => Command[];
206
+ /**
207
+ * A member CONTAINER is moving from this board to another by a gesture
208
+ * (tile first, 4b-ii). Answers the commands that carry the host's own
209
+ * bookkeeping for it — the spec entry, the registry — in the same batch.
210
+ */
211
+ onMemberMoving?: (memberId: string, fromBoardId: string, toBoardId: string) => Command[];
202
212
  /** A widget dragged over a tab STRIP becomes a new tab there: the hooks that hit-test, mark and commit it. */
203
213
  tabDrop?: TabDropHooks;
204
214
  /** Fires after commits/cancels/removals so the page can refocus/refit/flash. */
@@ -275,30 +285,6 @@ export interface DashboardGridOptions {
275
285
  */
276
286
  squeeze?: boolean;
277
287
  }
278
- /** A painted grip: the only drag zone, placed along the card's top edge. */
279
- export interface DragGripOptions {
280
- grip: true;
281
- /** Where along the top edge. Default 'left'. */
282
- position?: 'left' | 'center' | 'right';
283
- /** In the header band, or a tab above the card. Default 'inside'. */
284
- placement?: 'inside' | 'outside';
285
- }
286
- export type DragHandleOption = boolean | string | DragGripOptions;
287
- /** The class of the painted grip element (a child of the node host). */
288
- export declare const GRIP_CLASS = "axdb-grip";
289
- /** The container class that turns the caption strip's grip dots on. */
290
- export declare const DRAG_HANDLE_CLASS = "axdb-drag-handle";
291
- /** A `dragHandle` value with its defaults filled in — the form the handle reports. */
292
- export declare const normalizeDragHandle: (v: DragHandleOption | undefined) => DragHandleOption;
293
- /** The selector a `dragHandle` value names — `null` when the whole card is the handle. */
294
- export declare const dragHandleSelector: (v: DragHandleOption) => string | null;
295
- /** The grip config of a value, or null when it paints no grip. */
296
- export declare const gripOf: (v: DragHandleOption) => DragGripOptions | null;
297
- /**
298
- * Paint (or remove) the grip on one host, and stamp the host with the grip's
299
- * placement so the header can make room for it. `movable` false = no grip.
300
- */
301
- export declare function syncGrip(host: HTMLElement, cfg: DragGripOptions | null, movable: boolean): void;
302
288
  /** The member host a press on a painted grip belongs to (the grip may sit OUTSIDE the host's box). */
303
289
  /**
304
290
  * Is this press OURS? The renderer's tool registry is PAGE-GLOBAL: every
@@ -317,16 +303,6 @@ export declare function ownsPress(container: HTMLElement, diagram: {
317
303
  id: string;
318
304
  };
319
305
  }): boolean;
320
- export declare function gripHostOf(target: Element | null): HTMLElement | null;
321
- /**
322
- * Did a press land on the drag handle? A press INSIDE the handle element
323
- * always does. The default handle is a CAPTION BAR the DevExpress way: the
324
- * strip from the card's top edge down to the header's bottom, padding
325
- * included — so the pointer need not hit the header's text to grab the tile.
326
- */
327
- export declare function pressOnDragHandle(sel: string, target: Element | null, hostEl: HTMLElement | null, clientX: number, clientY: number): boolean;
328
- /** The caption strip of a host with no kit header, px from the card's top. */
329
- export declare const CAPTION_BAND = 28;
330
306
  export interface DashboardGridHandle {
331
307
  /** Rebuild the engine from the group's members + their cells, re-project pixels. */
332
308
  sync(): void;
@@ -705,13 +681,4 @@ export declare function parentPeerOf(container: HTMLElement, groupId: string): B
705
681
  export declare function clearOtherSelections(container: HTMLElement, self: BinderPeer | null): void;
706
682
  export declare function registerBoardPeer(container: HTMLElement, peer: BinderPeer): () => void;
707
683
  export type { BinderPeer };
708
- /** A press this close (CSS px) to a tile's border takes that edge for a resize. */
709
- export declare const EDGE_GRIP = 7;
710
- export interface ResizeEdges {
711
- n: boolean;
712
- e: boolean;
713
- s: boolean;
714
- w: boolean;
715
- }
716
- export declare const anyEdge: (E: ResizeEdges) => boolean;
717
684
  export declare function bindDashboardGrid(api: DashboardGridApi, group: GroupModel, options?: DashboardGridOptions): DashboardGridHandle;