dnd-block-tree 0.5.0 → 1.1.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.
- package/README.md +43 -10
- package/dist/index.d.mts +82 -60
- package/dist/index.d.ts +82 -60
- package/dist/index.js +151 -40
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +152 -42
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
# dnd-block-tree
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/dnd-block-tree)
|
|
4
|
-
[](https://www.npmjs.com/package/dnd-block-tree)
|
|
5
|
-
[](https://bundlephobia.com/package/dnd-block-tree)
|
|
6
4
|
[](https://github.com/thesandybridge/dnd-block-tree/actions/workflows/ci.yml)
|
|
7
|
-
[](https://www.typescriptlang.org/)
|
|
9
|
-
[](https://dnd-block-tree.vercel.app)
|
|
5
|
+
[](https://blocktree.sandybridge.io)
|
|
10
6
|
|
|
11
7
|
A headless React library for building hierarchical drag-and-drop interfaces. Bring your own components, we handle the complexity.
|
|
12
8
|
|
|
13
9
|
## Features
|
|
14
10
|
|
|
15
11
|
- **Stable Drop Zones** - Zones render based on original block positions, not preview state, ensuring consistent drop targets during drag
|
|
16
|
-
- **Ghost Preview** -
|
|
17
|
-
- **
|
|
12
|
+
- **Ghost Preview** - In-flow semi-transparent preview shows where blocks will land with accurate layout
|
|
13
|
+
- **Snapshotted Collision** - Zone rects are frozen on drag start and re-measured after each ghost commit, preventing layout-shift feedback loops
|
|
14
|
+
- **Depth-Aware Collision** - Smart algorithm prefers nested zones when cursor is at indented levels, with cross-depth-aware hysteresis
|
|
18
15
|
- **Mobile & Touch Support** - Separate touch/pointer activation constraints with configurable `longPressDelay` and optional `hapticFeedback`
|
|
19
16
|
- **Snapshot-Based Computation** - State captured at drag start. All preview computations use snapshot, ensuring consistent behavior
|
|
20
17
|
- **Debounced Preview** - 150ms debounced virtual state for smooth drag previews without jitter
|
|
@@ -516,7 +513,7 @@ Enable accessible tree navigation with the `keyboardNavigation` prop:
|
|
|
516
513
|
| Home | Focus first block |
|
|
517
514
|
| End | Focus last block |
|
|
518
515
|
|
|
519
|
-
Blocks receive `data-block-id` and `tabIndex` attributes for focus management, and the tree root gets `role="tree"`.
|
|
516
|
+
Blocks receive `data-block-id` and `tabIndex` attributes for focus management, and the tree root gets `role="tree"`. Each block element includes WAI-ARIA TreeView attributes: `aria-level`, `aria-posinset`, `aria-setsize`, `aria-expanded` (containers only), and `aria-selected`.
|
|
520
517
|
|
|
521
518
|
## Multi-Select Drag
|
|
522
519
|
|
|
@@ -627,6 +624,31 @@ const collision = createStickyCollision(20)
|
|
|
627
624
|
|
|
628
625
|
You can also pass any `CollisionDetection` function from `@dnd-kit/core`.
|
|
629
626
|
|
|
627
|
+
### Snapshotted Zone Rects
|
|
628
|
+
|
|
629
|
+
`createStickyCollision` accepts an optional `SnapshotRectsRef` — a ref to a `Map<string, DOMRect>` of frozen zone positions. When provided, collision detection uses these snapshots instead of live DOM measurements, preventing feedback loops caused by the in-flow ghost preview shifting zone positions.
|
|
630
|
+
|
|
631
|
+
```typescript
|
|
632
|
+
import { createStickyCollision, type SnapshotRectsRef } from 'dnd-block-tree'
|
|
633
|
+
|
|
634
|
+
const snapshotRef: SnapshotRectsRef = { current: null }
|
|
635
|
+
const collision = createStickyCollision(20, snapshotRef)
|
|
636
|
+
|
|
637
|
+
// Snapshot all zone rects after drag starts:
|
|
638
|
+
snapshotRef.current = new Map(
|
|
639
|
+
[...document.querySelectorAll('[data-zone-id]')].map(el => [
|
|
640
|
+
el.getAttribute('data-zone-id')!,
|
|
641
|
+
el.getBoundingClientRect(),
|
|
642
|
+
])
|
|
643
|
+
)
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
`BlockTree` handles this lifecycle automatically — zones are snapshotted on drag start and re-measured via `requestAnimationFrame` after each ghost position commit.
|
|
647
|
+
|
|
648
|
+
### Cross-Depth Hysteresis
|
|
649
|
+
|
|
650
|
+
The sticky collision uses a reduced threshold (25% of normal) when switching between zones at different indentation levels. This makes it easy to drag blocks in and out of containers while still preventing flickering between same-depth adjacent zones.
|
|
651
|
+
|
|
630
652
|
## Type Safety
|
|
631
653
|
|
|
632
654
|
The library provides automatic type inference for container vs non-container renderers:
|
|
@@ -663,6 +685,7 @@ import {
|
|
|
663
685
|
deleteBlockAndDescendants, // Remove a block and all its descendants from index
|
|
664
686
|
getBlockDepth, // Compute depth of a block (root = 1)
|
|
665
687
|
getSubtreeDepth, // Max depth of a subtree (leaf = 1)
|
|
688
|
+
validateBlockTree, // Validate tree for cycles, orphans, stale refs
|
|
666
689
|
|
|
667
690
|
// Serialization
|
|
668
691
|
flatToNested, // Convert flat block array to nested tree
|
|
@@ -687,12 +710,22 @@ import {
|
|
|
687
710
|
// Collision detection
|
|
688
711
|
weightedVerticalCollision, // Edge-distance collision, depth-aware
|
|
689
712
|
closestCenterCollision, // Simple closest-center collision
|
|
690
|
-
createStickyCollision, // Hysteresis wrapper
|
|
713
|
+
createStickyCollision, // Hysteresis wrapper with snapshot support
|
|
714
|
+
type SnapshotRectsRef, // Ref type for frozen zone rects
|
|
715
|
+
|
|
716
|
+
// Internal helpers
|
|
717
|
+
cloneMap, // Clone a Map
|
|
718
|
+
cloneParentMap, // Deep clone a parent->children Map
|
|
719
|
+
debounce, // Debounce with cancel()
|
|
691
720
|
|
|
692
721
|
// Hooks
|
|
722
|
+
createBlockState, // Factory for block state context + provider
|
|
723
|
+
createTreeState, // Factory for tree UI state context + provider
|
|
693
724
|
useBlockHistory, // Undo/redo state management
|
|
694
725
|
useLayoutAnimation, // FLIP-based reorder animations
|
|
695
726
|
useVirtualTree, // Virtual scrolling primitives
|
|
727
|
+
useConfiguredSensors, // Configure dnd-kit sensors
|
|
728
|
+
getSensorConfig, // Get sensor config from SensorConfig
|
|
696
729
|
|
|
697
730
|
// Components
|
|
698
731
|
BlockTree, // Main drag-and-drop tree component
|
|
@@ -705,7 +738,7 @@ import {
|
|
|
705
738
|
|
|
706
739
|
## Demo
|
|
707
740
|
|
|
708
|
-
Check out the [live demo](https://
|
|
741
|
+
Check out the [live demo](https://blocktree.sandybridge.io) to see the library in action with two example use cases:
|
|
709
742
|
|
|
710
743
|
- **Productivity** - Sections, tasks, and notes with undo/redo, max depth control, and keyboard navigation
|
|
711
744
|
- **File System** - Folders and files
|
package/dist/index.d.mts
CHANGED
|
@@ -389,6 +389,81 @@ interface TreeStateProviderProps<T extends BaseBlock = BaseBlock> {
|
|
|
389
389
|
blockMap: Map<string, T>;
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
+
/**
|
|
393
|
+
* Clone a Map
|
|
394
|
+
*/
|
|
395
|
+
declare function cloneMap<K, V>(map: Map<K, V>): Map<K, V>;
|
|
396
|
+
/**
|
|
397
|
+
* Clone a parent map with arrays
|
|
398
|
+
*/
|
|
399
|
+
declare function cloneParentMap(map: Map<string | null, string[]>): Map<string | null, string[]>;
|
|
400
|
+
/**
|
|
401
|
+
* Compute normalized index from flat block array.
|
|
402
|
+
*
|
|
403
|
+
* With `orderingStrategy: 'fractional'`, siblings are sorted by their `order`
|
|
404
|
+
* field (lexicographic). With `'integer'` (default), the input order is preserved.
|
|
405
|
+
*/
|
|
406
|
+
declare function computeNormalizedIndex<T extends BaseBlock>(blocks: T[], orderingStrategy?: OrderingStrategy): BlockIndex<T>;
|
|
407
|
+
/**
|
|
408
|
+
* Build ordered flat array from BlockIndex.
|
|
409
|
+
*
|
|
410
|
+
* With `'integer'` ordering (default), assigns sequential `order: 0, 1, 2, …`.
|
|
411
|
+
* With `'fractional'` ordering, preserves existing `order` values — the moved
|
|
412
|
+
* block already has its new fractional key set by `reparentBlockIndex`.
|
|
413
|
+
*/
|
|
414
|
+
declare function buildOrderedBlocks<T extends BaseBlock>(index: BlockIndex<T>, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy): T[];
|
|
415
|
+
/**
|
|
416
|
+
* Reparent a block based on drop zone ID.
|
|
417
|
+
*
|
|
418
|
+
* @param state - Current block index
|
|
419
|
+
* @param activeId - ID of the dragged block
|
|
420
|
+
* @param targetZone - Drop zone ID (e.g., "after-uuid", "before-uuid", "into-uuid")
|
|
421
|
+
* @param containerTypes - Block types that can have children
|
|
422
|
+
* @param orderingStrategy - Whether to assign a fractional key to the moved block
|
|
423
|
+
*/
|
|
424
|
+
declare function reparentBlockIndex<T extends BaseBlock>(state: BlockIndex<T>, activeId: UniqueIdentifier, targetZone: string, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy, maxDepth?: number): BlockIndex<T>;
|
|
425
|
+
/**
|
|
426
|
+
* Compute the depth of a block by walking its parentId chain.
|
|
427
|
+
* Root-level blocks have depth 1.
|
|
428
|
+
*/
|
|
429
|
+
declare function getBlockDepth<T extends BaseBlock>(index: BlockIndex<T>, blockId: string): number;
|
|
430
|
+
/**
|
|
431
|
+
* Compute the maximum depth of a subtree rooted at blockId (inclusive).
|
|
432
|
+
* A leaf block returns 1.
|
|
433
|
+
*/
|
|
434
|
+
declare function getSubtreeDepth<T extends BaseBlock>(index: BlockIndex<T>, blockId: string, visited?: Set<string>): number;
|
|
435
|
+
/**
|
|
436
|
+
* Get all descendant IDs of a block
|
|
437
|
+
*/
|
|
438
|
+
declare function getDescendantIds<T extends BaseBlock>(state: BlockIndex<T>, parentId: string): Set<string>;
|
|
439
|
+
/**
|
|
440
|
+
* Reparent multiple blocks to a target zone, preserving their relative order.
|
|
441
|
+
* The first block in `blockIds` is treated as the primary (anchor) block.
|
|
442
|
+
*/
|
|
443
|
+
declare function reparentMultipleBlocks<T extends BaseBlock>(state: BlockIndex<T>, blockIds: string[], targetZone: string, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy, maxDepth?: number): BlockIndex<T>;
|
|
444
|
+
/**
|
|
445
|
+
* Result of validating a block tree
|
|
446
|
+
*/
|
|
447
|
+
interface TreeValidationResult {
|
|
448
|
+
valid: boolean;
|
|
449
|
+
issues: string[];
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Validate a block tree index for structural integrity.
|
|
453
|
+
* Checks for cycles, orphans (parentId references non-existent block),
|
|
454
|
+
* and stale refs (byParent lists IDs not present in byId).
|
|
455
|
+
*
|
|
456
|
+
* Opt-in utility — not called automatically.
|
|
457
|
+
*/
|
|
458
|
+
declare function validateBlockTree<T extends BaseBlock>(index: BlockIndex<T>): TreeValidationResult;
|
|
459
|
+
/**
|
|
460
|
+
* Delete a block and all its descendants
|
|
461
|
+
*/
|
|
462
|
+
declare function deleteBlockAndDescendants<T extends BaseBlock>(state: BlockIndex<T>, id: string): BlockIndex<T>;
|
|
463
|
+
|
|
464
|
+
type SnapshotRectsRef = {
|
|
465
|
+
current: Map<UniqueIdentifier, DOMRect> | null;
|
|
466
|
+
};
|
|
392
467
|
/**
|
|
393
468
|
* Custom collision detection that scores drop zones by distance to nearest edge.
|
|
394
469
|
* Uses edge-distance scoring with a bottom bias for more natural drag behavior.
|
|
@@ -404,8 +479,11 @@ declare const weightedVerticalCollision: CollisionDetection;
|
|
|
404
479
|
* between adjacent drop zones.
|
|
405
480
|
*
|
|
406
481
|
* @param threshold - Minimum score improvement required to switch zones (default: 15px)
|
|
482
|
+
* @param snapshotRef - Optional ref to snapshotted zone rects. When populated,
|
|
483
|
+
* collision detection uses these frozen rects instead of live DOM measurements,
|
|
484
|
+
* preventing layout-shift feedback loops from in-flow ghost previews.
|
|
407
485
|
*/
|
|
408
|
-
declare function createStickyCollision(threshold?: number): CollisionDetection & {
|
|
486
|
+
declare function createStickyCollision(threshold?: number, snapshotRef?: SnapshotRectsRef): CollisionDetection & {
|
|
409
487
|
reset: () => void;
|
|
410
488
|
};
|
|
411
489
|
/**
|
|
@@ -521,7 +599,8 @@ interface TreeRendererProps<T extends BaseBlock> {
|
|
|
521
599
|
/**
|
|
522
600
|
* Recursive tree renderer with smart drop zones
|
|
523
601
|
*/
|
|
524
|
-
declare function
|
|
602
|
+
declare function TreeRendererInner<T extends BaseBlock>({ blocks, blocksByParent, parentId, activeId, expandedMap, renderers, containerTypes, onHover, onToggleExpand, depth, dropZoneClassName, dropZoneActiveClassName, indentClassName, rootClassName, canDrag, previewPosition, draggedBlock, focusedId, selectedIds, onBlockClick, animation, virtualVisibleIds, }: TreeRendererProps<T>): react_jsx_runtime.JSX.Element;
|
|
603
|
+
declare const TreeRenderer: typeof TreeRendererInner;
|
|
525
604
|
|
|
526
605
|
interface DropZoneProps {
|
|
527
606
|
id: string;
|
|
@@ -666,63 +745,6 @@ interface UseVirtualTreeResult {
|
|
|
666
745
|
*/
|
|
667
746
|
declare function useVirtualTree({ containerRef, itemCount, itemHeight, overscan, }: UseVirtualTreeOptions): UseVirtualTreeResult;
|
|
668
747
|
|
|
669
|
-
/**
|
|
670
|
-
* Clone a Map
|
|
671
|
-
*/
|
|
672
|
-
declare function cloneMap<K, V>(map: Map<K, V>): Map<K, V>;
|
|
673
|
-
/**
|
|
674
|
-
* Clone a parent map with arrays
|
|
675
|
-
*/
|
|
676
|
-
declare function cloneParentMap(map: Map<string | null, string[]>): Map<string | null, string[]>;
|
|
677
|
-
/**
|
|
678
|
-
* Compute normalized index from flat block array.
|
|
679
|
-
*
|
|
680
|
-
* With `orderingStrategy: 'fractional'`, siblings are sorted by their `order`
|
|
681
|
-
* field (lexicographic). With `'integer'` (default), the input order is preserved.
|
|
682
|
-
*/
|
|
683
|
-
declare function computeNormalizedIndex<T extends BaseBlock>(blocks: T[], orderingStrategy?: OrderingStrategy): BlockIndex<T>;
|
|
684
|
-
/**
|
|
685
|
-
* Build ordered flat array from BlockIndex.
|
|
686
|
-
*
|
|
687
|
-
* With `'integer'` ordering (default), assigns sequential `order: 0, 1, 2, …`.
|
|
688
|
-
* With `'fractional'` ordering, preserves existing `order` values — the moved
|
|
689
|
-
* block already has its new fractional key set by `reparentBlockIndex`.
|
|
690
|
-
*/
|
|
691
|
-
declare function buildOrderedBlocks<T extends BaseBlock>(index: BlockIndex<T>, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy): T[];
|
|
692
|
-
/**
|
|
693
|
-
* Reparent a block based on drop zone ID.
|
|
694
|
-
*
|
|
695
|
-
* @param state - Current block index
|
|
696
|
-
* @param activeId - ID of the dragged block
|
|
697
|
-
* @param targetZone - Drop zone ID (e.g., "after-uuid", "before-uuid", "into-uuid")
|
|
698
|
-
* @param containerTypes - Block types that can have children
|
|
699
|
-
* @param orderingStrategy - Whether to assign a fractional key to the moved block
|
|
700
|
-
*/
|
|
701
|
-
declare function reparentBlockIndex<T extends BaseBlock>(state: BlockIndex<T>, activeId: UniqueIdentifier, targetZone: string, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy, maxDepth?: number): BlockIndex<T>;
|
|
702
|
-
/**
|
|
703
|
-
* Compute the depth of a block by walking its parentId chain.
|
|
704
|
-
* Root-level blocks have depth 1.
|
|
705
|
-
*/
|
|
706
|
-
declare function getBlockDepth<T extends BaseBlock>(index: BlockIndex<T>, blockId: string): number;
|
|
707
|
-
/**
|
|
708
|
-
* Compute the maximum depth of a subtree rooted at blockId (inclusive).
|
|
709
|
-
* A leaf block returns 1.
|
|
710
|
-
*/
|
|
711
|
-
declare function getSubtreeDepth<T extends BaseBlock>(index: BlockIndex<T>, blockId: string): number;
|
|
712
|
-
/**
|
|
713
|
-
* Get all descendant IDs of a block
|
|
714
|
-
*/
|
|
715
|
-
declare function getDescendantIds<T extends BaseBlock>(state: BlockIndex<T>, parentId: string): Set<string>;
|
|
716
|
-
/**
|
|
717
|
-
* Reparent multiple blocks to a target zone, preserving their relative order.
|
|
718
|
-
* The first block in `blockIds` is treated as the primary (anchor) block.
|
|
719
|
-
*/
|
|
720
|
-
declare function reparentMultipleBlocks<T extends BaseBlock>(state: BlockIndex<T>, blockIds: string[], targetZone: string, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy, maxDepth?: number): BlockIndex<T>;
|
|
721
|
-
/**
|
|
722
|
-
* Delete a block and all its descendants
|
|
723
|
-
*/
|
|
724
|
-
declare function deleteBlockAndDescendants<T extends BaseBlock>(state: BlockIndex<T>, id: string): BlockIndex<T>;
|
|
725
|
-
|
|
726
748
|
/**
|
|
727
749
|
* Extract UUID from a zone ID by removing the prefix (before-, after-, into-, end-)
|
|
728
750
|
*/
|
|
@@ -811,4 +833,4 @@ declare function initFractionalOrder<T extends {
|
|
|
811
833
|
order: number | string;
|
|
812
834
|
}>(blocks: T[]): T[];
|
|
813
835
|
|
|
814
|
-
export { type AnimationConfig, type AutoExpandConfig, type BaseBlock, type BlockAction, type BlockAddEvent, type BlockDeleteEvent, type BlockIndex, type BlockMoveEvent, type BlockPosition, type BlockRendererProps, type BlockRenderers, type BlockStateContextValue, type BlockStateProviderProps, BlockTree, type BlockTreeCallbacks, type BlockTreeConfig, type BlockTreeCustomization, type BlockTreeProps, BlockTreeSSR, type BlockTreeSSRProps, type CanDragFn, type CanDropFn, type ContainerRendererProps, type DragEndEvent, type DragMoveEvent, DragOverlay, type DragOverlayProps$1 as DragOverlayProps, type DragStartEvent, DropZone, type DropZoneConfig, type DropZoneProps, type DropZoneType, type ExpandChangeEvent, type HoverChangeEvent, type IdGeneratorFn, type InternalRenderers, type MoveOperation, type NestedBlock, type OrderingStrategy, type RendererPropsFor, type SensorConfig, TreeRenderer, type TreeRendererProps, type TreeStateContextValue, type TreeStateProviderProps, type UseBlockHistoryOptions, type UseBlockHistoryResult, type UseLayoutAnimationOptions, type UseVirtualTreeOptions, type UseVirtualTreeResult, buildOrderedBlocks, cloneMap, cloneParentMap, closestCenterCollision, compareFractionalKeys, computeNormalizedIndex, createBlockState, createStickyCollision, createTreeState, debounce, deleteBlockAndDescendants, extractBlockId, extractUUID, flatToNested, generateId, generateInitialKeys, generateKeyBetween, generateNKeysBetween, getBlockDepth, getDescendantIds, getDropZoneType, getSensorConfig, getSubtreeDepth, initFractionalOrder, nestedToFlat, reparentBlockIndex, reparentMultipleBlocks, triggerHaptic, useBlockHistory, useConfiguredSensors, useLayoutAnimation, useVirtualTree, weightedVerticalCollision };
|
|
836
|
+
export { type AnimationConfig, type AutoExpandConfig, type BaseBlock, type BlockAction, type BlockAddEvent, type BlockDeleteEvent, type BlockIndex, type BlockMoveEvent, type BlockPosition, type BlockRendererProps, type BlockRenderers, type BlockStateContextValue, type BlockStateProviderProps, BlockTree, type BlockTreeCallbacks, type BlockTreeConfig, type BlockTreeCustomization, type BlockTreeProps, BlockTreeSSR, type BlockTreeSSRProps, type CanDragFn, type CanDropFn, type ContainerRendererProps, type DragEndEvent, type DragMoveEvent, DragOverlay, type DragOverlayProps$1 as DragOverlayProps, type DragStartEvent, DropZone, type DropZoneConfig, type DropZoneProps, type DropZoneType, type ExpandChangeEvent, type HoverChangeEvent, type IdGeneratorFn, type InternalRenderers, type MoveOperation, type NestedBlock, type OrderingStrategy, type RendererPropsFor, type SensorConfig, type SnapshotRectsRef, TreeRenderer, type TreeRendererProps, type TreeStateContextValue, type TreeStateProviderProps, type TreeValidationResult, type UseBlockHistoryOptions, type UseBlockHistoryResult, type UseLayoutAnimationOptions, type UseVirtualTreeOptions, type UseVirtualTreeResult, buildOrderedBlocks, cloneMap, cloneParentMap, closestCenterCollision, compareFractionalKeys, computeNormalizedIndex, createBlockState, createStickyCollision, createTreeState, debounce, deleteBlockAndDescendants, extractBlockId, extractUUID, flatToNested, generateId, generateInitialKeys, generateKeyBetween, generateNKeysBetween, getBlockDepth, getDescendantIds, getDropZoneType, getSensorConfig, getSubtreeDepth, initFractionalOrder, nestedToFlat, reparentBlockIndex, reparentMultipleBlocks, triggerHaptic, useBlockHistory, useConfiguredSensors, useLayoutAnimation, useVirtualTree, validateBlockTree, weightedVerticalCollision };
|
package/dist/index.d.ts
CHANGED
|
@@ -389,6 +389,81 @@ interface TreeStateProviderProps<T extends BaseBlock = BaseBlock> {
|
|
|
389
389
|
blockMap: Map<string, T>;
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
+
/**
|
|
393
|
+
* Clone a Map
|
|
394
|
+
*/
|
|
395
|
+
declare function cloneMap<K, V>(map: Map<K, V>): Map<K, V>;
|
|
396
|
+
/**
|
|
397
|
+
* Clone a parent map with arrays
|
|
398
|
+
*/
|
|
399
|
+
declare function cloneParentMap(map: Map<string | null, string[]>): Map<string | null, string[]>;
|
|
400
|
+
/**
|
|
401
|
+
* Compute normalized index from flat block array.
|
|
402
|
+
*
|
|
403
|
+
* With `orderingStrategy: 'fractional'`, siblings are sorted by their `order`
|
|
404
|
+
* field (lexicographic). With `'integer'` (default), the input order is preserved.
|
|
405
|
+
*/
|
|
406
|
+
declare function computeNormalizedIndex<T extends BaseBlock>(blocks: T[], orderingStrategy?: OrderingStrategy): BlockIndex<T>;
|
|
407
|
+
/**
|
|
408
|
+
* Build ordered flat array from BlockIndex.
|
|
409
|
+
*
|
|
410
|
+
* With `'integer'` ordering (default), assigns sequential `order: 0, 1, 2, …`.
|
|
411
|
+
* With `'fractional'` ordering, preserves existing `order` values — the moved
|
|
412
|
+
* block already has its new fractional key set by `reparentBlockIndex`.
|
|
413
|
+
*/
|
|
414
|
+
declare function buildOrderedBlocks<T extends BaseBlock>(index: BlockIndex<T>, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy): T[];
|
|
415
|
+
/**
|
|
416
|
+
* Reparent a block based on drop zone ID.
|
|
417
|
+
*
|
|
418
|
+
* @param state - Current block index
|
|
419
|
+
* @param activeId - ID of the dragged block
|
|
420
|
+
* @param targetZone - Drop zone ID (e.g., "after-uuid", "before-uuid", "into-uuid")
|
|
421
|
+
* @param containerTypes - Block types that can have children
|
|
422
|
+
* @param orderingStrategy - Whether to assign a fractional key to the moved block
|
|
423
|
+
*/
|
|
424
|
+
declare function reparentBlockIndex<T extends BaseBlock>(state: BlockIndex<T>, activeId: UniqueIdentifier, targetZone: string, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy, maxDepth?: number): BlockIndex<T>;
|
|
425
|
+
/**
|
|
426
|
+
* Compute the depth of a block by walking its parentId chain.
|
|
427
|
+
* Root-level blocks have depth 1.
|
|
428
|
+
*/
|
|
429
|
+
declare function getBlockDepth<T extends BaseBlock>(index: BlockIndex<T>, blockId: string): number;
|
|
430
|
+
/**
|
|
431
|
+
* Compute the maximum depth of a subtree rooted at blockId (inclusive).
|
|
432
|
+
* A leaf block returns 1.
|
|
433
|
+
*/
|
|
434
|
+
declare function getSubtreeDepth<T extends BaseBlock>(index: BlockIndex<T>, blockId: string, visited?: Set<string>): number;
|
|
435
|
+
/**
|
|
436
|
+
* Get all descendant IDs of a block
|
|
437
|
+
*/
|
|
438
|
+
declare function getDescendantIds<T extends BaseBlock>(state: BlockIndex<T>, parentId: string): Set<string>;
|
|
439
|
+
/**
|
|
440
|
+
* Reparent multiple blocks to a target zone, preserving their relative order.
|
|
441
|
+
* The first block in `blockIds` is treated as the primary (anchor) block.
|
|
442
|
+
*/
|
|
443
|
+
declare function reparentMultipleBlocks<T extends BaseBlock>(state: BlockIndex<T>, blockIds: string[], targetZone: string, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy, maxDepth?: number): BlockIndex<T>;
|
|
444
|
+
/**
|
|
445
|
+
* Result of validating a block tree
|
|
446
|
+
*/
|
|
447
|
+
interface TreeValidationResult {
|
|
448
|
+
valid: boolean;
|
|
449
|
+
issues: string[];
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Validate a block tree index for structural integrity.
|
|
453
|
+
* Checks for cycles, orphans (parentId references non-existent block),
|
|
454
|
+
* and stale refs (byParent lists IDs not present in byId).
|
|
455
|
+
*
|
|
456
|
+
* Opt-in utility — not called automatically.
|
|
457
|
+
*/
|
|
458
|
+
declare function validateBlockTree<T extends BaseBlock>(index: BlockIndex<T>): TreeValidationResult;
|
|
459
|
+
/**
|
|
460
|
+
* Delete a block and all its descendants
|
|
461
|
+
*/
|
|
462
|
+
declare function deleteBlockAndDescendants<T extends BaseBlock>(state: BlockIndex<T>, id: string): BlockIndex<T>;
|
|
463
|
+
|
|
464
|
+
type SnapshotRectsRef = {
|
|
465
|
+
current: Map<UniqueIdentifier, DOMRect> | null;
|
|
466
|
+
};
|
|
392
467
|
/**
|
|
393
468
|
* Custom collision detection that scores drop zones by distance to nearest edge.
|
|
394
469
|
* Uses edge-distance scoring with a bottom bias for more natural drag behavior.
|
|
@@ -404,8 +479,11 @@ declare const weightedVerticalCollision: CollisionDetection;
|
|
|
404
479
|
* between adjacent drop zones.
|
|
405
480
|
*
|
|
406
481
|
* @param threshold - Minimum score improvement required to switch zones (default: 15px)
|
|
482
|
+
* @param snapshotRef - Optional ref to snapshotted zone rects. When populated,
|
|
483
|
+
* collision detection uses these frozen rects instead of live DOM measurements,
|
|
484
|
+
* preventing layout-shift feedback loops from in-flow ghost previews.
|
|
407
485
|
*/
|
|
408
|
-
declare function createStickyCollision(threshold?: number): CollisionDetection & {
|
|
486
|
+
declare function createStickyCollision(threshold?: number, snapshotRef?: SnapshotRectsRef): CollisionDetection & {
|
|
409
487
|
reset: () => void;
|
|
410
488
|
};
|
|
411
489
|
/**
|
|
@@ -521,7 +599,8 @@ interface TreeRendererProps<T extends BaseBlock> {
|
|
|
521
599
|
/**
|
|
522
600
|
* Recursive tree renderer with smart drop zones
|
|
523
601
|
*/
|
|
524
|
-
declare function
|
|
602
|
+
declare function TreeRendererInner<T extends BaseBlock>({ blocks, blocksByParent, parentId, activeId, expandedMap, renderers, containerTypes, onHover, onToggleExpand, depth, dropZoneClassName, dropZoneActiveClassName, indentClassName, rootClassName, canDrag, previewPosition, draggedBlock, focusedId, selectedIds, onBlockClick, animation, virtualVisibleIds, }: TreeRendererProps<T>): react_jsx_runtime.JSX.Element;
|
|
603
|
+
declare const TreeRenderer: typeof TreeRendererInner;
|
|
525
604
|
|
|
526
605
|
interface DropZoneProps {
|
|
527
606
|
id: string;
|
|
@@ -666,63 +745,6 @@ interface UseVirtualTreeResult {
|
|
|
666
745
|
*/
|
|
667
746
|
declare function useVirtualTree({ containerRef, itemCount, itemHeight, overscan, }: UseVirtualTreeOptions): UseVirtualTreeResult;
|
|
668
747
|
|
|
669
|
-
/**
|
|
670
|
-
* Clone a Map
|
|
671
|
-
*/
|
|
672
|
-
declare function cloneMap<K, V>(map: Map<K, V>): Map<K, V>;
|
|
673
|
-
/**
|
|
674
|
-
* Clone a parent map with arrays
|
|
675
|
-
*/
|
|
676
|
-
declare function cloneParentMap(map: Map<string | null, string[]>): Map<string | null, string[]>;
|
|
677
|
-
/**
|
|
678
|
-
* Compute normalized index from flat block array.
|
|
679
|
-
*
|
|
680
|
-
* With `orderingStrategy: 'fractional'`, siblings are sorted by their `order`
|
|
681
|
-
* field (lexicographic). With `'integer'` (default), the input order is preserved.
|
|
682
|
-
*/
|
|
683
|
-
declare function computeNormalizedIndex<T extends BaseBlock>(blocks: T[], orderingStrategy?: OrderingStrategy): BlockIndex<T>;
|
|
684
|
-
/**
|
|
685
|
-
* Build ordered flat array from BlockIndex.
|
|
686
|
-
*
|
|
687
|
-
* With `'integer'` ordering (default), assigns sequential `order: 0, 1, 2, …`.
|
|
688
|
-
* With `'fractional'` ordering, preserves existing `order` values — the moved
|
|
689
|
-
* block already has its new fractional key set by `reparentBlockIndex`.
|
|
690
|
-
*/
|
|
691
|
-
declare function buildOrderedBlocks<T extends BaseBlock>(index: BlockIndex<T>, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy): T[];
|
|
692
|
-
/**
|
|
693
|
-
* Reparent a block based on drop zone ID.
|
|
694
|
-
*
|
|
695
|
-
* @param state - Current block index
|
|
696
|
-
* @param activeId - ID of the dragged block
|
|
697
|
-
* @param targetZone - Drop zone ID (e.g., "after-uuid", "before-uuid", "into-uuid")
|
|
698
|
-
* @param containerTypes - Block types that can have children
|
|
699
|
-
* @param orderingStrategy - Whether to assign a fractional key to the moved block
|
|
700
|
-
*/
|
|
701
|
-
declare function reparentBlockIndex<T extends BaseBlock>(state: BlockIndex<T>, activeId: UniqueIdentifier, targetZone: string, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy, maxDepth?: number): BlockIndex<T>;
|
|
702
|
-
/**
|
|
703
|
-
* Compute the depth of a block by walking its parentId chain.
|
|
704
|
-
* Root-level blocks have depth 1.
|
|
705
|
-
*/
|
|
706
|
-
declare function getBlockDepth<T extends BaseBlock>(index: BlockIndex<T>, blockId: string): number;
|
|
707
|
-
/**
|
|
708
|
-
* Compute the maximum depth of a subtree rooted at blockId (inclusive).
|
|
709
|
-
* A leaf block returns 1.
|
|
710
|
-
*/
|
|
711
|
-
declare function getSubtreeDepth<T extends BaseBlock>(index: BlockIndex<T>, blockId: string): number;
|
|
712
|
-
/**
|
|
713
|
-
* Get all descendant IDs of a block
|
|
714
|
-
*/
|
|
715
|
-
declare function getDescendantIds<T extends BaseBlock>(state: BlockIndex<T>, parentId: string): Set<string>;
|
|
716
|
-
/**
|
|
717
|
-
* Reparent multiple blocks to a target zone, preserving their relative order.
|
|
718
|
-
* The first block in `blockIds` is treated as the primary (anchor) block.
|
|
719
|
-
*/
|
|
720
|
-
declare function reparentMultipleBlocks<T extends BaseBlock>(state: BlockIndex<T>, blockIds: string[], targetZone: string, containerTypes?: readonly string[], orderingStrategy?: OrderingStrategy, maxDepth?: number): BlockIndex<T>;
|
|
721
|
-
/**
|
|
722
|
-
* Delete a block and all its descendants
|
|
723
|
-
*/
|
|
724
|
-
declare function deleteBlockAndDescendants<T extends BaseBlock>(state: BlockIndex<T>, id: string): BlockIndex<T>;
|
|
725
|
-
|
|
726
748
|
/**
|
|
727
749
|
* Extract UUID from a zone ID by removing the prefix (before-, after-, into-, end-)
|
|
728
750
|
*/
|
|
@@ -811,4 +833,4 @@ declare function initFractionalOrder<T extends {
|
|
|
811
833
|
order: number | string;
|
|
812
834
|
}>(blocks: T[]): T[];
|
|
813
835
|
|
|
814
|
-
export { type AnimationConfig, type AutoExpandConfig, type BaseBlock, type BlockAction, type BlockAddEvent, type BlockDeleteEvent, type BlockIndex, type BlockMoveEvent, type BlockPosition, type BlockRendererProps, type BlockRenderers, type BlockStateContextValue, type BlockStateProviderProps, BlockTree, type BlockTreeCallbacks, type BlockTreeConfig, type BlockTreeCustomization, type BlockTreeProps, BlockTreeSSR, type BlockTreeSSRProps, type CanDragFn, type CanDropFn, type ContainerRendererProps, type DragEndEvent, type DragMoveEvent, DragOverlay, type DragOverlayProps$1 as DragOverlayProps, type DragStartEvent, DropZone, type DropZoneConfig, type DropZoneProps, type DropZoneType, type ExpandChangeEvent, type HoverChangeEvent, type IdGeneratorFn, type InternalRenderers, type MoveOperation, type NestedBlock, type OrderingStrategy, type RendererPropsFor, type SensorConfig, TreeRenderer, type TreeRendererProps, type TreeStateContextValue, type TreeStateProviderProps, type UseBlockHistoryOptions, type UseBlockHistoryResult, type UseLayoutAnimationOptions, type UseVirtualTreeOptions, type UseVirtualTreeResult, buildOrderedBlocks, cloneMap, cloneParentMap, closestCenterCollision, compareFractionalKeys, computeNormalizedIndex, createBlockState, createStickyCollision, createTreeState, debounce, deleteBlockAndDescendants, extractBlockId, extractUUID, flatToNested, generateId, generateInitialKeys, generateKeyBetween, generateNKeysBetween, getBlockDepth, getDescendantIds, getDropZoneType, getSensorConfig, getSubtreeDepth, initFractionalOrder, nestedToFlat, reparentBlockIndex, reparentMultipleBlocks, triggerHaptic, useBlockHistory, useConfiguredSensors, useLayoutAnimation, useVirtualTree, weightedVerticalCollision };
|
|
836
|
+
export { type AnimationConfig, type AutoExpandConfig, type BaseBlock, type BlockAction, type BlockAddEvent, type BlockDeleteEvent, type BlockIndex, type BlockMoveEvent, type BlockPosition, type BlockRendererProps, type BlockRenderers, type BlockStateContextValue, type BlockStateProviderProps, BlockTree, type BlockTreeCallbacks, type BlockTreeConfig, type BlockTreeCustomization, type BlockTreeProps, BlockTreeSSR, type BlockTreeSSRProps, type CanDragFn, type CanDropFn, type ContainerRendererProps, type DragEndEvent, type DragMoveEvent, DragOverlay, type DragOverlayProps$1 as DragOverlayProps, type DragStartEvent, DropZone, type DropZoneConfig, type DropZoneProps, type DropZoneType, type ExpandChangeEvent, type HoverChangeEvent, type IdGeneratorFn, type InternalRenderers, type MoveOperation, type NestedBlock, type OrderingStrategy, type RendererPropsFor, type SensorConfig, type SnapshotRectsRef, TreeRenderer, type TreeRendererProps, type TreeStateContextValue, type TreeStateProviderProps, type TreeValidationResult, type UseBlockHistoryOptions, type UseBlockHistoryResult, type UseLayoutAnimationOptions, type UseVirtualTreeOptions, type UseVirtualTreeResult, buildOrderedBlocks, cloneMap, cloneParentMap, closestCenterCollision, compareFractionalKeys, computeNormalizedIndex, createBlockState, createStickyCollision, createTreeState, debounce, deleteBlockAndDescendants, extractBlockId, extractUUID, flatToNested, generateId, generateInitialKeys, generateKeyBetween, generateNKeysBetween, getBlockDepth, getDescendantIds, getDropZoneType, getSensorConfig, getSubtreeDepth, initFractionalOrder, nestedToFlat, reparentBlockIndex, reparentMultipleBlocks, triggerHaptic, useBlockHistory, useConfiguredSensors, useLayoutAnimation, useVirtualTree, validateBlockTree, weightedVerticalCollision };
|