react-calendar-timeline
Advanced tools
Comparing version 0.27.6-gamma to 0.27.7-gamma
@@ -311,4 +311,5 @@ "use strict"; | ||
var dragTime = _this2.dragTime(e); | ||
var dragTime = _this2.dragTime(e); // if(dragTime !== _get(this.props.item, this.props.keys.itemTimeStartKey)){ | ||
if (_this2.props.moveResizeValidator) { | ||
@@ -321,3 +322,4 @@ dragTime = _this2.props.moveResizeValidator('move', _this2.props.item, dragTime); | ||
} | ||
} | ||
} // } | ||
} | ||
@@ -364,8 +366,13 @@ }).on('dragend', function (e) { | ||
if (_this2.props.moveResizeValidator) { | ||
resizeTime = _this2.props.moveResizeValidator('resize', _this2.props.item, resizeTime, resizeEdge); | ||
} | ||
var isResizeTimeChangedRight = resizeEdge === 'right' && resizeTime !== (0, _generic._get)(_this2.props.item, _this2.props.keys.itemTimeEndKey); | ||
var isResizeTimeChangedLeft = resizeEdge === 'left' && resizeTime !== (0, _generic._get)(_this2.props.item, _this2.props.keys.itemTimeStartKey); | ||
if (_this2.props.onResizing) { | ||
_this2.props.onResizing(_this2.itemId, resizeTime, resizeEdge); | ||
if (isResizeTimeChangedRight || isResizeTimeChangedLeft) { | ||
if (_this2.props.moveResizeValidator) { | ||
resizeTime = _this2.props.moveResizeValidator('resize', _this2.props.item, resizeTime, resizeEdge); | ||
} | ||
if (_this2.props.onResizing) { | ||
_this2.props.onResizing(_this2.itemId, resizeTime, resizeEdge); | ||
} | ||
} | ||
@@ -503,2 +510,7 @@ } | ||
}, { | ||
key: "componentWillUnmount", | ||
value: function componentWillUnmount() { | ||
console.log("unmount item"); | ||
} | ||
}, { | ||
key: "render", | ||
@@ -505,0 +517,0 @@ value: function render() { |
@@ -84,3 +84,3 @@ "use strict"; | ||
value: function shouldComponentUpdate(nextProps) { | ||
return !((0, _generic.arraysEqual)(nextProps.items, this.props.items) && nextProps.groupDimensions === this.props.groupDimensions && nextProps.keys === this.props.keys && nextProps.canvasTimeStart === this.props.canvasTimeStart && nextProps.canvasTimeEnd === this.props.canvasTimeEnd && nextProps.canvasWidth === this.props.canvasWidth && nextProps.selectedItem === this.props.selectedItem && nextProps.selected === this.props.selected && nextProps.dragSnap === this.props.dragSnap && nextProps.minResizeWidth === this.props.minResizeWidth && nextProps.canChangeGroup === this.props.canChangeGroup && nextProps.canMove === this.props.canMove && nextProps.canResize === this.props.canResize && nextProps.canSelect === this.props.canSelect && nextProps.dragging === this.props.dragging && nextProps.resizing === this.props.resizing && nextProps.resizeEdge === this.props.resizeEdge && nextProps.resizeTime === this.props.resizeTime && nextProps.interactingItemId === this.props.interactingItemId); | ||
return !((0, _generic.arraysEqual)(nextProps.items, this.props.items) && nextProps.groupDimensions === this.props.groupDimensions && nextProps.keys === this.props.keys && nextProps.canvasTimeStart === this.props.canvasTimeStart && nextProps.canvasTimeEnd === this.props.canvasTimeEnd && nextProps.canvasWidth === this.props.canvasWidth && nextProps.selectedItem === this.props.selectedItem && nextProps.selected === this.props.selected && nextProps.dragSnap === this.props.dragSnap && nextProps.minResizeWidth === this.props.minResizeWidth && nextProps.canChangeGroup === this.props.canChangeGroup && nextProps.canMove === this.props.canMove && nextProps.canResize === this.props.canResize && nextProps.canSelect === this.props.canSelect && nextProps.dragging === this.props.dragging && nextProps.resizing === this.props.resizing && nextProps.resizeEdge === this.props.resizeEdge && nextProps.interactingItemId === this.props.interactingItemId); | ||
} | ||
@@ -145,3 +145,2 @@ }, { | ||
resizeEdge: isInteractingItem ? _this2.props.resizeEdge : undefined, | ||
resizeTime: isInteractingItem ? _this2.props.resizeTime : 0, | ||
onDragStart: _this2.props.onDragStart, | ||
@@ -193,4 +192,3 @@ onDragEnd: _this2.props.onDragEnd, | ||
interactingItemId: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), | ||
resizeEdge: _propTypes["default"].oneOf(['right', 'left']), | ||
resizeTime: _propTypes["default"].number | ||
resizeEdge: _propTypes["default"].oneOf(['right', 'left']) | ||
}); | ||
@@ -197,0 +195,0 @@ |
@@ -67,3 +67,2 @@ "use strict"; | ||
resizeEdge: undefined, | ||
resizeTime: undefined, | ||
dragging: undefined, | ||
@@ -138,4 +137,3 @@ resizing: undefined, | ||
interactingItemId: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), | ||
resizeEdge: _propTypes["default"].oneOf(['right', 'left']), | ||
resizeTime: _propTypes["default"].number | ||
resizeEdge: _propTypes["default"].oneOf(['right', 'left']) | ||
}); | ||
@@ -142,0 +140,0 @@ |
@@ -190,11 +190,7 @@ "use strict"; | ||
items = _this$props2.items, | ||
keys = _this$props2.keys; | ||
keys = _this$props2.keys, | ||
resizeEdge = _this$props2.resizeEdge; | ||
var _this$context = this.context, | ||
getTimelineState = _this$context.getTimelineState, | ||
getLeftOffsetFromDate = _this$context.getLeftOffsetFromDate; | ||
var _getTimelineState = getTimelineState(), | ||
resizeEdge = _getTimelineState.resizeEdge, | ||
resizeTime = _getTimelineState.resizeTime; | ||
getLeftOffsetFromDate = _this$context.getLeftOffsetFromDate, | ||
getDateFromLeftOffsetPosition = _this$context.getDateFromLeftOffsetPosition; | ||
return _react["default"].createElement("div", { | ||
@@ -208,23 +204,16 @@ style: { | ||
var group = groupsWithItemsDimensions[groupId]; | ||
return _react["default"].createElement(_GroupRowContext.GroupRowContextProvider, { | ||
return _react["default"].createElement(Group, { | ||
key: "horizontal-line-".concat(groupId), | ||
clickTolerance: clickTolerance, | ||
onContextMenu: onRowContextClick, | ||
onClick: onRowClick, | ||
onDoubleClick: onRowDoubleClick, | ||
isEvenRow: i % 2 === 0, | ||
group: groups[i], | ||
onRowContextClick: onRowContextClick, | ||
onRowClick: onRowClick, | ||
onRowDoubleClick: onRowDoubleClick, | ||
index: i, | ||
groups: groups, | ||
horizontalLineClassNamesForGroup: horizontalLineClassNamesForGroup, | ||
groupHeight: groupHeight, | ||
groupIndex: i | ||
}, _react["default"].createElement(_ColumnsContext.ColumnsContextProvider, { | ||
lineCount: (0, _generic._length)(groups), | ||
minUnit: minUnit, | ||
timeSteps: timeSteps, | ||
height: groupHeight, | ||
verticalLineClassNamesForTime: verticalLineClassNamesForTime | ||
}, _react["default"].createElement(_ItemsContext.ItemsContextProvider //TODO: fix groups with no items | ||
, { | ||
items: group.items || [], | ||
groupDimensions: group, | ||
verticalLineClassNamesForTime: verticalLineClassNamesForTime, | ||
group: group, | ||
dragSnap: dragSnap, | ||
@@ -242,3 +231,2 @@ minResizeWidth: minResizeWidth, | ||
itemResizing: itemResizing, | ||
itemResized: _this2.handleResizeEnd, | ||
onItemDoubleClick: onItemDoubleClick, | ||
@@ -250,24 +238,20 @@ onItemContextMenu: onItemContextMenu, | ||
scrollRef: scrollRef, | ||
order: group, | ||
resizeEdge: resizeEdge, | ||
Layers: Layers, | ||
getLeftOffsetFromDate: getLeftOffsetFromDate, | ||
rowData: rowData, | ||
items: items, | ||
itemResized: _this2.handleResizeEnd, | ||
onDragStart: _this2.handleDragStart, | ||
onDragEnd: _this2.handleDragEnd, | ||
onResizeStart: _this2.handleResizeStart, | ||
resizeEdge: resizeEdge, | ||
resizeTime: resizeTime, | ||
dragging: _this2.state.dragging, | ||
resizing: _this2.state.resizing, | ||
dragOffset: _this2.state.dragOffset, | ||
interactingItemId: _this2.state.interactingItemId | ||
}, _react["default"].createElement(Layers, { | ||
interactingItemId: _this2.state.interactingItemId, | ||
getLayerRootProps: _this2.getLayerRootProps, | ||
helpers: { | ||
getLeftOffsetFromDate: getLeftOffsetFromDate, | ||
getDateFromLeftOffsetPosition: _this2.getDateFromLeftOffsetPosition, | ||
getItemAbsoluteLocation: _this2.getItemAbsoluteLocation, | ||
getItemDimensions: _this2.getItemDimensionsHelper | ||
}, | ||
rowData: rowData, | ||
group: group.group, | ||
itemsWithInteractions: items | ||
})))); | ||
getDateFromLeftOffsetPosition: getDateFromLeftOffsetPosition, | ||
getItemAbsoluteLocation: _this2.getItemAbsoluteLocation, | ||
getItemDimensions: _this2.getItemDimensionsHelper | ||
}); | ||
})); | ||
@@ -282,3 +266,131 @@ } | ||
var Group = | ||
/*#__PURE__*/ | ||
function (_React$PureComponent2) { | ||
_inherits(Group, _React$PureComponent2); | ||
function Group() { | ||
_classCallCheck(this, Group); | ||
return _possibleConstructorReturn(this, _getPrototypeOf(Group).apply(this, arguments)); | ||
} | ||
_createClass(Group, [{ | ||
key: "render", | ||
value: function render() { | ||
var _this$props3 = this.props, | ||
clickTolerance = _this$props3.clickTolerance, | ||
onRowContextClick = _this$props3.onRowContextClick, | ||
onRowClick = _this$props3.onRowClick, | ||
onRowDoubleClick = _this$props3.onRowDoubleClick, | ||
index = _this$props3.index, | ||
groups = _this$props3.groups, | ||
horizontalLineClassNamesForGroup = _this$props3.horizontalLineClassNamesForGroup, | ||
groupHeight = _this$props3.groupHeight, | ||
minUnit = _this$props3.minUnit, | ||
timeSteps = _this$props3.timeSteps, | ||
verticalLineClassNamesForTime = _this$props3.verticalLineClassNamesForTime, | ||
group = _this$props3.group, | ||
dragSnap = _this$props3.dragSnap, | ||
minResizeWidth = _this$props3.minResizeWidth, | ||
selectedItem = _this$props3.selectedItem, | ||
canChangeGroup = _this$props3.canChangeGroup, | ||
canMove = _this$props3.canMove, | ||
canResize = _this$props3.canResize, | ||
canSelect = _this$props3.canSelect, | ||
moveResizeValidator = _this$props3.moveResizeValidator, | ||
itemSelect = _this$props3.itemSelect, | ||
itemDrag = _this$props3.itemDrag, | ||
itemDrop = _this$props3.itemDrop, | ||
itemResizing = _this$props3.itemResizing, | ||
onItemDoubleClick = _this$props3.onItemDoubleClick, | ||
onItemContextMenu = _this$props3.onItemContextMenu, | ||
itemRenderer = _this$props3.itemRenderer, | ||
selected = _this$props3.selected, | ||
useResizeHandle = _this$props3.useResizeHandle, | ||
scrollRef = _this$props3.scrollRef, | ||
resizeEdge = _this$props3.resizeEdge, | ||
Layers = _this$props3.Layers, | ||
getLeftOffsetFromDate = _this$props3.getLeftOffsetFromDate, | ||
rowData = _this$props3.rowData, | ||
items = _this$props3.items, | ||
itemResized = _this$props3.itemResized, | ||
onDragStart = _this$props3.onDragStart, | ||
onDragEnd = _this$props3.onDragEnd, | ||
onResizeStart = _this$props3.onResizeStart, | ||
dragging = _this$props3.dragging, | ||
resizing = _this$props3.resizing, | ||
dragOffset = _this$props3.dragOffset, | ||
interactingItemId = _this$props3.interactingItemId, | ||
getLayerRootProps = _this$props3.getLayerRootProps, | ||
getDateFromLeftOffsetPosition = _this$props3.getDateFromLeftOffsetPosition, | ||
getItemAbsoluteLocation = _this$props3.getItemAbsoluteLocation, | ||
getItemDimensions = _this$props3.getItemDimensions; | ||
return _react["default"].createElement(_GroupRowContext.GroupRowContextProvider, { | ||
clickTolerance: clickTolerance, | ||
onContextMenu: onRowContextClick, | ||
onClick: onRowClick, | ||
onDoubleClick: onRowDoubleClick, | ||
isEvenRow: index % 2 === 0, | ||
group: groups[index], | ||
horizontalLineClassNamesForGroup: horizontalLineClassNamesForGroup, | ||
groupHeight: groupHeight, | ||
groupIndex: index | ||
}, _react["default"].createElement(_ColumnsContext.ColumnsContextProvider, { | ||
lineCount: (0, _generic._length)(groups), | ||
minUnit: minUnit, | ||
timeSteps: timeSteps, | ||
height: groupHeight, | ||
verticalLineClassNamesForTime: verticalLineClassNamesForTime | ||
}, _react["default"].createElement(_ItemsContext.ItemsContextProvider //TODO: fix groups with no items | ||
, { | ||
items: group.items || [], | ||
groupDimensions: group, | ||
dragSnap: dragSnap, | ||
minResizeWidth: minResizeWidth, | ||
selectedItem: selectedItem, | ||
canChangeGroup: canChangeGroup, | ||
canMove: canMove, | ||
canResize: canResize, | ||
canSelect: canSelect, | ||
moveResizeValidator: moveResizeValidator, | ||
itemSelect: itemSelect, | ||
itemDrag: itemDrag, | ||
itemDrop: itemDrop, | ||
itemResizing: itemResizing, | ||
itemResized: itemResized, | ||
onItemDoubleClick: onItemDoubleClick, | ||
onItemContextMenu: onItemContextMenu, | ||
itemRenderer: itemRenderer, | ||
selected: selected, | ||
useResizeHandle: useResizeHandle, | ||
scrollRef: scrollRef, | ||
order: group, | ||
onDragStart: onDragStart, | ||
onDragEnd: onDragEnd, | ||
onResizeStart: onResizeStart, | ||
resizeEdge: resizeEdge, | ||
dragging: dragging, | ||
resizing: resizing, | ||
dragOffset: dragOffset, | ||
interactingItemId: interactingItemId | ||
}, _react["default"].createElement(Layers, { | ||
getLayerRootProps: getLayerRootProps, | ||
helpers: { | ||
getLeftOffsetFromDate: getLeftOffsetFromDate, | ||
getDateFromLeftOffsetPosition: getDateFromLeftOffsetPosition, | ||
getItemAbsoluteLocation: getItemAbsoluteLocation, | ||
getItemDimensions: getItemDimensions | ||
}, | ||
rowData: rowData, | ||
group: group.group, | ||
itemsWithInteractions: items | ||
})))); | ||
} | ||
}]); | ||
return Group; | ||
}(_react["default"].PureComponent); | ||
var _default = Rows; | ||
exports["default"] = _default; |
@@ -12,10 +12,4 @@ "use strict"; | ||
var _moment = _interopRequireDefault(require("moment")); | ||
var _Items = _interopRequireDefault(require("./items/Items")); | ||
var _Sidebar = _interopRequireDefault(require("./layout/Sidebar")); | ||
var _Columns = _interopRequireDefault(require("./columns/Columns")); | ||
var _ScrollElement = _interopRequireDefault(require("./scroll/ScrollElement")); | ||
@@ -45,4 +39,2 @@ | ||
var _SidebarHeader = _interopRequireDefault(require("./headers/SidebarHeader")); | ||
var _DefaultLayer = _interopRequireDefault(require("./rows/DefaultLayer")); | ||
@@ -703,3 +695,3 @@ | ||
itemResized: this.resizedItem, | ||
itemResizing: this.resizedItem, | ||
itemResizing: this.resizingItem, | ||
moveResizeValidator: this.props.moveResizeValidator, | ||
@@ -727,3 +719,4 @@ itemSelect: this.selectItem, | ||
items: items, | ||
keys: keys | ||
keys: keys, | ||
resizeEdge: this.state.resizingEdge | ||
}))), rightSidebarWidth > 0 ? this.rightSidebar(height, groupHeights) : null))))); | ||
@@ -730,0 +723,0 @@ } |
@@ -38,4 +38,10 @@ "use strict"; | ||
var _memoizeOne = _interopRequireDefault(require("memoize-one")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
function _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest(); } | ||
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } | ||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { if (i % 2) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } else { Object.defineProperties(target, Object.getOwnPropertyDescriptors(arguments[i])); } } return target; } | ||
@@ -445,2 +451,10 @@ | ||
} | ||
var aa = [{ | ||
a: {} | ||
}, { | ||
b: {} | ||
}, { | ||
c: {} | ||
}]; | ||
/** | ||
@@ -466,3 +480,2 @@ * Stack the items that will be visible | ||
function stackTimelineItems(items, groups, canvasWidth, canvasTimeStart, canvasTimeEnd, keys, lineHeight, itemHeightRatio, stackItems, draggingItem, resizingItem, dragTime, resizingEdge, resizeTime, newGroupId) { | ||
@@ -494,3 +507,3 @@ var visibleItems = getVisibleItems(items, canvasTimeStart, canvasTimeEnd, keys); | ||
var groupsWithItems = getOrderedGroupsWithItems(groups, visibleItemsWithInteraction, keys); | ||
var groupsWithItemsDimensions = getGroupsWithItemDimensions(groupsWithItems, keys, lineHeight, itemHeightRatio, stackItems, canvasTimeStart, canvasTimeEnd, canvasWidth); | ||
var groupsWithItemsDimensions = getGroupsWithItemDimensions(groupsWithItems, keys, lineHeight, itemHeightRatio, stackItems, canvasTimeStart, canvasTimeEnd, canvasWidth, groups); | ||
var groupHeights = groups.map(function (group) { | ||
@@ -601,4 +614,6 @@ var groupKey = (0, _generic._get)(group, keys.groupIdKey); | ||
var isDragging = itemId === draggingItem; | ||
var isResizing = itemId === resizingItem; | ||
var isResizing = itemId === resizingItem; //return item if is not being dragged or resized | ||
if (!isResizing && !isDragging) return item; | ||
var _calculateInteraction = calculateInteractionNewTimes({ | ||
@@ -751,10 +766,62 @@ itemTimeStart: (0, _generic._get)(item, keys.itemTimeStartKey), | ||
} | ||
/** | ||
* shallow compare ordered groups with items | ||
* if index or group changed reference compare then not equal | ||
* if new/old group's items changed array shallow equality then not equal | ||
* @param {*} newGroup | ||
* @param {*} oldGroup | ||
*/ | ||
function getGroupsWithItemDimensions(groupsWithItems, keys, lineHeight, itemHeightRatio, stackItems, canvasTimeStart, canvasTimeEnd, canvasWidth) { | ||
function shallowIsEqualOrderedGroup(newGroup, oldGroup) { | ||
if (newGroup.group !== oldGroup.group) return false; | ||
if (newGroup.index !== oldGroup.index) return false; | ||
return (0, _generic.arraysEqual)(newGroup.items, oldGroup.items); | ||
} | ||
/** | ||
* compare getGroupWithItemDimensions params. All params are compared via reference equality | ||
* only groups are checked via a custom shallow equality | ||
* @param {*} newArgs | ||
* @param {*} oldArgs | ||
*/ | ||
var isEqualItemWithDimensions = function isEqualItemWithDimensions(newArgs, oldArgs) { | ||
var _newArgs = _toArray(newArgs), | ||
newGroup = _newArgs[0], | ||
newRest = _newArgs.slice(1); | ||
var _oldArgs = _toArray(oldArgs), | ||
oldGroup = _oldArgs[0], | ||
oldRest = _oldArgs.slice(1); //shallow equality | ||
if (!(0, _generic.arraysEqual)(newRest, oldRest)) return false; | ||
return shallowIsEqualOrderedGroup(newGroup, oldGroup); | ||
}; | ||
/** | ||
* returns a cache in the form of dictionary ([groupId]: cachedMethod) for calculating getGroupWithItemDimensions | ||
* the cache is cleared if groups or keys changed in reference | ||
* @param {*} groups | ||
* @param {*} keys | ||
*/ | ||
var getGroupsCache = (0, _memoizeOne["default"])(function (groups, keys) { | ||
return groups.reduce(function (acc, group) { | ||
var id = (0, _generic._get)(group, keys.groupIdKey); | ||
acc[id] = (0, _memoizeOne["default"])(getGroupWithItemDimensions, isEqualItemWithDimensions); | ||
return acc; | ||
}, {}); | ||
}); | ||
function getGroupsWithItemDimensions(groupsWithItems, keys, lineHeight, itemHeightRatio, stackItems, canvasTimeStart, canvasTimeEnd, canvasWidth, groups) { | ||
var cache = getGroupsCache(groups, keys); | ||
var groupKeys = Object.keys(groupsWithItems); | ||
return groupKeys.reduce(function (acc, groupKey) { | ||
var group = groupsWithItems[groupKey]; | ||
acc[groupKey] = getGroupWithItemDimensions(group, keys, canvasTimeStart, canvasTimeEnd, canvasWidth, lineHeight, itemHeightRatio, stackItems); | ||
var cachedGetGroupWithItemDimensions = cache[groupKey]; | ||
acc[groupKey] = cachedGetGroupWithItemDimensions(group, keys, canvasTimeStart, canvasTimeEnd, canvasWidth, lineHeight, itemHeightRatio, stackItems); | ||
return acc; | ||
}, {}); | ||
} |
{ | ||
"name": "react-calendar-timeline", | ||
"version": "0.27.6-gamma", | ||
"version": "0.27.7-gamma", | ||
"description": "react calendar timeline", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
286
README.md
@@ -1156,2 +1156,288 @@ # React Calendar Timeline | ||
### `rowData` prop | ||
Data to be passed to `rowRenderer`'s `rowData` param. Changing this prop will cause rerender of the `rowRenderer` | ||
### Row renderer | ||
This API would give you control to add custom UI on calendar rows using a render prop. You can control what is rendered by default with the library like Items and Vertical/Horizontal lines, and the renderer will provide you the ability to render custom backgrounds and droppable layers for custom dnd. | ||
#### example | ||
[CodeSandbox](https://codesandbox.io/s/timeline-demo-rowrenderer-doc-example-66pvw) | ||
```javascript | ||
import Timeline, { | ||
RowColumns, | ||
RowItems, | ||
GroupRow | ||
} from "react-calendar-timeline"; | ||
import moment from 'moment' | ||
const groups = [{ id: 1, title: 'group 1' }, { id: 2, title: 'group 2' }] | ||
const items = [ | ||
{ | ||
id: 1, | ||
group: 1, | ||
title: 'item 1', | ||
start_time: moment(), | ||
end_time: moment().add(1, 'hour') | ||
}, | ||
{ | ||
id: 2, | ||
group: 2, | ||
title: 'item 2', | ||
start_time: moment().add(-0.5, 'hour'), | ||
end_time: moment().add(0.5, 'hour') | ||
}, | ||
{ | ||
id: 3, | ||
group: 1, | ||
title: 'item 3', | ||
start_time: moment().add(2, 'hour'), | ||
end_time: moment().add(3, 'hour') | ||
} | ||
] | ||
ReactDOM.render( | ||
<Timeline | ||
groups={groups} | ||
items={items} | ||
stackItems | ||
defaultTimeStart={defaultTimeStart} | ||
defaultTimeEnd={defaultTimeEnd} | ||
rowRenderer={({ | ||
rowData, | ||
helpers: { getLeftOffsetFromDate }, | ||
getLayerRootProps, | ||
group | ||
}) => { | ||
const { unavailableSlots } = rowData; | ||
const groupUnavailableSlots = unavailableSlots[group.id] | ||
? unavailableSlots[group.id] | ||
: []; | ||
return ( | ||
<GroupRow> | ||
<RowColumns /> | ||
<RowItems /> | ||
<UnavailableLayer | ||
getLayerRootProps={getLayerRootProps} | ||
getLeftOffsetFromDate={getLeftOffsetFromDate} | ||
groupUnavailableSlots={groupUnavailableSlots} | ||
/> | ||
</GroupRow> | ||
); | ||
}} | ||
rowData={{ | ||
//keys here are groupIds | ||
unavailableSlots: { | ||
"1": [ | ||
{ | ||
id: "0", | ||
groupId: "0", | ||
startTime: moment() | ||
.startOf("day") | ||
.add(16, "h"), | ||
endTime: moment() | ||
.startOf("day") | ||
.add(20, "h") | ||
} | ||
] | ||
} | ||
}} | ||
/> | ||
) | ||
function UnavailableLayer({ | ||
getLayerRootProps, | ||
groupUnavailableSlots, | ||
getLeftOffsetFromDate | ||
}) { | ||
return ( | ||
<div {...getLayerRootProps()}> | ||
{groupUnavailableSlots.map(slot => { | ||
const left = getLeftOffsetFromDate(slot.startTime.valueOf()); | ||
const right = getLeftOffsetFromDate(slot.endTime.valueOf()); | ||
return ( | ||
<div | ||
key={slot.id} | ||
style={{ | ||
position: "absolute", | ||
left: left, | ||
width: right - left, | ||
backgroundColor: "#ECF0F1", | ||
height: "100%", | ||
display: "flex", | ||
alignItems: "center", | ||
justifyContent: "center" | ||
}} | ||
> | ||
<span style={{ height: 12 }}>unavailable</span> | ||
</div> | ||
); | ||
})} | ||
</div> | ||
); | ||
} | ||
``` | ||
#### API | ||
`rowRenderer` follow the render prop pattern with some prebuilt components to display the rows, items and columns. | ||
_Note_ : the renderProp can be a component or a function for convenience | ||
#### `rowRenderer` prop | ||
```typescript | ||
interface params { | ||
getLayerRootProps: (props: React.HTMLProps<HTMLElement>) => React.HTMLProps<HTMLElement>; | ||
helpers: { | ||
getLeftOffsetFromDate: (x: number) => number; | ||
getDateFromLeftOffsetPosition: (x: number) => number; | ||
getItemAbsoluteLocation: (itemId: string | number) => {left: number, top: number}; | ||
getItemDimensions: (itemId) => {left: number, top: number}; | ||
}; | ||
rowData : any; | ||
group: Group; | ||
itemsWithInteractions: Items[]; | ||
} | ||
type rowRenderer = (args: Params) => React.Node | ||
``` | ||
##### getLayerRootProps | ||
These functions are used to apply props to the layer that you want to render. This gives you maximum flexibility to render what, when, and wherever you like. | ||
##### Helpers | ||
- `getLeftOffsetFromDate(x: milliseconds): number`: This function is used to get the left position of the custom layer to render. This functions accepts time in milliseconds and returns a number that should be passed to `style.left` to be displayed. | ||
example: | ||
```typescript | ||
<div {...getLayerRootProps()}> | ||
{groupUnavailableSlots.map(slot => { | ||
const left = getLeftOffsetFromDate(slot.startTime.valueOf()); | ||
const right = getLeftOffsetFromDate(slot.endTime.valueOf()); | ||
return ( | ||
<div | ||
key={slot.id} | ||
style={{ | ||
position: "absolute", | ||
left: left, | ||
width: right - left, | ||
height: "100%", | ||
}} | ||
> | ||
<span style={{ height: 12 }}>unavailable</span> | ||
</div> | ||
); | ||
})} | ||
</div> | ||
``` | ||
here you calculate `left` and `right` using `getLeftOffsetFromDate` and use it to render the slot in the right place in the calendar. | ||
- `getDateFromLeftOffsetPosition(left: number): milliseconds`: This method is opposite of `getLeftOffsetFromDate` where you give it a left value and it will give you back the time in millisecond relative to the timeline. | ||
- `getItemDimensions(itemId: string|number): dimensions`. Given a item id, It will return back the left and top of the item relative to row it is in. This is useful to know the where an item is relative to other items in the same group. | ||
- `getItemAbsoluteLocation(itemId: string|number): dimensions`. Given a item id, It will return back the left and top of the item relative to the calendar container. This is useful to know the position of items in different rows relative to each other. | ||
##### `rowData` | ||
object passed by the `rowData` prop. | ||
#### group | ||
current group being rendered in the row. | ||
#### items | ||
items to be rendered in the row. These items respect visibility and interaction. This means that the items you will get back are only the items in the visible + buffer zone and if dragging/resizing is happening you will get the items the start/end time with the interaction. | ||
#### Components | ||
Row renderer comes with some components needed to render the rows and the default layers (columns and rows). The default value for the row renderer is: | ||
```typescript | ||
import React from 'react'; | ||
import {GroupRow, RowColumns, RowItems} from '../../index' | ||
const DefaultRowRenderer = () => { | ||
return <GroupRow> | ||
<RowColumns/> | ||
<RowItems/> | ||
</GroupRow> | ||
} | ||
``` | ||
##### GroupRow | ||
renders the row's root div. | ||
##### ItemsRow | ||
renders the row's items | ||
##### columnsRow | ||
renders the row's columns | ||
##### Custom Layers | ||
To render custom layers you need to implement the row renderer with the necessary layers | ||
```typescript | ||
import React from 'react'; | ||
import {GroupRow, RowColumns, RowItems} from '../../index' | ||
const rowRenderer = ({ | ||
helpers: { getLeftOffsetFromDate }, | ||
getLayerRootProps, | ||
group, | ||
itemsWithInteractions | ||
}) => { | ||
return ( | ||
<GroupRow> | ||
<RowColumns /> | ||
<RowItems /> | ||
<div {...getLayerRootProps()}> | ||
<div | ||
style={{ | ||
left: getLeftOffsetFromDate(moment().valueOf()), | ||
width: 200, | ||
background: "lightblue", | ||
position: "absolute", | ||
height: '100%' | ||
}} | ||
> | ||
{`group id: ${group.id} renders ${itemsWithInteractions.length} items`} | ||
</div> | ||
</div> | ||
<div {...getLayerRootProps()}> | ||
<div | ||
style={{ | ||
left: getLeftOffsetFromDate(moment().add(5,'h').valueOf()), | ||
width: 200, | ||
background: "lightblue", | ||
position: "absolute", | ||
height: '100%' | ||
}} | ||
> | ||
some other layer | ||
</div> | ||
</div> | ||
</GroupRow> | ||
); | ||
} | ||
``` | ||
##### order | ||
You can switch the order between `RowColumns`, `RowItems` and custom layers. This will change what renders above what. So if you had `RowItems` in the bottom all the other layer will render in top of it | ||
# FAQ | ||
@@ -1158,0 +1444,0 @@ |
@@ -221,10 +221,12 @@ import { Component } from 'react' | ||
let dragTime = this.dragTime(e) | ||
if (this.props.moveResizeValidator) { | ||
dragTime = this.props.moveResizeValidator('move', this.props.item, dragTime) | ||
// if(dragTime !== _get(this.props.item, this.props.keys.itemTimeStartKey)){ | ||
if (this.props.moveResizeValidator) { | ||
dragTime = this.props.moveResizeValidator('move', this.props.item, dragTime) | ||
} | ||
if (this.props.onDrag) { | ||
this.props.onDrag(this.itemId, dragTime, newGroupId) | ||
} | ||
} | ||
if (this.props.onDrag) { | ||
this.props.onDrag(this.itemId, dragTime, newGroupId) | ||
} | ||
} | ||
// } | ||
} | ||
@@ -269,10 +271,12 @@ }) | ||
let resizeTime = this.resizeTimeSnap(this.timeFor(e)) | ||
if (this.props.moveResizeValidator) { | ||
resizeTime = this.props.moveResizeValidator('resize', this.props.item, resizeTime, resizeEdge) | ||
const isResizeTimeChangedRight = resizeEdge === 'right' && resizeTime !== _get(this.props.item, this.props.keys.itemTimeEndKey) | ||
const isResizeTimeChangedLeft = resizeEdge === 'left' && resizeTime !== _get(this.props.item, this.props.keys.itemTimeStartKey) | ||
if(isResizeTimeChangedRight || isResizeTimeChangedLeft){ | ||
if (this.props.moveResizeValidator) { | ||
resizeTime = this.props.moveResizeValidator('resize', this.props.item, resizeTime, resizeEdge) | ||
} | ||
if (this.props.onResizing) { | ||
this.props.onResizing(this.itemId, resizeTime, resizeEdge) | ||
} | ||
} | ||
if (this.props.onResizing) { | ||
this.props.onResizing(this.itemId, resizeTime, resizeEdge) | ||
} | ||
} | ||
@@ -527,2 +531,6 @@ }) | ||
componentWillUnmount(){ | ||
console.log("unmount item") | ||
} | ||
render() { | ||
@@ -529,0 +537,0 @@ if (typeof this.props.order === 'undefined' || this.props.order === null) { |
@@ -64,3 +64,2 @@ import PropTypes from 'prop-types' | ||
resizeEdge: PropTypes.oneOf(['right', 'left']), | ||
resizeTime: PropTypes.number | ||
} | ||
@@ -91,3 +90,2 @@ | ||
nextProps.resizeEdge === this.props.resizeEdge && | ||
nextProps.resizeTime === this.props.resizeTime && | ||
nextProps.interactingItemId === this.props.interactingItemId | ||
@@ -167,3 +165,2 @@ ) | ||
resizeEdge={isInteractingItem ? this.props.resizeEdge: undefined} | ||
resizeTime={isInteractingItem ? this.props.resizeTime: 0} | ||
onDragStart={this.props.onDragStart} | ||
@@ -170,0 +167,0 @@ onDragEnd={this.props.onDragEnd} |
@@ -31,3 +31,2 @@ import React, { PureComponent } from 'react' | ||
resizeEdge: undefined, | ||
resizeTime: undefined, | ||
dragging: undefined, | ||
@@ -74,3 +73,2 @@ resizing: undefined, | ||
resizeEdge: PropTypes.oneOf(['right', 'left']), | ||
resizeTime: PropTypes.number | ||
} | ||
@@ -77,0 +75,0 @@ render(){ |
@@ -126,7 +126,6 @@ import React from 'react' | ||
items, | ||
keys | ||
keys, | ||
resizeEdge, | ||
} = this.props | ||
const { getTimelineState, getLeftOffsetFromDate } = this.context | ||
const { resizeEdge, resizeTime } = getTimelineState() | ||
const { getLeftOffsetFromDate, getDateFromLeftOffsetPosition } = this.context | ||
return ( | ||
@@ -138,10 +137,10 @@ <div style={{ position: 'absolute', top: 0 }}> | ||
return ( | ||
<GroupRowContextProvider | ||
<Group | ||
key={`horizontal-line-${groupId}`} | ||
clickTolerance={clickTolerance} | ||
onContextMenu={onRowContextClick} | ||
onClick={onRowClick} | ||
onDoubleClick={onRowDoubleClick} | ||
isEvenRow={i % 2 === 0} | ||
group={groups[i]} | ||
onRowContextClick={onRowContextClick} | ||
onRowClick={onRowClick} | ||
onRowDoubleClick={onRowDoubleClick} | ||
index={i} | ||
groups={groups} | ||
horizontalLineClassNamesForGroup={ | ||
@@ -151,61 +150,42 @@ horizontalLineClassNamesForGroup | ||
groupHeight={groupHeight} | ||
groupIndex={i} | ||
> | ||
<ColumnsContextProvider | ||
lineCount={_length(groups)} | ||
minUnit={minUnit} | ||
timeSteps={timeSteps} | ||
height={groupHeight} | ||
verticalLineClassNamesForTime={verticalLineClassNamesForTime} | ||
> | ||
<ItemsContextProvider | ||
//TODO: fix groups with no items | ||
items={group.items || []} | ||
groupDimensions={group} | ||
dragSnap={dragSnap} | ||
minResizeWidth={minResizeWidth} | ||
selectedItem={selectedItem} | ||
canChangeGroup={canChangeGroup} | ||
canMove={canMove} | ||
canResize={canResize} | ||
canSelect={canSelect} | ||
moveResizeValidator={moveResizeValidator} | ||
itemSelect={itemSelect} | ||
itemDrag={itemDrag} | ||
itemDrop={itemDrop} | ||
itemResizing={itemResizing} | ||
itemResized={this.handleResizeEnd} | ||
onItemDoubleClick={onItemDoubleClick} | ||
onItemContextMenu={onItemContextMenu} | ||
itemRenderer={itemRenderer} | ||
selected={selected} | ||
useResizeHandle={useResizeHandle} | ||
scrollRef={scrollRef} | ||
order={group} | ||
onDragStart={this.handleDragStart} | ||
onDragEnd={this.handleDragEnd} | ||
onResizeStart={this.handleResizeStart} | ||
resizeEdge={resizeEdge} | ||
resizeTime={resizeTime} | ||
dragging={this.state.dragging} | ||
resizing={this.state.resizing} | ||
dragOffset={this.state.dragOffset} | ||
interactingItemId={this.state.interactingItemId} | ||
> | ||
<Layers | ||
getLayerRootProps={this.getLayerRootProps} | ||
helpers={{ | ||
getLeftOffsetFromDate: getLeftOffsetFromDate, | ||
getDateFromLeftOffsetPosition: this | ||
.getDateFromLeftOffsetPosition, | ||
getItemAbsoluteLocation: this.getItemAbsoluteLocation, | ||
getItemDimensions: this.getItemDimensionsHelper | ||
}} | ||
rowData={rowData} | ||
group={group.group} | ||
itemsWithInteractions={items} | ||
/> | ||
</ItemsContextProvider> | ||
</ColumnsContextProvider> | ||
</GroupRowContextProvider> | ||
minUnit={minUnit} | ||
timeSteps={timeSteps} | ||
verticalLineClassNamesForTime={verticalLineClassNamesForTime} | ||
group={group} | ||
dragSnap={dragSnap} | ||
minResizeWidth={minResizeWidth} | ||
selectedItem={selectedItem} | ||
canChangeGroup={canChangeGroup} | ||
canMove={canMove} | ||
canResize={canResize} | ||
canSelect={canSelect} | ||
moveResizeValidator={moveResizeValidator} | ||
itemSelect={itemSelect} | ||
itemDrag={itemDrag} | ||
itemDrop={itemDrop} | ||
itemResizing={itemResizing} | ||
onItemDoubleClick={onItemDoubleClick} | ||
onItemContextMenu={onItemContextMenu} | ||
itemRenderer={itemRenderer} | ||
selected={selected} | ||
useResizeHandle={useResizeHandle} | ||
scrollRef={scrollRef} | ||
resizeEdge={resizeEdge} | ||
Layers={Layers} | ||
getLeftOffsetFromDate={getLeftOffsetFromDate} | ||
rowData={rowData} | ||
items={items} | ||
itemResized={this.handleResizeEnd} | ||
onDragStart={this.handleDragStart} | ||
onDragEnd={this.handleDragEnd} | ||
onResizeStart={this.handleResizeStart} | ||
dragging={this.state.dragging} | ||
resizing={this.state.resizing} | ||
dragOffset={this.state.dragOffset} | ||
interactingItemId={this.state.interactingItemId} | ||
getLayerRootProps={this.getLayerRootProps} | ||
getDateFromLeftOffsetPosition={getDateFromLeftOffsetPosition} | ||
getItemAbsoluteLocation={this.getItemAbsoluteLocation} | ||
getItemDimensions={this.getItemDimensionsHelper} | ||
/> | ||
) | ||
@@ -218,2 +198,126 @@ })} | ||
class Group extends React.PureComponent { | ||
render() { | ||
const { | ||
clickTolerance, | ||
onRowContextClick, | ||
onRowClick, | ||
onRowDoubleClick, | ||
index, | ||
groups, | ||
horizontalLineClassNamesForGroup, | ||
groupHeight, | ||
minUnit, | ||
timeSteps, | ||
verticalLineClassNamesForTime, | ||
group, | ||
dragSnap, | ||
minResizeWidth, | ||
selectedItem, | ||
canChangeGroup, | ||
canMove, | ||
canResize, | ||
canSelect, | ||
moveResizeValidator, | ||
itemSelect, | ||
itemDrag, | ||
itemDrop, | ||
itemResizing, | ||
onItemDoubleClick, | ||
onItemContextMenu, | ||
itemRenderer, | ||
selected, | ||
useResizeHandle, | ||
scrollRef, | ||
resizeEdge, | ||
Layers, | ||
getLeftOffsetFromDate, | ||
rowData, | ||
items, | ||
itemResized, | ||
onDragStart, | ||
onDragEnd, | ||
onResizeStart, | ||
dragging, | ||
resizing, | ||
dragOffset, | ||
interactingItemId, | ||
getLayerRootProps, | ||
getDateFromLeftOffsetPosition, | ||
getItemAbsoluteLocation, | ||
getItemDimensions | ||
} = this.props | ||
return ( | ||
<GroupRowContextProvider | ||
clickTolerance={clickTolerance} | ||
onContextMenu={onRowContextClick} | ||
onClick={onRowClick} | ||
onDoubleClick={onRowDoubleClick} | ||
isEvenRow={index % 2 === 0} | ||
group={groups[index]} | ||
horizontalLineClassNamesForGroup={horizontalLineClassNamesForGroup} | ||
groupHeight={groupHeight} | ||
groupIndex={index} | ||
> | ||
<ColumnsContextProvider | ||
lineCount={_length(groups)} | ||
minUnit={minUnit} | ||
timeSteps={timeSteps} | ||
height={groupHeight} | ||
verticalLineClassNamesForTime={verticalLineClassNamesForTime} | ||
> | ||
<ItemsContextProvider | ||
//TODO: fix groups with no items | ||
items={group.items || []} | ||
groupDimensions={group} | ||
dragSnap={dragSnap} | ||
minResizeWidth={minResizeWidth} | ||
selectedItem={selectedItem} | ||
canChangeGroup={canChangeGroup} | ||
canMove={canMove} | ||
canResize={canResize} | ||
canSelect={canSelect} | ||
moveResizeValidator={moveResizeValidator} | ||
itemSelect={itemSelect} | ||
itemDrag={itemDrag} | ||
itemDrop={itemDrop} | ||
itemResizing={itemResizing} | ||
itemResized={itemResized} | ||
onItemDoubleClick={onItemDoubleClick} | ||
onItemContextMenu={onItemContextMenu} | ||
itemRenderer={itemRenderer} | ||
selected={selected} | ||
useResizeHandle={useResizeHandle} | ||
scrollRef={scrollRef} | ||
order={group} | ||
onDragStart={onDragStart} | ||
onDragEnd={onDragEnd} | ||
onResizeStart={onResizeStart} | ||
resizeEdge={resizeEdge} | ||
dragging={dragging} | ||
resizing={resizing} | ||
dragOffset={dragOffset} | ||
interactingItemId={interactingItemId} | ||
> | ||
<Layers | ||
getLayerRootProps={getLayerRootProps} | ||
helpers={{ | ||
getLeftOffsetFromDate: getLeftOffsetFromDate, | ||
getDateFromLeftOffsetPosition: getDateFromLeftOffsetPosition, | ||
getItemAbsoluteLocation: getItemAbsoluteLocation, | ||
getItemDimensions: getItemDimensions | ||
}} | ||
rowData={rowData} | ||
group={group.group} | ||
itemsWithInteractions={items} | ||
/> | ||
</ItemsContextProvider> | ||
</ColumnsContextProvider> | ||
</GroupRowContextProvider> | ||
) | ||
} | ||
} | ||
export default Rows |
import PropTypes from 'prop-types' | ||
import React, { Component } from 'react' | ||
import moment from 'moment' | ||
import Items from './items/Items' | ||
import Sidebar from './layout/Sidebar' | ||
import Columns from './columns/Columns' | ||
import ScrollElement from './scroll/ScrollElement' | ||
@@ -16,12 +13,7 @@ import MarkerCanvas from './markers/MarkerCanvas' | ||
getMinUnit, | ||
getNextUnit, | ||
calculateTimeForXPosition, | ||
calculateScrollCanvas, | ||
getCanvasBoundariesFromVisibleTime, | ||
getCanvasWidth, | ||
calculateScrollCanvas, | ||
stackTimelineItems, | ||
getItemWithInteractions, | ||
getVisibleItems, | ||
getOrderedGroupsWithItems, | ||
getgroupsWithItemsDimensions, | ||
} from './utility/calendar' | ||
@@ -40,3 +32,2 @@ import { _get, _length } from './utility/generic' | ||
import DateHeader from './headers/DateHeader' | ||
import SidebarHeader from './headers/SidebarHeader' | ||
import DefaultLayer from './rows/DefaultLayer' | ||
@@ -989,3 +980,3 @@ | ||
itemResized={this.resizedItem} | ||
itemResizing={this.resizedItem} | ||
itemResizing={this.resizingItem} | ||
moveResizeValidator={this.props.moveResizeValidator} | ||
@@ -1016,2 +1007,3 @@ itemSelect={this.selectItem} | ||
keys={keys} | ||
resizeEdge={this.state.resizingEdge} | ||
/> | ||
@@ -1018,0 +1010,0 @@ </MarkerCanvas> |
import moment from 'moment' | ||
import { _get } from './generic' | ||
import { _get, arraysEqual } from './generic' | ||
import memoize from 'memoize-one'; | ||
@@ -444,2 +445,4 @@ /** | ||
const aa= [{a: {}}, {b: {}}, {c: {}}] | ||
/** | ||
@@ -525,3 +528,4 @@ * Stack the items that will be visible | ||
canvasTimeEnd, | ||
canvasWidth | ||
canvasWidth, | ||
groups, | ||
) | ||
@@ -628,2 +632,4 @@ const groupHeights = groups.map(group => { | ||
const isResizing = itemId === resizingItem | ||
//return item if is not being dragged or resized | ||
if(!isResizing && !isDragging) return item | ||
const [itemTimeStart, itemTimeEnd] = calculateInteractionNewTimes({ | ||
@@ -813,2 +819,44 @@ itemTimeStart: _get(item, keys.itemTimeStartKey), | ||
} | ||
/** | ||
* shallow compare ordered groups with items | ||
* if index or group changed reference compare then not equal | ||
* if new/old group's items changed array shallow equality then not equal | ||
* @param {*} newGroup | ||
* @param {*} oldGroup | ||
*/ | ||
function shallowIsEqualOrderedGroup(newGroup, oldGroup){ | ||
if(newGroup.group !== oldGroup.group) return false | ||
if(newGroup.index !== oldGroup.index) return false | ||
return arraysEqual(newGroup.items, oldGroup.items) | ||
} | ||
/** | ||
* compare getGroupWithItemDimensions params. All params are compared via reference equality | ||
* only groups are checked via a custom shallow equality | ||
* @param {*} newArgs | ||
* @param {*} oldArgs | ||
*/ | ||
const isEqualItemWithDimensions = (newArgs, oldArgs) => { | ||
const [newGroup, ...newRest] = newArgs; | ||
const [oldGroup, ...oldRest] = oldArgs; | ||
//shallow equality | ||
if(!arraysEqual(newRest, oldRest)) return false; | ||
return shallowIsEqualOrderedGroup(newGroup, oldGroup) | ||
} | ||
/** | ||
* returns a cache in the form of dictionary ([groupId]: cachedMethod) for calculating getGroupWithItemDimensions | ||
* the cache is cleared if groups or keys changed in reference | ||
* @param {*} groups | ||
* @param {*} keys | ||
*/ | ||
const getGroupsCache = memoize((groups, keys)=>{ | ||
return groups.reduce((acc, group) => { | ||
const id = _get(group, keys.groupIdKey); | ||
acc[id] = memoize(getGroupWithItemDimensions, isEqualItemWithDimensions) | ||
return acc | ||
}, {}) | ||
}) | ||
export function getGroupsWithItemDimensions( | ||
@@ -822,8 +870,11 @@ groupsWithItems, | ||
canvasTimeEnd, | ||
canvasWidth | ||
canvasWidth, | ||
groups, | ||
) { | ||
const cache = getGroupsCache(groups, keys) | ||
const groupKeys = Object.keys(groupsWithItems) | ||
return groupKeys.reduce((acc, groupKey) => { | ||
const group = groupsWithItems[groupKey] | ||
acc[groupKey] = getGroupWithItemDimensions( | ||
const cachedGetGroupWithItemDimensions = cache[groupKey]; | ||
acc[groupKey] = cachedGetGroupWithItemDimensions( | ||
group, | ||
@@ -830,0 +881,0 @@ keys, |
551340
10944
1561