orcasvn-react-diagrams 0.2.6 → 0.2.7
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.
- package/CHANGELOG.md +18 -0
- package/README.md +12 -15
- package/ai/api-contract.json +7 -0
- package/ai/manifest.json +1 -1
- package/dist/cjs/examples.js +509 -245
- package/dist/cjs/index.js +79 -53
- package/dist/cjs/types/api/types.d.ts +4 -0
- package/dist/cjs/types/displaybox/demos/autoLayoutDemo.d.ts +2 -0
- package/dist/cjs/types/engine/DiagramEngine.d.ts +2 -0
- package/dist/cjs/types/models/ElementModel.d.ts +1 -0
- package/dist/cjs/types/renderer/konva/KonvaInteraction.d.ts +1 -2
- package/dist/esm/examples.js +509 -245
- package/dist/esm/examples.js.map +1 -1
- package/dist/esm/index.js +79 -53
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/api/types.d.ts +4 -0
- package/dist/esm/types/displaybox/demos/autoLayoutDemo.d.ts +2 -0
- package/dist/esm/types/engine/DiagramEngine.d.ts +2 -0
- package/dist/esm/types/models/ElementModel.d.ts +1 -0
- package/dist/esm/types/renderer/konva/KonvaInteraction.d.ts +1 -2
- package/dist/examples.d.ts +4 -0
- package/dist/index.d.ts +6 -1
- package/docs/API_CONTRACT.md +13 -2
- package/docs/CAPABILITIES.md +1 -0
- package/docs/COMMANDS_EVENTS.md +1 -0
- package/docs/DOCUMENTATION_WORKFLOW.md +2 -1
- package/docs/INTEGRATION_PLAYBOOK.md +1 -0
- package/package.json +1 -1
- package/src/displaybox/demos/AutoLayoutDemoTab.tsx +96 -18
- package/src/displaybox/demos/autoLayoutDemo.ts +150 -31
- package/src/displaybox/demos/nestedDemo.ts +122 -69
|
@@ -29,6 +29,9 @@ export type TextInteractionPolicy = {
|
|
|
29
29
|
movable?: boolean;
|
|
30
30
|
editable?: boolean;
|
|
31
31
|
};
|
|
32
|
+
export type ElementChildInteractionPolicy = {
|
|
33
|
+
movable?: boolean;
|
|
34
|
+
};
|
|
32
35
|
export type BorderSide = 'left' | 'right' | 'top' | 'bottom';
|
|
33
36
|
export type HostAnchorPreset = 'vertices' | 'cardinal';
|
|
34
37
|
export type PortLinkAttachMode = 'external' | 'internal';
|
|
@@ -270,6 +273,7 @@ export type ElementData = {
|
|
|
270
273
|
moveMode?: MoveConstraint;
|
|
271
274
|
anchorCenter?: boolean;
|
|
272
275
|
layout?: ElementLayout;
|
|
276
|
+
childElementInteraction?: ElementChildInteractionPolicy;
|
|
273
277
|
portMovement?: ElementPortMovementPolicy;
|
|
274
278
|
};
|
|
275
279
|
export type PortData = {
|
|
@@ -94,6 +94,8 @@ export default class DiagramEngine {
|
|
|
94
94
|
private shouldRestrictAutoLayoutChildRightGrowth;
|
|
95
95
|
private resolveSnappedGridChildWidth;
|
|
96
96
|
private resolveGridChildWidthResizeTopologyChange;
|
|
97
|
+
private isLeafGridChildResizeCandidate;
|
|
98
|
+
private isEnabledGridChildWidthResizeCandidate;
|
|
97
99
|
getPortWorldPosition(id: string): Point | null;
|
|
98
100
|
getPortLinkWorldPosition(id: string, options?: {
|
|
99
101
|
oppositePortId?: string;
|
|
@@ -11,6 +11,7 @@ export default class ElementModel {
|
|
|
11
11
|
moveMode?: MoveConstraint;
|
|
12
12
|
anchorCenter?: boolean;
|
|
13
13
|
layout?: ElementData['layout'];
|
|
14
|
+
childElementInteraction?: ElementData['childElementInteraction'];
|
|
14
15
|
portMovement?: ElementData['portMovement'];
|
|
15
16
|
constructor(data: ElementData);
|
|
16
17
|
setPosition(position: Point): void;
|
|
@@ -74,7 +74,6 @@ export default class KonvaInteraction {
|
|
|
74
74
|
private readonly occupiedVertexTolerance;
|
|
75
75
|
private readonly nestedHoverElementPadding;
|
|
76
76
|
private emittingElementLinkEnded;
|
|
77
|
-
private panKey;
|
|
78
77
|
constructor(engine: DiagramEngine, config?: InteractionConfig);
|
|
79
78
|
setShapeHoverControls(controls?: ElementShapeHoverControls): void;
|
|
80
79
|
startLinkFromPort(sourcePortId: string, pointer?: Point): void;
|
|
@@ -147,6 +146,7 @@ export default class KonvaInteraction {
|
|
|
147
146
|
private getPortById;
|
|
148
147
|
private getTextById;
|
|
149
148
|
private isTextMovable;
|
|
149
|
+
private isElementMovable;
|
|
150
150
|
private isTextEditable;
|
|
151
151
|
private getLinkById;
|
|
152
152
|
private resolveTextScreenPosition;
|
|
@@ -154,5 +154,4 @@ export default class KonvaInteraction {
|
|
|
154
154
|
private applyStageTransform;
|
|
155
155
|
private cancelLinkDrag;
|
|
156
156
|
private isEditableTarget;
|
|
157
|
-
private isPanKeyPressed;
|
|
158
157
|
}
|
package/dist/examples.d.ts
CHANGED
|
@@ -31,6 +31,9 @@ type TextInteractionPolicy = {
|
|
|
31
31
|
movable?: boolean;
|
|
32
32
|
editable?: boolean;
|
|
33
33
|
};
|
|
34
|
+
type ElementChildInteractionPolicy = {
|
|
35
|
+
movable?: boolean;
|
|
36
|
+
};
|
|
34
37
|
type BorderSide = 'left' | 'right' | 'top' | 'bottom';
|
|
35
38
|
type HostAnchorPreset = 'vertices' | 'cardinal';
|
|
36
39
|
type PortLinkAttachMode = 'external' | 'internal';
|
|
@@ -243,6 +246,7 @@ type ElementData = {
|
|
|
243
246
|
moveMode?: MoveConstraint;
|
|
244
247
|
anchorCenter?: boolean;
|
|
245
248
|
layout?: ElementLayout;
|
|
249
|
+
childElementInteraction?: ElementChildInteractionPolicy;
|
|
246
250
|
portMovement?: ElementPortMovementPolicy;
|
|
247
251
|
};
|
|
248
252
|
type PortData = {
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,9 @@ type TextInteractionPolicy = {
|
|
|
29
29
|
movable?: boolean;
|
|
30
30
|
editable?: boolean;
|
|
31
31
|
};
|
|
32
|
+
type ElementChildInteractionPolicy = {
|
|
33
|
+
movable?: boolean;
|
|
34
|
+
};
|
|
32
35
|
type BorderSide$1 = 'left' | 'right' | 'top' | 'bottom';
|
|
33
36
|
type HostAnchorPreset = 'vertices' | 'cardinal';
|
|
34
37
|
type PortLinkAttachMode = 'external' | 'internal';
|
|
@@ -270,6 +273,7 @@ type ElementData = {
|
|
|
270
273
|
moveMode?: MoveConstraint;
|
|
271
274
|
anchorCenter?: boolean;
|
|
272
275
|
layout?: ElementLayout;
|
|
276
|
+
childElementInteraction?: ElementChildInteractionPolicy;
|
|
273
277
|
portMovement?: ElementPortMovementPolicy;
|
|
274
278
|
};
|
|
275
279
|
type PortData = {
|
|
@@ -543,6 +547,7 @@ declare class ElementModel {
|
|
|
543
547
|
moveMode?: MoveConstraint;
|
|
544
548
|
anchorCenter?: boolean;
|
|
545
549
|
layout?: ElementData['layout'];
|
|
550
|
+
childElementInteraction?: ElementData['childElementInteraction'];
|
|
546
551
|
portMovement?: ElementData['portMovement'];
|
|
547
552
|
constructor(data: ElementData);
|
|
548
553
|
setPosition(position: Point): void;
|
|
@@ -834,4 +839,4 @@ type DiagramEditorHandle = DiagramEngineHandle & {
|
|
|
834
839
|
};
|
|
835
840
|
declare const createDiagramEditor: (config: DiagramEditorConfig) => DiagramEditorHandle;
|
|
836
841
|
|
|
837
|
-
export { type AnchorReference, type BorderSide$1 as BorderSide, type ClientRectLike, type DiagramContainer, type DiagramEditorConfig, type DiagramEditorHandle, type DiagramEngineHandle, type DiagramImageExportOptions, type DiagramPatch, type DiagramState, type EdgeHoverControl, type ElementData, type ElementDeletedEvent, type ElementDropEvent, type ElementLayout, type ElementLayoutAlign, type ElementLayoutAutoResizeMode, type ElementLayoutChildFitCrossAxis, type ElementLayoutChildFitMainAxis, type ElementLayoutGridRowTemplate, type ElementLayoutLabelReservedSpace, type ElementLayoutLabelReservedSpaceMode, type ElementLayoutLabelReservedSpacePlacement, type ElementLayoutMode, type ElementLinkConnectingEvent, type ElementLinkEndedEvent, type ElementLinkStartedEvent, type ElementMovedEvent, type ElementPointerEvent, type ElementPortMovementPolicy, type ElementResizedEvent, type ElementSelectedEvent, type ElementShapeControlDragEvent, type ElementShapeControlEventType, type ElementShapeHoverControlActivationEvent, type ElementShapeHoverControlInteractionEvent, type ElementShapeHoverControls, EllipseMidPoint, type EngineChangeEvent, type EngineConfigEvent, type EngineEventMap, type EnginePointerInfo, type EngineSelectionEvent, type GridLayoutChangedEvent, type GridLayoutChangedReason, type GridRowSnapshot, type HostAnchorPreset, type HoverControlIcon, type LinkColorPoolPolicy, type LinkData, type LinkDeletedEvent, type LinkRouteRefreshMode, type LinkRouteRefreshPolicy, type LinkRoutingMode, type MoveConstraint, type OverlayShapeConfig, type OverlayShapeHandle, type PaperClickEvent, type Point, type PortAnchor, type PortAnchorConstraint, type PortBorderTransformContext, type PortBorderTransformResult, type PortData, type PortDeletedEvent, type PortLinkAttachMode, type PortMouseEvent, type PortMovedEvent, type PortPositionLimits, type PortSelectedEvent, type PositionAxisLimit, type Rect, type RerouteLinksOptions, type ResolvePortAnchorsOptions, type ShapeControlDefinition, type ShapeControlTargetKind, type ShapeControlVisibilityTrigger, type ShapeDrawContext, type ShapeEdgeTarget, type ShapeEllipseMidPointTarget, type ShapeHoverGeometry, type ShapeVertexTarget, type SimpleShape, type Size, type TextData, type TextDeletedEvent, type TextInteractionPolicy, type TextLayout, type TextLayoutBoundsMode, type TextLayoutOverflowMode, type TextLayoutWrapMode, type TextSelectedEvent, type TextUpdatedEvent, type VertexHoverControl, type ViewportFitOptions, createDiagramEditor, createDiagramEngine };
|
|
842
|
+
export { type AnchorReference, type BorderSide$1 as BorderSide, type ClientRectLike, type DiagramContainer, type DiagramEditorConfig, type DiagramEditorHandle, type DiagramEngineHandle, type DiagramImageExportOptions, type DiagramPatch, type DiagramState, type EdgeHoverControl, type ElementChildInteractionPolicy, type ElementData, type ElementDeletedEvent, type ElementDropEvent, type ElementLayout, type ElementLayoutAlign, type ElementLayoutAutoResizeMode, type ElementLayoutChildFitCrossAxis, type ElementLayoutChildFitMainAxis, type ElementLayoutGridRowTemplate, type ElementLayoutLabelReservedSpace, type ElementLayoutLabelReservedSpaceMode, type ElementLayoutLabelReservedSpacePlacement, type ElementLayoutMode, type ElementLinkConnectingEvent, type ElementLinkEndedEvent, type ElementLinkStartedEvent, type ElementMovedEvent, type ElementPointerEvent, type ElementPortMovementPolicy, type ElementResizedEvent, type ElementSelectedEvent, type ElementShapeControlDragEvent, type ElementShapeControlEventType, type ElementShapeHoverControlActivationEvent, type ElementShapeHoverControlInteractionEvent, type ElementShapeHoverControls, EllipseMidPoint, type EngineChangeEvent, type EngineConfigEvent, type EngineEventMap, type EnginePointerInfo, type EngineSelectionEvent, type GridLayoutChangedEvent, type GridLayoutChangedReason, type GridRowSnapshot, type HostAnchorPreset, type HoverControlIcon, type LinkColorPoolPolicy, type LinkData, type LinkDeletedEvent, type LinkRouteRefreshMode, type LinkRouteRefreshPolicy, type LinkRoutingMode, type MoveConstraint, type OverlayShapeConfig, type OverlayShapeHandle, type PaperClickEvent, type Point, type PortAnchor, type PortAnchorConstraint, type PortBorderTransformContext, type PortBorderTransformResult, type PortData, type PortDeletedEvent, type PortLinkAttachMode, type PortMouseEvent, type PortMovedEvent, type PortPositionLimits, type PortSelectedEvent, type PositionAxisLimit, type Rect, type RerouteLinksOptions, type ResolvePortAnchorsOptions, type ShapeControlDefinition, type ShapeControlTargetKind, type ShapeControlVisibilityTrigger, type ShapeDrawContext, type ShapeEdgeTarget, type ShapeEllipseMidPointTarget, type ShapeHoverGeometry, type ShapeVertexTarget, type SimpleShape, type Size, type TextData, type TextDeletedEvent, type TextInteractionPolicy, type TextLayout, type TextLayoutBoundsMode, type TextLayoutOverflowMode, type TextLayoutWrapMode, type TextSelectedEvent, type TextUpdatedEvent, type VertexHoverControl, type ViewportFitOptions, createDiagramEditor, createDiagramEngine };
|
package/docs/API_CONTRACT.md
CHANGED
|
@@ -22,7 +22,7 @@ Primary definitions:
|
|
|
22
22
|
- `initialState?: DiagramState`
|
|
23
23
|
- `elementShapes?: SimpleShape[]`
|
|
24
24
|
- `portShapes?: SimpleShape[]`
|
|
25
|
-
- `panKey?: 'Control' | 'Shift' | 'Alt' | 'Meta'` (default: `'Control'
|
|
25
|
+
- `panKey?: 'Control' | 'Shift' | 'Alt' | 'Meta'` (default: `'Control'`; accepted for compatibility, but built-in empty-paper panning no longer depends on it)
|
|
26
26
|
- `elementShapeHoverControls?: ElementShapeHoverControls`
|
|
27
27
|
- `onElementShapeHoverControlInteraction?: (event: ElementShapeHoverControlInteractionEvent) => void`
|
|
28
28
|
- `onElementShapeHoverControlActivated?: (event: ElementShapeHoverControlActivationEvent) => void` (deprecated callback contract)
|
|
@@ -62,7 +62,7 @@ Defaults:
|
|
|
62
62
|
|
|
63
63
|
### `ElementData`
|
|
64
64
|
- Required: `id`, `position`, `size`, `shapeId`
|
|
65
|
-
- Optional: `style`, `portIds`, `textIds`, `parentId`, `moveMode`, `anchorCenter`, `layout`, `portMovement`
|
|
65
|
+
- Optional: `style`, `portIds`, `textIds`, `parentId`, `moveMode`, `anchorCenter`, `layout`, `childElementInteraction`, `portMovement`
|
|
66
66
|
- Defaults at runtime/model:
|
|
67
67
|
- `portIds`: `[]`
|
|
68
68
|
- `textIds`: `[]`
|
|
@@ -74,6 +74,7 @@ Defaults:
|
|
|
74
74
|
- Optional: `autoResize?: 'grow' | 'grow-shrink'` (default: `'grow'`)
|
|
75
75
|
- Optional grid controls: `gridTemplate?: number[]`
|
|
76
76
|
- Optional grid interaction policy: `gridChildWidthResizeEnabled?: boolean` (default: `false`)
|
|
77
|
+
- Enabled grid-child width topology semantics apply to all direct children of the grid parent, including nested layout-container children.
|
|
77
78
|
- Optional fit controls: `childFitMainAxis?: 'none' | 'distribute'`, `childFitCrossAxis?: 'none' | 'stretch'`, `childFitMinSize?: Partial<Size>`, `childFitMaxSize?: Partial<Size>`
|
|
78
79
|
- Optional child size aliases: `childMinWidth?: number`, `childMaxWidth?: number`, `childMinHeight?: number`, `childMaxHeight?: number`
|
|
79
80
|
- Optional label reservation: `labelReservedSpace?: ElementLayoutLabelReservedSpace`
|
|
@@ -100,6 +101,14 @@ Defaults:
|
|
|
100
101
|
- omitted fields preserve existing built-in behavior
|
|
101
102
|
- programmatic `moveTextTo(...)` and `updateText(...)` remain allowed
|
|
102
103
|
|
|
104
|
+
### `ElementChildInteractionPolicy`
|
|
105
|
+
- Optional `movable?: boolean` (default behavior: `true`)
|
|
106
|
+
- Semantics:
|
|
107
|
+
- configured on a parent element through `ElementData.childElementInteraction`
|
|
108
|
+
- applies to direct child elements only
|
|
109
|
+
- `movable: false` suppresses built-in pointer drag for those direct child elements
|
|
110
|
+
- selection, linking, resize, and programmatic/layout-driven movement remain available
|
|
111
|
+
|
|
103
112
|
### `ElementPortMovementPolicy`
|
|
104
113
|
- `moveMode: 'free' | 'inside' | 'border' | 'anchors'`
|
|
105
114
|
- Optional `anchorConstraint?: PortAnchorConstraint`
|
|
@@ -253,12 +262,14 @@ Defaults:
|
|
|
253
262
|
- `setViewport` emits a `change` patch with `entity: 'viewport'` and skips immediate render scheduling.
|
|
254
263
|
- `zoomToFitElements` computes bounds from `elements[]` only, ignores ports/links/texts for fit expansion, and no-ops when no elements exist.
|
|
255
264
|
- `zoomToFitElements` applies its result through `setViewport`, so hosts observe the standard viewport patch/change path.
|
|
265
|
+
- Built-in empty-paper panning now starts from plain primary-button drag and no longer requires `panKey`; marquee selection uses `Shift + primary drag`.
|
|
256
266
|
- `clientToWorld` uses: `world = (client - containerRect - pan) / zoom`, with zoom fallback to `1` when zoom is `0`.
|
|
257
267
|
- `rerouteLinks(ids)` skips manual links unless `options.includeManual === true`.
|
|
258
268
|
- `linkRouteRefreshPolicy.mode` defaults to `'mutation-only'`; `'redraw-two-endpoint-change'` enables redraw-cycle reroute checks for links whose two endpoints changed.
|
|
259
269
|
- `updateLinkPoints` always marks the link as manual routing.
|
|
260
270
|
- `linkColorPoolPolicy` is opt-in and applies only to newly created links; explicitly provided non-empty `style.stroke` values are preserved.
|
|
261
271
|
- `gridLayoutChanged` is additive and does not replace standard `change` / `elementResized` flows.
|
|
272
|
+
- `ElementData.childElementInteraction.movable = false` suppresses built-in drag only for direct child elements; programmatic `moveElementTo(...)` and layout/ancestor-driven repositioning remain allowed.
|
|
262
273
|
- `TextData.interaction.movable = false` blocks built-in drag only; selection still works and programmatic movement remains allowed.
|
|
263
274
|
- `TextData.interaction.editable = false` blocks built-in textarea editing only; selection still works and programmatic text updates remain allowed.
|
|
264
275
|
- Text layout/overflow resolution updates `displayContent` and emits `textUpdated` when `updateText` is called.
|
package/docs/CAPABILITIES.md
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
- Auto-layout modes: `manual`, `horizontal`, `vertical`, and `grid` with template rows/columns.
|
|
17
17
|
- Auto-layout parent resize policy (`grow` / `grow-shrink`) and child size constraints.
|
|
18
18
|
- Optional grid-child width topology editing with `gridLayoutChanged` host events.
|
|
19
|
+
- Parent-owned direct-child drag suppression through `ElementData.childElementInteraction`.
|
|
19
20
|
- Element shape hover controls with edge/vertex/midpoint targets and interaction callbacks.
|
|
20
21
|
- Optional random link color assignment from configurable pools during link creation.
|
|
21
22
|
- Per-text interaction policy for suppressing built-in text drag and/or built-in text editing.
|
package/docs/COMMANDS_EVENTS.md
CHANGED
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
## Failure Modes
|
|
65
65
|
- Unknown IDs do not emit entity-specific movement/selection events.
|
|
66
66
|
- Canceled link creation emits `elementLinkEnded` with `cancelled=true` and no link creation.
|
|
67
|
+
- Built-in drag on a direct child element emits no move/drop mutation when its parent sets `childElementInteraction.movable = false`.
|
|
67
68
|
- `textUpdated` emits only when target text exists; missing IDs remain no-op.
|
|
68
69
|
|
|
69
70
|
## Verification References
|
|
@@ -59,7 +59,7 @@ When resuming later:
|
|
|
59
59
|
5. Re-run packaging verification.
|
|
60
60
|
|
|
61
61
|
## 6. Current Status
|
|
62
|
-
- Last updated: 2026-05-
|
|
62
|
+
- Last updated: 2026-05-18
|
|
63
63
|
- Last completed step: 10
|
|
64
64
|
- Next step: 7 (optional additional fixture coverage for deeper nested/manual-route scenarios)
|
|
65
65
|
- Owner: Codex (with repository maintainers)
|
|
@@ -85,3 +85,4 @@ When resuming later:
|
|
|
85
85
|
- 2026-05-10: Completed release-doc pass for `v0.2.5`; refreshed release highlights, API contract updates (`linkRouteRefreshPolicy`, `linkColorPoolPolicy`, grid auto-layout fields), and machine-readable contract metadata.
|
|
86
86
|
- 2026-05-10: Ran release validations: `npm run typecheck`, `npm test -- --watchAll=false`, `npm run build`, `npm run rollup-build-lib`, and `npm pack --dry-run`.
|
|
87
87
|
- 2026-05-14: Completed release-doc pass for `v0.2.6`; refreshed release highlights, API contract updates (`zoomToFitElements`, `ViewportFitOptions`, `gridChildWidthResizeEnabled`, `gridLayoutChanged`, `TextInteractionPolicy`), and machine-readable contract metadata.
|
|
88
|
+
- 2026-05-18: Completed release-doc pass for `v0.2.7`; refreshed release highlights, API contract updates (`ElementChildInteractionPolicy`, `childElementInteraction`, and built-in pan gesture behavior), and machine-readable contract metadata.
|
|
@@ -18,6 +18,7 @@ Embed this library into another diagram host while preserving deterministic stat
|
|
|
18
18
|
5. For shape controls, pass `elementShapeHoverControls` and handle `onElementShapeHoverControlInteraction`.
|
|
19
19
|
6. Use `zoomToFitElements(options?)` when the host needs library-owned fit-to-elements navigation instead of recomputing viewport math externally.
|
|
20
20
|
7. Set `TextData.interaction` when some labels must remain read-only or fixed in place while still using library selection behavior.
|
|
21
|
+
8. Set `ElementData.childElementInteraction` on parent elements when direct child nodes should stay selectable but not be draggable through built-in interaction.
|
|
21
22
|
|
|
22
23
|
## Path B: Engine-Only Adapter
|
|
23
24
|
1. Implement `Renderer`:
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useMemo, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import type {
|
|
3
3
|
ElementLayout,
|
|
4
4
|
ElementLayoutAutoResizeMode,
|
|
@@ -13,7 +13,7 @@ import useDemoControls from '../useDemoControls';
|
|
|
13
13
|
import useDemoEditor from '../useDemoEditor';
|
|
14
14
|
import useOffsetSequence from '../useOffsetSequence';
|
|
15
15
|
import type { DemoActionHelpers } from '../types';
|
|
16
|
-
import { autoLayoutDemoConfig } from './autoLayoutDemo';
|
|
16
|
+
import { autoLayoutDemoConfig, createAutoLayoutState } from './autoLayoutDemo';
|
|
17
17
|
import { gridStageStyle } from './shared';
|
|
18
18
|
|
|
19
19
|
const parentOptions = [
|
|
@@ -21,12 +21,17 @@ const parentOptions = [
|
|
|
21
21
|
{ id: 'layout-column', label: 'Vertical layout' },
|
|
22
22
|
{ id: 'layout-grid', label: 'Grid layout' },
|
|
23
23
|
{ id: 'layout-nested', label: 'Nested layout' },
|
|
24
|
+
{ id: 'layout-grid-deep', label: 'Nested grid' },
|
|
25
|
+
{ id: 'layout-lock-compare', label: 'Child lock compare' },
|
|
24
26
|
{ id: 'layout-manual', label: 'Manual (compare)' },
|
|
25
27
|
];
|
|
26
28
|
const shortLabel = 'Parent label lane demo';
|
|
27
29
|
const longLabel =
|
|
28
30
|
'Parent label lane demo with longer content to increase flexible reserved space and push children downward.';
|
|
29
31
|
const defaultGridTemplateText = '[12,4,8]';
|
|
32
|
+
const lockComparisonContainerId = 'layout-lock-compare';
|
|
33
|
+
const lockParentId = 'deep-lock-parent';
|
|
34
|
+
const lockTargetId = 'deep-lock-child-a';
|
|
30
35
|
|
|
31
36
|
const serializeGridTemplate = (template?: ElementLayoutGridRowTemplate[]): string =>
|
|
32
37
|
Array.isArray(template) && template.length > 0 ? JSON.stringify(template) : defaultGridTemplateText;
|
|
@@ -61,8 +66,13 @@ const parseGridTemplate = (value: string): ElementLayoutGridRowTemplate[] | unde
|
|
|
61
66
|
|
|
62
67
|
const AutoLayoutDemo = () => {
|
|
63
68
|
const demo = autoLayoutDemoConfig;
|
|
69
|
+
const [lockComparisonChildren, setLockComparisonChildren] = useState<boolean>(true);
|
|
70
|
+
const createState = useCallback(
|
|
71
|
+
() => createAutoLayoutState(lockComparisonChildren),
|
|
72
|
+
[lockComparisonChildren],
|
|
73
|
+
);
|
|
64
74
|
const { containerRef, editorRef, diagramState, selection, snapEnabled, setSnapEnabled } = useDemoEditor({
|
|
65
|
-
createState
|
|
75
|
+
createState,
|
|
66
76
|
elementShapes: demo.elementShapes,
|
|
67
77
|
portShapes: demo.portShapes,
|
|
68
78
|
});
|
|
@@ -136,6 +146,34 @@ const AutoLayoutDemo = () => {
|
|
|
136
146
|
() => diagramState?.elements.find((el) => el.id === targetId),
|
|
137
147
|
[diagramState, targetId],
|
|
138
148
|
);
|
|
149
|
+
const resolveElementWorldPosition = useCallback(
|
|
150
|
+
(elementId: string) => {
|
|
151
|
+
if (!diagramState) return null;
|
|
152
|
+
const byId = new Map(diagramState.elements.map((element) => [element.id, element]));
|
|
153
|
+
let current = byId.get(elementId);
|
|
154
|
+
if (!current) return null;
|
|
155
|
+
let x = 0;
|
|
156
|
+
let y = 0;
|
|
157
|
+
while (current) {
|
|
158
|
+
x += current.position.x;
|
|
159
|
+
y += current.position.y;
|
|
160
|
+
current = current.parentId ? byId.get(current.parentId) : undefined;
|
|
161
|
+
}
|
|
162
|
+
return { x, y };
|
|
163
|
+
},
|
|
164
|
+
[diagramState],
|
|
165
|
+
);
|
|
166
|
+
const lockDemoContext = useMemo(() => {
|
|
167
|
+
if (!diagramState) return null;
|
|
168
|
+
const outer = diagramState.elements.find((el) => el.id === lockComparisonContainerId);
|
|
169
|
+
const parent = diagramState.elements.find((el) => el.id === lockParentId);
|
|
170
|
+
if (!outer || !parent) return null;
|
|
171
|
+
return {
|
|
172
|
+
outer,
|
|
173
|
+
parent,
|
|
174
|
+
isLocked: parent.childElementInteraction?.movable === false,
|
|
175
|
+
};
|
|
176
|
+
}, [diagramState]);
|
|
139
177
|
|
|
140
178
|
const targetOptions = useMemo(() => {
|
|
141
179
|
const seen = new Set<string>();
|
|
@@ -304,20 +342,28 @@ const AutoLayoutDemo = () => {
|
|
|
304
342
|
}
|
|
305
343
|
};
|
|
306
344
|
|
|
307
|
-
const
|
|
345
|
+
const handleFocusLockTarget = () => {
|
|
308
346
|
const editor = editorRef.current;
|
|
309
347
|
if (!editor) return;
|
|
310
|
-
setTargetId(
|
|
311
|
-
editor.setSelection([
|
|
312
|
-
setLastTrigger('focus
|
|
348
|
+
setTargetId(lockParentId);
|
|
349
|
+
editor.setSelection([lockTargetId]);
|
|
350
|
+
setLastTrigger(lockComparisonChildren ? 'focus locked child' : 'focus unlocked comparison child');
|
|
313
351
|
};
|
|
314
352
|
|
|
315
|
-
const
|
|
353
|
+
const handleFocusLockParent = () => {
|
|
316
354
|
const editor = editorRef.current;
|
|
317
355
|
if (!editor) return;
|
|
318
|
-
setTargetId(
|
|
319
|
-
editor.setSelection([
|
|
320
|
-
setLastTrigger('focus
|
|
356
|
+
setTargetId(lockParentId);
|
|
357
|
+
editor.setSelection([lockParentId]);
|
|
358
|
+
setLastTrigger('focus lock parent');
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
const handleMoveLockTargetViaApi = () => {
|
|
362
|
+
const editor = editorRef.current;
|
|
363
|
+
const parentWorld = resolveElementWorldPosition(lockParentId);
|
|
364
|
+
if (!editor || !lockDemoContext || !parentWorld) return;
|
|
365
|
+
editor.moveElementTo(lockTargetId, parentWorld.x + 56, parentWorld.y + 18);
|
|
366
|
+
setLastTrigger(lockDemoContext.isLocked ? 'locked child moved by api' : 'comparison child moved by api');
|
|
321
367
|
};
|
|
322
368
|
|
|
323
369
|
const alignmentLabel =
|
|
@@ -337,10 +383,19 @@ const AutoLayoutDemo = () => {
|
|
|
337
383
|
remove children to see automatic reflow. Use fit controls, explicit child min/max constraints, auto-resize
|
|
338
384
|
policy, 12-unit grid templates, and the optional grid child width-resize capability to validate current behavior.
|
|
339
385
|
</p>
|
|
386
|
+
<p style={{ marginTop: 0, fontSize: 13, color: '#333' }}>
|
|
387
|
+
Grid child width resize starts enabled for the seeded grid parents in this demo. With the capability on, horizontal
|
|
388
|
+
drag can wrap rows automatically from a flat 12-unit slot array, resize direct grid children in 1/12 steps, and
|
|
389
|
+
reorder peers by drag position. That now includes nested layout parents as well as leaf children. Turn the checkbox
|
|
390
|
+
off on a selected grid parent to compare the older locked-width behavior where a mostly downward drag keeps width
|
|
391
|
+
stable while height changes.
|
|
392
|
+
</p>
|
|
340
393
|
<p style={{ marginTop: 0, marginBottom: 0, fontSize: 13, color: '#333' }}>
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
394
|
+
The <code>layout-grid-deep</code> scenario now keeps the outer container focused on grid behavior with three direct
|
|
395
|
+
grid children, including one nested grid parent that also follows the enabled 12-unit resize path. The child drag
|
|
396
|
+
lock comparison lives beside it in <code> layout-lock-compare</code>; toggle the lock, try dragging
|
|
397
|
+
<code> deep-lock-child-a</code> versus <code> deep-free-child-a</code>, then use the API move shortcut to confirm
|
|
398
|
+
the policy suppresses built-in drag without freezing geometry.
|
|
344
399
|
</p>
|
|
345
400
|
</div>
|
|
346
401
|
<DisplayBoxControls
|
|
@@ -554,6 +609,23 @@ const AutoLayoutDemo = () => {
|
|
|
554
609
|
Enable 12-unit resize on child width drag
|
|
555
610
|
</label>
|
|
556
611
|
|
|
612
|
+
<label htmlFor="lock-comparison-child-drag" style={{ fontWeight: 600 }}>
|
|
613
|
+
Lock comparison child drag
|
|
614
|
+
</label>
|
|
615
|
+
<label style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
|
|
616
|
+
<input
|
|
617
|
+
id="lock-comparison-child-drag"
|
|
618
|
+
type="checkbox"
|
|
619
|
+
checked={lockComparisonChildren}
|
|
620
|
+
onChange={(event) => {
|
|
621
|
+
setLockComparisonChildren(event.target.checked);
|
|
622
|
+
setTargetId(lockComparisonContainerId);
|
|
623
|
+
setLastTrigger(event.target.checked ? 'comparison child drag locked' : 'comparison child drag unlocked');
|
|
624
|
+
}}
|
|
625
|
+
/>
|
|
626
|
+
Reload parent-owned lock demo
|
|
627
|
+
</label>
|
|
628
|
+
|
|
557
629
|
<label htmlFor="label-reserved-mode-select" style={{ fontWeight: 600 }}>
|
|
558
630
|
Label lane
|
|
559
631
|
</label>
|
|
@@ -643,12 +715,15 @@ const AutoLayoutDemo = () => {
|
|
|
643
715
|
>
|
|
644
716
|
Label long
|
|
645
717
|
</button>
|
|
646
|
-
<button type="button" onClick={
|
|
647
|
-
Focus lock
|
|
718
|
+
<button type="button" onClick={handleFocusLockTarget} style={{ padding: '6px 10px' }}>
|
|
719
|
+
Focus lock target
|
|
648
720
|
</button>
|
|
649
|
-
<button type="button" onClick={
|
|
721
|
+
<button type="button" onClick={handleFocusLockParent} style={{ padding: '6px 10px' }}>
|
|
650
722
|
Focus lock parent
|
|
651
723
|
</button>
|
|
724
|
+
<button type="button" onClick={handleMoveLockTargetViaApi} style={{ padding: '6px 10px' }}>
|
|
725
|
+
Move lock target via API
|
|
726
|
+
</button>
|
|
652
727
|
</div>
|
|
653
728
|
|
|
654
729
|
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
|
|
@@ -670,6 +745,10 @@ const AutoLayoutDemo = () => {
|
|
|
670
745
|
<div>
|
|
671
746
|
<div style={{ fontWeight: 600, marginBottom: 6 }}>Scenario tips</div>
|
|
672
747
|
<ul style={{ marginTop: 0, paddingLeft: 18, fontSize: 13 }}>
|
|
748
|
+
<li>Nested grid: target layout-grid-deep to inspect an outer grid where all three direct children, including the nested grid parent, use enabled 12-unit resize.</li>
|
|
749
|
+
<li>Select deep-grid-nested-parent and drag a horizontal resize handle; it should snap in grid units and then reflow inner children inside the resized container.</li>
|
|
750
|
+
<li>Lock comparison: target layout-lock-compare, toggle Lock comparison child drag, then compare deep-lock-child-a and deep-free-child-a.</li>
|
|
751
|
+
<li>Use Move lock target via API after locking; the child should still reposition because the policy only suppresses built-in drag.</li>
|
|
673
752
|
<li>Resize lock: with grid child width resize off, select grid-b and drag diagonally; width should stay fixed.</li>
|
|
674
753
|
<li>Enable grid child width resize, then shrink a full-width grid child; it should snap smaller without flashing, and later siblings should keep their own widths.</li>
|
|
675
754
|
<li>Enable grid child width resize, then grow a child; siblings on the right should keep their own widths and only move down when they no longer fit.</li>
|
|
@@ -734,4 +813,3 @@ const AutoLayoutDemo = () => {
|
|
|
734
813
|
};
|
|
735
814
|
|
|
736
815
|
export default AutoLayoutDemo;
|
|
737
|
-
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { DiagramState } from '../../api';
|
|
2
|
-
import type { DemoConfig } from '../types';
|
|
3
|
-
import { baseElementShapes, basePortShapes } from './shared';
|
|
4
|
-
|
|
5
|
-
const createAutoLayoutState = (): DiagramState => ({
|
|
6
|
-
elements: [
|
|
1
|
+
import type { DiagramState } from '../../api';
|
|
2
|
+
import type { DemoConfig } from '../types';
|
|
3
|
+
import { baseElementShapes, basePortShapes } from './shared';
|
|
4
|
+
|
|
5
|
+
export const createAutoLayoutState = (lockComparisonChildren = true): DiagramState => ({
|
|
6
|
+
elements: [
|
|
7
7
|
{
|
|
8
8
|
id: 'layout-row',
|
|
9
9
|
position: { x: 60, y: 80 },
|
|
@@ -44,14 +44,14 @@ const createAutoLayoutState = (): DiagramState => ({
|
|
|
44
44
|
layout: {
|
|
45
45
|
mode: 'grid',
|
|
46
46
|
padding: { x: 10, y: 10 },
|
|
47
|
-
gap: 10,
|
|
48
|
-
align: 'center',
|
|
49
|
-
autoResize: 'grow-shrink',
|
|
50
|
-
gridTemplate: [12, 4, 8],
|
|
51
|
-
gridChildWidthResizeEnabled:
|
|
52
|
-
childMinWidth: 24,
|
|
53
|
-
childMinHeight: 18,
|
|
54
|
-
},
|
|
47
|
+
gap: 10,
|
|
48
|
+
align: 'center',
|
|
49
|
+
autoResize: 'grow-shrink',
|
|
50
|
+
gridTemplate: [12, 4, 8],
|
|
51
|
+
gridChildWidthResizeEnabled: true,
|
|
52
|
+
childMinWidth: 24,
|
|
53
|
+
childMinHeight: 18,
|
|
54
|
+
},
|
|
55
55
|
},
|
|
56
56
|
{ id: 'grid-a', position: { x: 0, y: 0 }, size: { width: 36, height: 26 }, shapeId: 'default', parentId: 'layout-grid' },
|
|
57
57
|
{ id: 'grid-b', position: { x: 0, y: 0 }, size: { width: 44, height: 24 }, shapeId: 'default', parentId: 'layout-grid' },
|
|
@@ -82,14 +82,95 @@ const createAutoLayoutState = (): DiagramState => ({
|
|
|
82
82
|
size: { width: 110, height: 26 },
|
|
83
83
|
shapeId: 'default',
|
|
84
84
|
parentId: 'nested-stack',
|
|
85
|
-
},
|
|
86
|
-
{ id: 'nested-peer', position: { x: 0, y: 0 }, size: { width: 50, height: 90 }, shapeId: 'default', parentId: 'layout-nested' },
|
|
87
|
-
|
|
88
|
-
{
|
|
89
|
-
id: 'layout-
|
|
90
|
-
position: { x:
|
|
91
|
-
size: { width:
|
|
92
|
-
shapeId: 'panel',
|
|
85
|
+
},
|
|
86
|
+
{ id: 'nested-peer', position: { x: 0, y: 0 }, size: { width: 50, height: 90 }, shapeId: 'default', parentId: 'layout-nested' },
|
|
87
|
+
|
|
88
|
+
{
|
|
89
|
+
id: 'layout-grid-deep',
|
|
90
|
+
position: { x: 640, y: 250 },
|
|
91
|
+
size: { width: 250, height: 180 },
|
|
92
|
+
shapeId: 'panel',
|
|
93
|
+
layout: {
|
|
94
|
+
mode: 'grid',
|
|
95
|
+
padding: { x: 12, y: 12 },
|
|
96
|
+
gap: 12,
|
|
97
|
+
align: 'center',
|
|
98
|
+
autoResize: 'grow-shrink',
|
|
99
|
+
gridTemplate: [4, 4, 4],
|
|
100
|
+
gridChildWidthResizeEnabled: true,
|
|
101
|
+
childMinWidth: 48,
|
|
102
|
+
childMinHeight: 60,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: 'deep-grid-leaf-left',
|
|
107
|
+
position: { x: 0, y: 0 },
|
|
108
|
+
size: { width: 58, height: 72 },
|
|
109
|
+
shapeId: 'default',
|
|
110
|
+
parentId: 'layout-grid-deep',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: 'deep-grid-nested-parent',
|
|
114
|
+
position: { x: 0, y: 0 },
|
|
115
|
+
size: { width: 108, height: 90 },
|
|
116
|
+
shapeId: 'default',
|
|
117
|
+
parentId: 'layout-grid-deep',
|
|
118
|
+
layout: {
|
|
119
|
+
mode: 'grid',
|
|
120
|
+
padding: { x: 8, y: 8 },
|
|
121
|
+
gap: 8,
|
|
122
|
+
align: 'center',
|
|
123
|
+
autoResize: 'grow-shrink',
|
|
124
|
+
gridTemplate: [6, 6],
|
|
125
|
+
gridChildWidthResizeEnabled: true,
|
|
126
|
+
childMinWidth: 18,
|
|
127
|
+
childMinHeight: 18,
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: 'deep-grid-leaf-right',
|
|
132
|
+
position: { x: 0, y: 0 },
|
|
133
|
+
size: { width: 52, height: 78 },
|
|
134
|
+
shapeId: 'default',
|
|
135
|
+
parentId: 'layout-grid-deep',
|
|
136
|
+
},
|
|
137
|
+
{ id: 'deep-grid-a', position: { x: 0, y: 0 }, size: { width: 34, height: 24 }, shapeId: 'default', parentId: 'deep-grid-nested-parent' },
|
|
138
|
+
{ id: 'deep-grid-b', position: { x: 0, y: 0 }, size: { width: 40, height: 28 }, shapeId: 'default', parentId: 'deep-grid-nested-parent' },
|
|
139
|
+
{ id: 'deep-grid-c', position: { x: 0, y: 0 }, size: { width: 52, height: 24 }, shapeId: 'default', parentId: 'deep-grid-nested-parent' },
|
|
140
|
+
{ id: 'deep-grid-d', position: { x: 0, y: 0 }, size: { width: 28, height: 30 }, shapeId: 'default', parentId: 'deep-grid-nested-parent' },
|
|
141
|
+
|
|
142
|
+
{
|
|
143
|
+
id: 'layout-lock-compare',
|
|
144
|
+
position: { x: 420, y: 410 },
|
|
145
|
+
size: { width: 240, height: 160 },
|
|
146
|
+
shapeId: 'panel',
|
|
147
|
+
layout: { mode: 'horizontal', padding: { x: 12, y: 12 }, gap: 12, align: 'start' },
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
id: 'deep-lock-parent',
|
|
151
|
+
position: { x: 0, y: 0 },
|
|
152
|
+
size: { width: 110, height: 92 },
|
|
153
|
+
shapeId: 'default',
|
|
154
|
+
parentId: 'layout-lock-compare',
|
|
155
|
+
childElementInteraction: lockComparisonChildren ? { movable: false } : undefined,
|
|
156
|
+
},
|
|
157
|
+
{ id: 'deep-lock-child-a', position: { x: 12, y: 24 }, size: { width: 38, height: 24 }, shapeId: 'default', parentId: 'deep-lock-parent' },
|
|
158
|
+
{ id: 'deep-lock-child-b', position: { x: 56, y: 54 }, size: { width: 42, height: 24 }, shapeId: 'default', parentId: 'deep-lock-parent' },
|
|
159
|
+
{
|
|
160
|
+
id: 'deep-free-parent',
|
|
161
|
+
position: { x: 0, y: 0 },
|
|
162
|
+
size: { width: 110, height: 92 },
|
|
163
|
+
shapeId: 'default',
|
|
164
|
+
parentId: 'layout-lock-compare',
|
|
165
|
+
},
|
|
166
|
+
{ id: 'deep-free-child-a', position: { x: 12, y: 24 }, size: { width: 38, height: 24 }, shapeId: 'default', parentId: 'deep-free-parent' },
|
|
167
|
+
{ id: 'deep-free-child-b', position: { x: 56, y: 54 }, size: { width: 42, height: 24 }, shapeId: 'default', parentId: 'deep-free-parent' },
|
|
168
|
+
|
|
169
|
+
{
|
|
170
|
+
id: 'layout-manual',
|
|
171
|
+
position: { x: 420, y: 260 },
|
|
172
|
+
size: { width: 190, height: 120 },
|
|
173
|
+
shapeId: 'panel',
|
|
93
174
|
},
|
|
94
175
|
{ id: 'manual-a', position: { x: 12, y: 18 }, size: { width: 60, height: 30 }, shapeId: 'default', parentId: 'layout-manual' },
|
|
95
176
|
{ id: 'manual-b', position: { x: 90, y: 60 }, size: { width: 68, height: 32 }, shapeId: 'default', parentId: 'layout-manual' },
|
|
@@ -142,15 +223,53 @@ const createAutoLayoutState = (): DiagramState => ({
|
|
|
142
223
|
},
|
|
143
224
|
{ id: 'label-nested-stack', content: 'nested stack', position: { x: 6, y: -16 }, ownerId: 'nested-stack' },
|
|
144
225
|
{ id: 'label-stack-a', content: 'stack-a', position: { x: 6, y: -14 }, ownerId: 'stack-a' },
|
|
145
|
-
{ id: 'label-stack-b', content: 'stack-b', position: { x: 6, y: -14 }, ownerId: 'stack-b' },
|
|
146
|
-
{ id: 'label-stack-overflow', content: 'stack-overflow', position: { x: 6, y: -14 }, ownerId: 'stack-overflow' },
|
|
147
|
-
{ id: 'label-nested-peer', content: 'nested-peer', position: { x: 6, y: -14 }, ownerId: 'nested-peer' },
|
|
148
|
-
|
|
149
|
-
{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
226
|
+
{ id: 'label-stack-b', content: 'stack-b', position: { x: 6, y: -14 }, ownerId: 'stack-b' },
|
|
227
|
+
{ id: 'label-stack-overflow', content: 'stack-overflow', position: { x: 6, y: -14 }, ownerId: 'stack-overflow' },
|
|
228
|
+
{ id: 'label-nested-peer', content: 'nested-peer', position: { x: 6, y: -14 }, ownerId: 'nested-peer' },
|
|
229
|
+
|
|
230
|
+
{
|
|
231
|
+
id: 'label-layout-grid-deep',
|
|
232
|
+
content: 'Outer grid: all direct children snap',
|
|
233
|
+
position: { x: 8, y: 6 },
|
|
234
|
+
ownerId: 'layout-grid-deep',
|
|
235
|
+
layout: { boundsMode: 'owner-width', wrap: 'word', overflow: 'clip', padding: 0 },
|
|
236
|
+
},
|
|
237
|
+
{ id: 'label-deep-grid-leaf-left', content: 'leaf resize/reorder', position: { x: 6, y: -16 }, ownerId: 'deep-grid-leaf-left' },
|
|
238
|
+
{ id: 'label-deep-grid-nested-parent', content: 'nested grid 12-unit child', position: { x: 6, y: -16 }, ownerId: 'deep-grid-nested-parent' },
|
|
239
|
+
{ id: 'label-deep-grid-leaf-right', content: 'leaf resize/reorder', position: { x: 6, y: -16 }, ownerId: 'deep-grid-leaf-right' },
|
|
240
|
+
{ id: 'label-deep-grid-a', content: 'grid-a', position: { x: 6, y: -14 }, ownerId: 'deep-grid-a' },
|
|
241
|
+
{ id: 'label-deep-grid-b', content: 'grid-b', position: { x: 6, y: -14 }, ownerId: 'deep-grid-b' },
|
|
242
|
+
{ id: 'label-deep-grid-c', content: 'grid-c', position: { x: 6, y: -14 }, ownerId: 'deep-grid-c' },
|
|
243
|
+
{ id: 'label-deep-grid-d', content: 'grid-d', position: { x: 6, y: -14 }, ownerId: 'deep-grid-d' },
|
|
244
|
+
{
|
|
245
|
+
id: 'label-layout-lock-compare',
|
|
246
|
+
content: 'Child drag lock comparison',
|
|
247
|
+
position: { x: 8, y: 6 },
|
|
248
|
+
ownerId: 'layout-lock-compare',
|
|
249
|
+
layout: { boundsMode: 'owner-width', wrap: 'word', overflow: 'clip', padding: 0 },
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
id: 'label-deep-lock-parent',
|
|
253
|
+
content: lockComparisonChildren ? 'parent lock: on' : 'parent lock: off',
|
|
254
|
+
position: { x: 6, y: -16 },
|
|
255
|
+
ownerId: 'deep-lock-parent',
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
id: 'label-deep-lock-child-a',
|
|
259
|
+
content: lockComparisonChildren ? 'drag target (locked)' : 'drag target (unlocked)',
|
|
260
|
+
position: { x: 4, y: -14 },
|
|
261
|
+
ownerId: 'deep-lock-child-a',
|
|
262
|
+
},
|
|
263
|
+
{ id: 'label-deep-lock-child-b', content: 'api move still works', position: { x: 4, y: -14 }, ownerId: 'deep-lock-child-b' },
|
|
264
|
+
{ id: 'label-deep-free-parent', content: 'movable reference', position: { x: 6, y: -16 }, ownerId: 'deep-free-parent' },
|
|
265
|
+
{ id: 'label-deep-free-child-a', content: 'drag target', position: { x: 4, y: -14 }, ownerId: 'deep-free-child-a' },
|
|
266
|
+
{ id: 'label-deep-free-child-b', content: 'free sibling', position: { x: 4, y: -14 }, ownerId: 'deep-free-child-b' },
|
|
267
|
+
|
|
268
|
+
{ id: 'label-layout-manual', content: 'Manual (no layout)', position: { x: 6, y: -18 }, ownerId: 'layout-manual' },
|
|
269
|
+
{ id: 'label-manual-a', content: 'manual-a', position: { x: 6, y: -14 }, ownerId: 'manual-a' },
|
|
270
|
+
{ id: 'label-manual-b', content: 'manual-b', position: { x: 6, y: -14 }, ownerId: 'manual-b' },
|
|
271
|
+
],
|
|
272
|
+
});
|
|
154
273
|
|
|
155
274
|
export const autoLayoutDemoConfig: DemoConfig = ({
|
|
156
275
|
id: 'auto-layout',
|