react-zeugma 1.3.1 → 1.4.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/entities/dashboard/model/context.ts","../src/entities/dashboard/model/hooks.ts","../src/shared/lib/tree/tree-helpers.ts","../src/shared/config/constants.ts","../src/entities/dashboard/ui/DashboardProvider.tsx","../src/entities/dashboard/ui/RootDropZone.tsx","../src/features/resize-pane/hooks/useResizer.ts","../src/widgets/pane-tree/ui/PaneTree.tsx","../src/entities/pane/model/context.ts","../src/entities/pane/ui/Pane.tsx","../src/entities/pane/ui/DragHandle.tsx"],"names":["DashboardStateContext","createContext","DashboardActionsContext","useDashboardState","state","useContext","useDashboardActions","actions","removePane","tree","idToRemove","newFirst","newSecond","splitPane","targetId","direction","splitType","paneToAdd","addedNode","isFirst","swapPanes","idA","idB","nodeA","findPane","nodeB","swap","node","addPane","insert","parentDirection","updateSplitPercentage","target","newPercentage","splitRoot","draggingId","draggedPaneNode","treeWithoutDragging","draggedNode","paneId","updatePaneMetadata","updater","newMetadata","_","rest","DEFAULT_SNAP_THRESHOLD","DEFAULT_DRAG_ACTIVATION_DISTANCE","DEFAULT_RESIZER_SIZE","CursorOverlay","activeId","render","className","ref","useRef","useEffect","handleMove","e","jsx","SmartPointerSensor","PointerSensor","event","SmartTouchSensor","TouchSensor","DashboardProvider","layout","onChange","renderPane","renderDragOverlay","classNames","fullscreenPaneId","onFullscreenChange","onRemove","dragActivationDistance","snapThreshold","onDragStart","onDragEnd","onResizeStart","onResize","onResizeEnd","renderResizer","minSplitPercentage","maxSplitPercentage","enableDragToDismiss","dismissThreshold","onDismissIntentChange","children","localLayout","setLocalLayout","useState","prevLayout","setPrevLayout","setActiveId","dismissIntentId","setDismissIntentId","containerRef","containerRectRef","setContainerRef","useCallback","element","onDismissIntentChangeRef","layoutRef","onChangeRef","renderPaneRef","onResizeEndPropRef","stableRenderPane","stableClassNames","useMemo","sensors","useSensors","useSensor","handleDragStart","handleDragMove","containerRect","ae","px","py","touch","distance","dx","dy","activeRect","cx","cy","handleDragEnd","active","over","wasDismissIntent","handleRemovePane","overIdStr","rootMatch","dropZone","newLayout","swapMatch","match","handleLocalLayoutChange","handleAddPane","handleSwapPanes","paneIdA","paneIdB","handleSplitPane","handleUpdateSplitPercentage","currentNode","percentage","handleUpdatePaneMetadata","handleResizeEnd","finalLayout","stateValue","actionsValue","jsxs","DndContext","pointerWithin","rootActivationPositions","rootPreviewPositions","RootDropZone","id","position","activeClassName","setNodeRef","isOver","useDroppable","Fragment","RootDropZones","hasOtherPanes","dropPreviewClassName","pos","useResizer","isRow","splitPercentage","resizerSize","onLayoutChange","localOnResizeStart","localOnResizeEnd","globalOnResizeStart","globalOnResize","globalOnResizeEnd","container","styleEl","rect","startX","startY","startPercentage","resizerEl","otherPositions","el","r","currentPercentage","handlePointerMove","moveEvent","delta","proposedPercentage","proposedPos","closestDistance","bestTarget","dist","snappedPercentage","finalPercentage","firstChild","secondChild","handlePointerUp","globalStyle","PaneSplit","propRenderResizer","contextRenderResizer","isResizing","setIsResizing","first","second","handlePointerDown","PaneTree","propSnapThreshold","contextSnapThreshold","renderContent","DragListenersCtx","activationPositions","previewPositions","DropZone","Pane","style","showDropZones","attributes","listeners","isDragging","useDraggable","dragging","isFullscreen","metadata","renderProps","contextValue","DragHandle","dragProps"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createContext, ReactNode } from 'react'\nimport { TreeNode, SplitDirection, SplitNode } from '../../../shared/model'\n\nexport interface ZeugmaClassNames {\n pane?: string\n dropPreview?: string\n swapPreview?: string\n dragOverlay?: string\n resizer?: string\n dismissPreview?: string\n}\n\nexport interface ResizerRenderProps {\n direction: SplitDirection\n splitPercentage: number\n resizerSize: number\n isResizing: boolean\n onPointerDown: (e: React.PointerEvent<HTMLDivElement>) => void\n}\n\n/**\n * State context — holds reactive values that change during runtime.\n * All consumers of this context will re-render when any of these values change.\n */\nexport interface DashboardStateValue {\n layout: TreeNode | null\n onLayoutChange: (newLayout: TreeNode | null) => void\n renderPane: (paneId: string) => ReactNode\n activeId: string | null\n dismissIntentId: string | null\n setContainerRef: (element: HTMLElement | null) => void\n fullscreenPaneId: string | null\n classNames: ZeugmaClassNames\n onRemove?: (paneId: string) => void\n onFullscreenChange?: (paneId: string | null) => void\n snapThreshold?: number\n onResizeStart?: (currentNode: SplitNode) => void\n onResize?: (currentNode: SplitNode, percentage: number) => void\n onResizeEnd?: (currentNode: SplitNode, percentage: number) => void\n renderResizer?: (props: ResizerRenderProps) => ReactNode\n minSplitPercentage?: number\n maxSplitPercentage?: number\n}\n\n/**\n * Actions context — holds stable dispatch functions with permanent identity.\n * Consumers of only this context will never re-render from layout/drag state changes.\n */\nexport interface DashboardActionsValue {\n removePane: (paneId: string) => void\n addPane: (paneId: string) => void\n swapPanes: (paneIdA: string, paneIdB: string) => void\n splitPane: (\n targetId: string,\n direction: SplitDirection,\n splitType: 'left' | 'right' | 'top' | 'bottom',\n paneToAdd: string,\n ) => void\n updateSplitPercentage: (currentNode: SplitNode, percentage: number) => void\n updatePaneMetadata: (\n paneId: string,\n updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined,\n ) => void\n}\nexport const DashboardStateContext = createContext<DashboardStateValue | undefined>(undefined)\nexport const DashboardActionsContext = createContext<DashboardActionsValue | undefined>(undefined)\n","import { useContext } from 'react'\nimport {\n DashboardStateContext,\n DashboardActionsContext,\n DashboardStateValue,\n DashboardActionsValue,\n} from './context'\n\n/** Returns only reactive state. Use when you need layout, activeId, classNames, etc. */\nexport const useDashboardState = (): DashboardStateValue => {\n const state = useContext(DashboardStateContext)\n if (!state) {\n throw new Error('useDashboardState must be used within a DashboardProvider')\n }\n return state\n}\n\n/** Returns only stable action dispatchers. Consumers of this hook never re-render from state changes. */\nexport const useDashboardActions = (): DashboardActionsValue => {\n const actions = useContext(DashboardActionsContext)\n if (!actions) {\n throw new Error('useDashboardActions must be used within a DashboardProvider')\n }\n return actions\n}\n","import { TreeNode, SplitNode, SplitDirection, PaneNode } from '../../model'\n\n/**\n * Tree Helper: Remove a pane and consolidate the tree structure.\n */\nexport function removePane(tree: TreeNode | null, idToRemove: string): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n return tree.paneId === idToRemove ? null : tree\n }\n const newFirst = removePane(tree.first, idToRemove)\n const newSecond = removePane(tree.second, idToRemove)\n if (newFirst === null) return newSecond\n if (newSecond === null) return newFirst\n return { ...tree, first: newFirst, second: newSecond }\n}\n\n/**\n * Tree Helper: Insert a pane by splitting an existing target node.\n */\nexport function splitPane(\n tree: TreeNode | null,\n targetId: string,\n direction: SplitDirection,\n splitType: 'left' | 'right' | 'top' | 'bottom',\n paneToAdd: string | PaneNode,\n): TreeNode | null {\n if (tree === null) {\n return typeof paneToAdd === 'string' ? { type: 'pane', paneId: paneToAdd } : paneToAdd\n }\n if (tree.type === 'pane') {\n if (tree.paneId === targetId) {\n const addedNode: PaneNode =\n typeof paneToAdd === 'string' ? { type: 'pane', paneId: paneToAdd } : paneToAdd\n const isFirst = splitType === 'left' || splitType === 'top'\n return {\n type: 'split',\n direction,\n first: isFirst ? addedNode : tree,\n second: isFirst ? tree : addedNode,\n splitPercentage: 50,\n }\n }\n return tree\n }\n return {\n ...tree,\n first: splitPane(tree.first, targetId, direction, splitType, paneToAdd) || tree.first,\n second: splitPane(tree.second, targetId, direction, splitType, paneToAdd) || tree.second,\n }\n}\n\n/**\n * Tree Helper: Swap the position of two panes in the tree structure.\n */\nexport function swapPanes(tree: TreeNode | null, idA: string, idB: string): TreeNode | null {\n if (tree === null) return null\n\n // First pass: collect the full PaneNode references\n const nodeA = findPane(tree, idA)\n const nodeB = findPane(tree, idB)\n if (!nodeA || !nodeB) return tree\n\n // Second pass: replace each location with the other node\n function swap(node: TreeNode): TreeNode {\n if (node.type === 'pane') {\n if (node.paneId === idA) return { ...nodeB! }\n if (node.paneId === idB) return { ...nodeA! }\n return node\n }\n return {\n ...node,\n first: swap(node.first),\n second: swap(node.second),\n }\n }\n\n return swap(tree)\n}\n\n/**\n * Tree Helper: Add a pane by recursively splitting the rightmost/bottommost pane in the tree.\n */\nexport function addPane(tree: TreeNode | null, paneToAdd: string): TreeNode {\n if (tree === null) {\n return { type: 'pane', paneId: paneToAdd }\n }\n\n function insert(node: TreeNode, parentDirection: SplitDirection | null): TreeNode {\n if (node.type === 'pane') {\n const direction: SplitDirection = parentDirection === 'row' ? 'column' : 'row'\n return {\n type: 'split',\n direction,\n splitPercentage: 50,\n first: node,\n second: { type: 'pane', paneId: paneToAdd },\n }\n }\n\n return {\n ...node,\n second: insert(node.second, node.direction),\n }\n }\n\n return insert(tree, null)\n}\n\n/**\n * Tree Helper: Update split percentage recursively.\n */\nexport function updateSplitPercentage(\n tree: TreeNode | null,\n target: SplitNode,\n newPercentage: number,\n): TreeNode | null {\n if (tree === null) return null\n if (tree === target) {\n return { ...tree, splitPercentage: newPercentage } as SplitNode\n }\n if (tree.type === 'split') {\n return {\n ...tree,\n first: updateSplitPercentage(tree.first, target, newPercentage) || tree.first,\n second: updateSplitPercentage(tree.second, target, newPercentage) || tree.second,\n }\n }\n return tree\n}\n\n/**\n * Tree Helper: Split the entire tree at the root using a dragged pane.\n */\nexport function splitRoot(\n tree: TreeNode | null,\n draggingId: string,\n splitType: 'left' | 'right' | 'top' | 'bottom',\n): TreeNode | null {\n // Preserve dragged pane's metadata\n const draggedPaneNode: PaneNode = findPane(tree, draggingId) ?? {\n type: 'pane',\n paneId: draggingId,\n }\n const treeWithoutDragging = removePane(tree, draggingId)\n if (treeWithoutDragging === null) {\n return { ...draggedPaneNode }\n }\n\n const direction: SplitDirection = splitType === 'left' || splitType === 'right' ? 'row' : 'column'\n const isFirst = splitType === 'left' || splitType === 'top'\n const draggedNode: TreeNode = { ...draggedPaneNode }\n\n return {\n type: 'split',\n direction,\n first: isFirst ? draggedNode : treeWithoutDragging,\n second: isFirst ? treeWithoutDragging : draggedNode,\n splitPercentage: 50,\n }\n}\n\n/**\n * Find a PaneNode by its paneId.\n */\nexport function findPane(tree: TreeNode | null, paneId: string): PaneNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n return tree.paneId === paneId ? tree : null\n }\n return findPane(tree.first, paneId) ?? findPane(tree.second, paneId)\n}\n\n/**\n * Update metadata on a specific pane node using an updater function.\n */\nexport function updatePaneMetadata(\n tree: TreeNode | null,\n paneId: string,\n updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined,\n): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.paneId === paneId) {\n const newMetadata = updater(tree.metadata)\n if (newMetadata === undefined) {\n // Remove metadata key\n const { metadata: _, ...rest } = tree\n return rest as PaneNode\n }\n return { ...tree, metadata: newMetadata }\n }\n return tree\n }\n return {\n ...tree,\n first: updatePaneMetadata(tree.first, paneId, updater) ?? tree.first,\n second: updatePaneMetadata(tree.second, paneId, updater) ?? tree.second,\n }\n}\n","export const DEFAULT_SNAP_THRESHOLD = 8 // px\nexport const DEFAULT_DRAG_ACTIVATION_DISTANCE = 8 // px\nexport const DEFAULT_RESIZER_SIZE = 4 // px\n","import React, { useState, useEffect, useRef, ReactNode, useMemo, useCallback } from 'react'\nimport {\n DndContext,\n useSensor,\n useSensors,\n PointerSensor,\n TouchSensor,\n DragStartEvent,\n DragEndEvent,\n DragMoveEvent,\n pointerWithin,\n} from '@dnd-kit/core'\nimport { TreeNode, SplitDirection, SplitNode } from '../../../shared/model'\nimport {\n removePane,\n splitPane,\n swapPanes,\n addPane,\n updateSplitPercentage,\n splitRoot,\n updatePaneMetadata,\n findPane,\n} from '../../../shared/lib/tree'\nimport { DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_SNAP_THRESHOLD } from '../../../shared/config'\nimport {\n DashboardStateContext,\n DashboardActionsContext,\n ZeugmaClassNames,\n ResizerRenderProps,\n} from '../model/context'\n\n/** Cursor-following overlay rendered via portal */\nconst CursorOverlay: React.FC<{\n activeId: string\n render: (id: string) => ReactNode\n className?: string\n}> = ({ activeId, render, className }) => {\n const ref = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const handleMove = (e: PointerEvent) => {\n if (ref.current) {\n ref.current.style.transform = `translate(${e.clientX + 12}px, ${e.clientY + 12}px)`\n }\n }\n document.addEventListener('pointermove', handleMove)\n return () => document.removeEventListener('pointermove', handleMove)\n }, [])\n\n return (\n <div\n ref={ref}\n className={className}\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n zIndex: 9999,\n pointerEvents: 'none',\n }}\n >\n {render(activeId)}\n </div>\n )\n}\n\nclass SmartPointerSensor extends PointerSensor {\n static activators = [\n {\n eventName: 'onPointerDown' as const,\n handler: ({ nativeEvent: event }: { nativeEvent: PointerEvent }) => {\n const element = event.target as HTMLElement | null\n if (element?.closest('.drag-cancel')) {\n return false\n }\n return true\n },\n },\n ]\n}\n\nclass SmartTouchSensor extends TouchSensor {\n static activators = [\n {\n eventName: 'onTouchStart' as const,\n handler: ({ nativeEvent: event }: { nativeEvent: TouchEvent }) => {\n const element = event.target as HTMLElement | null\n if (element?.closest('.drag-cancel')) {\n return false\n }\n return true\n },\n },\n ]\n}\n\ninterface DashboardProviderProps {\n layout: TreeNode | null\n onChange: (newLayout: TreeNode | null) => void\n renderPane: (paneId: string) => ReactNode\n renderDragOverlay?: (activeId: string) => ReactNode\n classNames?: ZeugmaClassNames\n fullscreenPaneId?: string | null\n onFullscreenChange?: (paneId: string | null) => void\n onRemove?: (paneId: string) => void\n dragActivationDistance?: number\n snapThreshold?: number\n onDragStart?: (activeId: string) => void\n onDragEnd?: (\n activeId: string,\n overId: string | null,\n dropAction: {\n type: 'split' | 'swap'\n direction?: SplitDirection\n position?: 'top' | 'bottom' | 'left' | 'right' | 'center'\n } | null,\n ) => void\n onResizeStart?: (currentNode: SplitNode) => void\n onResize?: (currentNode: SplitNode, percentage: number) => void\n onResizeEnd?: (currentNode: SplitNode, percentage: number) => void\n renderResizer?: (props: ResizerRenderProps) => ReactNode\n minSplitPercentage?: number\n maxSplitPercentage?: number\n enableDragToDismiss?: boolean\n dismissThreshold?: number\n onDismissIntentChange?: (paneId: string | null) => void\n children: ReactNode\n}\n\nexport const DashboardProvider: React.FC<DashboardProviderProps> = ({\n layout,\n onChange,\n renderPane,\n renderDragOverlay,\n classNames = {},\n fullscreenPaneId = null,\n onFullscreenChange,\n onRemove,\n dragActivationDistance = DEFAULT_DRAG_ACTIVATION_DISTANCE,\n snapThreshold = DEFAULT_SNAP_THRESHOLD,\n onDragStart,\n onDragEnd,\n onResizeStart,\n onResize,\n onResizeEnd,\n renderResizer,\n minSplitPercentage = 5,\n maxSplitPercentage = 95,\n enableDragToDismiss = false,\n dismissThreshold = 60,\n onDismissIntentChange,\n children,\n}) => {\n const [localLayout, setLocalLayout] = useState<TreeNode | null>(layout)\n const [prevLayout, setPrevLayout] = useState<TreeNode | null>(layout)\n\n if (layout !== prevLayout) {\n setPrevLayout(layout)\n setLocalLayout(layout)\n }\n\n const [activeId, setActiveId] = useState<string | null>(null)\n const [dismissIntentId, setDismissIntentId] = useState<string | null>(null)\n const containerRef = useRef<HTMLElement | null>(null)\n const containerRectRef = useRef<DOMRect | null>(null)\n\n const setContainerRef = useCallback((element: HTMLElement | null) => {\n containerRef.current = element\n }, [])\n\n const onDismissIntentChangeRef = useRef(onDismissIntentChange)\n onDismissIntentChangeRef.current = onDismissIntentChange\n\n // Refs for stable closure access — prevents callback identity changes on every layout update\n const layoutRef = useRef(localLayout)\n layoutRef.current = localLayout\n\n const onChangeRef = useRef(onChange)\n onChangeRef.current = onChange\n\n const renderPaneRef = useRef(renderPane)\n renderPaneRef.current = renderPane\n\n const onResizeEndPropRef = useRef(onResizeEnd)\n onResizeEndPropRef.current = onResizeEnd\n\n // Stable renderPane wrapper — immune to consumer passing inline functions\n const stableRenderPane = useCallback((paneId: string) => renderPaneRef.current(paneId), [])\n\n // Shallow-memoize classNames by individual fields to avoid identity busting from inline objects\n const stableClassNames = useMemo(\n () => classNames,\n [\n classNames.pane,\n classNames.dropPreview,\n classNames.swapPreview,\n classNames.dragOverlay,\n classNames.resizer,\n classNames.dismissPreview,\n ],\n )\n\n const sensors = useSensors(\n useSensor(SmartPointerSensor, {\n activationConstraint: { distance: dragActivationDistance },\n }),\n useSensor(SmartTouchSensor, {\n activationConstraint: { delay: 250, tolerance: 5 },\n }),\n )\n\n const handleDragStart = (event: DragStartEvent) => {\n const draggingId = event.active.id.toString()\n setActiveId(draggingId)\n if (enableDragToDismiss && containerRef.current) {\n containerRectRef.current = containerRef.current.getBoundingClientRect()\n } else {\n containerRectRef.current = null\n }\n if (onDragStart) {\n onDragStart(draggingId)\n }\n }\n\n const handleDragMove = (event: DragMoveEvent) => {\n if (!enableDragToDismiss) return\n\n const draggingId = event.active.id.toString()\n const containerRect = containerRectRef.current\n\n if (!containerRect) {\n if (dismissIntentId !== null) {\n setDismissIntentId(null)\n onDismissIntentChangeRef.current?.(null)\n }\n return\n }\n\n const ae = event.activatorEvent\n let px: number | null = null\n let py: number | null = null\n\n if (ae instanceof MouseEvent || ae instanceof PointerEvent) {\n px = ae.clientX + event.delta.x\n py = ae.clientY + event.delta.y\n } else if (typeof TouchEvent !== 'undefined' && ae instanceof TouchEvent) {\n const touch = ae.touches[0] || ae.changedTouches[0]\n if (touch) {\n px = touch.clientX + event.delta.x\n py = touch.clientY + event.delta.y\n }\n }\n\n let distance = 0\n if (px !== null && py !== null) {\n let dx = 0\n let dy = 0\n\n if (px < containerRect.left) {\n dx = containerRect.left - px\n } else if (px > containerRect.right) {\n dx = px - containerRect.right\n }\n\n if (py < containerRect.top) {\n dy = containerRect.top - py\n } else if (py > containerRect.bottom) {\n dy = py - containerRect.bottom\n }\n\n distance = Math.sqrt(dx * dx + dy * dy)\n } else {\n const activeRect = event.active.rect.current.translated\n if (activeRect) {\n const cx = activeRect.left + activeRect.width / 2\n const cy = activeRect.top + activeRect.height / 2\n let dx = 0\n let dy = 0\n\n if (cx < containerRect.left) {\n dx = containerRect.left - cx\n } else if (cx > containerRect.right) {\n dx = cx - containerRect.right\n }\n\n if (cy < containerRect.top) {\n dy = containerRect.top - cy\n } else if (cy > containerRect.bottom) {\n dy = cy - containerRect.bottom\n }\n\n distance = Math.sqrt(dx * dx + dy * dy)\n }\n }\n\n const isDismissIntent = distance > dismissThreshold\n if (isDismissIntent) {\n if (dismissIntentId !== draggingId) {\n setDismissIntentId(draggingId)\n onDismissIntentChangeRef.current?.(draggingId)\n }\n } else {\n if (dismissIntentId !== null) {\n setDismissIntentId(null)\n onDismissIntentChangeRef.current?.(null)\n }\n }\n }\n\n const handleDragEnd = (event: DragEndEvent) => {\n setActiveId(null)\n const { active, over } = event\n const draggingId = active.id.toString()\n\n const wasDismissIntent = enableDragToDismiss && dismissIntentId === draggingId\n\n setDismissIntentId(null)\n onDismissIntentChangeRef.current?.(null)\n containerRectRef.current = null\n\n if (wasDismissIntent) {\n if (onRemove) {\n onRemove(draggingId)\n } else {\n handleRemovePane(draggingId)\n }\n\n if (onDragEnd) {\n onDragEnd(draggingId, null, null)\n }\n return\n }\n\n if (!over) {\n if (onDragEnd) {\n onDragEnd(draggingId, null, null)\n }\n return\n }\n\n const overIdStr = over.id.toString()\n\n // Check for root drop (places pane like half of the root)\n const rootMatch = overIdStr.match(/^drop-root-(left|right|top|bottom)$/)\n if (rootMatch) {\n const [, dropZone] = rootMatch\n const newLayout = splitRoot(\n localLayout,\n draggingId,\n dropZone as 'left' | 'right' | 'top' | 'bottom',\n )\n setLocalLayout(newLayout)\n onChange(newLayout)\n\n if (onDragEnd) {\n const direction: SplitDirection =\n dropZone === 'left' || dropZone === 'right' ? 'row' : 'column'\n onDragEnd(draggingId, 'root', {\n type: 'split',\n direction,\n position: dropZone as 'left' | 'right' | 'top' | 'bottom',\n })\n }\n return\n }\n\n // Check for center (swap) drop\n const swapMatch = overIdStr.match(/^drop-center-(.+)$/)\n if (swapMatch) {\n const [, targetId] = swapMatch\n if (draggingId !== targetId) {\n const newLayout = swapPanes(localLayout, draggingId, targetId)\n setLocalLayout(newLayout)\n onChange(newLayout)\n }\n if (onDragEnd) {\n onDragEnd(draggingId, targetId, { type: 'swap', position: 'center' })\n }\n return\n }\n\n // Check for edge (split) drop\n const match = overIdStr.match(/^drop-(left|right|top|bottom)-(.+)$/)\n if (!match) {\n if (onDragEnd) {\n onDragEnd(draggingId, null, null)\n }\n return\n }\n\n const [, dropZone, targetId] = match\n if (draggingId === targetId) {\n if (onDragEnd) {\n onDragEnd(draggingId, null, null)\n }\n return\n }\n\n const direction: SplitDirection = dropZone === 'left' || dropZone === 'right' ? 'row' : 'column'\n const draggedPaneNode = findPane(localLayout, draggingId) ?? {\n type: 'pane',\n paneId: draggingId,\n }\n const treeWithoutDragging = removePane(localLayout, draggingId)\n\n const newLayout = splitPane(\n treeWithoutDragging,\n targetId,\n direction,\n dropZone as 'left' | 'right' | 'top' | 'bottom',\n draggedPaneNode,\n )\n setLocalLayout(newLayout)\n onChange(newLayout)\n if (onDragEnd) {\n onDragEnd(draggingId, targetId, {\n type: 'split',\n direction,\n position: dropZone as 'left' | 'right' | 'top' | 'bottom',\n })\n }\n }\n\n const handleLocalLayoutChange = useCallback((newLayout: TreeNode | null) => {\n setLocalLayout(newLayout)\n }, [])\n\n const handleRemovePane = useCallback((paneId: string) => {\n const newLayout = removePane(layoutRef.current, paneId)\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n }, [])\n\n const handleAddPane = useCallback((paneId: string) => {\n const newLayout = addPane(layoutRef.current, paneId)\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n }, [])\n\n const handleSwapPanes = useCallback((paneIdA: string, paneIdB: string) => {\n const newLayout = swapPanes(layoutRef.current, paneIdA, paneIdB)\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n }, [])\n\n const handleSplitPane = useCallback(\n (\n targetId: string,\n direction: SplitDirection,\n splitType: 'left' | 'right' | 'top' | 'bottom',\n paneToAdd: string,\n ) => {\n const draggedPaneNode = findPane(layoutRef.current, paneToAdd) ?? {\n type: 'pane',\n paneId: paneToAdd,\n }\n const treeWithoutDragging = removePane(layoutRef.current, paneToAdd)\n const newLayout = splitPane(\n treeWithoutDragging,\n targetId,\n direction,\n splitType,\n draggedPaneNode,\n )\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n },\n [],\n )\n\n const handleUpdateSplitPercentage = useCallback((currentNode: SplitNode, percentage: number) => {\n const newLayout = updateSplitPercentage(layoutRef.current, currentNode, percentage)\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n }, [])\n\n const handleUpdatePaneMetadata = useCallback(\n (\n paneId: string,\n updater: (\n current: Record<string, unknown> | undefined,\n ) => Record<string, unknown> | undefined,\n ) => {\n const newLayout = updatePaneMetadata(layoutRef.current, paneId, updater)\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n },\n [],\n )\n\n const handleResizeEnd = useCallback((currentNode: SplitNode, percentage: number) => {\n const finalLayout = updateSplitPercentage(layoutRef.current, currentNode, percentage)\n setLocalLayout(finalLayout)\n onChangeRef.current(finalLayout)\n if (onResizeEndPropRef.current) {\n onResizeEndPropRef.current(currentNode, percentage)\n }\n }, [])\n\n // State context — reactive values that change during runtime\n const stateValue = useMemo(\n () => ({\n layout: localLayout,\n onLayoutChange: handleLocalLayoutChange,\n renderPane: stableRenderPane,\n activeId,\n dismissIntentId,\n setContainerRef,\n fullscreenPaneId,\n classNames: stableClassNames,\n onRemove,\n onFullscreenChange,\n snapThreshold,\n onResizeStart,\n onResize,\n onResizeEnd: handleResizeEnd,\n renderResizer,\n minSplitPercentage,\n maxSplitPercentage,\n }),\n [\n localLayout,\n activeId,\n dismissIntentId,\n setContainerRef,\n fullscreenPaneId,\n stableClassNames,\n onRemove,\n onFullscreenChange,\n snapThreshold,\n onResizeStart,\n onResize,\n renderResizer,\n minSplitPercentage,\n maxSplitPercentage,\n // Stable callbacks (empty deps) — included for exhaustive-deps lint rule\n handleLocalLayoutChange,\n stableRenderPane,\n handleResizeEnd,\n ],\n )\n\n // Actions context — stable dispatch functions that never change identity\n const actionsValue = useMemo(\n () => ({\n removePane: handleRemovePane,\n addPane: handleAddPane,\n swapPanes: handleSwapPanes,\n splitPane: handleSplitPane,\n updateSplitPercentage: handleUpdateSplitPercentage,\n updatePaneMetadata: handleUpdatePaneMetadata,\n }),\n [\n handleRemovePane,\n handleAddPane,\n handleSwapPanes,\n handleSplitPane,\n handleUpdateSplitPercentage,\n handleUpdatePaneMetadata,\n ],\n )\n\n return (\n <DashboardActionsContext.Provider value={actionsValue}>\n <DashboardStateContext.Provider value={stateValue}>\n <DndContext\n id=\"zeugma-dnd-context\"\n sensors={sensors}\n collisionDetection={pointerWithin}\n onDragStart={handleDragStart}\n onDragMove={handleDragMove}\n onDragEnd={handleDragEnd}\n >\n {children}\n </DndContext>\n {activeId && renderDragOverlay && (\n <CursorOverlay\n activeId={activeId}\n render={renderDragOverlay}\n className={`${classNames.dragOverlay || ''} ${\n activeId === dismissIntentId\n ? classNames.dismissPreview || 'zeugma-dismiss-preview'\n : ''\n }`.trim()}\n />\n )}\n </DashboardStateContext.Provider>\n </DashboardActionsContext.Provider>\n )\n}\n","import React from 'react'\nimport { useDroppable } from '@dnd-kit/core'\n\nconst rootActivationPositions: Record<string, React.CSSProperties> = {\n top: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: '32px',\n zIndex: 30,\n pointerEvents: 'auto',\n },\n bottom: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: '32px',\n zIndex: 30,\n pointerEvents: 'auto',\n },\n left: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n width: '32px',\n zIndex: 30,\n pointerEvents: 'auto',\n },\n right: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n right: 0,\n width: '32px',\n zIndex: 30,\n pointerEvents: 'auto',\n },\n}\n\nconst rootPreviewPositions: Record<string, React.CSSProperties> = {\n top: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: '50%',\n zIndex: 31,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n bottom: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: '50%',\n zIndex: 31,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n left: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n width: '50%',\n zIndex: 31,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n right: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n right: 0,\n width: '50%',\n zIndex: 31,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n}\n\nexport interface RootDropZoneProps {\n id: string\n position: 'top' | 'bottom' | 'left' | 'right'\n activeClassName?: string\n}\n\nexport const RootDropZone: React.FC<RootDropZoneProps> = ({ id, position, activeClassName }) => {\n const { setNodeRef, isOver } = useDroppable({ id })\n return (\n <>\n <div ref={setNodeRef} style={rootActivationPositions[position]} />\n {isOver && <div className={activeClassName} style={rootPreviewPositions[position]} />}\n </>\n )\n}\n\nexport interface RootDropZonesProps {\n activeId: string | null\n hasOtherPanes: boolean\n dropPreviewClassName?: string\n}\n\nexport const RootDropZones: React.FC<RootDropZonesProps> = ({\n activeId,\n hasOtherPanes,\n dropPreviewClassName,\n}) => {\n if (!activeId || !hasOtherPanes) return null\n\n return (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 30,\n pointerEvents: 'none',\n }}\n >\n {(['top', 'bottom', 'left', 'right'] as const).map((pos) => (\n <RootDropZone\n key={pos}\n id={`drop-root-${pos}`}\n position={pos}\n activeClassName={dropPreviewClassName}\n />\n ))}\n </div>\n )\n}\n","import React, { useCallback } from 'react'\nimport { TreeNode, SplitNode, SplitDirection } from '../../../shared/model'\nimport { updateSplitPercentage } from '../../../shared/lib/tree'\nimport { useDashboardState } from '../../../entities/dashboard'\n\ninterface UseResizerProps {\n containerRef: React.RefObject<HTMLDivElement | null>\n isRow: boolean\n direction: SplitDirection\n splitPercentage: number\n resizerSize: number\n snapThreshold: number\n layout: TreeNode | null\n currentNode: SplitNode\n onLayoutChange: (newLayout: TreeNode | null) => void\n onResizeStart?: () => void\n onResizeEnd?: () => void\n}\n\nexport function useResizer({\n containerRef,\n isRow,\n direction,\n splitPercentage,\n resizerSize,\n snapThreshold,\n layout,\n currentNode,\n onLayoutChange,\n onResizeStart: localOnResizeStart,\n onResizeEnd: localOnResizeEnd,\n}: UseResizerProps) {\n const {\n onResizeStart: globalOnResizeStart,\n onResize: globalOnResize,\n onResizeEnd: globalOnResizeEnd,\n minSplitPercentage = 5,\n maxSplitPercentage = 95,\n } = useDashboardState()\n\n return useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n e.preventDefault()\n const container = containerRef.current\n if (!container) return\n\n document.body.classList.add('zeugma-resizing')\n\n // Inject global cursor style to keep resizing cursor active across the entire page during drag\n const styleEl = document.createElement('style')\n styleEl.id = 'zeugma-global-cursor-style'\n styleEl.textContent = `\n * {\n cursor: ${isRow ? 'col-resize' : 'row-resize'} !important;\n user-select: none !important;\n }\n `\n document.head.appendChild(styleEl)\n\n if (localOnResizeStart) {\n localOnResizeStart()\n }\n if (globalOnResizeStart) {\n globalOnResizeStart(currentNode)\n }\n\n const rect = container.getBoundingClientRect()\n const startX = e.clientX\n const startY = e.clientY\n const startPercentage = splitPercentage\n\n // Cache other resizers of the same direction once at drag-start to prevent layout thrashing on move\n const resizerEl = e.currentTarget\n resizerEl.setAttribute('data-resizing', 'true')\n\n const otherResizers = Array.from(\n document.querySelectorAll('div[role=\"separator\"][data-direction]'),\n ).filter((el) => el !== resizerEl && el.getAttribute('data-direction') === direction)\n\n const otherPositions = otherResizers.map((el) => {\n const r = el.getBoundingClientRect()\n return isRow ? r.left + r.width / 2 : r.top + r.height / 2\n })\n\n let currentPercentage = startPercentage\n\n const handlePointerMove = (moveEvent: PointerEvent) => {\n const delta = isRow\n ? ((moveEvent.clientX - startX) / rect.width) * 100\n : ((moveEvent.clientY - startY) / rect.height) * 100\n const proposedPercentage = startPercentage + delta\n\n // Find physical position corresponding to proposed percentage\n const proposedPos = isRow\n ? rect.left + (rect.width - resizerSize) * (proposedPercentage / 100) + resizerSize / 2\n : rect.top + (rect.height - resizerSize) * (proposedPercentage / 100) + resizerSize / 2\n\n let closestDistance = Infinity\n let bestTarget: number | null = null\n\n for (const pos of otherPositions) {\n const dist = Math.abs(proposedPos - pos)\n if (dist < snapThreshold && dist < closestDistance) {\n closestDistance = dist\n bestTarget = pos\n }\n }\n\n let snappedPercentage = proposedPercentage\n if (bestTarget !== null) {\n snappedPercentage = isRow\n ? ((bestTarget - resizerSize / 2 - rect.left) / (rect.width - resizerSize)) * 100\n : ((bestTarget - resizerSize / 2 - rect.top) / (rect.height - resizerSize)) * 100\n }\n\n const finalPercentage = Math.max(\n minSplitPercentage,\n Math.min(maxSplitPercentage, snappedPercentage),\n )\n currentPercentage = finalPercentage\n\n // Imperatively update the sibling pane container flex sizes during drag\n const firstChild = container.children[0] as HTMLElement\n const secondChild = container.children[container.children.length - 1] as HTMLElement\n if (firstChild && secondChild) {\n firstChild.style.flex = `${finalPercentage} 1 0%`\n secondChild.style.flex = `${100 - finalPercentage} 1 0%`\n }\n\n if (globalOnResize) {\n globalOnResize(currentNode, finalPercentage)\n }\n }\n\n const handlePointerUp = () => {\n document.body.classList.remove('zeugma-resizing')\n resizerEl.removeAttribute('data-resizing')\n\n const globalStyle = document.getElementById('zeugma-global-cursor-style')\n if (globalStyle) {\n globalStyle.remove()\n }\n\n document.removeEventListener('pointermove', handlePointerMove)\n document.removeEventListener('pointerup', handlePointerUp)\n\n // Write to React state once resizing completes\n const newLayout = updateSplitPercentage(layout, currentNode, currentPercentage)\n console.log('onLayoutChange (finalized) called with percentage:', currentPercentage)\n onLayoutChange(newLayout)\n\n if (localOnResizeEnd) {\n localOnResizeEnd()\n }\n if (globalOnResizeEnd) {\n globalOnResizeEnd(currentNode, currentPercentage)\n }\n }\n\n document.addEventListener('pointermove', handlePointerMove)\n document.addEventListener('pointerup', handlePointerUp)\n },\n [\n containerRef,\n isRow,\n direction,\n splitPercentage,\n resizerSize,\n snapThreshold,\n layout,\n currentNode,\n onLayoutChange,\n localOnResizeStart,\n localOnResizeEnd,\n globalOnResizeStart,\n globalOnResize,\n globalOnResizeEnd,\n minSplitPercentage,\n maxSplitPercentage,\n ],\n )\n}\n","import React, { useRef, useState, useMemo } from 'react'\nimport { useDashboardState, ResizerRenderProps, RootDropZones } from '../../../entities/dashboard'\nimport { useResizer } from '../../../features/resize-pane'\nimport { TreeNode, SplitNode } from '../../../shared/model'\nimport { removePane } from '../../../shared'\n\nexport interface PaneTreeProps {\n tree?: TreeNode | null\n /** Size of the resizer in pixels (default 4) */\n resizerSize?: number\n /** Threshold in pixels to snap to adjacent resizer edges (default 8) */\n snapThreshold?: number\n /** Custom resizer renderer to override context-level renderResizer */\n renderResizer?: (props: ResizerRenderProps) => React.ReactNode\n}\n\ninterface PaneSplitProps {\n currentNode: SplitNode\n resizerSize: number\n snapThreshold?: number\n renderResizer?: (props: ResizerRenderProps) => React.ReactNode\n}\n\nconst PaneSplit: React.FC<PaneSplitProps> = ({\n currentNode,\n resizerSize,\n snapThreshold,\n renderResizer: propRenderResizer,\n}) => {\n const {\n layout,\n onLayoutChange,\n classNames,\n renderResizer: contextRenderResizer,\n } = useDashboardState()\n const [isResizing, setIsResizing] = useState(false)\n\n const renderResizer = propRenderResizer || contextRenderResizer\n\n const containerRef = useRef<HTMLDivElement>(null)\n const { direction, first, second, splitPercentage } = currentNode\n const isRow = direction === 'row'\n\n const handlePointerDown = useResizer({\n containerRef,\n isRow,\n direction,\n splitPercentage,\n resizerSize,\n snapThreshold: snapThreshold ?? 8,\n layout,\n currentNode,\n onLayoutChange,\n onResizeStart: () => setIsResizing(true),\n onResizeEnd: () => setIsResizing(false),\n })\n\n return (\n <div\n ref={containerRef}\n style={{\n display: 'flex',\n flexDirection: isRow ? 'row' : 'column',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n }}\n >\n <div style={{ flex: `${splitPercentage} 1 0%`, overflow: 'hidden' }}>\n <PaneTree\n tree={first}\n resizerSize={resizerSize}\n snapThreshold={snapThreshold}\n renderResizer={propRenderResizer}\n />\n </div>\n {renderResizer ? (\n renderResizer({\n direction,\n splitPercentage,\n resizerSize,\n isResizing,\n onPointerDown: handlePointerDown,\n })\n ) : (\n <div\n className={classNames.resizer}\n data-direction={direction}\n style={{\n width: isRow ? `${resizerSize}px` : '100%',\n height: isRow ? '100%' : `${resizerSize}px`,\n cursor: isRow ? 'col-resize' : 'row-resize',\n position: 'relative',\n zIndex: 10,\n userSelect: 'none',\n touchAction: 'none',\n boxSizing: 'border-box',\n flexShrink: 0,\n }}\n onPointerDown={handlePointerDown}\n role=\"separator\"\n aria-valuenow={splitPercentage}\n aria-valuemin={5}\n aria-valuemax={95}\n />\n )}\n <div style={{ flex: `${100 - splitPercentage} 1 0%`, overflow: 'hidden' }}>\n <PaneTree\n tree={second}\n resizerSize={resizerSize}\n snapThreshold={snapThreshold}\n renderResizer={propRenderResizer}\n />\n </div>\n </div>\n )\n}\n\nexport const PaneTree: React.FC<PaneTreeProps> = ({\n tree,\n resizerSize = 4,\n snapThreshold: propSnapThreshold,\n renderResizer,\n}) => {\n const {\n layout,\n renderPane,\n activeId,\n dismissIntentId,\n setContainerRef,\n classNames,\n fullscreenPaneId,\n snapThreshold: contextSnapThreshold,\n } = useDashboardState()\n\n const snapThreshold = propSnapThreshold !== undefined ? propSnapThreshold : contextSnapThreshold\n\n const hasOtherPanes = useMemo(() => {\n if (tree !== undefined || !activeId) return false\n return removePane(layout, activeId) !== null\n }, [tree, layout, activeId])\n\n // Fullscreen bypass\n if (fullscreenPaneId && !tree) {\n return (\n <div style={{ width: '100%', height: '100%', position: 'relative' }}>\n {renderPane(fullscreenPaneId)}\n </div>\n )\n }\n\n const currentNode = tree !== undefined ? tree : layout\n\n if (!currentNode) return null\n\n const renderContent = () => {\n if (currentNode.type === 'pane') {\n return (\n <div style={{ width: '100%', height: '100%', position: 'relative' }}>\n {renderPane(currentNode.paneId)}\n </div>\n )\n }\n\n return (\n <PaneSplit\n currentNode={currentNode}\n resizerSize={resizerSize}\n snapThreshold={snapThreshold}\n renderResizer={renderResizer}\n />\n )\n }\n\n // Only render RootDropZones at the top-level PaneTree (where tree is undefined)\n if (tree === undefined) {\n const isDismissActive = activeId !== null && activeId === dismissIntentId\n return (\n <div\n ref={setContainerRef}\n className={`zeugma-dashboard-root ${isDismissActive ? 'zeugma-dashboard-dismiss-active' : ''}`.trim()}\n style={{\n position: 'relative',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n }}\n >\n {renderContent()}\n <RootDropZones\n activeId={activeId}\n hasOtherPanes={hasOtherPanes}\n dropPreviewClassName={classNames.dropPreview}\n />\n </div>\n )\n }\n\n return renderContent()\n}\n","import { createContext } from 'react'\n\nexport const DragListenersCtx = createContext<Record<string, unknown> | null>(null)\n","import React, { useMemo } from 'react'\nimport { useDraggable, useDroppable } from '@dnd-kit/core'\nimport { useDashboardState, useDashboardActions } from '../../dashboard'\nimport { DragListenersCtx } from '../model/context'\nimport { PaneRenderProps } from '../model/types'\nimport { findPane } from '../../../shared/lib/tree'\n\ninterface DropZoneProps {\n id: string\n position: 'top' | 'bottom' | 'left' | 'right' | 'center'\n activeClassName?: string\n}\n\nconst activationPositions: Record<string, React.CSSProperties> = {\n top: {\n position: 'absolute',\n top: 0,\n left: '25%',\n width: '50%',\n height: '25%',\n zIndex: 20,\n pointerEvents: 'auto',\n },\n bottom: {\n position: 'absolute',\n bottom: 0,\n left: '25%',\n width: '50%',\n height: '25%',\n zIndex: 20,\n pointerEvents: 'auto',\n },\n left: {\n position: 'absolute',\n top: '25%',\n left: 0,\n width: '25%',\n height: '50%',\n zIndex: 20,\n pointerEvents: 'auto',\n },\n right: {\n position: 'absolute',\n top: '25%',\n right: 0,\n width: '25%',\n height: '50%',\n zIndex: 20,\n pointerEvents: 'auto',\n },\n center: {\n position: 'absolute',\n top: '25%',\n left: '25%',\n width: '50%',\n height: '50%',\n zIndex: 20,\n pointerEvents: 'auto',\n },\n}\n\nconst previewPositions: Record<string, React.CSSProperties> = {\n top: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: '50%',\n zIndex: 21,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n bottom: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: '50%',\n zIndex: 21,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n left: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n width: '50%',\n zIndex: 21,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n right: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n right: 0,\n width: '50%',\n zIndex: 21,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n center: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 21,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n}\n\nconst DropZone: React.FC<DropZoneProps> = ({ id, position, activeClassName }) => {\n const { setNodeRef, isOver } = useDroppable({ id })\n return (\n <>\n <div ref={setNodeRef} style={activationPositions[position]} />\n {isOver && <div className={activeClassName} style={previewPositions[position]} />}\n </>\n )\n}\n\ninterface PaneProps {\n id: string\n children: (props: PaneRenderProps) => React.ReactNode\n style?: React.CSSProperties\n}\n\nexport const Pane: React.FC<PaneProps> = ({ id, children, style }) => {\n const { layout, activeId, classNames, fullscreenPaneId, onRemove, onFullscreenChange } =\n useDashboardState()\n const { removePane, updatePaneMetadata } = useDashboardActions()\n const showDropZones = activeId !== null && activeId !== id\n\n const { attributes, listeners, setNodeRef, isDragging } = useDraggable({ id })\n const dragging = activeId === id || isDragging\n const isFullscreen = fullscreenPaneId === id\n\n const paneNode = useMemo(() => findPane(layout, id), [layout, id])\n const metadata = paneNode?.metadata\n\n const renderProps: PaneRenderProps = useMemo(\n () => ({\n isDragging: dragging,\n isFullscreen,\n toggleFullscreen: () => onFullscreenChange?.(isFullscreen ? null : id),\n remove: () => {\n if (isFullscreen) {\n onFullscreenChange?.(null)\n }\n if (onRemove) {\n onRemove(id)\n } else {\n removePane(id)\n }\n },\n metadata,\n updateMetadata: (updater) => {\n updatePaneMetadata(id, updater)\n },\n }),\n [\n dragging,\n isFullscreen,\n onFullscreenChange,\n id,\n onRemove,\n removePane,\n metadata,\n updatePaneMetadata,\n ],\n )\n\n // Best practice: Memoize drag context value to prevent unnecessary re-renders of the drag handle.\n const contextValue = useMemo(\n () => ({\n ...listeners,\n ...attributes,\n }),\n [listeners, attributes],\n )\n\n return (\n <DragListenersCtx.Provider value={contextValue}>\n <div\n ref={setNodeRef}\n className={classNames.pane}\n style={{ position: 'relative', width: '100%', height: '100%', ...style }}\n >\n {children(renderProps)}\n\n {showDropZones && (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 15,\n pointerEvents: 'none',\n }}\n >\n {(['top', 'bottom', 'left', 'right'] as const).map((pos) => (\n <DropZone\n key={pos}\n id={`drop-${pos}-${id}`}\n position={pos}\n activeClassName={classNames.dropPreview}\n />\n ))}\n <DropZone\n id={`drop-center-${id}`}\n position=\"center\"\n activeClassName={classNames.swapPreview}\n />\n </div>\n )}\n </div>\n </DragListenersCtx.Provider>\n )\n}\n","import React, { useContext } from 'react'\nimport { DragListenersCtx } from '../model/context'\n\ninterface DragHandleProps {\n children: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\nexport const DragHandle: React.FC<DragHandleProps> = ({ children, className, style }) => {\n const dragProps = useContext(DragListenersCtx)\n if (!dragProps) {\n throw new Error('<DragHandle> must be used inside a <Pane>')\n }\n return (\n <div\n className={className}\n style={{ cursor: 'grab', userSelect: 'none', touchAction: 'none', ...style }}\n {...dragProps}\n >\n {children}\n </div>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/entities/dashboard/model/context.ts","../src/entities/dashboard/model/hooks.ts","../src/shared/lib/tree/tree-helpers.ts","../src/shared/config/constants.ts","../src/entities/dashboard/ui/DashboardProvider.tsx","../src/entities/dashboard/ui/RootDropZone.tsx","../src/shared/lib/drag-session.ts","../src/features/resize-pane/hooks/useResizer.ts","../src/widgets/pane-tree/ui/PaneTree.tsx","../src/widgets/resizable-container/ui/ResizableContainer.tsx","../src/entities/pane/model/context.ts","../src/entities/pane/ui/Pane.tsx","../src/entities/pane/ui/DragHandle.tsx"],"names":["DashboardStateContext","createContext","DashboardActionsContext","useDashboardState","state","useContext","useDashboardActions","actions","removePane","tree","idToRemove","newFirst","newSecond","splitPane","targetId","direction","splitType","paneToAdd","addedNode","isFirst","swapPanes","idA","idB","nodeA","findPane","nodeB","swap","node","addPane","insert","parentDirection","updateSplitPercentage","target","newPercentage","splitRoot","draggingId","draggedPaneNode","treeWithoutDragging","draggedNode","paneId","updatePaneMetadata","updater","newMetadata","_","rest","DEFAULT_SNAP_THRESHOLD","DEFAULT_DRAG_ACTIVATION_DISTANCE","DEFAULT_RESIZER_SIZE","CursorOverlay","activeId","render","className","ref","useRef","useEffect","handleMove","e","jsx","SmartPointerSensor","PointerSensor","event","SmartTouchSensor","TouchSensor","DashboardProvider","layout","onChange","renderPane","renderDragOverlay","classNames","fullscreenPaneId","onFullscreenChange","onRemove","dragActivationDistance","snapThreshold","onDragStart","onDragEnd","onResizeStart","onResize","onResizeEnd","minSplitPercentage","maxSplitPercentage","enableDragToDismiss","dismissThreshold","onDismissIntentChange","children","localLayout","setLocalLayout","useState","prevLayout","setPrevLayout","setActiveId","dismissIntentId","setDismissIntentId","containerRef","containerRectRef","setContainerRef","useCallback","element","onDismissIntentChangeRef","layoutRef","onChangeRef","renderPaneRef","onResizeEndPropRef","stableRenderPane","stableClassNames","useMemo","sensors","useSensors","useSensor","handleDragStart","handleDragMove","containerRect","ae","px","py","touch","distance","dx","dy","activeRect","cx","cy","handleDragEnd","active","over","wasDismissIntent","handleRemovePane","overIdStr","rootMatch","dropZone","newLayout","swapMatch","match","handleLocalLayoutChange","handleAddPane","handleSwapPanes","paneIdA","paneIdB","handleSplitPane","handleUpdateSplitPercentage","currentNode","percentage","handleUpdatePaneMetadata","handleResizeEnd","finalLayout","stateValue","actionsValue","jsxs","DndContext","pointerWithin","rootActivationPositions","rootPreviewPositions","RootDropZone","id","position","activeClassName","setNodeRef","isOver","useDroppable","Fragment","RootDropZones","hasOtherPanes","dropPreviewClassName","pos","createDragSession","cursor","resizerEl","onMove","onEnd","styleEl","handlePointerMove","handlePointerUp","globalStyle","useResizer","isRow","splitPercentage","resizerSize","onLayoutChange","localOnResizeStart","localOnResizeEnd","globalOnResizeStart","globalOnResize","globalOnResizeEnd","container","rect","startX","startY","startPercentage","otherPositions","el","r","currentPercentage","moveEvent","delta","proposedPercentage","proposedPos","closestDistance","bestTarget","dist","snappedPercentage","finalPercentage","firstChild","secondChild","PaneSplit","isResizing","setIsResizing","first","second","handlePointerDown","PaneTree","propSnapThreshold","contextSnapThreshold","renderContent","STORAGE_PREFIX","DEFAULT_PERSIST_KEY","readPersistedHeight","key","raw","parsed","writePersistedHeight","height","ResizableContainer","heightProp","onHeightChange","minHeight","maxHeight","persist","localStorageKey","resizerHeight","resizerClassName","storageKey","getInitialHeight","baseHeight","clamp","internalHeight","setInternalHeight","effectiveHeight","prevHeightPropRef","clamped","resolveMaxHeight","startHeight","resolvedMaxHeight","scrollParent","getScrollParent","startScrollTop","lastClientY","animationFrameId","updateHeight","clientY","currentScrollTop","scrollDelta","totalDelta","newHeight","scrollLoop","parentRect","threshold","maxSpeed","finalHeight","value","min","max","parent","overflowY","DragListenersCtx","activationPositions","previewPositions","DropZone","Pane","style","showDropZones","attributes","listeners","isDragging","useDraggable","dragging","isFullscreen","metadata","renderProps","contextValue","DragHandle","dragProps"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createContext, ReactNode } from 'react'\nimport { TreeNode, SplitDirection, SplitNode } from '../../../shared/model'\n\nexport interface ZeugmaClassNames {\n pane?: string\n dropPreview?: string\n swapPreview?: string\n dragOverlay?: string\n resizer?: string\n dismissPreview?: string\n}\n\n/**\n * State context — holds reactive values that change during runtime.\n * All consumers of this context will re-render when any of these values change.\n */\nexport interface DashboardStateValue {\n layout: TreeNode | null\n onLayoutChange: (newLayout: TreeNode | null) => void\n renderPane: (paneId: string) => ReactNode\n activeId: string | null\n dismissIntentId: string | null\n setContainerRef: (element: HTMLElement | null) => void\n fullscreenPaneId: string | null\n classNames: ZeugmaClassNames\n onRemove?: (paneId: string) => void\n onFullscreenChange?: (paneId: string | null) => void\n snapThreshold?: number\n onResizeStart?: (currentNode: SplitNode) => void\n onResize?: (currentNode: SplitNode, percentage: number) => void\n onResizeEnd?: (currentNode: SplitNode, percentage: number) => void\n minSplitPercentage?: number\n maxSplitPercentage?: number\n}\n\n/**\n * Actions context — holds stable dispatch functions with permanent identity.\n * Consumers of only this context will never re-render from layout/drag state changes.\n */\nexport interface DashboardActionsValue {\n removePane: (paneId: string) => void\n addPane: (paneId: string) => void\n swapPanes: (paneIdA: string, paneIdB: string) => void\n splitPane: (\n targetId: string,\n direction: SplitDirection,\n splitType: 'left' | 'right' | 'top' | 'bottom',\n paneToAdd: string,\n ) => void\n updateSplitPercentage: (currentNode: SplitNode, percentage: number) => void\n updatePaneMetadata: (\n paneId: string,\n updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined,\n ) => void\n}\nexport const DashboardStateContext = createContext<DashboardStateValue | undefined>(undefined)\nexport const DashboardActionsContext = createContext<DashboardActionsValue | undefined>(undefined)\n","import { useContext } from 'react'\nimport {\n DashboardStateContext,\n DashboardActionsContext,\n DashboardStateValue,\n DashboardActionsValue,\n} from './context'\n\n/** Returns only reactive state. Use when you need layout, activeId, classNames, etc. */\nexport const useDashboardState = (): DashboardStateValue => {\n const state = useContext(DashboardStateContext)\n if (!state) {\n throw new Error('useDashboardState must be used within a DashboardProvider')\n }\n return state\n}\n\n/** Returns only stable action dispatchers. Consumers of this hook never re-render from state changes. */\nexport const useDashboardActions = (): DashboardActionsValue => {\n const actions = useContext(DashboardActionsContext)\n if (!actions) {\n throw new Error('useDashboardActions must be used within a DashboardProvider')\n }\n return actions\n}\n","import { TreeNode, SplitNode, SplitDirection, PaneNode } from '../../model'\n\n/**\n * Tree Helper: Remove a pane and consolidate the tree structure.\n */\nexport function removePane(tree: TreeNode | null, idToRemove: string): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n return tree.paneId === idToRemove ? null : tree\n }\n const newFirst = removePane(tree.first, idToRemove)\n const newSecond = removePane(tree.second, idToRemove)\n if (newFirst === null) return newSecond\n if (newSecond === null) return newFirst\n return { ...tree, first: newFirst, second: newSecond }\n}\n\n/**\n * Tree Helper: Insert a pane by splitting an existing target node.\n */\nexport function splitPane(\n tree: TreeNode | null,\n targetId: string,\n direction: SplitDirection,\n splitType: 'left' | 'right' | 'top' | 'bottom',\n paneToAdd: string | PaneNode,\n): TreeNode | null {\n if (tree === null) {\n return typeof paneToAdd === 'string' ? { type: 'pane', paneId: paneToAdd } : paneToAdd\n }\n if (tree.type === 'pane') {\n if (tree.paneId === targetId) {\n const addedNode: PaneNode =\n typeof paneToAdd === 'string' ? { type: 'pane', paneId: paneToAdd } : paneToAdd\n const isFirst = splitType === 'left' || splitType === 'top'\n return {\n type: 'split',\n direction,\n first: isFirst ? addedNode : tree,\n second: isFirst ? tree : addedNode,\n splitPercentage: 50,\n }\n }\n return tree\n }\n return {\n ...tree,\n first: splitPane(tree.first, targetId, direction, splitType, paneToAdd) || tree.first,\n second: splitPane(tree.second, targetId, direction, splitType, paneToAdd) || tree.second,\n }\n}\n\n/**\n * Tree Helper: Swap the position of two panes in the tree structure.\n */\nexport function swapPanes(tree: TreeNode | null, idA: string, idB: string): TreeNode | null {\n if (tree === null) return null\n\n // First pass: collect the full PaneNode references\n const nodeA = findPane(tree, idA)\n const nodeB = findPane(tree, idB)\n if (!nodeA || !nodeB) return tree\n\n // Second pass: replace each location with the other node\n function swap(node: TreeNode): TreeNode {\n if (node.type === 'pane') {\n if (node.paneId === idA) return { ...nodeB! }\n if (node.paneId === idB) return { ...nodeA! }\n return node\n }\n return {\n ...node,\n first: swap(node.first),\n second: swap(node.second),\n }\n }\n\n return swap(tree)\n}\n\n/**\n * Tree Helper: Add a pane by recursively splitting the rightmost/bottommost pane in the tree.\n */\nexport function addPane(tree: TreeNode | null, paneToAdd: string): TreeNode {\n if (tree === null) {\n return { type: 'pane', paneId: paneToAdd }\n }\n\n function insert(node: TreeNode, parentDirection: SplitDirection | null): TreeNode {\n if (node.type === 'pane') {\n const direction: SplitDirection = parentDirection === 'row' ? 'column' : 'row'\n return {\n type: 'split',\n direction,\n splitPercentage: 50,\n first: node,\n second: { type: 'pane', paneId: paneToAdd },\n }\n }\n\n return {\n ...node,\n second: insert(node.second, node.direction),\n }\n }\n\n return insert(tree, null)\n}\n\n/**\n * Tree Helper: Update split percentage recursively.\n */\nexport function updateSplitPercentage(\n tree: TreeNode | null,\n target: SplitNode,\n newPercentage: number,\n): TreeNode | null {\n if (tree === null) return null\n if (tree === target) {\n return { ...tree, splitPercentage: newPercentage } as SplitNode\n }\n if (tree.type === 'split') {\n return {\n ...tree,\n first: updateSplitPercentage(tree.first, target, newPercentage) || tree.first,\n second: updateSplitPercentage(tree.second, target, newPercentage) || tree.second,\n }\n }\n return tree\n}\n\n/**\n * Tree Helper: Split the entire tree at the root using a dragged pane.\n */\nexport function splitRoot(\n tree: TreeNode | null,\n draggingId: string,\n splitType: 'left' | 'right' | 'top' | 'bottom',\n): TreeNode | null {\n // Preserve dragged pane's metadata\n const draggedPaneNode: PaneNode = findPane(tree, draggingId) ?? {\n type: 'pane',\n paneId: draggingId,\n }\n const treeWithoutDragging = removePane(tree, draggingId)\n if (treeWithoutDragging === null) {\n return { ...draggedPaneNode }\n }\n\n const direction: SplitDirection = splitType === 'left' || splitType === 'right' ? 'row' : 'column'\n const isFirst = splitType === 'left' || splitType === 'top'\n const draggedNode: TreeNode = { ...draggedPaneNode }\n\n return {\n type: 'split',\n direction,\n first: isFirst ? draggedNode : treeWithoutDragging,\n second: isFirst ? treeWithoutDragging : draggedNode,\n splitPercentage: 50,\n }\n}\n\n/**\n * Find a PaneNode by its paneId.\n */\nexport function findPane(tree: TreeNode | null, paneId: string): PaneNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n return tree.paneId === paneId ? tree : null\n }\n return findPane(tree.first, paneId) ?? findPane(tree.second, paneId)\n}\n\n/**\n * Update metadata on a specific pane node using an updater function.\n */\nexport function updatePaneMetadata(\n tree: TreeNode | null,\n paneId: string,\n updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined,\n): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.paneId === paneId) {\n const newMetadata = updater(tree.metadata)\n if (newMetadata === undefined) {\n // Remove metadata key\n const { metadata: _, ...rest } = tree\n return rest as PaneNode\n }\n return { ...tree, metadata: newMetadata }\n }\n return tree\n }\n return {\n ...tree,\n first: updatePaneMetadata(tree.first, paneId, updater) ?? tree.first,\n second: updatePaneMetadata(tree.second, paneId, updater) ?? tree.second,\n }\n}\n","export const DEFAULT_SNAP_THRESHOLD = 8 // px\nexport const DEFAULT_DRAG_ACTIVATION_DISTANCE = 8 // px\nexport const DEFAULT_RESIZER_SIZE = 4 // px\n","import React, { useState, useEffect, useRef, ReactNode, useMemo, useCallback } from 'react'\nimport {\n DndContext,\n useSensor,\n useSensors,\n PointerSensor,\n TouchSensor,\n DragStartEvent,\n DragEndEvent,\n DragMoveEvent,\n pointerWithin,\n} from '@dnd-kit/core'\nimport { TreeNode, SplitDirection, SplitNode } from '../../../shared/model'\nimport {\n removePane,\n splitPane,\n swapPanes,\n addPane,\n updateSplitPercentage,\n splitRoot,\n updatePaneMetadata,\n findPane,\n} from '../../../shared/lib/tree'\nimport { DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_SNAP_THRESHOLD } from '../../../shared/config'\nimport { DashboardStateContext, DashboardActionsContext, ZeugmaClassNames } from '../model/context'\n\n/** Cursor-following overlay rendered via portal */\nconst CursorOverlay: React.FC<{\n activeId: string\n render: (id: string) => ReactNode\n className?: string\n}> = ({ activeId, render, className }) => {\n const ref = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const handleMove = (e: PointerEvent) => {\n if (ref.current) {\n ref.current.style.transform = `translate(${e.clientX + 12}px, ${e.clientY + 12}px)`\n }\n }\n document.addEventListener('pointermove', handleMove)\n return () => document.removeEventListener('pointermove', handleMove)\n }, [])\n\n return (\n <div\n ref={ref}\n className={className}\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n zIndex: 9999,\n pointerEvents: 'none',\n }}\n >\n {render(activeId)}\n </div>\n )\n}\n\nclass SmartPointerSensor extends PointerSensor {\n static activators = [\n {\n eventName: 'onPointerDown' as const,\n handler: ({ nativeEvent: event }: { nativeEvent: PointerEvent }) => {\n const element = event.target as HTMLElement | null\n if (element?.closest('.drag-cancel')) {\n return false\n }\n return true\n },\n },\n ]\n}\n\nclass SmartTouchSensor extends TouchSensor {\n static activators = [\n {\n eventName: 'onTouchStart' as const,\n handler: ({ nativeEvent: event }: { nativeEvent: TouchEvent }) => {\n const element = event.target as HTMLElement | null\n if (element?.closest('.drag-cancel')) {\n return false\n }\n return true\n },\n },\n ]\n}\n\ninterface DashboardProviderProps {\n layout: TreeNode | null\n onChange: (newLayout: TreeNode | null) => void\n renderPane: (paneId: string) => ReactNode\n renderDragOverlay?: (activeId: string) => ReactNode\n classNames?: ZeugmaClassNames\n fullscreenPaneId?: string | null\n onFullscreenChange?: (paneId: string | null) => void\n onRemove?: (paneId: string) => void\n dragActivationDistance?: number\n snapThreshold?: number\n onDragStart?: (activeId: string) => void\n onDragEnd?: (\n activeId: string,\n overId: string | null,\n dropAction: {\n type: 'split' | 'swap'\n direction?: SplitDirection\n position?: 'top' | 'bottom' | 'left' | 'right' | 'center'\n } | null,\n ) => void\n onResizeStart?: (currentNode: SplitNode) => void\n onResize?: (currentNode: SplitNode, percentage: number) => void\n onResizeEnd?: (currentNode: SplitNode, percentage: number) => void\n minSplitPercentage?: number\n maxSplitPercentage?: number\n enableDragToDismiss?: boolean\n dismissThreshold?: number\n onDismissIntentChange?: (paneId: string | null) => void\n children: ReactNode\n}\n\nexport const DashboardProvider: React.FC<DashboardProviderProps> = ({\n layout,\n onChange,\n renderPane,\n renderDragOverlay,\n classNames = {},\n fullscreenPaneId = null,\n onFullscreenChange,\n onRemove,\n dragActivationDistance = DEFAULT_DRAG_ACTIVATION_DISTANCE,\n snapThreshold = DEFAULT_SNAP_THRESHOLD,\n onDragStart,\n onDragEnd,\n onResizeStart,\n onResize,\n onResizeEnd,\n minSplitPercentage = 5,\n maxSplitPercentage = 95,\n enableDragToDismiss = false,\n dismissThreshold = 60,\n onDismissIntentChange,\n children,\n}) => {\n const [localLayout, setLocalLayout] = useState<TreeNode | null>(layout)\n const [prevLayout, setPrevLayout] = useState<TreeNode | null>(layout)\n\n if (layout !== prevLayout) {\n setPrevLayout(layout)\n setLocalLayout(layout)\n }\n\n const [activeId, setActiveId] = useState<string | null>(null)\n const [dismissIntentId, setDismissIntentId] = useState<string | null>(null)\n const containerRef = useRef<HTMLElement | null>(null)\n const containerRectRef = useRef<DOMRect | null>(null)\n\n const setContainerRef = useCallback((element: HTMLElement | null) => {\n containerRef.current = element\n }, [])\n\n const onDismissIntentChangeRef = useRef(onDismissIntentChange)\n onDismissIntentChangeRef.current = onDismissIntentChange\n\n // Refs for stable closure access — prevents callback identity changes on every layout update\n const layoutRef = useRef(localLayout)\n layoutRef.current = localLayout\n\n const onChangeRef = useRef(onChange)\n onChangeRef.current = onChange\n\n const renderPaneRef = useRef(renderPane)\n renderPaneRef.current = renderPane\n\n const onResizeEndPropRef = useRef(onResizeEnd)\n onResizeEndPropRef.current = onResizeEnd\n\n // Stable renderPane wrapper — immune to consumer passing inline functions\n const stableRenderPane = useCallback((paneId: string) => renderPaneRef.current(paneId), [])\n\n // Shallow-memoize classNames by individual fields to avoid identity busting from inline objects\n const stableClassNames = useMemo(\n () => classNames,\n [\n classNames.pane,\n classNames.dropPreview,\n classNames.swapPreview,\n classNames.dragOverlay,\n classNames.resizer,\n classNames.dismissPreview,\n ],\n )\n\n const sensors = useSensors(\n useSensor(SmartPointerSensor, {\n activationConstraint: { distance: dragActivationDistance },\n }),\n useSensor(SmartTouchSensor, {\n activationConstraint: { delay: 250, tolerance: 5 },\n }),\n )\n\n const handleDragStart = (event: DragStartEvent) => {\n const draggingId = event.active.id.toString()\n setActiveId(draggingId)\n if (enableDragToDismiss && containerRef.current) {\n containerRectRef.current = containerRef.current.getBoundingClientRect()\n } else {\n containerRectRef.current = null\n }\n if (onDragStart) {\n onDragStart(draggingId)\n }\n }\n\n const handleDragMove = (event: DragMoveEvent) => {\n if (!enableDragToDismiss) return\n\n const draggingId = event.active.id.toString()\n const containerRect = containerRectRef.current\n\n if (!containerRect) {\n if (dismissIntentId !== null) {\n setDismissIntentId(null)\n onDismissIntentChangeRef.current?.(null)\n }\n return\n }\n\n const ae = event.activatorEvent\n let px: number | null = null\n let py: number | null = null\n\n if (ae instanceof MouseEvent || ae instanceof PointerEvent) {\n px = ae.clientX + event.delta.x\n py = ae.clientY + event.delta.y\n } else if (typeof TouchEvent !== 'undefined' && ae instanceof TouchEvent) {\n const touch = ae.touches[0] || ae.changedTouches[0]\n if (touch) {\n px = touch.clientX + event.delta.x\n py = touch.clientY + event.delta.y\n }\n }\n\n let distance = 0\n if (px !== null && py !== null) {\n let dx = 0\n let dy = 0\n\n if (px < containerRect.left) {\n dx = containerRect.left - px\n } else if (px > containerRect.right) {\n dx = px - containerRect.right\n }\n\n if (py < containerRect.top) {\n dy = containerRect.top - py\n } else if (py > containerRect.bottom) {\n dy = py - containerRect.bottom\n }\n\n distance = Math.sqrt(dx * dx + dy * dy)\n } else {\n const activeRect = event.active.rect.current.translated\n if (activeRect) {\n const cx = activeRect.left + activeRect.width / 2\n const cy = activeRect.top + activeRect.height / 2\n let dx = 0\n let dy = 0\n\n if (cx < containerRect.left) {\n dx = containerRect.left - cx\n } else if (cx > containerRect.right) {\n dx = cx - containerRect.right\n }\n\n if (cy < containerRect.top) {\n dy = containerRect.top - cy\n } else if (cy > containerRect.bottom) {\n dy = cy - containerRect.bottom\n }\n\n distance = Math.sqrt(dx * dx + dy * dy)\n }\n }\n\n const isDismissIntent = distance > dismissThreshold\n if (isDismissIntent) {\n if (dismissIntentId !== draggingId) {\n setDismissIntentId(draggingId)\n onDismissIntentChangeRef.current?.(draggingId)\n }\n } else {\n if (dismissIntentId !== null) {\n setDismissIntentId(null)\n onDismissIntentChangeRef.current?.(null)\n }\n }\n }\n\n const handleDragEnd = (event: DragEndEvent) => {\n setActiveId(null)\n const { active, over } = event\n const draggingId = active.id.toString()\n\n const wasDismissIntent = enableDragToDismiss && dismissIntentId === draggingId\n\n setDismissIntentId(null)\n onDismissIntentChangeRef.current?.(null)\n containerRectRef.current = null\n\n if (wasDismissIntent) {\n if (onRemove) {\n onRemove(draggingId)\n } else {\n handleRemovePane(draggingId)\n }\n\n if (onDragEnd) {\n onDragEnd(draggingId, null, null)\n }\n return\n }\n\n if (!over) {\n if (onDragEnd) {\n onDragEnd(draggingId, null, null)\n }\n return\n }\n\n const overIdStr = over.id.toString()\n\n // Check for root drop (places pane like half of the root)\n const rootMatch = overIdStr.match(/^drop-root-(left|right|top|bottom)$/)\n if (rootMatch) {\n const [, dropZone] = rootMatch\n const newLayout = splitRoot(\n localLayout,\n draggingId,\n dropZone as 'left' | 'right' | 'top' | 'bottom',\n )\n setLocalLayout(newLayout)\n onChange(newLayout)\n\n if (onDragEnd) {\n const direction: SplitDirection =\n dropZone === 'left' || dropZone === 'right' ? 'row' : 'column'\n onDragEnd(draggingId, 'root', {\n type: 'split',\n direction,\n position: dropZone as 'left' | 'right' | 'top' | 'bottom',\n })\n }\n return\n }\n\n // Check for center (swap) drop\n const swapMatch = overIdStr.match(/^drop-center-(.+)$/)\n if (swapMatch) {\n const [, targetId] = swapMatch\n if (draggingId !== targetId) {\n const newLayout = swapPanes(localLayout, draggingId, targetId)\n setLocalLayout(newLayout)\n onChange(newLayout)\n }\n if (onDragEnd) {\n onDragEnd(draggingId, targetId, { type: 'swap', position: 'center' })\n }\n return\n }\n\n // Check for edge (split) drop\n const match = overIdStr.match(/^drop-(left|right|top|bottom)-(.+)$/)\n if (!match) {\n if (onDragEnd) {\n onDragEnd(draggingId, null, null)\n }\n return\n }\n\n const [, dropZone, targetId] = match\n if (draggingId === targetId) {\n if (onDragEnd) {\n onDragEnd(draggingId, null, null)\n }\n return\n }\n\n const direction: SplitDirection = dropZone === 'left' || dropZone === 'right' ? 'row' : 'column'\n const draggedPaneNode = findPane(localLayout, draggingId) ?? {\n type: 'pane',\n paneId: draggingId,\n }\n const treeWithoutDragging = removePane(localLayout, draggingId)\n\n const newLayout = splitPane(\n treeWithoutDragging,\n targetId,\n direction,\n dropZone as 'left' | 'right' | 'top' | 'bottom',\n draggedPaneNode,\n )\n setLocalLayout(newLayout)\n onChange(newLayout)\n if (onDragEnd) {\n onDragEnd(draggingId, targetId, {\n type: 'split',\n direction,\n position: dropZone as 'left' | 'right' | 'top' | 'bottom',\n })\n }\n }\n\n const handleLocalLayoutChange = useCallback((newLayout: TreeNode | null) => {\n setLocalLayout(newLayout)\n }, [])\n\n const handleRemovePane = useCallback((paneId: string) => {\n const newLayout = removePane(layoutRef.current, paneId)\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n }, [])\n\n const handleAddPane = useCallback((paneId: string) => {\n const newLayout = addPane(layoutRef.current, paneId)\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n }, [])\n\n const handleSwapPanes = useCallback((paneIdA: string, paneIdB: string) => {\n const newLayout = swapPanes(layoutRef.current, paneIdA, paneIdB)\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n }, [])\n\n const handleSplitPane = useCallback(\n (\n targetId: string,\n direction: SplitDirection,\n splitType: 'left' | 'right' | 'top' | 'bottom',\n paneToAdd: string,\n ) => {\n const draggedPaneNode = findPane(layoutRef.current, paneToAdd) ?? {\n type: 'pane',\n paneId: paneToAdd,\n }\n const treeWithoutDragging = removePane(layoutRef.current, paneToAdd)\n const newLayout = splitPane(\n treeWithoutDragging,\n targetId,\n direction,\n splitType,\n draggedPaneNode,\n )\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n },\n [],\n )\n\n const handleUpdateSplitPercentage = useCallback((currentNode: SplitNode, percentage: number) => {\n const newLayout = updateSplitPercentage(layoutRef.current, currentNode, percentage)\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n }, [])\n\n const handleUpdatePaneMetadata = useCallback(\n (\n paneId: string,\n updater: (\n current: Record<string, unknown> | undefined,\n ) => Record<string, unknown> | undefined,\n ) => {\n const newLayout = updatePaneMetadata(layoutRef.current, paneId, updater)\n setLocalLayout(newLayout)\n onChangeRef.current(newLayout)\n },\n [],\n )\n\n const handleResizeEnd = useCallback((currentNode: SplitNode, percentage: number) => {\n const finalLayout = updateSplitPercentage(layoutRef.current, currentNode, percentage)\n setLocalLayout(finalLayout)\n onChangeRef.current(finalLayout)\n if (onResizeEndPropRef.current) {\n onResizeEndPropRef.current(currentNode, percentage)\n }\n }, [])\n\n // State context — reactive values that change during runtime\n const stateValue = useMemo(\n () => ({\n layout: localLayout,\n onLayoutChange: handleLocalLayoutChange,\n renderPane: stableRenderPane,\n activeId,\n dismissIntentId,\n setContainerRef,\n fullscreenPaneId,\n classNames: stableClassNames,\n onRemove,\n onFullscreenChange,\n snapThreshold,\n onResizeStart,\n onResize,\n onResizeEnd: handleResizeEnd,\n minSplitPercentage,\n maxSplitPercentage,\n }),\n [\n localLayout,\n activeId,\n dismissIntentId,\n setContainerRef,\n fullscreenPaneId,\n stableClassNames,\n onRemove,\n onFullscreenChange,\n snapThreshold,\n onResizeStart,\n onResize,\n minSplitPercentage,\n maxSplitPercentage,\n // Stable callbacks (empty deps) — included for exhaustive-deps lint rule\n handleLocalLayoutChange,\n stableRenderPane,\n handleResizeEnd,\n ],\n )\n\n // Actions context — stable dispatch functions that never change identity\n const actionsValue = useMemo(\n () => ({\n removePane: handleRemovePane,\n addPane: handleAddPane,\n swapPanes: handleSwapPanes,\n splitPane: handleSplitPane,\n updateSplitPercentage: handleUpdateSplitPercentage,\n updatePaneMetadata: handleUpdatePaneMetadata,\n }),\n [\n handleRemovePane,\n handleAddPane,\n handleSwapPanes,\n handleSplitPane,\n handleUpdateSplitPercentage,\n handleUpdatePaneMetadata,\n ],\n )\n\n return (\n <DashboardActionsContext.Provider value={actionsValue}>\n <DashboardStateContext.Provider value={stateValue}>\n <DndContext\n id=\"zeugma-dnd-context\"\n sensors={sensors}\n collisionDetection={pointerWithin}\n onDragStart={handleDragStart}\n onDragMove={handleDragMove}\n onDragEnd={handleDragEnd}\n >\n {children}\n </DndContext>\n {activeId && renderDragOverlay && (\n <CursorOverlay\n activeId={activeId}\n render={renderDragOverlay}\n className={`${classNames.dragOverlay || ''} ${\n activeId === dismissIntentId\n ? classNames.dismissPreview || 'zeugma-dismiss-preview'\n : ''\n }`.trim()}\n />\n )}\n </DashboardStateContext.Provider>\n </DashboardActionsContext.Provider>\n )\n}\n","import React from 'react'\nimport { useDroppable } from '@dnd-kit/core'\n\nconst rootActivationPositions: Record<string, React.CSSProperties> = {\n top: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: '32px',\n zIndex: 30,\n pointerEvents: 'auto',\n },\n bottom: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: '32px',\n zIndex: 30,\n pointerEvents: 'auto',\n },\n left: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n width: '32px',\n zIndex: 30,\n pointerEvents: 'auto',\n },\n right: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n right: 0,\n width: '32px',\n zIndex: 30,\n pointerEvents: 'auto',\n },\n}\n\nconst rootPreviewPositions: Record<string, React.CSSProperties> = {\n top: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: '50%',\n zIndex: 31,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n bottom: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: '50%',\n zIndex: 31,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n left: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n width: '50%',\n zIndex: 31,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n right: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n right: 0,\n width: '50%',\n zIndex: 31,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n}\n\nexport interface RootDropZoneProps {\n id: string\n position: 'top' | 'bottom' | 'left' | 'right'\n activeClassName?: string\n}\n\nexport const RootDropZone: React.FC<RootDropZoneProps> = ({ id, position, activeClassName }) => {\n const { setNodeRef, isOver } = useDroppable({ id })\n return (\n <>\n <div ref={setNodeRef} style={rootActivationPositions[position]} />\n {isOver && <div className={activeClassName} style={rootPreviewPositions[position]} />}\n </>\n )\n}\n\nexport interface RootDropZonesProps {\n activeId: string | null\n hasOtherPanes: boolean\n dropPreviewClassName?: string\n}\n\nexport const RootDropZones: React.FC<RootDropZonesProps> = ({\n activeId,\n hasOtherPanes,\n dropPreviewClassName,\n}) => {\n if (!activeId || !hasOtherPanes) return null\n\n return (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 30,\n pointerEvents: 'none',\n }}\n >\n {(['top', 'bottom', 'left', 'right'] as const).map((pos) => (\n <RootDropZone\n key={pos}\n id={`drop-root-${pos}`}\n position={pos}\n activeClassName={dropPreviewClassName}\n />\n ))}\n </div>\n )\n}\n","/**\n * Shared drag-session lifecycle utility.\n *\n * Handles the common boilerplate for pointer-based resize operations:\n * - Adds `zeugma-resizing` class to `document.body`\n * - Injects a global `cursor` style so the resize cursor stays active\n * even when the pointer leaves the handle element\n * - Sets `data-resizing` on the resizer element\n * - Attaches `pointermove` / `pointerup` listeners to `document`\n * - Cleans everything up on pointer-up\n *\n * Consumers provide domain-specific `onMove` and `onEnd` callbacks.\n */\n\nexport interface DragSessionConfig {\n /** CSS cursor to enforce globally during the drag */\n cursor: 'col-resize' | 'row-resize'\n /** The resizer DOM element (receives `data-resizing` attribute) */\n resizerEl: HTMLElement\n /** Called on every `pointermove` during the drag */\n onMove: (e: PointerEvent) => void\n /** Called once on `pointerup` — after cleanup has already run */\n onEnd: () => void\n}\n\nexport function createDragSession({ cursor, resizerEl, onMove, onEnd }: DragSessionConfig): void {\n // 1. Body class\n document.body.classList.add('zeugma-resizing')\n\n // 2. Global cursor override\n const styleEl = document.createElement('style')\n styleEl.id = 'zeugma-global-cursor-style'\n styleEl.textContent = `\n * {\n cursor: ${cursor} !important;\n user-select: none !important;\n }\n `\n document.head.appendChild(styleEl)\n\n // 3. Mark the resizer element\n resizerEl.setAttribute('data-resizing', 'true')\n\n // 4. Document-level listeners\n const handlePointerMove = (e: PointerEvent) => {\n onMove(e)\n }\n\n const handlePointerUp = () => {\n // Cleanup\n document.body.classList.remove('zeugma-resizing')\n resizerEl.removeAttribute('data-resizing')\n\n const globalStyle = document.getElementById('zeugma-global-cursor-style')\n if (globalStyle) {\n globalStyle.remove()\n }\n\n document.removeEventListener('pointermove', handlePointerMove)\n document.removeEventListener('pointerup', handlePointerUp)\n\n // Notify consumer\n onEnd()\n }\n\n document.addEventListener('pointermove', handlePointerMove)\n document.addEventListener('pointerup', handlePointerUp)\n}\n","import React, { useCallback } from 'react'\nimport { TreeNode, SplitNode, SplitDirection } from '../../../shared/model'\nimport { updateSplitPercentage } from '../../../shared/lib/tree'\nimport { createDragSession } from '../../../shared/lib/drag-session'\nimport { useDashboardState } from '../../../entities/dashboard'\n\ninterface UseResizerProps {\n containerRef: React.RefObject<HTMLDivElement | null>\n isRow: boolean\n direction: SplitDirection\n splitPercentage: number\n resizerSize: number\n snapThreshold: number\n layout: TreeNode | null\n currentNode: SplitNode\n onLayoutChange: (newLayout: TreeNode | null) => void\n onResizeStart?: () => void\n onResizeEnd?: () => void\n}\n\nexport function useResizer({\n containerRef,\n isRow,\n direction,\n splitPercentage,\n resizerSize,\n snapThreshold,\n layout,\n currentNode,\n onLayoutChange,\n onResizeStart: localOnResizeStart,\n onResizeEnd: localOnResizeEnd,\n}: UseResizerProps) {\n const {\n onResizeStart: globalOnResizeStart,\n onResize: globalOnResize,\n onResizeEnd: globalOnResizeEnd,\n minSplitPercentage = 5,\n maxSplitPercentage = 95,\n } = useDashboardState()\n\n return useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n e.preventDefault()\n const container = containerRef.current\n if (!container) return\n\n if (localOnResizeStart) {\n localOnResizeStart()\n }\n if (globalOnResizeStart) {\n globalOnResizeStart(currentNode)\n }\n\n const rect = container.getBoundingClientRect()\n const startX = e.clientX\n const startY = e.clientY\n const startPercentage = splitPercentage\n const resizerEl = e.currentTarget\n\n // Cache other resizers of the same direction once at drag-start to prevent layout thrashing on move\n const otherResizers = Array.from(\n document.querySelectorAll('div[role=\"separator\"][data-direction]'),\n ).filter((el) => el !== resizerEl && el.getAttribute('data-direction') === direction)\n\n const otherPositions = otherResizers.map((el) => {\n const r = el.getBoundingClientRect()\n return isRow ? r.left + r.width / 2 : r.top + r.height / 2\n })\n\n let currentPercentage = startPercentage\n\n createDragSession({\n cursor: isRow ? 'col-resize' : 'row-resize',\n resizerEl,\n onMove: (moveEvent: PointerEvent) => {\n const delta = isRow\n ? ((moveEvent.clientX - startX) / rect.width) * 100\n : ((moveEvent.clientY - startY) / rect.height) * 100\n const proposedPercentage = startPercentage + delta\n\n // Find physical position corresponding to proposed percentage\n const proposedPos = isRow\n ? rect.left + (rect.width - resizerSize) * (proposedPercentage / 100) + resizerSize / 2\n : rect.top + (rect.height - resizerSize) * (proposedPercentage / 100) + resizerSize / 2\n\n let closestDistance = Infinity\n let bestTarget: number | null = null\n\n for (const pos of otherPositions) {\n const dist = Math.abs(proposedPos - pos)\n if (dist < snapThreshold && dist < closestDistance) {\n closestDistance = dist\n bestTarget = pos\n }\n }\n\n let snappedPercentage = proposedPercentage\n if (bestTarget !== null) {\n snappedPercentage = isRow\n ? ((bestTarget - resizerSize / 2 - rect.left) / (rect.width - resizerSize)) * 100\n : ((bestTarget - resizerSize / 2 - rect.top) / (rect.height - resizerSize)) * 100\n }\n\n const finalPercentage = Math.max(\n minSplitPercentage,\n Math.min(maxSplitPercentage, snappedPercentage),\n )\n currentPercentage = finalPercentage\n\n // Imperatively update the sibling pane container flex sizes during drag\n const firstChild = container.children[0] as HTMLElement\n const secondChild = container.children[container.children.length - 1] as HTMLElement\n if (firstChild && secondChild) {\n firstChild.style.flex = `${finalPercentage} 1 0%`\n secondChild.style.flex = `${100 - finalPercentage} 1 0%`\n }\n\n if (globalOnResize) {\n globalOnResize(currentNode, finalPercentage)\n }\n },\n onEnd: () => {\n // Write to React state once resizing completes\n const newLayout = updateSplitPercentage(layout, currentNode, currentPercentage)\n onLayoutChange(newLayout)\n\n if (localOnResizeEnd) {\n localOnResizeEnd()\n }\n if (globalOnResizeEnd) {\n globalOnResizeEnd(currentNode, currentPercentage)\n }\n },\n })\n },\n [\n containerRef,\n isRow,\n direction,\n splitPercentage,\n resizerSize,\n snapThreshold,\n layout,\n currentNode,\n onLayoutChange,\n localOnResizeStart,\n localOnResizeEnd,\n globalOnResizeStart,\n globalOnResize,\n globalOnResizeEnd,\n minSplitPercentage,\n maxSplitPercentage,\n ],\n )\n}\n","import React, { useRef, useState, useMemo } from 'react'\nimport { useDashboardState, RootDropZones } from '../../../entities/dashboard'\nimport { useResizer } from '../../../features/resize-pane'\nimport { TreeNode, SplitNode } from '../../../shared/model'\nimport { removePane } from '../../../shared'\n\nexport interface PaneTreeProps {\n tree?: TreeNode | null\n /** Size of the resizer in pixels (default 4) */\n resizerSize?: number\n /** Threshold in pixels to snap to adjacent resizer edges (default 8) */\n snapThreshold?: number\n}\n\ninterface PaneSplitProps {\n currentNode: SplitNode\n resizerSize: number\n snapThreshold?: number\n}\n\nconst PaneSplit: React.FC<PaneSplitProps> = ({ currentNode, resizerSize, snapThreshold }) => {\n const { layout, onLayoutChange, classNames } = useDashboardState()\n const [isResizing, setIsResizing] = useState(false)\n\n const containerRef = useRef<HTMLDivElement>(null)\n const { direction, first, second, splitPercentage } = currentNode\n const isRow = direction === 'row'\n\n const handlePointerDown = useResizer({\n containerRef,\n isRow,\n direction,\n splitPercentage,\n resizerSize,\n snapThreshold: snapThreshold ?? 8,\n layout,\n currentNode,\n onLayoutChange,\n onResizeStart: () => setIsResizing(true),\n onResizeEnd: () => setIsResizing(false),\n })\n\n return (\n <div\n ref={containerRef}\n style={{\n display: 'flex',\n flexDirection: isRow ? 'row' : 'column',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n }}\n >\n <div style={{ flex: `${splitPercentage} 1 0%`, overflow: 'hidden' }}>\n <PaneTree tree={first} resizerSize={resizerSize} snapThreshold={snapThreshold} />\n </div>\n <div\n className={`zeugma-resizer ${classNames.resizer || ''}`.trim()}\n data-direction={direction}\n data-resizing={isResizing || undefined}\n style={{\n width: isRow ? `${resizerSize}px` : '100%',\n height: isRow ? '100%' : `${resizerSize}px`,\n cursor: isRow ? 'col-resize' : 'row-resize',\n position: 'relative',\n zIndex: 10,\n userSelect: 'none',\n touchAction: 'none',\n boxSizing: 'border-box',\n flexShrink: 0,\n }}\n onPointerDown={handlePointerDown}\n role=\"separator\"\n aria-valuenow={splitPercentage}\n aria-valuemin={5}\n aria-valuemax={95}\n />\n <div style={{ flex: `${100 - splitPercentage} 1 0%`, overflow: 'hidden' }}>\n <PaneTree tree={second} resizerSize={resizerSize} snapThreshold={snapThreshold} />\n </div>\n </div>\n )\n}\n\nexport const PaneTree: React.FC<PaneTreeProps> = ({\n tree,\n resizerSize = 4,\n snapThreshold: propSnapThreshold,\n}) => {\n const {\n layout,\n renderPane,\n activeId,\n dismissIntentId,\n setContainerRef,\n classNames,\n fullscreenPaneId,\n snapThreshold: contextSnapThreshold,\n } = useDashboardState()\n\n const snapThreshold = propSnapThreshold !== undefined ? propSnapThreshold : contextSnapThreshold\n\n const hasOtherPanes = useMemo(() => {\n if (tree !== undefined || !activeId) return false\n return removePane(layout, activeId) !== null\n }, [tree, layout, activeId])\n\n // Fullscreen bypass\n if (fullscreenPaneId && !tree) {\n return (\n <div style={{ width: '100%', height: '100%', position: 'relative' }}>\n {renderPane(fullscreenPaneId)}\n </div>\n )\n }\n\n const currentNode = tree !== undefined ? tree : layout\n\n if (!currentNode) return null\n\n const renderContent = () => {\n if (currentNode.type === 'pane') {\n return (\n <div style={{ width: '100%', height: '100%', position: 'relative' }}>\n {renderPane(currentNode.paneId)}\n </div>\n )\n }\n\n return (\n <PaneSplit\n currentNode={currentNode}\n resizerSize={resizerSize}\n snapThreshold={snapThreshold}\n />\n )\n }\n\n // Only render RootDropZones at the top-level PaneTree (where tree is undefined)\n if (tree === undefined) {\n const isDismissActive = activeId !== null && activeId === dismissIntentId\n return (\n <div\n ref={setContainerRef}\n className={`zeugma-dashboard-root ${isDismissActive ? 'zeugma-dashboard-dismiss-active' : ''}`.trim()}\n style={{\n position: 'relative',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n }}\n >\n {renderContent()}\n <RootDropZones\n activeId={activeId}\n hasOtherPanes={hasOtherPanes}\n dropPreviewClassName={classNames.dropPreview}\n />\n </div>\n )\n }\n\n return renderContent()\n}\n","import React, { useState, useRef, useCallback, useEffect } from 'react'\nimport { createDragSession } from '../../../shared/lib/drag-session'\n\nconst STORAGE_PREFIX = 'zeugma-height:'\nconst DEFAULT_PERSIST_KEY = 'default-pane'\n\nexport interface ResizableContainerProps {\n children: React.ReactNode\n /** Whether the resizable container is active. When false, acts as a normal 100% height container. */\n active?: boolean\n /** Current height in pixels (controlled mode) or default/initial height */\n height?: number\n /** Called when the height changes during or after a drag */\n onHeightChange?: (height: number) => void\n /** Minimum height in pixels (default: 100) */\n minHeight?: number\n /** Maximum height in pixels (default: Infinity — bounded by parent) */\n maxHeight?: number\n /** Whether to persist height in localStorage */\n persist?: boolean\n /** Custom localStorage key to save the height under (default: 'default-pane') */\n localStorageKey?: string\n /** Height of the resizer handle in pixels (default: 6) */\n resizerHeight?: number\n /** CSS class applied to the outer container div */\n className?: string\n /** CSS class applied to the resizer handle */\n resizerClassName?: string\n}\n\nfunction readPersistedHeight(key: string): number | null {\n try {\n const raw = localStorage.getItem(STORAGE_PREFIX + key)\n if (raw !== null) {\n const parsed = Number(raw)\n if (Number.isFinite(parsed) && parsed > 0) return parsed\n }\n } catch {\n // localStorage may be unavailable (SSR, private browsing, etc.)\n }\n return null\n}\n\nfunction writePersistedHeight(key: string, height: number): void {\n try {\n localStorage.setItem(STORAGE_PREFIX + key, String(Math.round(height)))\n } catch {\n // Silently ignore storage errors\n }\n}\n\nexport const ResizableContainer: React.FC<ResizableContainerProps> = ({\n children,\n active = true,\n height: heightProp,\n onHeightChange,\n minHeight = 100,\n maxHeight = Infinity,\n persist,\n localStorageKey,\n resizerHeight = 6,\n className,\n resizerClassName,\n}) => {\n const storageKey = persist ? localStorageKey || DEFAULT_PERSIST_KEY : null\n\n const getInitialHeight = (): number => {\n const baseHeight = (storageKey ? readPersistedHeight(storageKey) : null) ?? heightProp ?? 400\n return clamp(baseHeight, minHeight, maxHeight)\n }\n\n const [internalHeight, setInternalHeight] = useState<number>(getInitialHeight)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // Determine effective height: if persist is set, use internal state; otherwise use prop\n const effectiveHeight = storageKey ? internalHeight : (heightProp ?? internalHeight)\n\n const prevHeightPropRef = useRef<number | undefined>(heightProp)\n\n // Sync from controlled prop when changed\n useEffect(() => {\n if (heightProp !== undefined && heightProp !== prevHeightPropRef.current) {\n const clamped = clamp(heightProp, minHeight, maxHeight)\n setInternalHeight(clamped)\n if (storageKey) {\n writePersistedHeight(storageKey, clamped)\n }\n }\n prevHeightPropRef.current = heightProp\n }, [heightProp, minHeight, maxHeight, storageKey])\n\n // Resolve maxHeight\n const resolveMaxHeight = useCallback((): number => {\n return maxHeight\n }, [maxHeight])\n\n const handlePointerDown = useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n e.preventDefault()\n\n const startY = e.clientY\n const startHeight = effectiveHeight\n const resolvedMaxHeight = resolveMaxHeight()\n const resizerEl = e.currentTarget\n\n const scrollParent = getScrollParent(containerRef.current)\n const startScrollTop = scrollParent ? scrollParent.scrollTop : 0\n\n let lastClientY = startY\n let animationFrameId: number | null = null\n\n const updateHeight = (clientY: number, currentScrollTop: number) => {\n const scrollDelta = currentScrollTop - startScrollTop\n const mouseDelta = clientY - startY\n const totalDelta = mouseDelta + scrollDelta\n const newHeight = clamp(startHeight + totalDelta, minHeight, resolvedMaxHeight)\n\n if (containerRef.current) {\n containerRef.current.style.height = `${newHeight}px`\n }\n return newHeight\n }\n\n const scrollLoop = () => {\n if (!scrollParent) return\n\n const parentRect =\n scrollParent === document.documentElement || scrollParent === document.body\n ? { top: 0, bottom: window.innerHeight, left: 0, right: window.innerWidth }\n : scrollParent.getBoundingClientRect()\n\n const threshold = 40\n const maxSpeed = 10\n\n let scrollDelta = 0\n if (lastClientY > parentRect.bottom - threshold) {\n const intensity = Math.min(1, (lastClientY - (parentRect.bottom - threshold)) / threshold)\n scrollDelta = intensity * maxSpeed\n } else if (lastClientY < parentRect.top + threshold) {\n const intensity = Math.min(1, (parentRect.top + threshold - lastClientY) / threshold)\n scrollDelta = -intensity * maxSpeed\n }\n\n if (scrollDelta !== 0) {\n scrollParent.scrollTop += scrollDelta\n updateHeight(lastClientY, scrollParent.scrollTop)\n }\n\n animationFrameId = requestAnimationFrame(scrollLoop)\n }\n\n // Start the auto-scroll animation loop\n animationFrameId = requestAnimationFrame(scrollLoop)\n\n createDragSession({\n cursor: 'row-resize',\n resizerEl,\n onMove: (moveEvent: PointerEvent) => {\n lastClientY = moveEvent.clientY\n if (scrollParent) {\n updateHeight(lastClientY, scrollParent.scrollTop)\n }\n },\n onEnd: () => {\n if (animationFrameId !== null) {\n cancelAnimationFrame(animationFrameId)\n }\n\n // Read the final height from the DOM\n let finalHeight = startHeight\n if (containerRef.current) {\n finalHeight = containerRef.current.getBoundingClientRect().height\n }\n finalHeight = clamp(finalHeight, minHeight, resolvedMaxHeight)\n\n // Commit to React state\n setInternalHeight(finalHeight)\n\n if (onHeightChange) {\n onHeightChange(finalHeight)\n }\n if (storageKey) {\n writePersistedHeight(storageKey, finalHeight)\n }\n },\n })\n },\n [effectiveHeight, minHeight, resolveMaxHeight, onHeightChange, storageKey],\n )\n\n if (!active) {\n return (\n <div\n className={`zeugma-resizable-container disabled ${className || ''}`.trim()}\n style={{\n height: '100%',\n position: 'relative',\n overflow: 'hidden',\n boxSizing: 'border-box',\n }}\n >\n <div style={{ height: '100%', overflow: 'hidden' }}>{children}</div>\n </div>\n )\n }\n\n return (\n <div\n ref={containerRef}\n className={`zeugma-resizable-container ${className || ''}`.trim()}\n style={{\n height: `${effectiveHeight}px`,\n position: 'relative',\n overflow: 'hidden',\n boxSizing: 'border-box',\n }}\n >\n {/* Content area fills entire container minus the resizer */}\n <div\n style={{\n height: `calc(100% - ${resizerHeight}px)`,\n overflow: 'hidden',\n }}\n >\n {children}\n </div>\n\n {/* Resizer handle */}\n <div\n className={`zeugma-resizable-handle ${resizerClassName || ''}`.trim()}\n style={{\n height: `${resizerHeight}px`,\n cursor: 'row-resize',\n position: 'relative',\n zIndex: 10,\n userSelect: 'none',\n touchAction: 'none',\n boxSizing: 'border-box',\n flexShrink: 0,\n }}\n onPointerDown={handlePointerDown}\n role=\"separator\"\n aria-orientation=\"horizontal\"\n aria-valuenow={Math.round(effectiveHeight)}\n aria-valuemin={minHeight}\n aria-valuemax={maxHeight === Infinity ? undefined : maxHeight}\n />\n </div>\n )\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value))\n}\n\nfunction getScrollParent(node: HTMLElement | null): HTMLElement | null {\n if (typeof window === 'undefined' || !node) {\n return null\n }\n\n const parent = node.parentElement\n if (!parent) {\n return document.documentElement\n }\n\n const style = window.getComputedStyle(parent)\n const overflowY = style.overflowY\n const isScrollable = overflowY === 'auto' || overflowY === 'scroll'\n\n if (isScrollable) {\n return parent\n }\n\n return getScrollParent(parent)\n}\n","import { createContext } from 'react'\n\nexport const DragListenersCtx = createContext<Record<string, unknown> | null>(null)\n","import React, { useMemo } from 'react'\nimport { useDraggable, useDroppable } from '@dnd-kit/core'\nimport { useDashboardState, useDashboardActions } from '../../dashboard'\nimport { DragListenersCtx } from '../model/context'\nimport { PaneRenderProps } from '../model/types'\nimport { findPane } from '../../../shared/lib/tree'\n\ninterface DropZoneProps {\n id: string\n position: 'top' | 'bottom' | 'left' | 'right' | 'center'\n activeClassName?: string\n}\n\nconst activationPositions: Record<string, React.CSSProperties> = {\n top: {\n position: 'absolute',\n top: 0,\n left: '25%',\n width: '50%',\n height: '25%',\n zIndex: 20,\n pointerEvents: 'auto',\n },\n bottom: {\n position: 'absolute',\n bottom: 0,\n left: '25%',\n width: '50%',\n height: '25%',\n zIndex: 20,\n pointerEvents: 'auto',\n },\n left: {\n position: 'absolute',\n top: '25%',\n left: 0,\n width: '25%',\n height: '50%',\n zIndex: 20,\n pointerEvents: 'auto',\n },\n right: {\n position: 'absolute',\n top: '25%',\n right: 0,\n width: '25%',\n height: '50%',\n zIndex: 20,\n pointerEvents: 'auto',\n },\n center: {\n position: 'absolute',\n top: '25%',\n left: '25%',\n width: '50%',\n height: '50%',\n zIndex: 20,\n pointerEvents: 'auto',\n },\n}\n\nconst previewPositions: Record<string, React.CSSProperties> = {\n top: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: '50%',\n zIndex: 21,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n bottom: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: '50%',\n zIndex: 21,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n left: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n width: '50%',\n zIndex: 21,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n right: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n right: 0,\n width: '50%',\n zIndex: 21,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n center: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 21,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n },\n}\n\nconst DropZone: React.FC<DropZoneProps> = ({ id, position, activeClassName }) => {\n const { setNodeRef, isOver } = useDroppable({ id })\n return (\n <>\n <div ref={setNodeRef} style={activationPositions[position]} />\n {isOver && <div className={activeClassName} style={previewPositions[position]} />}\n </>\n )\n}\n\ninterface PaneProps {\n id: string\n children: (props: PaneRenderProps) => React.ReactNode\n style?: React.CSSProperties\n}\n\nexport const Pane: React.FC<PaneProps> = ({ id, children, style }) => {\n const { layout, activeId, classNames, fullscreenPaneId, onRemove, onFullscreenChange } =\n useDashboardState()\n const { removePane, updatePaneMetadata } = useDashboardActions()\n const showDropZones = activeId !== null && activeId !== id\n\n const { attributes, listeners, setNodeRef, isDragging } = useDraggable({ id })\n const dragging = activeId === id || isDragging\n const isFullscreen = fullscreenPaneId === id\n\n const paneNode = useMemo(() => findPane(layout, id), [layout, id])\n const metadata = paneNode?.metadata\n\n const renderProps: PaneRenderProps = useMemo(\n () => ({\n isDragging: dragging,\n isFullscreen,\n toggleFullscreen: () => onFullscreenChange?.(isFullscreen ? null : id),\n remove: () => {\n if (isFullscreen) {\n onFullscreenChange?.(null)\n }\n if (onRemove) {\n onRemove(id)\n } else {\n removePane(id)\n }\n },\n metadata,\n updateMetadata: (updater) => {\n updatePaneMetadata(id, updater)\n },\n }),\n [\n dragging,\n isFullscreen,\n onFullscreenChange,\n id,\n onRemove,\n removePane,\n metadata,\n updatePaneMetadata,\n ],\n )\n\n // Best practice: Memoize drag context value to prevent unnecessary re-renders of the drag handle.\n const contextValue = useMemo(\n () => ({\n ...listeners,\n ...attributes,\n }),\n [listeners, attributes],\n )\n\n return (\n <DragListenersCtx.Provider value={contextValue}>\n <div\n ref={setNodeRef}\n className={classNames.pane}\n style={{ position: 'relative', width: '100%', height: '100%', ...style }}\n >\n {children(renderProps)}\n\n {showDropZones && (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 15,\n pointerEvents: 'none',\n }}\n >\n {(['top', 'bottom', 'left', 'right'] as const).map((pos) => (\n <DropZone\n key={pos}\n id={`drop-${pos}-${id}`}\n position={pos}\n activeClassName={classNames.dropPreview}\n />\n ))}\n <DropZone\n id={`drop-center-${id}`}\n position=\"center\"\n activeClassName={classNames.swapPreview}\n />\n </div>\n )}\n </div>\n </DragListenersCtx.Provider>\n )\n}\n","import React, { useContext } from 'react'\nimport { DragListenersCtx } from '../model/context'\n\ninterface DragHandleProps {\n children: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\nexport const DragHandle: React.FC<DragHandleProps> = ({ children, className, style }) => {\n const dragProps = useContext(DragListenersCtx)\n if (!dragProps) {\n throw new Error('<DragHandle> must be used inside a <Pane>')\n }\n return (\n <div\n className={className}\n style={{ cursor: 'grab', userSelect: 'none', touchAction: 'none', ...style }}\n {...dragProps}\n >\n {children}\n </div>\n )\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import React$1, { ReactNode } from 'react';
1
+ import React, { ReactNode } from 'react';
2
2
 
3
3
  type SplitDirection = 'row' | 'column';
4
4
  interface SplitNode {
@@ -23,13 +23,6 @@ interface ZeugmaClassNames {
23
23
  resizer?: string;
24
24
  dismissPreview?: string;
25
25
  }
26
- interface ResizerRenderProps {
27
- direction: SplitDirection;
28
- splitPercentage: number;
29
- resizerSize: number;
30
- isResizing: boolean;
31
- onPointerDown: (e: React.PointerEvent<HTMLDivElement>) => void;
32
- }
33
26
  /**
34
27
  * State context — holds reactive values that change during runtime.
35
28
  * All consumers of this context will re-render when any of these values change.
@@ -49,7 +42,6 @@ interface DashboardStateValue {
49
42
  onResizeStart?: (currentNode: SplitNode) => void;
50
43
  onResize?: (currentNode: SplitNode, percentage: number) => void;
51
44
  onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
52
- renderResizer?: (props: ResizerRenderProps) => ReactNode;
53
45
  minSplitPercentage?: number;
54
46
  maxSplitPercentage?: number;
55
47
  }
@@ -91,7 +83,6 @@ interface DashboardProviderProps {
91
83
  onResizeStart?: (currentNode: SplitNode) => void;
92
84
  onResize?: (currentNode: SplitNode, percentage: number) => void;
93
85
  onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
94
- renderResizer?: (props: ResizerRenderProps) => ReactNode;
95
86
  minSplitPercentage?: number;
96
87
  maxSplitPercentage?: number;
97
88
  enableDragToDismiss?: boolean;
@@ -99,10 +90,10 @@ interface DashboardProviderProps {
99
90
  onDismissIntentChange?: (paneId: string | null) => void;
100
91
  children: ReactNode;
101
92
  }
102
- declare const DashboardProvider: React$1.FC<DashboardProviderProps>;
93
+ declare const DashboardProvider: React.FC<DashboardProviderProps>;
103
94
 
104
95
  interface UseResizerProps {
105
- containerRef: React$1.RefObject<HTMLDivElement | null>;
96
+ containerRef: React.RefObject<HTMLDivElement | null>;
106
97
  isRow: boolean;
107
98
  direction: SplitDirection;
108
99
  splitPercentage: number;
@@ -114,7 +105,7 @@ interface UseResizerProps {
114
105
  onResizeStart?: () => void;
115
106
  onResizeEnd?: () => void;
116
107
  }
117
- declare function useResizer({ containerRef, isRow, direction, splitPercentage, resizerSize, snapThreshold, layout, currentNode, onLayoutChange, onResizeStart: localOnResizeStart, onResizeEnd: localOnResizeEnd, }: UseResizerProps): (e: React$1.PointerEvent<HTMLDivElement>) => void;
108
+ declare function useResizer({ containerRef, isRow, direction, splitPercentage, resizerSize, snapThreshold, layout, currentNode, onLayoutChange, onResizeStart: localOnResizeStart, onResizeEnd: localOnResizeEnd, }: UseResizerProps): (e: React.PointerEvent<HTMLDivElement>) => void;
118
109
 
119
110
  interface PaneTreeProps {
120
111
  tree?: TreeNode | null;
@@ -122,10 +113,33 @@ interface PaneTreeProps {
122
113
  resizerSize?: number;
123
114
  /** Threshold in pixels to snap to adjacent resizer edges (default 8) */
124
115
  snapThreshold?: number;
125
- /** Custom resizer renderer to override context-level renderResizer */
126
- renderResizer?: (props: ResizerRenderProps) => React$1.ReactNode;
127
116
  }
128
- declare const PaneTree: React$1.FC<PaneTreeProps>;
117
+ declare const PaneTree: React.FC<PaneTreeProps>;
118
+
119
+ interface ResizableContainerProps {
120
+ children: React.ReactNode;
121
+ /** Whether the resizable container is active. When false, acts as a normal 100% height container. */
122
+ active?: boolean;
123
+ /** Current height in pixels (controlled mode) or default/initial height */
124
+ height?: number;
125
+ /** Called when the height changes during or after a drag */
126
+ onHeightChange?: (height: number) => void;
127
+ /** Minimum height in pixels (default: 100) */
128
+ minHeight?: number;
129
+ /** Maximum height in pixels (default: Infinity — bounded by parent) */
130
+ maxHeight?: number;
131
+ /** Whether to persist height in localStorage */
132
+ persist?: boolean;
133
+ /** Custom localStorage key to save the height under (default: 'default-pane') */
134
+ localStorageKey?: string;
135
+ /** Height of the resizer handle in pixels (default: 6) */
136
+ resizerHeight?: number;
137
+ /** CSS class applied to the outer container div */
138
+ className?: string;
139
+ /** CSS class applied to the resizer handle */
140
+ resizerClassName?: string;
141
+ }
142
+ declare const ResizableContainer: React.FC<ResizableContainerProps>;
129
143
 
130
144
  interface PaneRenderProps {
131
145
  isDragging: boolean;
@@ -138,17 +152,17 @@ interface PaneRenderProps {
138
152
 
139
153
  interface PaneProps {
140
154
  id: string;
141
- children: (props: PaneRenderProps) => React$1.ReactNode;
142
- style?: React$1.CSSProperties;
155
+ children: (props: PaneRenderProps) => React.ReactNode;
156
+ style?: React.CSSProperties;
143
157
  }
144
- declare const Pane: React$1.FC<PaneProps>;
158
+ declare const Pane: React.FC<PaneProps>;
145
159
 
146
160
  interface DragHandleProps {
147
- children: React$1.ReactNode;
161
+ children: React.ReactNode;
148
162
  className?: string;
149
- style?: React$1.CSSProperties;
163
+ style?: React.CSSProperties;
150
164
  }
151
- declare const DragHandle: React$1.FC<DragHandleProps>;
165
+ declare const DragHandle: React.FC<DragHandleProps>;
152
166
 
153
167
  declare const DEFAULT_SNAP_THRESHOLD = 8;
154
168
  declare const DEFAULT_DRAG_ACTIVATION_DISTANCE = 8;
@@ -187,4 +201,29 @@ declare function findPane(tree: TreeNode | null, paneId: string): PaneNode | nul
187
201
  */
188
202
  declare function updatePaneMetadata(tree: TreeNode | null, paneId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined): TreeNode | null;
189
203
 
190
- export { DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_RESIZER_SIZE, DEFAULT_SNAP_THRESHOLD, type DashboardActionsValue, DashboardProvider, type DashboardStateValue, DragHandle, Pane, type PaneNode, type PaneRenderProps, PaneTree, type ResizerRenderProps, type SplitDirection, type SplitNode, type TreeNode, type ZeugmaClassNames, addPane, findPane, removePane, splitPane, splitRoot, swapPanes, updatePaneMetadata, updateSplitPercentage, useDashboardActions, useDashboardState, useResizer };
204
+ /**
205
+ * Shared drag-session lifecycle utility.
206
+ *
207
+ * Handles the common boilerplate for pointer-based resize operations:
208
+ * - Adds `zeugma-resizing` class to `document.body`
209
+ * - Injects a global `cursor` style so the resize cursor stays active
210
+ * even when the pointer leaves the handle element
211
+ * - Sets `data-resizing` on the resizer element
212
+ * - Attaches `pointermove` / `pointerup` listeners to `document`
213
+ * - Cleans everything up on pointer-up
214
+ *
215
+ * Consumers provide domain-specific `onMove` and `onEnd` callbacks.
216
+ */
217
+ interface DragSessionConfig {
218
+ /** CSS cursor to enforce globally during the drag */
219
+ cursor: 'col-resize' | 'row-resize';
220
+ /** The resizer DOM element (receives `data-resizing` attribute) */
221
+ resizerEl: HTMLElement;
222
+ /** Called on every `pointermove` during the drag */
223
+ onMove: (e: PointerEvent) => void;
224
+ /** Called once on `pointerup` — after cleanup has already run */
225
+ onEnd: () => void;
226
+ }
227
+ declare function createDragSession({ cursor, resizerEl, onMove, onEnd }: DragSessionConfig): void;
228
+
229
+ export { DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_RESIZER_SIZE, DEFAULT_SNAP_THRESHOLD, type DashboardActionsValue, DashboardProvider, type DashboardStateValue, DragHandle, type DragSessionConfig, Pane, type PaneNode, type PaneRenderProps, PaneTree, ResizableContainer, type ResizableContainerProps, type SplitDirection, type SplitNode, type TreeNode, type ZeugmaClassNames, addPane, createDragSession, findPane, removePane, splitPane, splitRoot, swapPanes, updatePaneMetadata, updateSplitPercentage, useDashboardActions, useDashboardState, useResizer };