react-complex-tree
Advanced tools
Comparing version 1.1.4 to 1.1.5
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
@@ -37,3 +26,2 @@ if (k2 === undefined) k2 = k; | ||
var ControlledTreeEnvironment_1 = require("./ControlledTreeEnvironment"); | ||
var getItemsLinearly_1 = require("../tree/getItemsLinearly"); | ||
var useOnDragOverTreeHandler_1 = require("./useOnDragOverTreeHandler"); | ||
@@ -43,12 +31,7 @@ var useCanDropAt_1 = require("./useCanDropAt"); | ||
var useSideEffect_1 = require("../useSideEffect"); | ||
var utils_1 = require("../utils"); | ||
var useCallSoon_1 = require("../useCallSoon"); | ||
var DragAndDropContext = React.createContext(null); | ||
var useDragAndDrop = function () { return React.useContext(DragAndDropContext); }; | ||
exports.useDragAndDrop = useDragAndDrop; | ||
var buildMapForTrees = function (treeIds, build) { | ||
return treeIds.map(function (id) { return [id, build(id)]; }).reduce(function (a, _a) { | ||
var _b; | ||
var id = _a[0], obj = _a[1]; | ||
return (__assign(__assign({}, a), (_b = {}, _b[id] = obj, _b))); | ||
}, {}); | ||
}; | ||
// TODO tidy up | ||
@@ -59,17 +42,18 @@ var DragAndDropProvider = function (props) { | ||
var _b = react_1.useState(4), itemHeight = _b[0], setItemHeight = _b[1]; | ||
var _c = react_1.useState({}), linearItems = _c[0], setLinearItems = _c[1]; | ||
var _d = react_1.useState({}), viableDragPositions = _d[0], setViableDragPositions = _d[1]; | ||
var _e = react_1.useState(0), programmaticDragIndex = _e[0], setProgrammaticDragIndex = _e[1]; | ||
var _f = react_1.useState(), draggingItems = _f[0], setDraggingItems = _f[1]; | ||
var _g = react_1.useState(), draggingPosition = _g[0], setDraggingPosition = _g[1]; | ||
var _h = react_1.useState('_nodrag'), dragCode = _h[0], setDragCode = _h[1]; | ||
var _c = react_1.useState({}), viableDragPositions = _c[0], setViableDragPositions = _c[1]; | ||
var _d = react_1.useState(0), programmaticDragIndex = _d[0], setProgrammaticDragIndex = _d[1]; | ||
var _e = react_1.useState(), draggingItems = _e[0], setDraggingItems = _e[1]; | ||
var _f = react_1.useState(), draggingPosition = _f[0], setDraggingPosition = _f[1]; | ||
var _g = react_1.useState('_nodrag'), dragCode = _g[0], setDragCode = _g[1]; | ||
var getViableDragPositions = useGetViableDragPositions_1.useGetViableDragPositions(); | ||
var resetProgrammaticDragIndexForCurrentTree = react_1.useCallback(function (viableDragPositions, linearItems, draggingItems) { | ||
var callSoon = useCallSoon_1.useCallSoon(); | ||
var shouldCancelDrag = react_1.useRef(false); | ||
var resetProgrammaticDragIndexForCurrentTree = react_1.useCallback(function (viableDragPositions, draggingItems) { | ||
var _a; | ||
if (environment.activeTreeId && | ||
((_a = environment.viewState[environment.activeTreeId]) === null || _a === void 0 ? void 0 : _a.focusedItem) && | ||
linearItems && | ||
environment.linearItems && | ||
draggingItems) { | ||
var focusItem_1 = environment.viewState[environment.activeTreeId].focusedItem; | ||
var treeDragPositions = getViableDragPositions(environment.activeTreeId, draggingItems, linearItems); | ||
var treeDragPositions = getViableDragPositions(environment.activeTreeId, draggingItems); | ||
var newPos = treeDragPositions.findIndex(function (pos) { | ||
@@ -93,7 +77,12 @@ if (pos.targetType === 'item') { | ||
} | ||
}, [environment.activeTreeId, environment.items, environment.viewState, getViableDragPositions]); | ||
}, [ | ||
environment.activeTreeId, | ||
environment.items, | ||
environment.linearItems, | ||
environment.viewState, | ||
getViableDragPositions, | ||
]); | ||
var resetState = react_1.useCallback(function () { | ||
setIsProgrammaticallyDragging(false); | ||
setItemHeight(4); | ||
setLinearItems({}); | ||
setViableDragPositions({}); | ||
@@ -107,5 +96,5 @@ setProgrammaticDragIndex(0); | ||
if (environment.activeTreeId && | ||
linearItems[environment.activeTreeId] && | ||
environment.linearItems[environment.activeTreeId] && | ||
viableDragPositions[environment.activeTreeId]) { | ||
resetProgrammaticDragIndexForCurrentTree(viableDragPositions[environment.activeTreeId], linearItems[environment.activeTreeId], draggingItems); | ||
resetProgrammaticDragIndexForCurrentTree(viableDragPositions[environment.activeTreeId], draggingItems); | ||
} | ||
@@ -115,3 +104,3 @@ }, [ | ||
environment.activeTreeId, | ||
linearItems, | ||
environment.linearItems, | ||
resetProgrammaticDragIndexForCurrentTree, | ||
@@ -138,7 +127,7 @@ viableDragPositions, | ||
}; | ||
var onDragOverTreeHandler = useOnDragOverTreeHandler_1.useOnDragOverTreeHandler(dragCode, setDragCode, itemHeight, linearItems, setDraggingPosition, performDrag); | ||
var onDropHandler = react_1.useMemo(function () { return function () { | ||
var onDragOverTreeHandler = useOnDragOverTreeHandler_1.useOnDragOverTreeHandler(dragCode, setDragCode, itemHeight, setDraggingPosition, performDrag); | ||
var onDropHandler = react_1.useCallback(function () { | ||
if (draggingItems && draggingPosition && environment.onDrop) { | ||
environment.onDrop(draggingItems, draggingPosition); | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
var _a; | ||
@@ -149,8 +138,7 @@ (_a = environment.onFocusItem) === null || _a === void 0 ? void 0 : _a.call(environment, draggingItems[0], draggingPosition.treeId); | ||
} | ||
}; }, [draggingItems, draggingPosition, environment, resetState]); | ||
}, [draggingItems, draggingPosition, environment, resetState, callSoon]); | ||
var onStartDraggingItems = react_1.useCallback(function (items, treeId) { | ||
var _a, _b; | ||
var treeLinearItems = buildMapForTrees(environment.treeIds, function (treeId) { var _a; return getItemsLinearly_1.getItemsLinearly(environment.trees[treeId].rootItem, (_a = environment.viewState[treeId]) !== null && _a !== void 0 ? _a : {}, environment.items); }); | ||
var treeViableDragPositions = buildMapForTrees(environment.treeIds, function (treeId) { | ||
return getViableDragPositions(treeId, items, treeLinearItems[treeId]); | ||
var treeViableDragPositions = utils_1.buildMapForTrees(environment.treeIds, function (treeId) { | ||
return getViableDragPositions(treeId, items); | ||
}); | ||
@@ -161,16 +149,7 @@ // TODO what if trees have different heights and drag target changes? | ||
setDraggingItems(items); | ||
setLinearItems(treeLinearItems); | ||
setViableDragPositions(treeViableDragPositions); | ||
if (environment.activeTreeId) { | ||
resetProgrammaticDragIndexForCurrentTree(treeViableDragPositions[environment.activeTreeId], treeLinearItems[environment.activeTreeId], items); | ||
resetProgrammaticDragIndexForCurrentTree(treeViableDragPositions[environment.activeTreeId], items); | ||
} | ||
}, [ | ||
environment.activeTreeId, | ||
environment.items, | ||
environment.treeIds, | ||
environment.trees, | ||
environment.viewState, | ||
getViableDragPositions, | ||
resetProgrammaticDragIndexForCurrentTree, | ||
]); | ||
}, [environment.activeTreeId, environment.treeIds, getViableDragPositions, resetProgrammaticDragIndexForCurrentTree]); | ||
var startProgrammaticDrag = react_1.useCallback(function () { | ||
@@ -229,7 +208,11 @@ var _a, _b, _c; | ||
react_1.useEffect(function () { | ||
window.addEventListener('dragend', onDropHandler); | ||
return function () { return window.removeEventListener('dragend', onDropHandler); }; | ||
}, [onDropHandler]); | ||
window.addEventListener('dragend', resetState); | ||
window.addEventListener('drop', onDropHandler); | ||
return function () { | ||
window.removeEventListener('dragend', resetState); | ||
window.removeEventListener('drop', onDropHandler); | ||
}; | ||
}, [onDropHandler, resetState]); | ||
return React.createElement(DragAndDropContext.Provider, { value: dnd }, props.children); | ||
}; | ||
exports.DragAndDropProvider = DragAndDropProvider; |
@@ -5,5 +5,6 @@ "use strict"; | ||
var ControlledTreeEnvironment_1 = require("./ControlledTreeEnvironment"); | ||
var react_1 = require("react"); | ||
var useCanDropAt = function () { | ||
var environment = ControlledTreeEnvironment_1.useTreeEnvironment(); | ||
return function (draggingPosition, draggingItems) { | ||
return react_1.useCallback(function (draggingPosition, draggingItems) { | ||
if (draggingPosition.targetType === 'between-items') { | ||
@@ -26,4 +27,4 @@ if (!environment.canReorderItems) { | ||
return true; | ||
}; | ||
}, [environment]); | ||
}; | ||
exports.useCanDropAt = useCanDropAt; |
@@ -17,17 +17,29 @@ "use strict"; | ||
var react_1 = require("react"); | ||
var useMemoizedObject_1 = require("../useMemoizedObject"); | ||
var useRenderers_1 = require("../renderers/useRenderers"); | ||
var utils_1 = require("../utils"); | ||
var getItemsLinearly_1 = require("../tree/getItemsLinearly"); | ||
var useRefCopy_1 = require("../useRefCopy"); | ||
var useUpdateLinearItems_1 = require("./useUpdateLinearItems"); | ||
var useControlledTreeEnvironmentProps = function (props) { | ||
var _a = react_1.useState({}), trees = _a[0], setTrees = _a[1]; | ||
var _b = react_1.useState(), activeTreeId = _b[0], setActiveTreeId = _b[1]; | ||
var memoizedProps = useMemoizedObject_1.useMemoizedObject(props); | ||
var onFocusItem = memoizedProps.onFocusItem, autoFocus = memoizedProps.autoFocus, onRegisterTree = memoizedProps.onRegisterTree, onUnregisterTree = memoizedProps.onUnregisterTree; | ||
var _b = react_1.useState({}), linearItems = _b[0], setLinearItems = _b[1]; | ||
var _c = react_1.useState(), activeTreeId = _c[0], setActiveTreeId = _c[1]; | ||
var viewStateRef = useRefCopy_1.useRefCopy(props.viewState); | ||
var treeIds = react_1.useMemo(function () { return Object.keys(trees); }, [trees]); | ||
var onFocusItem = props.onFocusItem, autoFocus = props.autoFocus, onRegisterTree = props.onRegisterTree, onUnregisterTree = props.onUnregisterTree, items = props.items; | ||
var onFocusItemRef = useRefCopy_1.useRefCopy(onFocusItem); | ||
var newChangeHandlers = useUpdateLinearItems_1.useUpdateLinearItems(react_1.useCallback(function () { | ||
setLinearItems(utils_1.buildMapForTrees(treeIds, function (treeId) { var _a; return getItemsLinearly_1.getItemsLinearly(trees[treeId].rootItem, (_a = viewStateRef.current[treeId]) !== null && _a !== void 0 ? _a : {}, items); })); | ||
}, [items, treeIds, trees, viewStateRef]), props, items); | ||
var onFocusItemHandler = react_1.useCallback(function (item, treeId) { | ||
var _a, _b, _c, _d; | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(item, treeId); | ||
var _a, _b, _c, _d, _e, _f; | ||
if (((_a = viewStateRef.current[treeId]) === null || _a === void 0 ? void 0 : _a.focusedItem) === item.index) { | ||
return; | ||
} | ||
(_b = onFocusItemRef.current) === null || _b === void 0 ? void 0 : _b.call(onFocusItemRef, item, treeId); | ||
var newItem = document.querySelector("[data-rct-tree=\"" + treeId + "\"] [data-rct-item-id=\"" + item.index + "\"]"); | ||
if (autoFocus !== null && autoFocus !== void 0 ? autoFocus : true) { | ||
if (((_b = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.attributes.getNamedItem('data-rct-search-input')) === null || _b === void 0 ? void 0 : _b.value) !== 'true') { | ||
if (((_d = (_c = document.activeElement) === null || _c === void 0 ? void 0 : _c.attributes.getNamedItem('data-rct-search-input')) === null || _d === void 0 ? void 0 : _d.value) !== 'true') { | ||
// Move DOM focus to item if the current focus is not on the search input | ||
(_d = (_c = newItem) === null || _c === void 0 ? void 0 : _c.focus) === null || _d === void 0 ? void 0 : _d.call(_c); | ||
(_f = (_e = newItem) === null || _e === void 0 ? void 0 : _e.focus) === null || _f === void 0 ? void 0 : _f.call(_e); | ||
} | ||
@@ -39,3 +51,3 @@ else { | ||
} | ||
}, [autoFocus, onFocusItem]); | ||
}, [autoFocus, onFocusItemRef, viewStateRef]); | ||
var registerTree = react_1.useCallback(function (tree) { | ||
@@ -80,5 +92,4 @@ setTrees(function (trees) { | ||
}, [autoFocus]); | ||
var treeIds = react_1.useMemo(function () { return Object.keys(trees); }, [trees]); | ||
var renderers = useRenderers_1.useRenderers(memoizedProps); | ||
return __assign(__assign(__assign({}, renderers), memoizedProps), { onFocusItem: onFocusItemHandler, registerTree: registerTree, | ||
var renderers = useRenderers_1.useRenderers(props); | ||
return __assign(__assign(__assign(__assign({}, renderers), props), newChangeHandlers), { onFocusItem: onFocusItemHandler, registerTree: registerTree, | ||
unregisterTree: unregisterTree, | ||
@@ -88,4 +99,5 @@ setActiveTree: setActiveTree, | ||
trees: trees, | ||
activeTreeId: activeTreeId }); | ||
activeTreeId: activeTreeId, | ||
linearItems: linearItems }); | ||
}; | ||
exports.useControlledTreeEnvironmentProps = useControlledTreeEnvironmentProps; |
@@ -1,5 +0,1 @@ | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
export declare const useGetGetParentOfLinearItem: () => (linearItems: ReturnType<typeof getItemsLinearly>, itemLinearIndex: number, treeId: string) => { | ||
item: import("..").TreeItemIndex; | ||
depth: number; | ||
}; | ||
export declare const useGetGetParentOfLinearItem: () => (itemLinearIndex: number, treeId: string) => import("..").LinearItem; |
@@ -5,5 +5,7 @@ "use strict"; | ||
var ControlledTreeEnvironment_1 = require("./ControlledTreeEnvironment"); | ||
var react_1 = require("react"); | ||
var useGetGetParentOfLinearItem = function () { | ||
var environment = ControlledTreeEnvironment_1.useTreeEnvironment(); | ||
return function (linearItems, itemLinearIndex, treeId) { | ||
return react_1.useCallback(function (itemLinearIndex, treeId) { | ||
var linearItems = environment.linearItems[treeId]; | ||
var depth = linearItems[itemLinearIndex].depth; | ||
@@ -19,4 +21,4 @@ var parentLinearIndex = itemLinearIndex; | ||
return parent; | ||
}; | ||
}, [environment.linearItems, environment.trees]); | ||
}; | ||
exports.useGetGetParentOfLinearItem = useGetGetParentOfLinearItem; |
import { DraggingPosition, TreeItem } from '../types'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
export declare const useGetViableDragPositions: () => (treeId: string, draggingItems: TreeItem[], linearItems: ReturnType<typeof getItemsLinearly>) => DraggingPosition[]; | ||
export declare const useGetViableDragPositions: () => (treeId: string, draggingItems: TreeItem[]) => DraggingPosition[]; |
@@ -12,2 +12,3 @@ "use strict"; | ||
var useCanDropAt_1 = require("./useCanDropAt"); | ||
var react_1 = require("react"); | ||
var useGetViableDragPositions = function () { | ||
@@ -17,3 +18,4 @@ var environment = ControlledTreeEnvironment_1.useTreeEnvironment(); | ||
var canDropAt = useCanDropAt_1.useCanDropAt(); | ||
return function (treeId, draggingItems, linearItems) { | ||
return react_1.useCallback(function (treeId, draggingItems) { | ||
var linearItems = environment.linearItems[treeId]; | ||
return linearItems | ||
@@ -23,3 +25,3 @@ .map(function (_a, linearIndex) { | ||
var item = _a.item, depth = _a.depth; | ||
var parent = getParentOfLinearItem(linearItems, linearIndex, treeId); | ||
var parent = getParentOfLinearItem(linearIndex, treeId); | ||
var childIndex = environment.items[parent.item].children.indexOf(item); | ||
@@ -62,4 +64,4 @@ var itemPosition = { | ||
.filter(function (position) { return canDropAt(position, draggingItems); }); | ||
}; | ||
}, [canDropAt, environment.items, environment.linearItems, getParentOfLinearItem]); | ||
}; | ||
exports.useGetViableDragPositions = useGetViableDragPositions; |
import * as React from 'react'; | ||
import { DraggingPosition } from '../types'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
export declare const useOnDragOverTreeHandler: (lastDragCode: string, setLastDragCode: (code: string) => void, itemHeight: number, linearItems: { | ||
[treeId: string]: { | ||
item: import("../types").TreeItemIndex; | ||
depth: number; | ||
}[]; | ||
}, onDragAtPosition: (draggingPosition: DraggingPosition | undefined) => void, onPerformDrag: (draggingPosition: DraggingPosition) => void) => (e: DragEvent, treeId: string, containerRef: React.MutableRefObject<HTMLElement | undefined>) => void; | ||
export declare const useOnDragOverTreeHandler: (lastDragCode: string, setLastDragCode: (code: string) => void, itemHeight: number, onDragAtPosition: (draggingPosition: DraggingPosition | undefined) => void, onPerformDrag: (draggingPosition: DraggingPosition) => void) => (e: DragEvent, treeId: string, containerRef: React.MutableRefObject<HTMLElement | undefined>) => void; |
@@ -6,10 +6,11 @@ "use strict"; | ||
var useGetParentOfLinearItem_1 = require("./useGetParentOfLinearItem"); | ||
var react_1 = require("react"); | ||
var isOutsideOfContainer = function (e, treeBb) { | ||
return e.clientX < treeBb.left || e.clientX > treeBb.right || e.clientY < treeBb.top || e.clientY > treeBb.bottom; | ||
}; | ||
var getHoveringPosition = function (clientY, treeTop, itemHeight, capabilities) { | ||
var getHoveringPosition = function (clientY, treeTop, itemHeight, canDropOnItemWithChildren, canDropOnItemWithoutChildren) { | ||
var hoveringPosition = (clientY - treeTop) / itemHeight; | ||
var linearIndex = Math.floor(hoveringPosition); | ||
var offset = undefined; | ||
var lineThreshold = capabilities.canDropOnItemWithChildren || capabilities.canDropOnItemWithoutChildren ? 0.2 : 0.5; | ||
var lineThreshold = canDropOnItemWithChildren || canDropOnItemWithoutChildren ? 0.2 : 0.5; | ||
if (hoveringPosition % 1 < lineThreshold) { | ||
@@ -23,8 +24,8 @@ offset = 'top'; | ||
}; | ||
var useOnDragOverTreeHandler = function (lastDragCode, setLastDragCode, itemHeight, linearItems, onDragAtPosition, onPerformDrag) { | ||
var environment = ControlledTreeEnvironment_1.useTreeEnvironment(); | ||
var useOnDragOverTreeHandler = function (lastDragCode, setLastDragCode, itemHeight, onDragAtPosition, onPerformDrag) { | ||
var _a = ControlledTreeEnvironment_1.useTreeEnvironment(), canDropOnItemWithChildren = _a.canDropOnItemWithChildren, canDropOnItemWithoutChildren = _a.canDropOnItemWithoutChildren, canDragAndDrop = _a.canDragAndDrop, linearItems = _a.linearItems, items = _a.items, canReorderItems = _a.canReorderItems, viewState = _a.viewState; | ||
var getParentOfLinearItem = useGetParentOfLinearItem_1.useGetGetParentOfLinearItem(); | ||
return function (e, treeId, containerRef) { | ||
return react_1.useCallback(function (e, treeId, containerRef) { | ||
var _a, _b, _c, _d; | ||
if (!environment.canDragAndDrop) { | ||
if (!canDragAndDrop) { | ||
return; | ||
@@ -40,3 +41,3 @@ } | ||
var outsideContainer = isOutsideOfContainer(e, treeBb); | ||
var _e = getHoveringPosition(e.clientY, treeBb.top, itemHeight, environment), linearIndex = _e.linearIndex, offset = _e.offset; | ||
var _e = getHoveringPosition(e.clientY, treeBb.top, itemHeight, canDropOnItemWithChildren, canDropOnItemWithoutChildren), linearIndex = _e.linearIndex, offset = _e.offset; | ||
var nextDragCode = outsideContainer ? 'outside' : "" + treeId + linearIndex + (offset !== null && offset !== void 0 ? offset : ''); | ||
@@ -57,20 +58,20 @@ if (lastDragCode === nextDragCode) { | ||
var depth = targetItem.depth; | ||
var targetItemData = environment.items[targetItem.item]; | ||
if (!offset && !environment.canDropOnItemWithoutChildren && !targetItemData.hasChildren) { | ||
var targetItemData = items[targetItem.item]; | ||
if (!offset && !canDropOnItemWithoutChildren && !targetItemData.hasChildren) { | ||
onDragAtPosition(undefined); | ||
return; | ||
} | ||
if (!offset && !environment.canDropOnItemWithChildren && targetItemData.hasChildren) { | ||
if (!offset && !canDropOnItemWithChildren && targetItemData.hasChildren) { | ||
onDragAtPosition(undefined); | ||
return; | ||
} | ||
if (offset && !environment.canReorderItems) { | ||
if (offset && !canReorderItems) { | ||
onDragAtPosition(undefined); | ||
return; | ||
} | ||
var parent = getParentOfLinearItem(linearItems[treeId], linearIndex, treeId); | ||
if ((_b = (_a = environment.viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(targetItem.item)) { | ||
var parent = getParentOfLinearItem(linearIndex, treeId); | ||
if ((_b = (_a = viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(targetItem.item)) { | ||
return; | ||
} | ||
var newChildIndex = environment.items[parent.item].children.indexOf(targetItem.item) + (offset === 'top' ? 0 : 1); | ||
var newChildIndex = items[parent.item].children.indexOf(targetItem.item) + (offset === 'top' ? 0 : 1); | ||
if (offset === 'top' && depth === ((_d = (_c = linearItems[treeId][linearIndex - 1]) === null || _c === void 0 ? void 0 : _c.depth) !== null && _d !== void 0 ? _d : -1)) { | ||
@@ -105,4 +106,18 @@ offset = 'bottom'; | ||
onPerformDrag(draggingPosition); | ||
}; | ||
}, [ | ||
canDragAndDrop, | ||
canDropOnItemWithChildren, | ||
canDropOnItemWithoutChildren, | ||
canReorderItems, | ||
getParentOfLinearItem, | ||
itemHeight, | ||
items, | ||
lastDragCode, | ||
linearItems, | ||
onDragAtPosition, | ||
onPerformDrag, | ||
setLastDragCode, | ||
viewState, | ||
]); | ||
}; | ||
exports.useOnDragOverTreeHandler = useOnDragOverTreeHandler; |
@@ -29,5 +29,5 @@ "use strict"; | ||
var React = __importStar(require("react")); | ||
var react_1 = require("react"); | ||
var DragAndDropProvider_1 = require("../controlledEnvironment/DragAndDropProvider"); | ||
var ControlledTreeEnvironment_1 = require("../controlledEnvironment/ControlledTreeEnvironment"); | ||
var getItemsLinearly_1 = require("../tree/getItemsLinearly"); | ||
var useCreatedEnvironmentRef_1 = require("./useCreatedEnvironmentRef"); | ||
@@ -38,93 +38,83 @@ var EnvironmentActionsContext = React.createContext(null); | ||
exports.EnvironmentActionsProvider = React.forwardRef(function (props, ref) { | ||
var environment = ControlledTreeEnvironment_1.useTreeEnvironment(); | ||
var dnd = DragAndDropProvider_1.useDragAndDrop(); | ||
var _a = ControlledTreeEnvironment_1.useTreeEnvironment(), onCollapseItem = _a.onCollapseItem, items = _a.items, trees = _a.trees, viewState = _a.viewState, onExpandItem = _a.onExpandItem, onFocusItem = _a.onFocusItem, setActiveTree = _a.setActiveTree, onRenameItem = _a.onRenameItem, onSelectItems = _a.onSelectItems, onPrimaryAction = _a.onPrimaryAction, linearItems = _a.linearItems; | ||
var _b = DragAndDropProvider_1.useDragAndDrop(), abortProgrammaticDrag = _b.abortProgrammaticDrag, completeProgrammaticDrag = _b.completeProgrammaticDrag, programmaticDragDown = _b.programmaticDragDown, programmaticDragUp = _b.programmaticDragUp, startProgrammaticDrag = _b.startProgrammaticDrag; | ||
// TODO change environment childs to use actions rather than output events where possible | ||
var actions = { | ||
abortProgrammaticDrag: function () { | ||
dnd.abortProgrammaticDrag(); | ||
}, | ||
collapseItem: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onCollapseItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
completeProgrammaticDrag: function () { | ||
dnd.completeProgrammaticDrag(); | ||
}, | ||
expandItem: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onExpandItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
focusItem: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onFocusItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
focusTree: function (treeId, autoFocus) { | ||
abortProgrammaticDrag: react_1.useCallback(function () { | ||
abortProgrammaticDrag(); | ||
}, [abortProgrammaticDrag]), | ||
collapseItem: react_1.useCallback(function (itemId, treeId) { | ||
onCollapseItem === null || onCollapseItem === void 0 ? void 0 : onCollapseItem(items[itemId], treeId); | ||
}, [items, onCollapseItem]), | ||
completeProgrammaticDrag: react_1.useCallback(function () { | ||
completeProgrammaticDrag(); | ||
}, [completeProgrammaticDrag]), | ||
expandItem: react_1.useCallback(function (itemId, treeId) { | ||
onExpandItem === null || onExpandItem === void 0 ? void 0 : onExpandItem(items[itemId], treeId); | ||
}, [items, onExpandItem]), | ||
focusItem: react_1.useCallback(function (itemId, treeId) { | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(items[itemId], treeId); | ||
}, [items, onFocusItem]), | ||
focusTree: react_1.useCallback(function (treeId, autoFocus) { | ||
if (autoFocus === void 0) { autoFocus = true; } | ||
environment.setActiveTree(treeId, autoFocus); | ||
}, | ||
moveFocusDown: function (treeId) { | ||
var _a, _b; | ||
var tree = environment.trees[treeId]; | ||
var linearItems = getItemsLinearly_1.getItemsLinearly(tree.rootItem, (_a = environment.viewState[treeId]) !== null && _a !== void 0 ? _a : {}, environment.items); | ||
var currentFocusIndex = linearItems.findIndex(function (_a) { | ||
setActiveTree(treeId, autoFocus); | ||
}, [setActiveTree]), | ||
moveFocusDown: react_1.useCallback(function (treeId) { | ||
var treeLinearItems = linearItems[treeId]; | ||
var currentFocusIndex = treeLinearItems.findIndex(function (_a) { | ||
var _b; | ||
var item = _a.item; | ||
return item === ((_b = environment.viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
return item === ((_b = viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
}); | ||
var newIndex = currentFocusIndex !== undefined ? Math.min(linearItems.length - 1, currentFocusIndex + 1) : 0; | ||
var newItem = environment.items[linearItems[newIndex].item]; | ||
(_b = environment.onFocusItem) === null || _b === void 0 ? void 0 : _b.call(environment, newItem, treeId); | ||
}, | ||
moveFocusUp: function (treeId) { | ||
var _a, _b; | ||
var tree = environment.trees[treeId]; | ||
var linearItems = getItemsLinearly_1.getItemsLinearly(tree.rootItem, (_a = environment.viewState[treeId]) !== null && _a !== void 0 ? _a : {}, environment.items); | ||
var currentFocusIndex = linearItems.findIndex(function (_a) { | ||
var newIndex = currentFocusIndex !== undefined ? Math.min(treeLinearItems.length - 1, currentFocusIndex + 1) : 0; | ||
var newItem = items[treeLinearItems[newIndex].item]; | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(newItem, treeId); | ||
}, [items, linearItems, onFocusItem, viewState]), | ||
moveFocusUp: react_1.useCallback(function (treeId) { | ||
var treeLinearItems = linearItems[treeId]; | ||
var currentFocusIndex = treeLinearItems.findIndex(function (_a) { | ||
var _b; | ||
var item = _a.item; | ||
return item === ((_b = environment.viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
return item === ((_b = viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
}); | ||
var newIndex = currentFocusIndex !== undefined ? Math.max(0, currentFocusIndex - 1) : 0; | ||
var newItem = environment.items[linearItems[newIndex].item]; | ||
(_b = environment.onFocusItem) === null || _b === void 0 ? void 0 : _b.call(environment, newItem, treeId); | ||
}, | ||
moveProgrammaticDragPositionDown: function () { | ||
dnd.programmaticDragDown(); | ||
}, | ||
moveProgrammaticDragPositionUp: function () { | ||
dnd.programmaticDragUp(); | ||
}, | ||
renameItem: function (itemId, name, treeId) { | ||
var _a; | ||
(_a = environment.onRenameItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], name, treeId); | ||
}, | ||
selectItems: function (itemsIds, treeId) { | ||
var _a; | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, itemsIds, treeId); | ||
}, | ||
startProgrammaticDrag: function () { | ||
dnd.startProgrammaticDrag(); | ||
}, | ||
toggleItemExpandedState: function (itemId, treeId) { | ||
var _a, _b, _c, _d; | ||
if ((_b = (_a = environment.viewState[treeId]) === null || _a === void 0 ? void 0 : _a.expandedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
(_c = environment.onCollapseItem) === null || _c === void 0 ? void 0 : _c.call(environment, environment.items[itemId], treeId); | ||
var newItem = items[treeLinearItems[newIndex].item]; | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(newItem, treeId); | ||
}, [items, linearItems, onFocusItem, viewState]), | ||
moveProgrammaticDragPositionDown: react_1.useCallback(function () { | ||
programmaticDragDown(); | ||
}, [programmaticDragDown]), | ||
moveProgrammaticDragPositionUp: react_1.useCallback(function () { | ||
programmaticDragUp(); | ||
}, [programmaticDragUp]), | ||
renameItem: react_1.useCallback(function (itemId, name, treeId) { | ||
onRenameItem === null || onRenameItem === void 0 ? void 0 : onRenameItem(items[itemId], name, treeId); | ||
}, [items, onRenameItem]), | ||
selectItems: react_1.useCallback(function (itemsIds, treeId) { | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(itemsIds, treeId); | ||
}, [onSelectItems]), | ||
startProgrammaticDrag: react_1.useCallback(function () { | ||
startProgrammaticDrag(); | ||
}, [startProgrammaticDrag]), | ||
toggleItemExpandedState: react_1.useCallback(function (itemId, treeId) { | ||
var _a, _b; | ||
if ((_b = (_a = viewState[treeId]) === null || _a === void 0 ? void 0 : _a.expandedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
onCollapseItem === null || onCollapseItem === void 0 ? void 0 : onCollapseItem(items[itemId], treeId); | ||
} | ||
else { | ||
(_d = environment.onExpandItem) === null || _d === void 0 ? void 0 : _d.call(environment, environment.items[itemId], treeId); | ||
onExpandItem === null || onExpandItem === void 0 ? void 0 : onExpandItem(items[itemId], treeId); | ||
} | ||
}, | ||
toggleItemSelectStatus: function (itemId, treeId) { | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
if ((_b = (_a = environment.viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
(_c = environment.onSelectItems) === null || _c === void 0 ? void 0 : _c.call(environment, (_e = (_d = environment.viewState[treeId].selectedItems) === null || _d === void 0 ? void 0 : _d.filter(function (item) { return item !== itemId; })) !== null && _e !== void 0 ? _e : [], treeId); | ||
}, [items, onCollapseItem, onExpandItem, viewState]), | ||
toggleItemSelectStatus: react_1.useCallback(function (itemId, treeId) { | ||
var _a, _b, _c, _d, _e; | ||
if ((_b = (_a = viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems((_d = (_c = viewState[treeId].selectedItems) === null || _c === void 0 ? void 0 : _c.filter(function (item) { return item !== itemId; })) !== null && _d !== void 0 ? _d : [], treeId); | ||
} | ||
else { | ||
(_f = environment.onSelectItems) === null || _f === void 0 ? void 0 : _f.call(environment, __spreadArray(__spreadArray([], ((_g = environment.viewState[treeId].selectedItems) !== null && _g !== void 0 ? _g : [])), [itemId]), treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(__spreadArray(__spreadArray([], ((_e = viewState[treeId].selectedItems) !== null && _e !== void 0 ? _e : [])), [itemId]), treeId); | ||
} | ||
}, | ||
invokePrimaryAction: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onPrimaryAction) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
}, [onSelectItems, viewState]), | ||
invokePrimaryAction: react_1.useCallback(function (itemId, treeId) { | ||
onPrimaryAction === null || onPrimaryAction === void 0 ? void 0 : onPrimaryAction(items[itemId], treeId); | ||
}, [items, onPrimaryAction]), | ||
}; | ||
@@ -131,0 +121,0 @@ useCreatedEnvironmentRef_1.useCreatedEnvironmentRef(ref, actions); |
@@ -12,2 +12,3 @@ "use strict"; | ||
var useKeyboardBindings_1 = require("./useKeyboardBindings"); | ||
var useCallSoon_1 = require("../useCallSoon"); | ||
var elementsThatCanTakeText = ['input', 'textarea']; | ||
@@ -18,2 +19,3 @@ var useHotkey = function (combinationName, onHit, active, activatableWhileFocusingInput, deps) { | ||
var keyboardBindings = useKeyboardBindings_1.useKeyboardBindings(); | ||
var callSoon = useCallSoon_1.useCallSoon(); | ||
var possibleCombinations = react_1.useMemo(function () { return keyboardBindings[combinationName].map(function (combination) { return combination.split('+'); }); }, [combinationName, keyboardBindings]); | ||
@@ -57,7 +59,7 @@ useHtmlElementEventListener_1.useHtmlElementEventListener(document, 'keydown', function (e) { | ||
if (match) { | ||
requestAnimationFrame(function () { return onHit(e); }); | ||
callSoon(function () { return onHit(e); }); | ||
} | ||
pressedKeys.current = pressedKeys.current.filter(function (key) { return key !== e.key; }); | ||
}, __spreadArray([possibleCombinations, onHit, active], (deps !== null && deps !== void 0 ? deps : []))); | ||
}, __spreadArray([possibleCombinations, onHit, active, callSoon], (deps !== null && deps !== void 0 ? deps : []))); | ||
}; | ||
exports.useHotkey = useHotkey; |
@@ -21,2 +21,3 @@ "use strict"; | ||
var useViewState_1 = require("../tree/useViewState"); | ||
var useCallSoon_1 = require("../useCallSoon"); | ||
var SearchInput = function (props) { | ||
@@ -29,2 +30,3 @@ var _a; | ||
var isActiveTree = environment.activeTreeId === treeId; | ||
var callSoon = useCallSoon_1.useCallSoon(); | ||
useSearchMatchFocus_1.useSearchMatchFocus(); | ||
@@ -42,9 +44,9 @@ var clearSearch = function () { | ||
useHotkey_1.useHotkey('abortSearch', function () { | ||
// Without the requestAnimationFrame, hitting enter to abort | ||
// Without the callSoon, hitting enter to abort | ||
// and then moving focus weirdly moves the selected item along | ||
// with the focused item. | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
clearSearch(); | ||
}); | ||
}, isActiveTree && search !== null, true, [search, isActiveTree]); | ||
}, isActiveTree && search !== null, true, [search, isActiveTree, callSoon]); | ||
useHtmlElementEventListener_1.useHtmlElementEventListener(props.containerRef, 'keydown', function (e) { | ||
@@ -51,0 +53,0 @@ var _a, _b, _c, _d; |
@@ -5,14 +5,16 @@ "use strict"; | ||
var Tree_1 = require("../tree/Tree"); | ||
var useGetLinearItems_1 = require("../tree/useGetLinearItems"); | ||
var ControlledTreeEnvironment_1 = require("../controlledEnvironment/ControlledTreeEnvironment"); | ||
var defaultMatcher_1 = require("./defaultMatcher"); | ||
var useSideEffect_1 = require("../useSideEffect"); | ||
var useLinearItems_1 = require("../controlledEnvironment/useLinearItems"); | ||
var useCallSoon_1 = require("../useCallSoon"); | ||
var useSearchMatchFocus = function () { | ||
var _a = ControlledTreeEnvironment_1.useTreeEnvironment(), doesSearchMatchItem = _a.doesSearchMatchItem, items = _a.items, getItemTitle = _a.getItemTitle, onFocusItem = _a.onFocusItem; | ||
var _b = Tree_1.useTree(), search = _b.search, treeId = _b.treeId; | ||
var getLinearItems = useGetLinearItems_1.useGetLinearItems(); | ||
var linearItems = useLinearItems_1.useLinearItems(treeId); | ||
var callSoon = useCallSoon_1.useCallSoon(); | ||
useSideEffect_1.useSideEffect(function () { | ||
if (search && search.length > 0) { | ||
requestAnimationFrame(function () { | ||
var focusItem = getLinearItems().find(function (_a) { | ||
callSoon(function () { | ||
var focusItem = linearItems.find(function (_a) { | ||
var item = _a.item; | ||
@@ -26,4 +28,4 @@ return (doesSearchMatchItem !== null && doesSearchMatchItem !== void 0 ? doesSearchMatchItem : defaultMatcher_1.defaultMatcher)(search, items[item], getItemTitle(items[item])); | ||
} | ||
}, [doesSearchMatchItem, getItemTitle, getLinearItems, items, onFocusItem, search, treeId], [search]); | ||
}, [doesSearchMatchItem, getItemTitle, linearItems, items, onFocusItem, search, treeId, callSoon], [search]); | ||
}; | ||
exports.useSearchMatchFocus = useSearchMatchFocus; |
@@ -5,3 +5,3 @@ "use strict"; | ||
exports.defaultLiveDescriptors = { | ||
introduction: "\n <p>Accessibility guide for tree {treeLabel}.</p>\n <p>\n Navigate the tree with the arrow keys. Common tree hotkeys apply. Further keybindings are available:\n </p>\n <ul>\n <li>{keybinding:primaryAction} to execute primary action on focused item</li>\n <li>{keybinding:renameItem} to start renaming the focused item</li>\n <li>{keybinding:abortRenameItem} to abort renaming an item</li>\n <li>{keybinding:startProgrammaticDnd} to start dragging selected items</li>\n </ul>\n <p>\n More details on keybindings are available <a href=\"https://rct.lukasbach.com/docs/guides/keyboard#default-bindings\" target=\"_blank\">here</a>.\n </p>\n ", | ||
introduction: "\n <p>Accessibility guide for tree {treeLabel}.</p>\n <p>\n Navigate the tree with the arrow keys. Common tree hotkeys apply. Further keybindings are available:\n </p>\n <ul>\n <li>{keybinding:primaryAction} to execute primary action on focused item</li>\n <li>{keybinding:renameItem} to start renaming the focused item</li>\n <li>{keybinding:abortRenameItem} to abort renaming an item</li>\n <li>{keybinding:startProgrammaticDnd} to start dragging selected items</li>\n </ul>\n ", | ||
renamingItem: "\n <p>Renaming the item {renamingItem}.</p>\n <p>Use the keybinding {keybinding:abortRenameItem} to abort renaming.</p>\n ", | ||
@@ -8,0 +8,0 @@ searching: "\n <p>Searching</p>\n ", |
@@ -1,5 +0,2 @@ | ||
import { IndividualTreeViewState, TreeItem, TreeItemIndex } from '../types'; | ||
export declare const getItemsLinearly: <T>(rootItem: TreeItemIndex, viewState: IndividualTreeViewState, items: Record<TreeItemIndex, TreeItem<T>>, depth?: number) => { | ||
item: TreeItemIndex; | ||
depth: number; | ||
}[]; | ||
import { IndividualTreeViewState, LinearItem, TreeItem, TreeItemIndex } from '../types'; | ||
export declare const getItemsLinearly: <T>(rootItem: TreeItemIndex, viewState: IndividualTreeViewState, items: Record<TreeItemIndex, TreeItem<T>>, depth?: number) => LinearItem[]; |
@@ -11,2 +11,3 @@ "use strict"; | ||
var react_1 = require("react"); | ||
var useCallSoon_1 = require("../useCallSoon"); | ||
var useFocusWithin = function (element, onFocusIn, onFocusOut, deps) { | ||
@@ -16,2 +17,3 @@ if (deps === void 0) { deps = []; } | ||
var isLoosingFocusFlag = react_1.useRef(false); | ||
var callSoon = useCallSoon_1.useCallSoon(); | ||
useHtmlElementEventListener_1.useHtmlElementEventListener(element, 'focusin', function () { | ||
@@ -28,3 +30,3 @@ if (!focusWithin) { | ||
isLoosingFocusFlag.current = true; | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
if (isLoosingFocusFlag.current && !(element === null || element === void 0 ? void 0 : element.contains(document.activeElement))) { | ||
@@ -36,5 +38,5 @@ onFocusOut === null || onFocusOut === void 0 ? void 0 : onFocusOut(); | ||
}); | ||
}, __spreadArray([element, onFocusOut], deps)); | ||
}, __spreadArray([element, onFocusOut, callSoon], deps)); | ||
return focusWithin; | ||
}; | ||
exports.useFocusWithin = useFocusWithin; |
@@ -1,2 +0,2 @@ | ||
import type { getItemsLinearly } from './getItemsLinearly'; | ||
export declare const useMoveFocusToIndex: () => (computeNewIndex: (currentIndex: number, linearItems: ReturnType<typeof getItemsLinearly>) => number) => import("..").TreeItem<any>; | ||
import { LinearItem } from '../types'; | ||
export declare const useMoveFocusToIndex: () => (computeNewIndex: (currentIndex: number, linearItems: LinearItem[]) => number) => import("../types").TreeItem<any>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.useMoveFocusToIndex = void 0; | ||
var useGetLinearItems_1 = require("./useGetLinearItems"); | ||
var useViewState_1 = require("./useViewState"); | ||
@@ -9,10 +8,10 @@ var Tree_1 = require("./Tree"); | ||
var react_1 = require("react"); | ||
var useLinearItems_1 = require("../controlledEnvironment/useLinearItems"); | ||
var useMoveFocusToIndex = function () { | ||
var treeId = Tree_1.useTree().treeId; | ||
var _a = ControlledTreeEnvironment_1.useTreeEnvironment(), onFocusItem = _a.onFocusItem, items = _a.items; | ||
var getLinearItems = useGetLinearItems_1.useGetLinearItems(); | ||
var linearItems = useLinearItems_1.useLinearItems(treeId); | ||
var viewState = useViewState_1.useViewState(); | ||
return react_1.useCallback(function (computeNewIndex) { | ||
var _a; | ||
var linearItems = getLinearItems(); | ||
var currentIndex = (_a = linearItems.findIndex(function (item) { return item.item === viewState.focusedItem; })) !== null && _a !== void 0 ? _a : 0; | ||
@@ -24,4 +23,4 @@ var newIndex = computeNewIndex(currentIndex, linearItems); | ||
return newFocusItem; | ||
}, [onFocusItem, items, getLinearItems, treeId, viewState.focusedItem]); | ||
}, [onFocusItem, items, linearItems, treeId, viewState.focusedItem]); | ||
}; | ||
exports.useMoveFocusToIndex = useMoveFocusToIndex; |
@@ -9,15 +9,16 @@ "use strict"; | ||
exports.useSelectUpTo = void 0; | ||
var getItemsLinearly_1 = require("./getItemsLinearly"); | ||
var useViewState_1 = require("./useViewState"); | ||
var Tree_1 = require("./Tree"); | ||
var ControlledTreeEnvironment_1 = require("../controlledEnvironment/ControlledTreeEnvironment"); | ||
var react_1 = require("react"); | ||
var useLinearItems_1 = require("../controlledEnvironment/useLinearItems"); | ||
var useSelectUpTo = function () { | ||
var viewState = useViewState_1.useViewState(); | ||
var _a = Tree_1.useTree(), rootItem = _a.rootItem, treeId = _a.treeId; | ||
var environment = ControlledTreeEnvironment_1.useTreeEnvironment(); | ||
return function (item) { | ||
var _a, _b, _c, _d, _e; | ||
var treeId = Tree_1.useTree().treeId; | ||
var linearItems = useLinearItems_1.useLinearItems(treeId); | ||
var onSelectItems = ControlledTreeEnvironment_1.useTreeEnvironment().onSelectItems; | ||
return react_1.useCallback(function (item) { | ||
var _a, _b; | ||
// TODO doesnt work that well if there are spaces between selections | ||
if (viewState && viewState.selectedItems && viewState.selectedItems.length > 0) { | ||
var linearItems = getItemsLinearly_1.getItemsLinearly(rootItem, viewState, environment.items); | ||
var selectionStart = linearItems.findIndex(function (linearItem) { var _a; return (_a = viewState.selectedItems) === null || _a === void 0 ? void 0 : _a.includes(linearItem.item); }); | ||
@@ -30,3 +31,3 @@ var selectionEnd = linearItems.findIndex(function (linearItem) { return linearItem.item === item.index; }); | ||
}); | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, __spreadArray(__spreadArray([], ((_b = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _b !== void 0 ? _b : [])), selection), treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(__spreadArray(__spreadArray([], ((_a = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _a !== void 0 ? _a : [])), selection), treeId); | ||
} | ||
@@ -38,10 +39,10 @@ else { | ||
}); | ||
(_c = environment.onSelectItems) === null || _c === void 0 ? void 0 : _c.call(environment, __spreadArray(__spreadArray([], ((_d = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _d !== void 0 ? _d : [])), selection), treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(__spreadArray(__spreadArray([], ((_b = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _b !== void 0 ? _b : [])), selection), treeId); | ||
} | ||
} | ||
else { | ||
(_e = environment.onSelectItems) === null || _e === void 0 ? void 0 : _e.call(environment, [item.index], treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems([item.index], treeId); | ||
} | ||
}; | ||
}, [onSelectItems, linearItems, treeId, viewState]); | ||
}; | ||
exports.useSelectUpTo = useSelectUpTo; |
@@ -15,6 +15,6 @@ "use strict"; | ||
var ControlledTreeEnvironment_1 = require("../controlledEnvironment/ControlledTreeEnvironment"); | ||
var useGetLinearItems_1 = require("./useGetLinearItems"); | ||
var DragAndDropProvider_1 = require("../controlledEnvironment/DragAndDropProvider"); | ||
var useSelectUpTo_1 = require("./useSelectUpTo"); | ||
var react_1 = require("react"); | ||
var useLinearItems_1 = require("../controlledEnvironment/useLinearItems"); | ||
var useTreeKeyboardBindings = function () { | ||
@@ -24,6 +24,6 @@ var _a; | ||
var _b = Tree_1.useTree(), treeId = _b.treeId, setRenamingItem = _b.setRenamingItem, setSearch = _b.setSearch, renamingItem = _b.renamingItem; | ||
var linearItems = useLinearItems_1.useLinearItems(treeId); | ||
var dnd = DragAndDropProvider_1.useDragAndDrop(); | ||
var viewState = useViewState_1.useViewState(); | ||
var moveFocusToIndex = useMoveFocusToIndex_1.useMoveFocusToIndex(); | ||
var getLinearItems = useGetLinearItems_1.useGetLinearItems(); | ||
var selectUpTo = useSelectUpTo_1.useSelectUpTo(); | ||
@@ -101,3 +101,3 @@ var isActiveTree = environment.activeTreeId === treeId; | ||
e.preventDefault(); | ||
if (viewState.focusedItem) { | ||
if (viewState.focusedItem !== undefined) { | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, [viewState.focusedItem], treeId); | ||
@@ -110,3 +110,3 @@ (_b = environment.onPrimaryAction) === null || _b === void 0 ? void 0 : _b.call(environment, environment.items[viewState.focusedItem], treeId); | ||
e.preventDefault(); | ||
if (viewState.focusedItem) { | ||
if (viewState.focusedItem !== undefined) { | ||
if (viewState.selectedItems && viewState.selectedItems.includes(viewState.focusedItem)) { | ||
@@ -123,10 +123,10 @@ (_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, viewState.selectedItems.filter(function (item) { return item !== viewState.focusedItem; }), treeId); | ||
e.preventDefault(); | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, getLinearItems().map(function (_a) { | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, linearItems.map(function (_a) { | ||
var item = _a.item; | ||
return item; | ||
}), treeId); | ||
}, [environment, getLinearItems, treeId]), isActiveTree && !dnd.isProgrammaticallyDragging && !isRenaming); | ||
}, [environment, linearItems, treeId]), isActiveTree && !dnd.isProgrammaticallyDragging && !isRenaming); | ||
useHotkey_1.useHotkey('renameItem', react_1.useCallback(function (e) { | ||
var _a; | ||
if (viewState.focusedItem) { | ||
if (viewState.focusedItem !== undefined) { | ||
e.preventDefault(); | ||
@@ -133,0 +133,0 @@ var item = environment.items[viewState.focusedItem]; |
@@ -21,3 +21,3 @@ "use strict"; | ||
var containerProps = { | ||
role: 'group', | ||
role: props.depth !== 0 ? 'group' : undefined, | ||
}; | ||
@@ -24,0 +24,0 @@ return renderers.renderItemsContainer({ |
@@ -9,2 +9,3 @@ "use strict"; | ||
var useSideEffect_1 = require("../useSideEffect"); | ||
var useCallSoon_1 = require("../useCallSoon"); | ||
var TreeItemRenamingInput = function (props) { | ||
@@ -17,2 +18,3 @@ var _a = Tree_1.useTree(), renderers = _a.renderers, treeInformation = _a.treeInformation, setRenamingItem = _a.setRenamingItem, treeId = _a.treeId; | ||
var _b = react_1.useState(environment.getItemTitle(item)), title = _b[0], setTitle = _b[1]; | ||
var callSoon = useCallSoon_1.useCallSoon(); | ||
var abort = function () { | ||
@@ -22,3 +24,3 @@ var _a; | ||
setRenamingItem(null); | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
environment.setActiveTree(treeId); | ||
@@ -31,3 +33,3 @@ }); | ||
setRenamingItem(null); | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
environment.setActiveTree(treeId); | ||
@@ -34,0 +36,0 @@ }); |
@@ -134,3 +134,3 @@ "use strict"; | ||
}; | ||
var interactiveElementProps = __assign(__assign({}, interactionManager.createInteractiveElementProps(item, treeId, actions, renderFlags)), (_a = {}, | ||
var interactiveElementProps = __assign(__assign({}, interactionManager.createInteractiveElementProps(item, treeId, actions, renderFlags, viewState)), (_a = {}, | ||
_a['data-rct-item-interactive'] = true, | ||
@@ -137,0 +137,0 @@ _a['data-rct-item-focus'] = renderFlags.isFocused ? 'true' : 'false', |
@@ -124,3 +124,5 @@ import React, { FormHTMLAttributes, HTMLProps, InputHTMLAttributes, Ref } from 'react'; | ||
extends?: InteractionMode; | ||
createInteractiveElementProps: (item: TreeItem, treeId: string, actions: TreeItemActions, renderFlags: TreeItemRenderFlags) => HTMLProps<HTMLElement>; | ||
createInteractiveElementProps: (item: TreeItem, treeId: string, actions: TreeItemActions, renderFlags: TreeItemRenderFlags, | ||
/** See https://github.com/lukasbach/react-complex-tree/issues/48 */ | ||
__unsafeViewState?: IndividualTreeViewState) => HTMLProps<HTMLElement>; | ||
} | ||
@@ -210,2 +212,3 @@ export interface TreeCapabilities<T = any> { | ||
trees: Record<string, TreeConfiguration>; | ||
linearItems: Record<string, LinearItem[]>; | ||
} | ||
@@ -315,2 +318,6 @@ export interface DragAndDropContextProps<T = any> { | ||
}; | ||
export interface LinearItem { | ||
item: TreeItemIndex; | ||
depth: number; | ||
} | ||
export interface KeyboardBindings { | ||
@@ -317,0 +324,0 @@ primaryAction?: string[]; |
@@ -95,3 +95,3 @@ "use strict"; | ||
}; }, []); | ||
var amendViewState = function (treeId, constructNewState) { | ||
var amendViewState = react_1.useCallback(function (treeId, constructNewState) { | ||
setViewState(function (oldState) { | ||
@@ -102,3 +102,3 @@ var _a; | ||
}); | ||
}; | ||
}, []); | ||
react_1.useEffect(function () { | ||
@@ -105,0 +105,0 @@ var dispose = dataProvider.onDidChangeTreeData(function (changedItemIds) { |
@@ -1,16 +0,4 @@ | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
import * as React from 'react'; | ||
import { useCallback, useEffect, useMemo, useState } from 'react'; | ||
import { useCallback, useEffect, useRef, useState } from 'react'; | ||
import { useTreeEnvironment } from './ControlledTreeEnvironment'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
import { useOnDragOverTreeHandler } from './useOnDragOverTreeHandler'; | ||
@@ -20,11 +8,6 @@ import { useCanDropAt } from './useCanDropAt'; | ||
import { useSideEffect } from '../useSideEffect'; | ||
import { buildMapForTrees } from '../utils'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
var DragAndDropContext = React.createContext(null); | ||
export var useDragAndDrop = function () { return React.useContext(DragAndDropContext); }; | ||
var buildMapForTrees = function (treeIds, build) { | ||
return treeIds.map(function (id) { return [id, build(id)]; }).reduce(function (a, _a) { | ||
var _b; | ||
var id = _a[0], obj = _a[1]; | ||
return (__assign(__assign({}, a), (_b = {}, _b[id] = obj, _b))); | ||
}, {}); | ||
}; | ||
// TODO tidy up | ||
@@ -35,17 +18,18 @@ export var DragAndDropProvider = function (props) { | ||
var _b = useState(4), itemHeight = _b[0], setItemHeight = _b[1]; | ||
var _c = useState({}), linearItems = _c[0], setLinearItems = _c[1]; | ||
var _d = useState({}), viableDragPositions = _d[0], setViableDragPositions = _d[1]; | ||
var _e = useState(0), programmaticDragIndex = _e[0], setProgrammaticDragIndex = _e[1]; | ||
var _f = useState(), draggingItems = _f[0], setDraggingItems = _f[1]; | ||
var _g = useState(), draggingPosition = _g[0], setDraggingPosition = _g[1]; | ||
var _h = useState('_nodrag'), dragCode = _h[0], setDragCode = _h[1]; | ||
var _c = useState({}), viableDragPositions = _c[0], setViableDragPositions = _c[1]; | ||
var _d = useState(0), programmaticDragIndex = _d[0], setProgrammaticDragIndex = _d[1]; | ||
var _e = useState(), draggingItems = _e[0], setDraggingItems = _e[1]; | ||
var _f = useState(), draggingPosition = _f[0], setDraggingPosition = _f[1]; | ||
var _g = useState('_nodrag'), dragCode = _g[0], setDragCode = _g[1]; | ||
var getViableDragPositions = useGetViableDragPositions(); | ||
var resetProgrammaticDragIndexForCurrentTree = useCallback(function (viableDragPositions, linearItems, draggingItems) { | ||
var callSoon = useCallSoon(); | ||
var shouldCancelDrag = useRef(false); | ||
var resetProgrammaticDragIndexForCurrentTree = useCallback(function (viableDragPositions, draggingItems) { | ||
var _a; | ||
if (environment.activeTreeId && | ||
((_a = environment.viewState[environment.activeTreeId]) === null || _a === void 0 ? void 0 : _a.focusedItem) && | ||
linearItems && | ||
environment.linearItems && | ||
draggingItems) { | ||
var focusItem_1 = environment.viewState[environment.activeTreeId].focusedItem; | ||
var treeDragPositions = getViableDragPositions(environment.activeTreeId, draggingItems, linearItems); | ||
var treeDragPositions = getViableDragPositions(environment.activeTreeId, draggingItems); | ||
var newPos = treeDragPositions.findIndex(function (pos) { | ||
@@ -69,7 +53,12 @@ if (pos.targetType === 'item') { | ||
} | ||
}, [environment.activeTreeId, environment.items, environment.viewState, getViableDragPositions]); | ||
}, [ | ||
environment.activeTreeId, | ||
environment.items, | ||
environment.linearItems, | ||
environment.viewState, | ||
getViableDragPositions, | ||
]); | ||
var resetState = useCallback(function () { | ||
setIsProgrammaticallyDragging(false); | ||
setItemHeight(4); | ||
setLinearItems({}); | ||
setViableDragPositions({}); | ||
@@ -83,5 +72,5 @@ setProgrammaticDragIndex(0); | ||
if (environment.activeTreeId && | ||
linearItems[environment.activeTreeId] && | ||
environment.linearItems[environment.activeTreeId] && | ||
viableDragPositions[environment.activeTreeId]) { | ||
resetProgrammaticDragIndexForCurrentTree(viableDragPositions[environment.activeTreeId], linearItems[environment.activeTreeId], draggingItems); | ||
resetProgrammaticDragIndexForCurrentTree(viableDragPositions[environment.activeTreeId], draggingItems); | ||
} | ||
@@ -91,3 +80,3 @@ }, [ | ||
environment.activeTreeId, | ||
linearItems, | ||
environment.linearItems, | ||
resetProgrammaticDragIndexForCurrentTree, | ||
@@ -114,7 +103,7 @@ viableDragPositions, | ||
}; | ||
var onDragOverTreeHandler = useOnDragOverTreeHandler(dragCode, setDragCode, itemHeight, linearItems, setDraggingPosition, performDrag); | ||
var onDropHandler = useMemo(function () { return function () { | ||
var onDragOverTreeHandler = useOnDragOverTreeHandler(dragCode, setDragCode, itemHeight, setDraggingPosition, performDrag); | ||
var onDropHandler = useCallback(function () { | ||
if (draggingItems && draggingPosition && environment.onDrop) { | ||
environment.onDrop(draggingItems, draggingPosition); | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
var _a; | ||
@@ -125,8 +114,7 @@ (_a = environment.onFocusItem) === null || _a === void 0 ? void 0 : _a.call(environment, draggingItems[0], draggingPosition.treeId); | ||
} | ||
}; }, [draggingItems, draggingPosition, environment, resetState]); | ||
}, [draggingItems, draggingPosition, environment, resetState, callSoon]); | ||
var onStartDraggingItems = useCallback(function (items, treeId) { | ||
var _a, _b; | ||
var treeLinearItems = buildMapForTrees(environment.treeIds, function (treeId) { var _a; return getItemsLinearly(environment.trees[treeId].rootItem, (_a = environment.viewState[treeId]) !== null && _a !== void 0 ? _a : {}, environment.items); }); | ||
var treeViableDragPositions = buildMapForTrees(environment.treeIds, function (treeId) { | ||
return getViableDragPositions(treeId, items, treeLinearItems[treeId]); | ||
return getViableDragPositions(treeId, items); | ||
}); | ||
@@ -137,16 +125,7 @@ // TODO what if trees have different heights and drag target changes? | ||
setDraggingItems(items); | ||
setLinearItems(treeLinearItems); | ||
setViableDragPositions(treeViableDragPositions); | ||
if (environment.activeTreeId) { | ||
resetProgrammaticDragIndexForCurrentTree(treeViableDragPositions[environment.activeTreeId], treeLinearItems[environment.activeTreeId], items); | ||
resetProgrammaticDragIndexForCurrentTree(treeViableDragPositions[environment.activeTreeId], items); | ||
} | ||
}, [ | ||
environment.activeTreeId, | ||
environment.items, | ||
environment.treeIds, | ||
environment.trees, | ||
environment.viewState, | ||
getViableDragPositions, | ||
resetProgrammaticDragIndexForCurrentTree, | ||
]); | ||
}, [environment.activeTreeId, environment.treeIds, getViableDragPositions, resetProgrammaticDragIndexForCurrentTree]); | ||
var startProgrammaticDrag = useCallback(function () { | ||
@@ -205,6 +184,10 @@ var _a, _b, _c; | ||
useEffect(function () { | ||
window.addEventListener('dragend', onDropHandler); | ||
return function () { return window.removeEventListener('dragend', onDropHandler); }; | ||
}, [onDropHandler]); | ||
window.addEventListener('dragend', resetState); | ||
window.addEventListener('drop', onDropHandler); | ||
return function () { | ||
window.removeEventListener('dragend', resetState); | ||
window.removeEventListener('drop', onDropHandler); | ||
}; | ||
}, [onDropHandler, resetState]); | ||
return React.createElement(DragAndDropContext.Provider, { value: dnd }, props.children); | ||
}; |
import { useTreeEnvironment } from './ControlledTreeEnvironment'; | ||
import { useCallback } from 'react'; | ||
export var useCanDropAt = function () { | ||
var environment = useTreeEnvironment(); | ||
return function (draggingPosition, draggingItems) { | ||
return useCallback(function (draggingPosition, draggingItems) { | ||
if (draggingPosition.targetType === 'between-items') { | ||
@@ -22,3 +23,3 @@ if (!environment.canReorderItems) { | ||
return true; | ||
}; | ||
}, [environment]); | ||
}; |
@@ -14,17 +14,29 @@ var __assign = (this && this.__assign) || function () { | ||
import { useCallback, useMemo, useState } from 'react'; | ||
import { useMemoizedObject } from '../useMemoizedObject'; | ||
import { useRenderers } from '../renderers/useRenderers'; | ||
import { buildMapForTrees } from '../utils'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
import { useRefCopy } from '../useRefCopy'; | ||
import { useUpdateLinearItems } from './useUpdateLinearItems'; | ||
export var useControlledTreeEnvironmentProps = function (props) { | ||
var _a = useState({}), trees = _a[0], setTrees = _a[1]; | ||
var _b = useState(), activeTreeId = _b[0], setActiveTreeId = _b[1]; | ||
var memoizedProps = useMemoizedObject(props); | ||
var onFocusItem = memoizedProps.onFocusItem, autoFocus = memoizedProps.autoFocus, onRegisterTree = memoizedProps.onRegisterTree, onUnregisterTree = memoizedProps.onUnregisterTree; | ||
var _b = useState({}), linearItems = _b[0], setLinearItems = _b[1]; | ||
var _c = useState(), activeTreeId = _c[0], setActiveTreeId = _c[1]; | ||
var viewStateRef = useRefCopy(props.viewState); | ||
var treeIds = useMemo(function () { return Object.keys(trees); }, [trees]); | ||
var onFocusItem = props.onFocusItem, autoFocus = props.autoFocus, onRegisterTree = props.onRegisterTree, onUnregisterTree = props.onUnregisterTree, items = props.items; | ||
var onFocusItemRef = useRefCopy(onFocusItem); | ||
var newChangeHandlers = useUpdateLinearItems(useCallback(function () { | ||
setLinearItems(buildMapForTrees(treeIds, function (treeId) { var _a; return getItemsLinearly(trees[treeId].rootItem, (_a = viewStateRef.current[treeId]) !== null && _a !== void 0 ? _a : {}, items); })); | ||
}, [items, treeIds, trees, viewStateRef]), props, items); | ||
var onFocusItemHandler = useCallback(function (item, treeId) { | ||
var _a, _b, _c, _d; | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(item, treeId); | ||
var _a, _b, _c, _d, _e, _f; | ||
if (((_a = viewStateRef.current[treeId]) === null || _a === void 0 ? void 0 : _a.focusedItem) === item.index) { | ||
return; | ||
} | ||
(_b = onFocusItemRef.current) === null || _b === void 0 ? void 0 : _b.call(onFocusItemRef, item, treeId); | ||
var newItem = document.querySelector("[data-rct-tree=\"" + treeId + "\"] [data-rct-item-id=\"" + item.index + "\"]"); | ||
if (autoFocus !== null && autoFocus !== void 0 ? autoFocus : true) { | ||
if (((_b = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.attributes.getNamedItem('data-rct-search-input')) === null || _b === void 0 ? void 0 : _b.value) !== 'true') { | ||
if (((_d = (_c = document.activeElement) === null || _c === void 0 ? void 0 : _c.attributes.getNamedItem('data-rct-search-input')) === null || _d === void 0 ? void 0 : _d.value) !== 'true') { | ||
// Move DOM focus to item if the current focus is not on the search input | ||
(_d = (_c = newItem) === null || _c === void 0 ? void 0 : _c.focus) === null || _d === void 0 ? void 0 : _d.call(_c); | ||
(_f = (_e = newItem) === null || _e === void 0 ? void 0 : _e.focus) === null || _f === void 0 ? void 0 : _f.call(_e); | ||
} | ||
@@ -36,3 +48,3 @@ else { | ||
} | ||
}, [autoFocus, onFocusItem]); | ||
}, [autoFocus, onFocusItemRef, viewStateRef]); | ||
var registerTree = useCallback(function (tree) { | ||
@@ -77,5 +89,4 @@ setTrees(function (trees) { | ||
}, [autoFocus]); | ||
var treeIds = useMemo(function () { return Object.keys(trees); }, [trees]); | ||
var renderers = useRenderers(memoizedProps); | ||
return __assign(__assign(__assign({}, renderers), memoizedProps), { onFocusItem: onFocusItemHandler, registerTree: registerTree, | ||
var renderers = useRenderers(props); | ||
return __assign(__assign(__assign(__assign({}, renderers), props), newChangeHandlers), { onFocusItem: onFocusItemHandler, registerTree: registerTree, | ||
unregisterTree: unregisterTree, | ||
@@ -85,3 +96,4 @@ setActiveTree: setActiveTree, | ||
trees: trees, | ||
activeTreeId: activeTreeId }); | ||
activeTreeId: activeTreeId, | ||
linearItems: linearItems }); | ||
}; |
@@ -1,5 +0,1 @@ | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
export declare const useGetGetParentOfLinearItem: () => (linearItems: ReturnType<typeof getItemsLinearly>, itemLinearIndex: number, treeId: string) => { | ||
item: import("..").TreeItemIndex; | ||
depth: number; | ||
}; | ||
export declare const useGetGetParentOfLinearItem: () => (itemLinearIndex: number, treeId: string) => import("..").LinearItem; |
import { useTreeEnvironment } from './ControlledTreeEnvironment'; | ||
import { useCallback } from 'react'; | ||
export var useGetGetParentOfLinearItem = function () { | ||
var environment = useTreeEnvironment(); | ||
return function (linearItems, itemLinearIndex, treeId) { | ||
return useCallback(function (itemLinearIndex, treeId) { | ||
var linearItems = environment.linearItems[treeId]; | ||
var depth = linearItems[itemLinearIndex].depth; | ||
@@ -15,3 +17,3 @@ var parentLinearIndex = itemLinearIndex; | ||
return parent; | ||
}; | ||
}, [environment.linearItems, environment.trees]); | ||
}; |
import { DraggingPosition, TreeItem } from '../types'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
export declare const useGetViableDragPositions: () => (treeId: string, draggingItems: TreeItem[], linearItems: ReturnType<typeof getItemsLinearly>) => DraggingPosition[]; | ||
export declare const useGetViableDragPositions: () => (treeId: string, draggingItems: TreeItem[]) => DraggingPosition[]; |
@@ -9,2 +9,3 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
import { useCanDropAt } from './useCanDropAt'; | ||
import { useCallback } from 'react'; | ||
export var useGetViableDragPositions = function () { | ||
@@ -14,3 +15,4 @@ var environment = useTreeEnvironment(); | ||
var canDropAt = useCanDropAt(); | ||
return function (treeId, draggingItems, linearItems) { | ||
return useCallback(function (treeId, draggingItems) { | ||
var linearItems = environment.linearItems[treeId]; | ||
return linearItems | ||
@@ -20,3 +22,3 @@ .map(function (_a, linearIndex) { | ||
var item = _a.item, depth = _a.depth; | ||
var parent = getParentOfLinearItem(linearItems, linearIndex, treeId); | ||
var parent = getParentOfLinearItem(linearIndex, treeId); | ||
var childIndex = environment.items[parent.item].children.indexOf(item); | ||
@@ -59,3 +61,3 @@ var itemPosition = { | ||
.filter(function (position) { return canDropAt(position, draggingItems); }); | ||
}; | ||
}, [canDropAt, environment.items, environment.linearItems, getParentOfLinearItem]); | ||
}; |
import * as React from 'react'; | ||
import { DraggingPosition } from '../types'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
export declare const useOnDragOverTreeHandler: (lastDragCode: string, setLastDragCode: (code: string) => void, itemHeight: number, linearItems: { | ||
[treeId: string]: { | ||
item: import("../types").TreeItemIndex; | ||
depth: number; | ||
}[]; | ||
}, onDragAtPosition: (draggingPosition: DraggingPosition | undefined) => void, onPerformDrag: (draggingPosition: DraggingPosition) => void) => (e: DragEvent, treeId: string, containerRef: React.MutableRefObject<HTMLElement | undefined>) => void; | ||
export declare const useOnDragOverTreeHandler: (lastDragCode: string, setLastDragCode: (code: string) => void, itemHeight: number, onDragAtPosition: (draggingPosition: DraggingPosition | undefined) => void, onPerformDrag: (draggingPosition: DraggingPosition) => void) => (e: DragEvent, treeId: string, containerRef: React.MutableRefObject<HTMLElement | undefined>) => void; |
import { useTreeEnvironment } from './ControlledTreeEnvironment'; | ||
import { useGetGetParentOfLinearItem } from './useGetParentOfLinearItem'; | ||
import { useCallback } from 'react'; | ||
var isOutsideOfContainer = function (e, treeBb) { | ||
return e.clientX < treeBb.left || e.clientX > treeBb.right || e.clientY < treeBb.top || e.clientY > treeBb.bottom; | ||
}; | ||
var getHoveringPosition = function (clientY, treeTop, itemHeight, capabilities) { | ||
var getHoveringPosition = function (clientY, treeTop, itemHeight, canDropOnItemWithChildren, canDropOnItemWithoutChildren) { | ||
var hoveringPosition = (clientY - treeTop) / itemHeight; | ||
var linearIndex = Math.floor(hoveringPosition); | ||
var offset = undefined; | ||
var lineThreshold = capabilities.canDropOnItemWithChildren || capabilities.canDropOnItemWithoutChildren ? 0.2 : 0.5; | ||
var lineThreshold = canDropOnItemWithChildren || canDropOnItemWithoutChildren ? 0.2 : 0.5; | ||
if (hoveringPosition % 1 < lineThreshold) { | ||
@@ -19,8 +20,8 @@ offset = 'top'; | ||
}; | ||
export var useOnDragOverTreeHandler = function (lastDragCode, setLastDragCode, itemHeight, linearItems, onDragAtPosition, onPerformDrag) { | ||
var environment = useTreeEnvironment(); | ||
export var useOnDragOverTreeHandler = function (lastDragCode, setLastDragCode, itemHeight, onDragAtPosition, onPerformDrag) { | ||
var _a = useTreeEnvironment(), canDropOnItemWithChildren = _a.canDropOnItemWithChildren, canDropOnItemWithoutChildren = _a.canDropOnItemWithoutChildren, canDragAndDrop = _a.canDragAndDrop, linearItems = _a.linearItems, items = _a.items, canReorderItems = _a.canReorderItems, viewState = _a.viewState; | ||
var getParentOfLinearItem = useGetGetParentOfLinearItem(); | ||
return function (e, treeId, containerRef) { | ||
return useCallback(function (e, treeId, containerRef) { | ||
var _a, _b, _c, _d; | ||
if (!environment.canDragAndDrop) { | ||
if (!canDragAndDrop) { | ||
return; | ||
@@ -36,3 +37,3 @@ } | ||
var outsideContainer = isOutsideOfContainer(e, treeBb); | ||
var _e = getHoveringPosition(e.clientY, treeBb.top, itemHeight, environment), linearIndex = _e.linearIndex, offset = _e.offset; | ||
var _e = getHoveringPosition(e.clientY, treeBb.top, itemHeight, canDropOnItemWithChildren, canDropOnItemWithoutChildren), linearIndex = _e.linearIndex, offset = _e.offset; | ||
var nextDragCode = outsideContainer ? 'outside' : "" + treeId + linearIndex + (offset !== null && offset !== void 0 ? offset : ''); | ||
@@ -53,20 +54,20 @@ if (lastDragCode === nextDragCode) { | ||
var depth = targetItem.depth; | ||
var targetItemData = environment.items[targetItem.item]; | ||
if (!offset && !environment.canDropOnItemWithoutChildren && !targetItemData.hasChildren) { | ||
var targetItemData = items[targetItem.item]; | ||
if (!offset && !canDropOnItemWithoutChildren && !targetItemData.hasChildren) { | ||
onDragAtPosition(undefined); | ||
return; | ||
} | ||
if (!offset && !environment.canDropOnItemWithChildren && targetItemData.hasChildren) { | ||
if (!offset && !canDropOnItemWithChildren && targetItemData.hasChildren) { | ||
onDragAtPosition(undefined); | ||
return; | ||
} | ||
if (offset && !environment.canReorderItems) { | ||
if (offset && !canReorderItems) { | ||
onDragAtPosition(undefined); | ||
return; | ||
} | ||
var parent = getParentOfLinearItem(linearItems[treeId], linearIndex, treeId); | ||
if ((_b = (_a = environment.viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(targetItem.item)) { | ||
var parent = getParentOfLinearItem(linearIndex, treeId); | ||
if ((_b = (_a = viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(targetItem.item)) { | ||
return; | ||
} | ||
var newChildIndex = environment.items[parent.item].children.indexOf(targetItem.item) + (offset === 'top' ? 0 : 1); | ||
var newChildIndex = items[parent.item].children.indexOf(targetItem.item) + (offset === 'top' ? 0 : 1); | ||
if (offset === 'top' && depth === ((_d = (_c = linearItems[treeId][linearIndex - 1]) === null || _c === void 0 ? void 0 : _c.depth) !== null && _d !== void 0 ? _d : -1)) { | ||
@@ -101,3 +102,17 @@ offset = 'bottom'; | ||
onPerformDrag(draggingPosition); | ||
}; | ||
}, [ | ||
canDragAndDrop, | ||
canDropOnItemWithChildren, | ||
canDropOnItemWithoutChildren, | ||
canReorderItems, | ||
getParentOfLinearItem, | ||
itemHeight, | ||
items, | ||
lastDragCode, | ||
linearItems, | ||
onDragAtPosition, | ||
onPerformDrag, | ||
setLastDragCode, | ||
viewState, | ||
]); | ||
}; |
@@ -7,5 +7,5 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
import * as React from 'react'; | ||
import { useCallback } from 'react'; | ||
import { useDragAndDrop } from '../controlledEnvironment/DragAndDropProvider'; | ||
import { useTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
import { useCreatedEnvironmentRef } from './useCreatedEnvironmentRef'; | ||
@@ -15,93 +15,83 @@ var EnvironmentActionsContext = React.createContext(null); | ||
export var EnvironmentActionsProvider = React.forwardRef(function (props, ref) { | ||
var environment = useTreeEnvironment(); | ||
var dnd = useDragAndDrop(); | ||
var _a = useTreeEnvironment(), onCollapseItem = _a.onCollapseItem, items = _a.items, trees = _a.trees, viewState = _a.viewState, onExpandItem = _a.onExpandItem, onFocusItem = _a.onFocusItem, setActiveTree = _a.setActiveTree, onRenameItem = _a.onRenameItem, onSelectItems = _a.onSelectItems, onPrimaryAction = _a.onPrimaryAction, linearItems = _a.linearItems; | ||
var _b = useDragAndDrop(), abortProgrammaticDrag = _b.abortProgrammaticDrag, completeProgrammaticDrag = _b.completeProgrammaticDrag, programmaticDragDown = _b.programmaticDragDown, programmaticDragUp = _b.programmaticDragUp, startProgrammaticDrag = _b.startProgrammaticDrag; | ||
// TODO change environment childs to use actions rather than output events where possible | ||
var actions = { | ||
abortProgrammaticDrag: function () { | ||
dnd.abortProgrammaticDrag(); | ||
}, | ||
collapseItem: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onCollapseItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
completeProgrammaticDrag: function () { | ||
dnd.completeProgrammaticDrag(); | ||
}, | ||
expandItem: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onExpandItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
focusItem: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onFocusItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
focusTree: function (treeId, autoFocus) { | ||
abortProgrammaticDrag: useCallback(function () { | ||
abortProgrammaticDrag(); | ||
}, [abortProgrammaticDrag]), | ||
collapseItem: useCallback(function (itemId, treeId) { | ||
onCollapseItem === null || onCollapseItem === void 0 ? void 0 : onCollapseItem(items[itemId], treeId); | ||
}, [items, onCollapseItem]), | ||
completeProgrammaticDrag: useCallback(function () { | ||
completeProgrammaticDrag(); | ||
}, [completeProgrammaticDrag]), | ||
expandItem: useCallback(function (itemId, treeId) { | ||
onExpandItem === null || onExpandItem === void 0 ? void 0 : onExpandItem(items[itemId], treeId); | ||
}, [items, onExpandItem]), | ||
focusItem: useCallback(function (itemId, treeId) { | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(items[itemId], treeId); | ||
}, [items, onFocusItem]), | ||
focusTree: useCallback(function (treeId, autoFocus) { | ||
if (autoFocus === void 0) { autoFocus = true; } | ||
environment.setActiveTree(treeId, autoFocus); | ||
}, | ||
moveFocusDown: function (treeId) { | ||
var _a, _b; | ||
var tree = environment.trees[treeId]; | ||
var linearItems = getItemsLinearly(tree.rootItem, (_a = environment.viewState[treeId]) !== null && _a !== void 0 ? _a : {}, environment.items); | ||
var currentFocusIndex = linearItems.findIndex(function (_a) { | ||
setActiveTree(treeId, autoFocus); | ||
}, [setActiveTree]), | ||
moveFocusDown: useCallback(function (treeId) { | ||
var treeLinearItems = linearItems[treeId]; | ||
var currentFocusIndex = treeLinearItems.findIndex(function (_a) { | ||
var _b; | ||
var item = _a.item; | ||
return item === ((_b = environment.viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
return item === ((_b = viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
}); | ||
var newIndex = currentFocusIndex !== undefined ? Math.min(linearItems.length - 1, currentFocusIndex + 1) : 0; | ||
var newItem = environment.items[linearItems[newIndex].item]; | ||
(_b = environment.onFocusItem) === null || _b === void 0 ? void 0 : _b.call(environment, newItem, treeId); | ||
}, | ||
moveFocusUp: function (treeId) { | ||
var _a, _b; | ||
var tree = environment.trees[treeId]; | ||
var linearItems = getItemsLinearly(tree.rootItem, (_a = environment.viewState[treeId]) !== null && _a !== void 0 ? _a : {}, environment.items); | ||
var currentFocusIndex = linearItems.findIndex(function (_a) { | ||
var newIndex = currentFocusIndex !== undefined ? Math.min(treeLinearItems.length - 1, currentFocusIndex + 1) : 0; | ||
var newItem = items[treeLinearItems[newIndex].item]; | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(newItem, treeId); | ||
}, [items, linearItems, onFocusItem, viewState]), | ||
moveFocusUp: useCallback(function (treeId) { | ||
var treeLinearItems = linearItems[treeId]; | ||
var currentFocusIndex = treeLinearItems.findIndex(function (_a) { | ||
var _b; | ||
var item = _a.item; | ||
return item === ((_b = environment.viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
return item === ((_b = viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
}); | ||
var newIndex = currentFocusIndex !== undefined ? Math.max(0, currentFocusIndex - 1) : 0; | ||
var newItem = environment.items[linearItems[newIndex].item]; | ||
(_b = environment.onFocusItem) === null || _b === void 0 ? void 0 : _b.call(environment, newItem, treeId); | ||
}, | ||
moveProgrammaticDragPositionDown: function () { | ||
dnd.programmaticDragDown(); | ||
}, | ||
moveProgrammaticDragPositionUp: function () { | ||
dnd.programmaticDragUp(); | ||
}, | ||
renameItem: function (itemId, name, treeId) { | ||
var _a; | ||
(_a = environment.onRenameItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], name, treeId); | ||
}, | ||
selectItems: function (itemsIds, treeId) { | ||
var _a; | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, itemsIds, treeId); | ||
}, | ||
startProgrammaticDrag: function () { | ||
dnd.startProgrammaticDrag(); | ||
}, | ||
toggleItemExpandedState: function (itemId, treeId) { | ||
var _a, _b, _c, _d; | ||
if ((_b = (_a = environment.viewState[treeId]) === null || _a === void 0 ? void 0 : _a.expandedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
(_c = environment.onCollapseItem) === null || _c === void 0 ? void 0 : _c.call(environment, environment.items[itemId], treeId); | ||
var newItem = items[treeLinearItems[newIndex].item]; | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(newItem, treeId); | ||
}, [items, linearItems, onFocusItem, viewState]), | ||
moveProgrammaticDragPositionDown: useCallback(function () { | ||
programmaticDragDown(); | ||
}, [programmaticDragDown]), | ||
moveProgrammaticDragPositionUp: useCallback(function () { | ||
programmaticDragUp(); | ||
}, [programmaticDragUp]), | ||
renameItem: useCallback(function (itemId, name, treeId) { | ||
onRenameItem === null || onRenameItem === void 0 ? void 0 : onRenameItem(items[itemId], name, treeId); | ||
}, [items, onRenameItem]), | ||
selectItems: useCallback(function (itemsIds, treeId) { | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(itemsIds, treeId); | ||
}, [onSelectItems]), | ||
startProgrammaticDrag: useCallback(function () { | ||
startProgrammaticDrag(); | ||
}, [startProgrammaticDrag]), | ||
toggleItemExpandedState: useCallback(function (itemId, treeId) { | ||
var _a, _b; | ||
if ((_b = (_a = viewState[treeId]) === null || _a === void 0 ? void 0 : _a.expandedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
onCollapseItem === null || onCollapseItem === void 0 ? void 0 : onCollapseItem(items[itemId], treeId); | ||
} | ||
else { | ||
(_d = environment.onExpandItem) === null || _d === void 0 ? void 0 : _d.call(environment, environment.items[itemId], treeId); | ||
onExpandItem === null || onExpandItem === void 0 ? void 0 : onExpandItem(items[itemId], treeId); | ||
} | ||
}, | ||
toggleItemSelectStatus: function (itemId, treeId) { | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
if ((_b = (_a = environment.viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
(_c = environment.onSelectItems) === null || _c === void 0 ? void 0 : _c.call(environment, (_e = (_d = environment.viewState[treeId].selectedItems) === null || _d === void 0 ? void 0 : _d.filter(function (item) { return item !== itemId; })) !== null && _e !== void 0 ? _e : [], treeId); | ||
}, [items, onCollapseItem, onExpandItem, viewState]), | ||
toggleItemSelectStatus: useCallback(function (itemId, treeId) { | ||
var _a, _b, _c, _d, _e; | ||
if ((_b = (_a = viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems((_d = (_c = viewState[treeId].selectedItems) === null || _c === void 0 ? void 0 : _c.filter(function (item) { return item !== itemId; })) !== null && _d !== void 0 ? _d : [], treeId); | ||
} | ||
else { | ||
(_f = environment.onSelectItems) === null || _f === void 0 ? void 0 : _f.call(environment, __spreadArray(__spreadArray([], ((_g = environment.viewState[treeId].selectedItems) !== null && _g !== void 0 ? _g : [])), [itemId]), treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(__spreadArray(__spreadArray([], ((_e = viewState[treeId].selectedItems) !== null && _e !== void 0 ? _e : [])), [itemId]), treeId); | ||
} | ||
}, | ||
invokePrimaryAction: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onPrimaryAction) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
}, [onSelectItems, viewState]), | ||
invokePrimaryAction: useCallback(function (itemId, treeId) { | ||
onPrimaryAction === null || onPrimaryAction === void 0 ? void 0 : onPrimaryAction(items[itemId], treeId); | ||
}, [items, onPrimaryAction]), | ||
}; | ||
@@ -108,0 +98,0 @@ useCreatedEnvironmentRef(ref, actions); |
@@ -9,2 +9,3 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
import { useKeyboardBindings } from './useKeyboardBindings'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
var elementsThatCanTakeText = ['input', 'textarea']; | ||
@@ -15,2 +16,3 @@ export var useHotkey = function (combinationName, onHit, active, activatableWhileFocusingInput, deps) { | ||
var keyboardBindings = useKeyboardBindings(); | ||
var callSoon = useCallSoon(); | ||
var possibleCombinations = useMemo(function () { return keyboardBindings[combinationName].map(function (combination) { return combination.split('+'); }); }, [combinationName, keyboardBindings]); | ||
@@ -54,6 +56,6 @@ useHtmlElementEventListener(document, 'keydown', function (e) { | ||
if (match) { | ||
requestAnimationFrame(function () { return onHit(e); }); | ||
callSoon(function () { return onHit(e); }); | ||
} | ||
pressedKeys.current = pressedKeys.current.filter(function (key) { return key !== e.key; }); | ||
}, __spreadArray([possibleCombinations, onHit, active], (deps !== null && deps !== void 0 ? deps : []))); | ||
}, __spreadArray([possibleCombinations, onHit, active, callSoon], (deps !== null && deps !== void 0 ? deps : []))); | ||
}; |
@@ -18,2 +18,3 @@ var __assign = (this && this.__assign) || function () { | ||
import { useViewState } from '../tree/useViewState'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
export var SearchInput = function (props) { | ||
@@ -26,2 +27,3 @@ var _a; | ||
var isActiveTree = environment.activeTreeId === treeId; | ||
var callSoon = useCallSoon(); | ||
useSearchMatchFocus(); | ||
@@ -39,9 +41,9 @@ var clearSearch = function () { | ||
useHotkey('abortSearch', function () { | ||
// Without the requestAnimationFrame, hitting enter to abort | ||
// Without the callSoon, hitting enter to abort | ||
// and then moving focus weirdly moves the selected item along | ||
// with the focused item. | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
clearSearch(); | ||
}); | ||
}, isActiveTree && search !== null, true, [search, isActiveTree]); | ||
}, isActiveTree && search !== null, true, [search, isActiveTree, callSoon]); | ||
useHtmlElementEventListener(props.containerRef, 'keydown', function (e) { | ||
@@ -48,0 +50,0 @@ var _a, _b, _c, _d; |
import { useTree } from '../tree/Tree'; | ||
import { useGetLinearItems } from '../tree/useGetLinearItems'; | ||
import { useTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment'; | ||
import { defaultMatcher } from './defaultMatcher'; | ||
import { useSideEffect } from '../useSideEffect'; | ||
import { useLinearItems } from '../controlledEnvironment/useLinearItems'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
export var useSearchMatchFocus = function () { | ||
var _a = useTreeEnvironment(), doesSearchMatchItem = _a.doesSearchMatchItem, items = _a.items, getItemTitle = _a.getItemTitle, onFocusItem = _a.onFocusItem; | ||
var _b = useTree(), search = _b.search, treeId = _b.treeId; | ||
var getLinearItems = useGetLinearItems(); | ||
var linearItems = useLinearItems(treeId); | ||
var callSoon = useCallSoon(); | ||
useSideEffect(function () { | ||
if (search && search.length > 0) { | ||
requestAnimationFrame(function () { | ||
var focusItem = getLinearItems().find(function (_a) { | ||
callSoon(function () { | ||
var focusItem = linearItems.find(function (_a) { | ||
var item = _a.item; | ||
@@ -22,3 +24,3 @@ return (doesSearchMatchItem !== null && doesSearchMatchItem !== void 0 ? doesSearchMatchItem : defaultMatcher)(search, items[item], getItemTitle(items[item])); | ||
} | ||
}, [doesSearchMatchItem, getItemTitle, getLinearItems, items, onFocusItem, search, treeId], [search]); | ||
}, [doesSearchMatchItem, getItemTitle, linearItems, items, onFocusItem, search, treeId, callSoon], [search]); | ||
}; |
export var defaultLiveDescriptors = { | ||
introduction: "\n <p>Accessibility guide for tree {treeLabel}.</p>\n <p>\n Navigate the tree with the arrow keys. Common tree hotkeys apply. Further keybindings are available:\n </p>\n <ul>\n <li>{keybinding:primaryAction} to execute primary action on focused item</li>\n <li>{keybinding:renameItem} to start renaming the focused item</li>\n <li>{keybinding:abortRenameItem} to abort renaming an item</li>\n <li>{keybinding:startProgrammaticDnd} to start dragging selected items</li>\n </ul>\n <p>\n More details on keybindings are available <a href=\"https://rct.lukasbach.com/docs/guides/keyboard#default-bindings\" target=\"_blank\">here</a>.\n </p>\n ", | ||
introduction: "\n <p>Accessibility guide for tree {treeLabel}.</p>\n <p>\n Navigate the tree with the arrow keys. Common tree hotkeys apply. Further keybindings are available:\n </p>\n <ul>\n <li>{keybinding:primaryAction} to execute primary action on focused item</li>\n <li>{keybinding:renameItem} to start renaming the focused item</li>\n <li>{keybinding:abortRenameItem} to abort renaming an item</li>\n <li>{keybinding:startProgrammaticDnd} to start dragging selected items</li>\n </ul>\n ", | ||
renamingItem: "\n <p>Renaming the item {renamingItem}.</p>\n <p>Use the keybinding {keybinding:abortRenameItem} to abort renaming.</p>\n ", | ||
@@ -4,0 +4,0 @@ searching: "\n <p>Searching</p>\n ", |
@@ -1,5 +0,2 @@ | ||
import { IndividualTreeViewState, TreeItem, TreeItemIndex } from '../types'; | ||
export declare const getItemsLinearly: <T>(rootItem: TreeItemIndex, viewState: IndividualTreeViewState, items: Record<TreeItemIndex, TreeItem<T>>, depth?: number) => { | ||
item: TreeItemIndex; | ||
depth: number; | ||
}[]; | ||
import { IndividualTreeViewState, LinearItem, TreeItem, TreeItemIndex } from '../types'; | ||
export declare const getItemsLinearly: <T>(rootItem: TreeItemIndex, viewState: IndividualTreeViewState, items: Record<TreeItemIndex, TreeItem<T>>, depth?: number) => LinearItem[]; |
@@ -8,2 +8,3 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
import { useRef, useState } from 'react'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
export var useFocusWithin = function (element, onFocusIn, onFocusOut, deps) { | ||
@@ -13,2 +14,3 @@ if (deps === void 0) { deps = []; } | ||
var isLoosingFocusFlag = useRef(false); | ||
var callSoon = useCallSoon(); | ||
useHtmlElementEventListener(element, 'focusin', function () { | ||
@@ -25,3 +27,3 @@ if (!focusWithin) { | ||
isLoosingFocusFlag.current = true; | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
if (isLoosingFocusFlag.current && !(element === null || element === void 0 ? void 0 : element.contains(document.activeElement))) { | ||
@@ -33,4 +35,4 @@ onFocusOut === null || onFocusOut === void 0 ? void 0 : onFocusOut(); | ||
}); | ||
}, __spreadArray([element, onFocusOut], deps)); | ||
}, __spreadArray([element, onFocusOut, callSoon], deps)); | ||
return focusWithin; | ||
}; |
@@ -1,2 +0,2 @@ | ||
import type { getItemsLinearly } from './getItemsLinearly'; | ||
export declare const useMoveFocusToIndex: () => (computeNewIndex: (currentIndex: number, linearItems: ReturnType<typeof getItemsLinearly>) => number) => import("..").TreeItem<any>; | ||
import { LinearItem } from '../types'; | ||
export declare const useMoveFocusToIndex: () => (computeNewIndex: (currentIndex: number, linearItems: LinearItem[]) => number) => import("../types").TreeItem<any>; |
@@ -1,2 +0,1 @@ | ||
import { useGetLinearItems } from './useGetLinearItems'; | ||
import { useViewState } from './useViewState'; | ||
@@ -6,10 +5,10 @@ import { useTree } from './Tree'; | ||
import { useCallback } from 'react'; | ||
import { useLinearItems } from '../controlledEnvironment/useLinearItems'; | ||
export var useMoveFocusToIndex = function () { | ||
var treeId = useTree().treeId; | ||
var _a = useTreeEnvironment(), onFocusItem = _a.onFocusItem, items = _a.items; | ||
var getLinearItems = useGetLinearItems(); | ||
var linearItems = useLinearItems(treeId); | ||
var viewState = useViewState(); | ||
return useCallback(function (computeNewIndex) { | ||
var _a; | ||
var linearItems = getLinearItems(); | ||
var currentIndex = (_a = linearItems.findIndex(function (item) { return item.item === viewState.focusedItem; })) !== null && _a !== void 0 ? _a : 0; | ||
@@ -21,3 +20,3 @@ var newIndex = computeNewIndex(currentIndex, linearItems); | ||
return newFocusItem; | ||
}, [onFocusItem, items, getLinearItems, treeId, viewState.focusedItem]); | ||
}, [onFocusItem, items, linearItems, treeId, viewState.focusedItem]); | ||
}; |
@@ -6,15 +6,16 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
}; | ||
import { getItemsLinearly } from './getItemsLinearly'; | ||
import { useViewState } from './useViewState'; | ||
import { useTree } from './Tree'; | ||
import { useTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment'; | ||
import { useCallback } from 'react'; | ||
import { useLinearItems } from '../controlledEnvironment/useLinearItems'; | ||
export var useSelectUpTo = function () { | ||
var viewState = useViewState(); | ||
var _a = useTree(), rootItem = _a.rootItem, treeId = _a.treeId; | ||
var environment = useTreeEnvironment(); | ||
return function (item) { | ||
var _a, _b, _c, _d, _e; | ||
var treeId = useTree().treeId; | ||
var linearItems = useLinearItems(treeId); | ||
var onSelectItems = useTreeEnvironment().onSelectItems; | ||
return useCallback(function (item) { | ||
var _a, _b; | ||
// TODO doesnt work that well if there are spaces between selections | ||
if (viewState && viewState.selectedItems && viewState.selectedItems.length > 0) { | ||
var linearItems = getItemsLinearly(rootItem, viewState, environment.items); | ||
var selectionStart = linearItems.findIndex(function (linearItem) { var _a; return (_a = viewState.selectedItems) === null || _a === void 0 ? void 0 : _a.includes(linearItem.item); }); | ||
@@ -27,3 +28,3 @@ var selectionEnd = linearItems.findIndex(function (linearItem) { return linearItem.item === item.index; }); | ||
}); | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, __spreadArray(__spreadArray([], ((_b = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _b !== void 0 ? _b : [])), selection), treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(__spreadArray(__spreadArray([], ((_a = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _a !== void 0 ? _a : [])), selection), treeId); | ||
} | ||
@@ -35,9 +36,9 @@ else { | ||
}); | ||
(_c = environment.onSelectItems) === null || _c === void 0 ? void 0 : _c.call(environment, __spreadArray(__spreadArray([], ((_d = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _d !== void 0 ? _d : [])), selection), treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(__spreadArray(__spreadArray([], ((_b = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _b !== void 0 ? _b : [])), selection), treeId); | ||
} | ||
} | ||
else { | ||
(_e = environment.onSelectItems) === null || _e === void 0 ? void 0 : _e.call(environment, [item.index], treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems([item.index], treeId); | ||
} | ||
}; | ||
}, [onSelectItems, linearItems, treeId, viewState]); | ||
}; |
@@ -12,6 +12,6 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
import { useTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment'; | ||
import { useGetLinearItems } from './useGetLinearItems'; | ||
import { useDragAndDrop } from '../controlledEnvironment/DragAndDropProvider'; | ||
import { useSelectUpTo } from './useSelectUpTo'; | ||
import { useCallback } from 'react'; | ||
import { useLinearItems } from '../controlledEnvironment/useLinearItems'; | ||
export var useTreeKeyboardBindings = function () { | ||
@@ -21,6 +21,6 @@ var _a; | ||
var _b = useTree(), treeId = _b.treeId, setRenamingItem = _b.setRenamingItem, setSearch = _b.setSearch, renamingItem = _b.renamingItem; | ||
var linearItems = useLinearItems(treeId); | ||
var dnd = useDragAndDrop(); | ||
var viewState = useViewState(); | ||
var moveFocusToIndex = useMoveFocusToIndex(); | ||
var getLinearItems = useGetLinearItems(); | ||
var selectUpTo = useSelectUpTo(); | ||
@@ -98,3 +98,3 @@ var isActiveTree = environment.activeTreeId === treeId; | ||
e.preventDefault(); | ||
if (viewState.focusedItem) { | ||
if (viewState.focusedItem !== undefined) { | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, [viewState.focusedItem], treeId); | ||
@@ -107,3 +107,3 @@ (_b = environment.onPrimaryAction) === null || _b === void 0 ? void 0 : _b.call(environment, environment.items[viewState.focusedItem], treeId); | ||
e.preventDefault(); | ||
if (viewState.focusedItem) { | ||
if (viewState.focusedItem !== undefined) { | ||
if (viewState.selectedItems && viewState.selectedItems.includes(viewState.focusedItem)) { | ||
@@ -120,10 +120,10 @@ (_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, viewState.selectedItems.filter(function (item) { return item !== viewState.focusedItem; }), treeId); | ||
e.preventDefault(); | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, getLinearItems().map(function (_a) { | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, linearItems.map(function (_a) { | ||
var item = _a.item; | ||
return item; | ||
}), treeId); | ||
}, [environment, getLinearItems, treeId]), isActiveTree && !dnd.isProgrammaticallyDragging && !isRenaming); | ||
}, [environment, linearItems, treeId]), isActiveTree && !dnd.isProgrammaticallyDragging && !isRenaming); | ||
useHotkey('renameItem', useCallback(function (e) { | ||
var _a; | ||
if (viewState.focusedItem) { | ||
if (viewState.focusedItem !== undefined) { | ||
e.preventDefault(); | ||
@@ -130,0 +130,0 @@ var item = environment.items[viewState.focusedItem]; |
@@ -15,3 +15,3 @@ import React from 'react'; | ||
var containerProps = { | ||
role: 'group', | ||
role: props.depth !== 0 ? 'group' : undefined, | ||
}; | ||
@@ -18,0 +18,0 @@ return renderers.renderItemsContainer({ |
@@ -6,2 +6,3 @@ import { useTree } from '../tree/Tree'; | ||
import { useSideEffect } from '../useSideEffect'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
export var TreeItemRenamingInput = function (props) { | ||
@@ -14,2 +15,3 @@ var _a = useTree(), renderers = _a.renderers, treeInformation = _a.treeInformation, setRenamingItem = _a.setRenamingItem, treeId = _a.treeId; | ||
var _b = useState(environment.getItemTitle(item)), title = _b[0], setTitle = _b[1]; | ||
var callSoon = useCallSoon(); | ||
var abort = function () { | ||
@@ -19,3 +21,3 @@ var _a; | ||
setRenamingItem(null); | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
environment.setActiveTree(treeId); | ||
@@ -28,3 +30,3 @@ }); | ||
setRenamingItem(null); | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
environment.setActiveTree(treeId); | ||
@@ -31,0 +33,0 @@ }); |
@@ -131,3 +131,3 @@ var __assign = (this && this.__assign) || function () { | ||
}; | ||
var interactiveElementProps = __assign(__assign({}, interactionManager.createInteractiveElementProps(item, treeId, actions, renderFlags)), (_a = {}, | ||
var interactiveElementProps = __assign(__assign({}, interactionManager.createInteractiveElementProps(item, treeId, actions, renderFlags, viewState)), (_a = {}, | ||
_a['data-rct-item-interactive'] = true, | ||
@@ -134,0 +134,0 @@ _a['data-rct-item-focus'] = renderFlags.isFocused ? 'true' : 'false', |
@@ -124,3 +124,5 @@ import React, { FormHTMLAttributes, HTMLProps, InputHTMLAttributes, Ref } from 'react'; | ||
extends?: InteractionMode; | ||
createInteractiveElementProps: (item: TreeItem, treeId: string, actions: TreeItemActions, renderFlags: TreeItemRenderFlags) => HTMLProps<HTMLElement>; | ||
createInteractiveElementProps: (item: TreeItem, treeId: string, actions: TreeItemActions, renderFlags: TreeItemRenderFlags, | ||
/** See https://github.com/lukasbach/react-complex-tree/issues/48 */ | ||
__unsafeViewState?: IndividualTreeViewState) => HTMLProps<HTMLElement>; | ||
} | ||
@@ -210,2 +212,3 @@ export interface TreeCapabilities<T = any> { | ||
trees: Record<string, TreeConfiguration>; | ||
linearItems: Record<string, LinearItem[]>; | ||
} | ||
@@ -315,2 +318,6 @@ export interface DragAndDropContextProps<T = any> { | ||
}; | ||
export interface LinearItem { | ||
item: TreeItemIndex; | ||
depth: number; | ||
} | ||
export interface KeyboardBindings { | ||
@@ -317,0 +324,0 @@ primaryAction?: string[]; |
@@ -54,3 +54,3 @@ var __assign = (this && this.__assign) || function () { | ||
import * as React from 'react'; | ||
import { useEffect, useMemo, useRef, useState } from 'react'; | ||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; | ||
import { ControlledTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment'; | ||
@@ -74,3 +74,3 @@ import { CompleteTreeDataProvider } from './CompleteTreeDataProvider'; | ||
}; }, []); | ||
var amendViewState = function (treeId, constructNewState) { | ||
var amendViewState = useCallback(function (treeId, constructNewState) { | ||
setViewState(function (oldState) { | ||
@@ -81,3 +81,3 @@ var _a; | ||
}); | ||
}; | ||
}, []); | ||
useEffect(function () { | ||
@@ -84,0 +84,0 @@ var dispose = dataProvider.onDidChangeTreeData(function (changedItemIds) { |
@@ -1,16 +0,4 @@ | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
import * as React from 'react'; | ||
import { useCallback, useEffect, useMemo, useState } from 'react'; | ||
import { useCallback, useEffect, useRef, useState } from 'react'; | ||
import { useTreeEnvironment } from './ControlledTreeEnvironment'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
import { useOnDragOverTreeHandler } from './useOnDragOverTreeHandler'; | ||
@@ -20,11 +8,6 @@ import { useCanDropAt } from './useCanDropAt'; | ||
import { useSideEffect } from '../useSideEffect'; | ||
import { buildMapForTrees } from '../utils'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
var DragAndDropContext = React.createContext(null); | ||
export var useDragAndDrop = function () { return React.useContext(DragAndDropContext); }; | ||
var buildMapForTrees = function (treeIds, build) { | ||
return treeIds.map(function (id) { return [id, build(id)]; }).reduce(function (a, _a) { | ||
var _b; | ||
var id = _a[0], obj = _a[1]; | ||
return (__assign(__assign({}, a), (_b = {}, _b[id] = obj, _b))); | ||
}, {}); | ||
}; | ||
// TODO tidy up | ||
@@ -35,17 +18,18 @@ export var DragAndDropProvider = function (props) { | ||
var _b = useState(4), itemHeight = _b[0], setItemHeight = _b[1]; | ||
var _c = useState({}), linearItems = _c[0], setLinearItems = _c[1]; | ||
var _d = useState({}), viableDragPositions = _d[0], setViableDragPositions = _d[1]; | ||
var _e = useState(0), programmaticDragIndex = _e[0], setProgrammaticDragIndex = _e[1]; | ||
var _f = useState(), draggingItems = _f[0], setDraggingItems = _f[1]; | ||
var _g = useState(), draggingPosition = _g[0], setDraggingPosition = _g[1]; | ||
var _h = useState('_nodrag'), dragCode = _h[0], setDragCode = _h[1]; | ||
var _c = useState({}), viableDragPositions = _c[0], setViableDragPositions = _c[1]; | ||
var _d = useState(0), programmaticDragIndex = _d[0], setProgrammaticDragIndex = _d[1]; | ||
var _e = useState(), draggingItems = _e[0], setDraggingItems = _e[1]; | ||
var _f = useState(), draggingPosition = _f[0], setDraggingPosition = _f[1]; | ||
var _g = useState('_nodrag'), dragCode = _g[0], setDragCode = _g[1]; | ||
var getViableDragPositions = useGetViableDragPositions(); | ||
var resetProgrammaticDragIndexForCurrentTree = useCallback(function (viableDragPositions, linearItems, draggingItems) { | ||
var callSoon = useCallSoon(); | ||
var shouldCancelDrag = useRef(false); | ||
var resetProgrammaticDragIndexForCurrentTree = useCallback(function (viableDragPositions, draggingItems) { | ||
var _a; | ||
if (environment.activeTreeId && | ||
((_a = environment.viewState[environment.activeTreeId]) === null || _a === void 0 ? void 0 : _a.focusedItem) && | ||
linearItems && | ||
environment.linearItems && | ||
draggingItems) { | ||
var focusItem_1 = environment.viewState[environment.activeTreeId].focusedItem; | ||
var treeDragPositions = getViableDragPositions(environment.activeTreeId, draggingItems, linearItems); | ||
var treeDragPositions = getViableDragPositions(environment.activeTreeId, draggingItems); | ||
var newPos = treeDragPositions.findIndex(function (pos) { | ||
@@ -69,7 +53,12 @@ if (pos.targetType === 'item') { | ||
} | ||
}, [environment.activeTreeId, environment.items, environment.viewState, getViableDragPositions]); | ||
}, [ | ||
environment.activeTreeId, | ||
environment.items, | ||
environment.linearItems, | ||
environment.viewState, | ||
getViableDragPositions, | ||
]); | ||
var resetState = useCallback(function () { | ||
setIsProgrammaticallyDragging(false); | ||
setItemHeight(4); | ||
setLinearItems({}); | ||
setViableDragPositions({}); | ||
@@ -83,5 +72,5 @@ setProgrammaticDragIndex(0); | ||
if (environment.activeTreeId && | ||
linearItems[environment.activeTreeId] && | ||
environment.linearItems[environment.activeTreeId] && | ||
viableDragPositions[environment.activeTreeId]) { | ||
resetProgrammaticDragIndexForCurrentTree(viableDragPositions[environment.activeTreeId], linearItems[environment.activeTreeId], draggingItems); | ||
resetProgrammaticDragIndexForCurrentTree(viableDragPositions[environment.activeTreeId], draggingItems); | ||
} | ||
@@ -91,3 +80,3 @@ }, [ | ||
environment.activeTreeId, | ||
linearItems, | ||
environment.linearItems, | ||
resetProgrammaticDragIndexForCurrentTree, | ||
@@ -114,7 +103,7 @@ viableDragPositions, | ||
}; | ||
var onDragOverTreeHandler = useOnDragOverTreeHandler(dragCode, setDragCode, itemHeight, linearItems, setDraggingPosition, performDrag); | ||
var onDropHandler = useMemo(function () { return function () { | ||
var onDragOverTreeHandler = useOnDragOverTreeHandler(dragCode, setDragCode, itemHeight, setDraggingPosition, performDrag); | ||
var onDropHandler = useCallback(function () { | ||
if (draggingItems && draggingPosition && environment.onDrop) { | ||
environment.onDrop(draggingItems, draggingPosition); | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
var _a; | ||
@@ -125,8 +114,7 @@ (_a = environment.onFocusItem) === null || _a === void 0 ? void 0 : _a.call(environment, draggingItems[0], draggingPosition.treeId); | ||
} | ||
}; }, [draggingItems, draggingPosition, environment, resetState]); | ||
}, [draggingItems, draggingPosition, environment, resetState, callSoon]); | ||
var onStartDraggingItems = useCallback(function (items, treeId) { | ||
var _a, _b; | ||
var treeLinearItems = buildMapForTrees(environment.treeIds, function (treeId) { var _a; return getItemsLinearly(environment.trees[treeId].rootItem, (_a = environment.viewState[treeId]) !== null && _a !== void 0 ? _a : {}, environment.items); }); | ||
var treeViableDragPositions = buildMapForTrees(environment.treeIds, function (treeId) { | ||
return getViableDragPositions(treeId, items, treeLinearItems[treeId]); | ||
return getViableDragPositions(treeId, items); | ||
}); | ||
@@ -137,16 +125,7 @@ // TODO what if trees have different heights and drag target changes? | ||
setDraggingItems(items); | ||
setLinearItems(treeLinearItems); | ||
setViableDragPositions(treeViableDragPositions); | ||
if (environment.activeTreeId) { | ||
resetProgrammaticDragIndexForCurrentTree(treeViableDragPositions[environment.activeTreeId], treeLinearItems[environment.activeTreeId], items); | ||
resetProgrammaticDragIndexForCurrentTree(treeViableDragPositions[environment.activeTreeId], items); | ||
} | ||
}, [ | ||
environment.activeTreeId, | ||
environment.items, | ||
environment.treeIds, | ||
environment.trees, | ||
environment.viewState, | ||
getViableDragPositions, | ||
resetProgrammaticDragIndexForCurrentTree, | ||
]); | ||
}, [environment.activeTreeId, environment.treeIds, getViableDragPositions, resetProgrammaticDragIndexForCurrentTree]); | ||
var startProgrammaticDrag = useCallback(function () { | ||
@@ -205,6 +184,10 @@ var _a, _b, _c; | ||
useEffect(function () { | ||
window.addEventListener('dragend', onDropHandler); | ||
return function () { return window.removeEventListener('dragend', onDropHandler); }; | ||
}, [onDropHandler]); | ||
window.addEventListener('dragend', resetState); | ||
window.addEventListener('drop', onDropHandler); | ||
return function () { | ||
window.removeEventListener('dragend', resetState); | ||
window.removeEventListener('drop', onDropHandler); | ||
}; | ||
}, [onDropHandler, resetState]); | ||
return React.createElement(DragAndDropContext.Provider, { value: dnd }, props.children); | ||
}; |
import { useTreeEnvironment } from './ControlledTreeEnvironment'; | ||
import { useCallback } from 'react'; | ||
export var useCanDropAt = function () { | ||
var environment = useTreeEnvironment(); | ||
return function (draggingPosition, draggingItems) { | ||
return useCallback(function (draggingPosition, draggingItems) { | ||
if (draggingPosition.targetType === 'between-items') { | ||
@@ -22,3 +23,3 @@ if (!environment.canReorderItems) { | ||
return true; | ||
}; | ||
}, [environment]); | ||
}; |
@@ -14,17 +14,29 @@ var __assign = (this && this.__assign) || function () { | ||
import { useCallback, useMemo, useState } from 'react'; | ||
import { useMemoizedObject } from '../useMemoizedObject'; | ||
import { useRenderers } from '../renderers/useRenderers'; | ||
import { buildMapForTrees } from '../utils'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
import { useRefCopy } from '../useRefCopy'; | ||
import { useUpdateLinearItems } from './useUpdateLinearItems'; | ||
export var useControlledTreeEnvironmentProps = function (props) { | ||
var _a = useState({}), trees = _a[0], setTrees = _a[1]; | ||
var _b = useState(), activeTreeId = _b[0], setActiveTreeId = _b[1]; | ||
var memoizedProps = useMemoizedObject(props); | ||
var onFocusItem = memoizedProps.onFocusItem, autoFocus = memoizedProps.autoFocus, onRegisterTree = memoizedProps.onRegisterTree, onUnregisterTree = memoizedProps.onUnregisterTree; | ||
var _b = useState({}), linearItems = _b[0], setLinearItems = _b[1]; | ||
var _c = useState(), activeTreeId = _c[0], setActiveTreeId = _c[1]; | ||
var viewStateRef = useRefCopy(props.viewState); | ||
var treeIds = useMemo(function () { return Object.keys(trees); }, [trees]); | ||
var onFocusItem = props.onFocusItem, autoFocus = props.autoFocus, onRegisterTree = props.onRegisterTree, onUnregisterTree = props.onUnregisterTree, items = props.items; | ||
var onFocusItemRef = useRefCopy(onFocusItem); | ||
var newChangeHandlers = useUpdateLinearItems(useCallback(function () { | ||
setLinearItems(buildMapForTrees(treeIds, function (treeId) { var _a; return getItemsLinearly(trees[treeId].rootItem, (_a = viewStateRef.current[treeId]) !== null && _a !== void 0 ? _a : {}, items); })); | ||
}, [items, treeIds, trees, viewStateRef]), props, items); | ||
var onFocusItemHandler = useCallback(function (item, treeId) { | ||
var _a, _b, _c, _d; | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(item, treeId); | ||
var _a, _b, _c, _d, _e, _f; | ||
if (((_a = viewStateRef.current[treeId]) === null || _a === void 0 ? void 0 : _a.focusedItem) === item.index) { | ||
return; | ||
} | ||
(_b = onFocusItemRef.current) === null || _b === void 0 ? void 0 : _b.call(onFocusItemRef, item, treeId); | ||
var newItem = document.querySelector("[data-rct-tree=\"" + treeId + "\"] [data-rct-item-id=\"" + item.index + "\"]"); | ||
if (autoFocus !== null && autoFocus !== void 0 ? autoFocus : true) { | ||
if (((_b = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.attributes.getNamedItem('data-rct-search-input')) === null || _b === void 0 ? void 0 : _b.value) !== 'true') { | ||
if (((_d = (_c = document.activeElement) === null || _c === void 0 ? void 0 : _c.attributes.getNamedItem('data-rct-search-input')) === null || _d === void 0 ? void 0 : _d.value) !== 'true') { | ||
// Move DOM focus to item if the current focus is not on the search input | ||
(_d = (_c = newItem) === null || _c === void 0 ? void 0 : _c.focus) === null || _d === void 0 ? void 0 : _d.call(_c); | ||
(_f = (_e = newItem) === null || _e === void 0 ? void 0 : _e.focus) === null || _f === void 0 ? void 0 : _f.call(_e); | ||
} | ||
@@ -36,3 +48,3 @@ else { | ||
} | ||
}, [autoFocus, onFocusItem]); | ||
}, [autoFocus, onFocusItemRef, viewStateRef]); | ||
var registerTree = useCallback(function (tree) { | ||
@@ -77,5 +89,4 @@ setTrees(function (trees) { | ||
}, [autoFocus]); | ||
var treeIds = useMemo(function () { return Object.keys(trees); }, [trees]); | ||
var renderers = useRenderers(memoizedProps); | ||
return __assign(__assign(__assign({}, renderers), memoizedProps), { onFocusItem: onFocusItemHandler, registerTree: registerTree, | ||
var renderers = useRenderers(props); | ||
return __assign(__assign(__assign(__assign({}, renderers), props), newChangeHandlers), { onFocusItem: onFocusItemHandler, registerTree: registerTree, | ||
unregisterTree: unregisterTree, | ||
@@ -85,3 +96,4 @@ setActiveTree: setActiveTree, | ||
trees: trees, | ||
activeTreeId: activeTreeId }); | ||
activeTreeId: activeTreeId, | ||
linearItems: linearItems }); | ||
}; |
@@ -1,5 +0,1 @@ | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
export declare const useGetGetParentOfLinearItem: () => (linearItems: ReturnType<typeof getItemsLinearly>, itemLinearIndex: number, treeId: string) => { | ||
item: import("..").TreeItemIndex; | ||
depth: number; | ||
}; | ||
export declare const useGetGetParentOfLinearItem: () => (itemLinearIndex: number, treeId: string) => import("..").LinearItem; |
import { useTreeEnvironment } from './ControlledTreeEnvironment'; | ||
import { useCallback } from 'react'; | ||
export var useGetGetParentOfLinearItem = function () { | ||
var environment = useTreeEnvironment(); | ||
return function (linearItems, itemLinearIndex, treeId) { | ||
return useCallback(function (itemLinearIndex, treeId) { | ||
var linearItems = environment.linearItems[treeId]; | ||
var depth = linearItems[itemLinearIndex].depth; | ||
@@ -15,3 +17,3 @@ var parentLinearIndex = itemLinearIndex; | ||
return parent; | ||
}; | ||
}, [environment.linearItems, environment.trees]); | ||
}; |
import { DraggingPosition, TreeItem } from '../types'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
export declare const useGetViableDragPositions: () => (treeId: string, draggingItems: TreeItem[], linearItems: ReturnType<typeof getItemsLinearly>) => DraggingPosition[]; | ||
export declare const useGetViableDragPositions: () => (treeId: string, draggingItems: TreeItem[]) => DraggingPosition[]; |
@@ -9,2 +9,3 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
import { useCanDropAt } from './useCanDropAt'; | ||
import { useCallback } from 'react'; | ||
export var useGetViableDragPositions = function () { | ||
@@ -14,3 +15,4 @@ var environment = useTreeEnvironment(); | ||
var canDropAt = useCanDropAt(); | ||
return function (treeId, draggingItems, linearItems) { | ||
return useCallback(function (treeId, draggingItems) { | ||
var linearItems = environment.linearItems[treeId]; | ||
return linearItems | ||
@@ -20,3 +22,3 @@ .map(function (_a, linearIndex) { | ||
var item = _a.item, depth = _a.depth; | ||
var parent = getParentOfLinearItem(linearItems, linearIndex, treeId); | ||
var parent = getParentOfLinearItem(linearIndex, treeId); | ||
var childIndex = environment.items[parent.item].children.indexOf(item); | ||
@@ -59,3 +61,3 @@ var itemPosition = { | ||
.filter(function (position) { return canDropAt(position, draggingItems); }); | ||
}; | ||
}, [canDropAt, environment.items, environment.linearItems, getParentOfLinearItem]); | ||
}; |
import * as React from 'react'; | ||
import { DraggingPosition } from '../types'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
export declare const useOnDragOverTreeHandler: (lastDragCode: string, setLastDragCode: (code: string) => void, itemHeight: number, linearItems: { | ||
[treeId: string]: { | ||
item: import("../types").TreeItemIndex; | ||
depth: number; | ||
}[]; | ||
}, onDragAtPosition: (draggingPosition: DraggingPosition | undefined) => void, onPerformDrag: (draggingPosition: DraggingPosition) => void) => (e: DragEvent, treeId: string, containerRef: React.MutableRefObject<HTMLElement | undefined>) => void; | ||
export declare const useOnDragOverTreeHandler: (lastDragCode: string, setLastDragCode: (code: string) => void, itemHeight: number, onDragAtPosition: (draggingPosition: DraggingPosition | undefined) => void, onPerformDrag: (draggingPosition: DraggingPosition) => void) => (e: DragEvent, treeId: string, containerRef: React.MutableRefObject<HTMLElement | undefined>) => void; |
import { useTreeEnvironment } from './ControlledTreeEnvironment'; | ||
import { useGetGetParentOfLinearItem } from './useGetParentOfLinearItem'; | ||
import { useCallback } from 'react'; | ||
var isOutsideOfContainer = function (e, treeBb) { | ||
return e.clientX < treeBb.left || e.clientX > treeBb.right || e.clientY < treeBb.top || e.clientY > treeBb.bottom; | ||
}; | ||
var getHoveringPosition = function (clientY, treeTop, itemHeight, capabilities) { | ||
var getHoveringPosition = function (clientY, treeTop, itemHeight, canDropOnItemWithChildren, canDropOnItemWithoutChildren) { | ||
var hoveringPosition = (clientY - treeTop) / itemHeight; | ||
var linearIndex = Math.floor(hoveringPosition); | ||
var offset = undefined; | ||
var lineThreshold = capabilities.canDropOnItemWithChildren || capabilities.canDropOnItemWithoutChildren ? 0.2 : 0.5; | ||
var lineThreshold = canDropOnItemWithChildren || canDropOnItemWithoutChildren ? 0.2 : 0.5; | ||
if (hoveringPosition % 1 < lineThreshold) { | ||
@@ -19,8 +20,8 @@ offset = 'top'; | ||
}; | ||
export var useOnDragOverTreeHandler = function (lastDragCode, setLastDragCode, itemHeight, linearItems, onDragAtPosition, onPerformDrag) { | ||
var environment = useTreeEnvironment(); | ||
export var useOnDragOverTreeHandler = function (lastDragCode, setLastDragCode, itemHeight, onDragAtPosition, onPerformDrag) { | ||
var _a = useTreeEnvironment(), canDropOnItemWithChildren = _a.canDropOnItemWithChildren, canDropOnItemWithoutChildren = _a.canDropOnItemWithoutChildren, canDragAndDrop = _a.canDragAndDrop, linearItems = _a.linearItems, items = _a.items, canReorderItems = _a.canReorderItems, viewState = _a.viewState; | ||
var getParentOfLinearItem = useGetGetParentOfLinearItem(); | ||
return function (e, treeId, containerRef) { | ||
return useCallback(function (e, treeId, containerRef) { | ||
var _a, _b, _c, _d; | ||
if (!environment.canDragAndDrop) { | ||
if (!canDragAndDrop) { | ||
return; | ||
@@ -36,3 +37,3 @@ } | ||
var outsideContainer = isOutsideOfContainer(e, treeBb); | ||
var _e = getHoveringPosition(e.clientY, treeBb.top, itemHeight, environment), linearIndex = _e.linearIndex, offset = _e.offset; | ||
var _e = getHoveringPosition(e.clientY, treeBb.top, itemHeight, canDropOnItemWithChildren, canDropOnItemWithoutChildren), linearIndex = _e.linearIndex, offset = _e.offset; | ||
var nextDragCode = outsideContainer ? 'outside' : "" + treeId + linearIndex + (offset !== null && offset !== void 0 ? offset : ''); | ||
@@ -53,20 +54,20 @@ if (lastDragCode === nextDragCode) { | ||
var depth = targetItem.depth; | ||
var targetItemData = environment.items[targetItem.item]; | ||
if (!offset && !environment.canDropOnItemWithoutChildren && !targetItemData.hasChildren) { | ||
var targetItemData = items[targetItem.item]; | ||
if (!offset && !canDropOnItemWithoutChildren && !targetItemData.hasChildren) { | ||
onDragAtPosition(undefined); | ||
return; | ||
} | ||
if (!offset && !environment.canDropOnItemWithChildren && targetItemData.hasChildren) { | ||
if (!offset && !canDropOnItemWithChildren && targetItemData.hasChildren) { | ||
onDragAtPosition(undefined); | ||
return; | ||
} | ||
if (offset && !environment.canReorderItems) { | ||
if (offset && !canReorderItems) { | ||
onDragAtPosition(undefined); | ||
return; | ||
} | ||
var parent = getParentOfLinearItem(linearItems[treeId], linearIndex, treeId); | ||
if ((_b = (_a = environment.viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(targetItem.item)) { | ||
var parent = getParentOfLinearItem(linearIndex, treeId); | ||
if ((_b = (_a = viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(targetItem.item)) { | ||
return; | ||
} | ||
var newChildIndex = environment.items[parent.item].children.indexOf(targetItem.item) + (offset === 'top' ? 0 : 1); | ||
var newChildIndex = items[parent.item].children.indexOf(targetItem.item) + (offset === 'top' ? 0 : 1); | ||
if (offset === 'top' && depth === ((_d = (_c = linearItems[treeId][linearIndex - 1]) === null || _c === void 0 ? void 0 : _c.depth) !== null && _d !== void 0 ? _d : -1)) { | ||
@@ -101,3 +102,17 @@ offset = 'bottom'; | ||
onPerformDrag(draggingPosition); | ||
}; | ||
}, [ | ||
canDragAndDrop, | ||
canDropOnItemWithChildren, | ||
canDropOnItemWithoutChildren, | ||
canReorderItems, | ||
getParentOfLinearItem, | ||
itemHeight, | ||
items, | ||
lastDragCode, | ||
linearItems, | ||
onDragAtPosition, | ||
onPerformDrag, | ||
setLastDragCode, | ||
viewState, | ||
]); | ||
}; |
@@ -7,5 +7,5 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
import * as React from 'react'; | ||
import { useCallback } from 'react'; | ||
import { useDragAndDrop } from '../controlledEnvironment/DragAndDropProvider'; | ||
import { useTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment'; | ||
import { getItemsLinearly } from '../tree/getItemsLinearly'; | ||
import { useCreatedEnvironmentRef } from './useCreatedEnvironmentRef'; | ||
@@ -15,93 +15,83 @@ var EnvironmentActionsContext = React.createContext(null); | ||
export var EnvironmentActionsProvider = React.forwardRef(function (props, ref) { | ||
var environment = useTreeEnvironment(); | ||
var dnd = useDragAndDrop(); | ||
var _a = useTreeEnvironment(), onCollapseItem = _a.onCollapseItem, items = _a.items, trees = _a.trees, viewState = _a.viewState, onExpandItem = _a.onExpandItem, onFocusItem = _a.onFocusItem, setActiveTree = _a.setActiveTree, onRenameItem = _a.onRenameItem, onSelectItems = _a.onSelectItems, onPrimaryAction = _a.onPrimaryAction, linearItems = _a.linearItems; | ||
var _b = useDragAndDrop(), abortProgrammaticDrag = _b.abortProgrammaticDrag, completeProgrammaticDrag = _b.completeProgrammaticDrag, programmaticDragDown = _b.programmaticDragDown, programmaticDragUp = _b.programmaticDragUp, startProgrammaticDrag = _b.startProgrammaticDrag; | ||
// TODO change environment childs to use actions rather than output events where possible | ||
var actions = { | ||
abortProgrammaticDrag: function () { | ||
dnd.abortProgrammaticDrag(); | ||
}, | ||
collapseItem: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onCollapseItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
completeProgrammaticDrag: function () { | ||
dnd.completeProgrammaticDrag(); | ||
}, | ||
expandItem: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onExpandItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
focusItem: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onFocusItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
focusTree: function (treeId, autoFocus) { | ||
abortProgrammaticDrag: useCallback(function () { | ||
abortProgrammaticDrag(); | ||
}, [abortProgrammaticDrag]), | ||
collapseItem: useCallback(function (itemId, treeId) { | ||
onCollapseItem === null || onCollapseItem === void 0 ? void 0 : onCollapseItem(items[itemId], treeId); | ||
}, [items, onCollapseItem]), | ||
completeProgrammaticDrag: useCallback(function () { | ||
completeProgrammaticDrag(); | ||
}, [completeProgrammaticDrag]), | ||
expandItem: useCallback(function (itemId, treeId) { | ||
onExpandItem === null || onExpandItem === void 0 ? void 0 : onExpandItem(items[itemId], treeId); | ||
}, [items, onExpandItem]), | ||
focusItem: useCallback(function (itemId, treeId) { | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(items[itemId], treeId); | ||
}, [items, onFocusItem]), | ||
focusTree: useCallback(function (treeId, autoFocus) { | ||
if (autoFocus === void 0) { autoFocus = true; } | ||
environment.setActiveTree(treeId, autoFocus); | ||
}, | ||
moveFocusDown: function (treeId) { | ||
var _a, _b; | ||
var tree = environment.trees[treeId]; | ||
var linearItems = getItemsLinearly(tree.rootItem, (_a = environment.viewState[treeId]) !== null && _a !== void 0 ? _a : {}, environment.items); | ||
var currentFocusIndex = linearItems.findIndex(function (_a) { | ||
setActiveTree(treeId, autoFocus); | ||
}, [setActiveTree]), | ||
moveFocusDown: useCallback(function (treeId) { | ||
var treeLinearItems = linearItems[treeId]; | ||
var currentFocusIndex = treeLinearItems.findIndex(function (_a) { | ||
var _b; | ||
var item = _a.item; | ||
return item === ((_b = environment.viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
return item === ((_b = viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
}); | ||
var newIndex = currentFocusIndex !== undefined ? Math.min(linearItems.length - 1, currentFocusIndex + 1) : 0; | ||
var newItem = environment.items[linearItems[newIndex].item]; | ||
(_b = environment.onFocusItem) === null || _b === void 0 ? void 0 : _b.call(environment, newItem, treeId); | ||
}, | ||
moveFocusUp: function (treeId) { | ||
var _a, _b; | ||
var tree = environment.trees[treeId]; | ||
var linearItems = getItemsLinearly(tree.rootItem, (_a = environment.viewState[treeId]) !== null && _a !== void 0 ? _a : {}, environment.items); | ||
var currentFocusIndex = linearItems.findIndex(function (_a) { | ||
var newIndex = currentFocusIndex !== undefined ? Math.min(treeLinearItems.length - 1, currentFocusIndex + 1) : 0; | ||
var newItem = items[treeLinearItems[newIndex].item]; | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(newItem, treeId); | ||
}, [items, linearItems, onFocusItem, viewState]), | ||
moveFocusUp: useCallback(function (treeId) { | ||
var treeLinearItems = linearItems[treeId]; | ||
var currentFocusIndex = treeLinearItems.findIndex(function (_a) { | ||
var _b; | ||
var item = _a.item; | ||
return item === ((_b = environment.viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
return item === ((_b = viewState[treeId]) === null || _b === void 0 ? void 0 : _b.focusedItem); | ||
}); | ||
var newIndex = currentFocusIndex !== undefined ? Math.max(0, currentFocusIndex - 1) : 0; | ||
var newItem = environment.items[linearItems[newIndex].item]; | ||
(_b = environment.onFocusItem) === null || _b === void 0 ? void 0 : _b.call(environment, newItem, treeId); | ||
}, | ||
moveProgrammaticDragPositionDown: function () { | ||
dnd.programmaticDragDown(); | ||
}, | ||
moveProgrammaticDragPositionUp: function () { | ||
dnd.programmaticDragUp(); | ||
}, | ||
renameItem: function (itemId, name, treeId) { | ||
var _a; | ||
(_a = environment.onRenameItem) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], name, treeId); | ||
}, | ||
selectItems: function (itemsIds, treeId) { | ||
var _a; | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, itemsIds, treeId); | ||
}, | ||
startProgrammaticDrag: function () { | ||
dnd.startProgrammaticDrag(); | ||
}, | ||
toggleItemExpandedState: function (itemId, treeId) { | ||
var _a, _b, _c, _d; | ||
if ((_b = (_a = environment.viewState[treeId]) === null || _a === void 0 ? void 0 : _a.expandedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
(_c = environment.onCollapseItem) === null || _c === void 0 ? void 0 : _c.call(environment, environment.items[itemId], treeId); | ||
var newItem = items[treeLinearItems[newIndex].item]; | ||
onFocusItem === null || onFocusItem === void 0 ? void 0 : onFocusItem(newItem, treeId); | ||
}, [items, linearItems, onFocusItem, viewState]), | ||
moveProgrammaticDragPositionDown: useCallback(function () { | ||
programmaticDragDown(); | ||
}, [programmaticDragDown]), | ||
moveProgrammaticDragPositionUp: useCallback(function () { | ||
programmaticDragUp(); | ||
}, [programmaticDragUp]), | ||
renameItem: useCallback(function (itemId, name, treeId) { | ||
onRenameItem === null || onRenameItem === void 0 ? void 0 : onRenameItem(items[itemId], name, treeId); | ||
}, [items, onRenameItem]), | ||
selectItems: useCallback(function (itemsIds, treeId) { | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(itemsIds, treeId); | ||
}, [onSelectItems]), | ||
startProgrammaticDrag: useCallback(function () { | ||
startProgrammaticDrag(); | ||
}, [startProgrammaticDrag]), | ||
toggleItemExpandedState: useCallback(function (itemId, treeId) { | ||
var _a, _b; | ||
if ((_b = (_a = viewState[treeId]) === null || _a === void 0 ? void 0 : _a.expandedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
onCollapseItem === null || onCollapseItem === void 0 ? void 0 : onCollapseItem(items[itemId], treeId); | ||
} | ||
else { | ||
(_d = environment.onExpandItem) === null || _d === void 0 ? void 0 : _d.call(environment, environment.items[itemId], treeId); | ||
onExpandItem === null || onExpandItem === void 0 ? void 0 : onExpandItem(items[itemId], treeId); | ||
} | ||
}, | ||
toggleItemSelectStatus: function (itemId, treeId) { | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
if ((_b = (_a = environment.viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
(_c = environment.onSelectItems) === null || _c === void 0 ? void 0 : _c.call(environment, (_e = (_d = environment.viewState[treeId].selectedItems) === null || _d === void 0 ? void 0 : _d.filter(function (item) { return item !== itemId; })) !== null && _e !== void 0 ? _e : [], treeId); | ||
}, [items, onCollapseItem, onExpandItem, viewState]), | ||
toggleItemSelectStatus: useCallback(function (itemId, treeId) { | ||
var _a, _b, _c, _d, _e; | ||
if ((_b = (_a = viewState[treeId]) === null || _a === void 0 ? void 0 : _a.selectedItems) === null || _b === void 0 ? void 0 : _b.includes(itemId)) { | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems((_d = (_c = viewState[treeId].selectedItems) === null || _c === void 0 ? void 0 : _c.filter(function (item) { return item !== itemId; })) !== null && _d !== void 0 ? _d : [], treeId); | ||
} | ||
else { | ||
(_f = environment.onSelectItems) === null || _f === void 0 ? void 0 : _f.call(environment, __spreadArray(__spreadArray([], ((_g = environment.viewState[treeId].selectedItems) !== null && _g !== void 0 ? _g : [])), [itemId]), treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(__spreadArray(__spreadArray([], ((_e = viewState[treeId].selectedItems) !== null && _e !== void 0 ? _e : [])), [itemId]), treeId); | ||
} | ||
}, | ||
invokePrimaryAction: function (itemId, treeId) { | ||
var _a; | ||
(_a = environment.onPrimaryAction) === null || _a === void 0 ? void 0 : _a.call(environment, environment.items[itemId], treeId); | ||
}, | ||
}, [onSelectItems, viewState]), | ||
invokePrimaryAction: useCallback(function (itemId, treeId) { | ||
onPrimaryAction === null || onPrimaryAction === void 0 ? void 0 : onPrimaryAction(items[itemId], treeId); | ||
}, [items, onPrimaryAction]), | ||
}; | ||
@@ -108,0 +98,0 @@ useCreatedEnvironmentRef(ref, actions); |
@@ -9,2 +9,3 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
import { useKeyboardBindings } from './useKeyboardBindings'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
var elementsThatCanTakeText = ['input', 'textarea']; | ||
@@ -15,2 +16,3 @@ export var useHotkey = function (combinationName, onHit, active, activatableWhileFocusingInput, deps) { | ||
var keyboardBindings = useKeyboardBindings(); | ||
var callSoon = useCallSoon(); | ||
var possibleCombinations = useMemo(function () { return keyboardBindings[combinationName].map(function (combination) { return combination.split('+'); }); }, [combinationName, keyboardBindings]); | ||
@@ -54,6 +56,6 @@ useHtmlElementEventListener(document, 'keydown', function (e) { | ||
if (match) { | ||
requestAnimationFrame(function () { return onHit(e); }); | ||
callSoon(function () { return onHit(e); }); | ||
} | ||
pressedKeys.current = pressedKeys.current.filter(function (key) { return key !== e.key; }); | ||
}, __spreadArray([possibleCombinations, onHit, active], (deps !== null && deps !== void 0 ? deps : []))); | ||
}, __spreadArray([possibleCombinations, onHit, active, callSoon], (deps !== null && deps !== void 0 ? deps : []))); | ||
}; |
@@ -18,2 +18,3 @@ var __assign = (this && this.__assign) || function () { | ||
import { useViewState } from '../tree/useViewState'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
export var SearchInput = function (props) { | ||
@@ -26,2 +27,3 @@ var _a; | ||
var isActiveTree = environment.activeTreeId === treeId; | ||
var callSoon = useCallSoon(); | ||
useSearchMatchFocus(); | ||
@@ -39,9 +41,9 @@ var clearSearch = function () { | ||
useHotkey('abortSearch', function () { | ||
// Without the requestAnimationFrame, hitting enter to abort | ||
// Without the callSoon, hitting enter to abort | ||
// and then moving focus weirdly moves the selected item along | ||
// with the focused item. | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
clearSearch(); | ||
}); | ||
}, isActiveTree && search !== null, true, [search, isActiveTree]); | ||
}, isActiveTree && search !== null, true, [search, isActiveTree, callSoon]); | ||
useHtmlElementEventListener(props.containerRef, 'keydown', function (e) { | ||
@@ -48,0 +50,0 @@ var _a, _b, _c, _d; |
import { useTree } from '../tree/Tree'; | ||
import { useGetLinearItems } from '../tree/useGetLinearItems'; | ||
import { useTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment'; | ||
import { defaultMatcher } from './defaultMatcher'; | ||
import { useSideEffect } from '../useSideEffect'; | ||
import { useLinearItems } from '../controlledEnvironment/useLinearItems'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
export var useSearchMatchFocus = function () { | ||
var _a = useTreeEnvironment(), doesSearchMatchItem = _a.doesSearchMatchItem, items = _a.items, getItemTitle = _a.getItemTitle, onFocusItem = _a.onFocusItem; | ||
var _b = useTree(), search = _b.search, treeId = _b.treeId; | ||
var getLinearItems = useGetLinearItems(); | ||
var linearItems = useLinearItems(treeId); | ||
var callSoon = useCallSoon(); | ||
useSideEffect(function () { | ||
if (search && search.length > 0) { | ||
requestAnimationFrame(function () { | ||
var focusItem = getLinearItems().find(function (_a) { | ||
callSoon(function () { | ||
var focusItem = linearItems.find(function (_a) { | ||
var item = _a.item; | ||
@@ -22,3 +24,3 @@ return (doesSearchMatchItem !== null && doesSearchMatchItem !== void 0 ? doesSearchMatchItem : defaultMatcher)(search, items[item], getItemTitle(items[item])); | ||
} | ||
}, [doesSearchMatchItem, getItemTitle, getLinearItems, items, onFocusItem, search, treeId], [search]); | ||
}, [doesSearchMatchItem, getItemTitle, linearItems, items, onFocusItem, search, treeId, callSoon], [search]); | ||
}; |
export var defaultLiveDescriptors = { | ||
introduction: "\n <p>Accessibility guide for tree {treeLabel}.</p>\n <p>\n Navigate the tree with the arrow keys. Common tree hotkeys apply. Further keybindings are available:\n </p>\n <ul>\n <li>{keybinding:primaryAction} to execute primary action on focused item</li>\n <li>{keybinding:renameItem} to start renaming the focused item</li>\n <li>{keybinding:abortRenameItem} to abort renaming an item</li>\n <li>{keybinding:startProgrammaticDnd} to start dragging selected items</li>\n </ul>\n <p>\n More details on keybindings are available <a href=\"https://rct.lukasbach.com/docs/guides/keyboard#default-bindings\" target=\"_blank\">here</a>.\n </p>\n ", | ||
introduction: "\n <p>Accessibility guide for tree {treeLabel}.</p>\n <p>\n Navigate the tree with the arrow keys. Common tree hotkeys apply. Further keybindings are available:\n </p>\n <ul>\n <li>{keybinding:primaryAction} to execute primary action on focused item</li>\n <li>{keybinding:renameItem} to start renaming the focused item</li>\n <li>{keybinding:abortRenameItem} to abort renaming an item</li>\n <li>{keybinding:startProgrammaticDnd} to start dragging selected items</li>\n </ul>\n ", | ||
renamingItem: "\n <p>Renaming the item {renamingItem}.</p>\n <p>Use the keybinding {keybinding:abortRenameItem} to abort renaming.</p>\n ", | ||
@@ -4,0 +4,0 @@ searching: "\n <p>Searching</p>\n ", |
@@ -1,5 +0,2 @@ | ||
import { IndividualTreeViewState, TreeItem, TreeItemIndex } from '../types'; | ||
export declare const getItemsLinearly: <T>(rootItem: TreeItemIndex, viewState: IndividualTreeViewState, items: Record<TreeItemIndex, TreeItem<T>>, depth?: number) => { | ||
item: TreeItemIndex; | ||
depth: number; | ||
}[]; | ||
import { IndividualTreeViewState, LinearItem, TreeItem, TreeItemIndex } from '../types'; | ||
export declare const getItemsLinearly: <T>(rootItem: TreeItemIndex, viewState: IndividualTreeViewState, items: Record<TreeItemIndex, TreeItem<T>>, depth?: number) => LinearItem[]; |
@@ -8,2 +8,3 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
import { useRef, useState } from 'react'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
export var useFocusWithin = function (element, onFocusIn, onFocusOut, deps) { | ||
@@ -13,2 +14,3 @@ if (deps === void 0) { deps = []; } | ||
var isLoosingFocusFlag = useRef(false); | ||
var callSoon = useCallSoon(); | ||
useHtmlElementEventListener(element, 'focusin', function () { | ||
@@ -25,3 +27,3 @@ if (!focusWithin) { | ||
isLoosingFocusFlag.current = true; | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
if (isLoosingFocusFlag.current && !(element === null || element === void 0 ? void 0 : element.contains(document.activeElement))) { | ||
@@ -33,4 +35,4 @@ onFocusOut === null || onFocusOut === void 0 ? void 0 : onFocusOut(); | ||
}); | ||
}, __spreadArray([element, onFocusOut], deps)); | ||
}, __spreadArray([element, onFocusOut, callSoon], deps)); | ||
return focusWithin; | ||
}; |
@@ -1,2 +0,2 @@ | ||
import type { getItemsLinearly } from './getItemsLinearly'; | ||
export declare const useMoveFocusToIndex: () => (computeNewIndex: (currentIndex: number, linearItems: ReturnType<typeof getItemsLinearly>) => number) => import("..").TreeItem<any>; | ||
import { LinearItem } from '../types'; | ||
export declare const useMoveFocusToIndex: () => (computeNewIndex: (currentIndex: number, linearItems: LinearItem[]) => number) => import("../types").TreeItem<any>; |
@@ -1,2 +0,1 @@ | ||
import { useGetLinearItems } from './useGetLinearItems'; | ||
import { useViewState } from './useViewState'; | ||
@@ -6,10 +5,10 @@ import { useTree } from './Tree'; | ||
import { useCallback } from 'react'; | ||
import { useLinearItems } from '../controlledEnvironment/useLinearItems'; | ||
export var useMoveFocusToIndex = function () { | ||
var treeId = useTree().treeId; | ||
var _a = useTreeEnvironment(), onFocusItem = _a.onFocusItem, items = _a.items; | ||
var getLinearItems = useGetLinearItems(); | ||
var linearItems = useLinearItems(treeId); | ||
var viewState = useViewState(); | ||
return useCallback(function (computeNewIndex) { | ||
var _a; | ||
var linearItems = getLinearItems(); | ||
var currentIndex = (_a = linearItems.findIndex(function (item) { return item.item === viewState.focusedItem; })) !== null && _a !== void 0 ? _a : 0; | ||
@@ -21,3 +20,3 @@ var newIndex = computeNewIndex(currentIndex, linearItems); | ||
return newFocusItem; | ||
}, [onFocusItem, items, getLinearItems, treeId, viewState.focusedItem]); | ||
}, [onFocusItem, items, linearItems, treeId, viewState.focusedItem]); | ||
}; |
@@ -6,15 +6,16 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
}; | ||
import { getItemsLinearly } from './getItemsLinearly'; | ||
import { useViewState } from './useViewState'; | ||
import { useTree } from './Tree'; | ||
import { useTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment'; | ||
import { useCallback } from 'react'; | ||
import { useLinearItems } from '../controlledEnvironment/useLinearItems'; | ||
export var useSelectUpTo = function () { | ||
var viewState = useViewState(); | ||
var _a = useTree(), rootItem = _a.rootItem, treeId = _a.treeId; | ||
var environment = useTreeEnvironment(); | ||
return function (item) { | ||
var _a, _b, _c, _d, _e; | ||
var treeId = useTree().treeId; | ||
var linearItems = useLinearItems(treeId); | ||
var onSelectItems = useTreeEnvironment().onSelectItems; | ||
return useCallback(function (item) { | ||
var _a, _b; | ||
// TODO doesnt work that well if there are spaces between selections | ||
if (viewState && viewState.selectedItems && viewState.selectedItems.length > 0) { | ||
var linearItems = getItemsLinearly(rootItem, viewState, environment.items); | ||
var selectionStart = linearItems.findIndex(function (linearItem) { var _a; return (_a = viewState.selectedItems) === null || _a === void 0 ? void 0 : _a.includes(linearItem.item); }); | ||
@@ -27,3 +28,3 @@ var selectionEnd = linearItems.findIndex(function (linearItem) { return linearItem.item === item.index; }); | ||
}); | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, __spreadArray(__spreadArray([], ((_b = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _b !== void 0 ? _b : [])), selection), treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(__spreadArray(__spreadArray([], ((_a = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _a !== void 0 ? _a : [])), selection), treeId); | ||
} | ||
@@ -35,9 +36,9 @@ else { | ||
}); | ||
(_c = environment.onSelectItems) === null || _c === void 0 ? void 0 : _c.call(environment, __spreadArray(__spreadArray([], ((_d = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _d !== void 0 ? _d : [])), selection), treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems(__spreadArray(__spreadArray([], ((_b = viewState === null || viewState === void 0 ? void 0 : viewState.selectedItems) !== null && _b !== void 0 ? _b : [])), selection), treeId); | ||
} | ||
} | ||
else { | ||
(_e = environment.onSelectItems) === null || _e === void 0 ? void 0 : _e.call(environment, [item.index], treeId); | ||
onSelectItems === null || onSelectItems === void 0 ? void 0 : onSelectItems([item.index], treeId); | ||
} | ||
}; | ||
}, [onSelectItems, linearItems, treeId, viewState]); | ||
}; |
@@ -12,6 +12,6 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
import { useTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment'; | ||
import { useGetLinearItems } from './useGetLinearItems'; | ||
import { useDragAndDrop } from '../controlledEnvironment/DragAndDropProvider'; | ||
import { useSelectUpTo } from './useSelectUpTo'; | ||
import { useCallback } from 'react'; | ||
import { useLinearItems } from '../controlledEnvironment/useLinearItems'; | ||
export var useTreeKeyboardBindings = function () { | ||
@@ -21,6 +21,6 @@ var _a; | ||
var _b = useTree(), treeId = _b.treeId, setRenamingItem = _b.setRenamingItem, setSearch = _b.setSearch, renamingItem = _b.renamingItem; | ||
var linearItems = useLinearItems(treeId); | ||
var dnd = useDragAndDrop(); | ||
var viewState = useViewState(); | ||
var moveFocusToIndex = useMoveFocusToIndex(); | ||
var getLinearItems = useGetLinearItems(); | ||
var selectUpTo = useSelectUpTo(); | ||
@@ -98,3 +98,3 @@ var isActiveTree = environment.activeTreeId === treeId; | ||
e.preventDefault(); | ||
if (viewState.focusedItem) { | ||
if (viewState.focusedItem !== undefined) { | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, [viewState.focusedItem], treeId); | ||
@@ -107,3 +107,3 @@ (_b = environment.onPrimaryAction) === null || _b === void 0 ? void 0 : _b.call(environment, environment.items[viewState.focusedItem], treeId); | ||
e.preventDefault(); | ||
if (viewState.focusedItem) { | ||
if (viewState.focusedItem !== undefined) { | ||
if (viewState.selectedItems && viewState.selectedItems.includes(viewState.focusedItem)) { | ||
@@ -120,10 +120,10 @@ (_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, viewState.selectedItems.filter(function (item) { return item !== viewState.focusedItem; }), treeId); | ||
e.preventDefault(); | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, getLinearItems().map(function (_a) { | ||
(_a = environment.onSelectItems) === null || _a === void 0 ? void 0 : _a.call(environment, linearItems.map(function (_a) { | ||
var item = _a.item; | ||
return item; | ||
}), treeId); | ||
}, [environment, getLinearItems, treeId]), isActiveTree && !dnd.isProgrammaticallyDragging && !isRenaming); | ||
}, [environment, linearItems, treeId]), isActiveTree && !dnd.isProgrammaticallyDragging && !isRenaming); | ||
useHotkey('renameItem', useCallback(function (e) { | ||
var _a; | ||
if (viewState.focusedItem) { | ||
if (viewState.focusedItem !== undefined) { | ||
e.preventDefault(); | ||
@@ -130,0 +130,0 @@ var item = environment.items[viewState.focusedItem]; |
@@ -15,3 +15,3 @@ import React from 'react'; | ||
var containerProps = { | ||
role: 'group', | ||
role: props.depth !== 0 ? 'group' : undefined, | ||
}; | ||
@@ -18,0 +18,0 @@ return renderers.renderItemsContainer({ |
@@ -6,2 +6,3 @@ import { useTree } from '../tree/Tree'; | ||
import { useSideEffect } from '../useSideEffect'; | ||
import { useCallSoon } from '../useCallSoon'; | ||
export var TreeItemRenamingInput = function (props) { | ||
@@ -14,2 +15,3 @@ var _a = useTree(), renderers = _a.renderers, treeInformation = _a.treeInformation, setRenamingItem = _a.setRenamingItem, treeId = _a.treeId; | ||
var _b = useState(environment.getItemTitle(item)), title = _b[0], setTitle = _b[1]; | ||
var callSoon = useCallSoon(); | ||
var abort = function () { | ||
@@ -19,3 +21,3 @@ var _a; | ||
setRenamingItem(null); | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
environment.setActiveTree(treeId); | ||
@@ -28,3 +30,3 @@ }); | ||
setRenamingItem(null); | ||
requestAnimationFrame(function () { | ||
callSoon(function () { | ||
environment.setActiveTree(treeId); | ||
@@ -31,0 +33,0 @@ }); |
@@ -131,3 +131,3 @@ var __assign = (this && this.__assign) || function () { | ||
}; | ||
var interactiveElementProps = __assign(__assign({}, interactionManager.createInteractiveElementProps(item, treeId, actions, renderFlags)), (_a = {}, | ||
var interactiveElementProps = __assign(__assign({}, interactionManager.createInteractiveElementProps(item, treeId, actions, renderFlags, viewState)), (_a = {}, | ||
_a['data-rct-item-interactive'] = true, | ||
@@ -134,0 +134,0 @@ _a['data-rct-item-focus'] = renderFlags.isFocused ? 'true' : 'false', |
@@ -124,3 +124,5 @@ import React, { FormHTMLAttributes, HTMLProps, InputHTMLAttributes, Ref } from 'react'; | ||
extends?: InteractionMode; | ||
createInteractiveElementProps: (item: TreeItem, treeId: string, actions: TreeItemActions, renderFlags: TreeItemRenderFlags) => HTMLProps<HTMLElement>; | ||
createInteractiveElementProps: (item: TreeItem, treeId: string, actions: TreeItemActions, renderFlags: TreeItemRenderFlags, | ||
/** See https://github.com/lukasbach/react-complex-tree/issues/48 */ | ||
__unsafeViewState?: IndividualTreeViewState) => HTMLProps<HTMLElement>; | ||
} | ||
@@ -210,2 +212,3 @@ export interface TreeCapabilities<T = any> { | ||
trees: Record<string, TreeConfiguration>; | ||
linearItems: Record<string, LinearItem[]>; | ||
} | ||
@@ -315,2 +318,6 @@ export interface DragAndDropContextProps<T = any> { | ||
}; | ||
export interface LinearItem { | ||
item: TreeItemIndex; | ||
depth: number; | ||
} | ||
export interface KeyboardBindings { | ||
@@ -317,0 +324,0 @@ primaryAction?: string[]; |
@@ -54,3 +54,3 @@ var __assign = (this && this.__assign) || function () { | ||
import * as React from 'react'; | ||
import { useEffect, useMemo, useRef, useState } from 'react'; | ||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; | ||
import { ControlledTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment'; | ||
@@ -74,3 +74,3 @@ import { CompleteTreeDataProvider } from './CompleteTreeDataProvider'; | ||
}; }, []); | ||
var amendViewState = function (treeId, constructNewState) { | ||
var amendViewState = useCallback(function (treeId, constructNewState) { | ||
setViewState(function (oldState) { | ||
@@ -81,3 +81,3 @@ var _a; | ||
}); | ||
}; | ||
}, []); | ||
useEffect(function () { | ||
@@ -84,0 +84,0 @@ var dispose = dataProvider.onDidChangeTreeData(function (changedItemIds) { |
{ | ||
"name": "react-complex-tree", | ||
"version": "1.1.4", | ||
"version": "1.1.5", | ||
"main": "lib/cjs/index.js", | ||
@@ -29,10 +29,10 @@ "module": "lib/esm/index.js", | ||
"@lukasbach/tsconfig": "^0.1.0", | ||
"@types/jest": "^26.0.23", | ||
"@types/jest": "^27.4.1", | ||
"@types/react": "^17.0.38", | ||
"@types/react-dom": "^17.0.11", | ||
"@welldone-software/why-did-you-render": "^6.2.0", | ||
"babel-jest": "^26.6.3", | ||
"babel-jest": "^27.5.1", | ||
"babel-loader": "^8.2.2", | ||
"cpy-cli": "^3.1.1", | ||
"demodata": "^1.1.4", | ||
"demodata": "^1.1.5", | ||
"jest": "^26.6.3", | ||
@@ -45,3 +45,3 @@ "loader-utils": "^2.0.0", | ||
"ts-loader": "^8.3.0", | ||
"ts-node": "^9.1.1", | ||
"ts-node": "^10.7.0", | ||
"typescript": "4.2.2", | ||
@@ -59,3 +59,3 @@ "webpack-cli": "^4.7.2" | ||
}, | ||
"gitHead": "9716969a3cd259caf5ee18a22a6bc052fba2595d" | ||
"gitHead": "a6aa58f9392ac659b04c275a8e00af9a63df7328" | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
372
967452
11357