@nodeject/ui-components
Version:
UI library for non-trivial components
169 lines (168 loc) • 9.6 kB
JavaScript
"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);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Lane = void 0;
var classcat_1 = require("classcat");
var lodash_1 = require("lodash");
var React = require("react");
var react_1 = require("react");
var react_smooth_dnd_1 = require("@richardrout/react-smooth-dnd");
var hooks_1 = require("../hooks");
var Item_1 = require("../item/Item");
var NewItemButton_1 = require("./components/NewItemButton");
var components_1 = require("./components");
var styles = require("./List.module.less");
var Lane = function (props) {
var list = props.list, Header = props.Header, items = props.items, filter = props.filter;
var refListStart = react_1.useRef();
var refListEnd = react_1.useRef();
var _a = hooks_1.DragDropListsContainer.useContainer(), components = _a.components, showNewItemListId = _a.showNewItemListId, showScrollbar = _a.showScrollbar, toggleShowNewItem = _a.toggleShowNewItem;
var NewItemButton = components.NewItemButton || NewItemButton_1.NewItemButtonDefault;
var showNewItem = list.id === showNewItemListId;
var _b = react_1.useState('none'), newItemPosition = _b[0], setNewItemPosition = _b[1];
var scrollbarClassName = getScrollbarClassName(showScrollbar);
var createNewItemButtonProps = {
NewItemButton: NewItemButton,
listId: list.id,
isDisabled: showNewItem,
refListEnd: refListEnd,
refListStart: refListStart,
setNewItemPosition: setNewItemPosition,
showNewItem: showNewItem,
toggleShowNewItem: toggleShowNewItem
};
// Takes into account invisible items to show button or not.
var showCreateNewItemBottomButton = props.filter.visibleItems.length > 0
? lodash_1.intersection(props.filter.visibleItems, props.list.itemIds)
.length > 0
: props.list.itemIds.length > 0;
var gap = 2; // This is tailwind's rem ratio, not pixels
var gapBetweenCards = "mb-" + gap;
var topCreateBtnMargin = "mb-" + gap;
var bottomCreateBtnMargin = "mt-" + gap;
return (React.createElement("div", { className: styles.listWrapper + " " + scrollbarClassName },
React.createElement("div", { className: styles.list + " " + scrollbarClassName },
Header,
React.createElement(components_1.CreateNewItemButton, __assign({}, createNewItemButtonProps, { className: topCreateBtnMargin })),
React.createElement(ItemListInner, { gapBetweenCards: gapBetweenCards, list: list, items: items, filter: filter, newItemPosition: newItemPosition, refListEnd: refListEnd, refListStart: refListStart, scrollbarClassName: scrollbarClassName }),
showCreateNewItemBottomButton && (React.createElement(components_1.CreateNewItemButton, __assign({}, createNewItemButtonProps, { position: "end", className: bottomCreateBtnMargin }))))));
};
exports.Lane = Lane;
var ItemListInner = function (props) {
var _a;
var droppableProvidedPlaceholder = props.droppableProvidedPlaceholder, filter = props.filter, gapBetweenCards = props.gapBetweenCards, items = props.items, list = props.list, newItemPosition = props.newItemPosition, refListEnd = props.refListEnd, refListStart = props.refListStart, scrollbarClassName = props.scrollbarClassName;
var _b = hooks_1.DragDropListsContainer.useContainer(), classNameItem = _b.classNameItem, itemDragAnimationDuration = _b.itemDragAnimationDuration, itemDropAnimationDuration = _b.itemDropAnimationDuration, components = _b.components, extraProps = _b.extraProps, onDrop = _b.onDropItem, onItemClick = _b.onItemClick, onItemDelete = _b.onItemDelete, showNewItemListId = _b.showNewItemListId;
var Item = components.Item;
var visibleItems = filter.visibleItems || [];
var handleOnItemDelete = function (id) {
onItemDelete({ id: id, listId: list.id });
};
var onDropItem = function (e) {
if (e.addedIndex !== null || e.removedIndex !== null) {
onDrop(list.id, e);
}
};
// Start Performance Improvements
// https://github.com/rcdexta/react-trello/issues/340#issuecomment-704796291
var avgItemHeightInPixels = 100;
var thresholdItemQty = 4;
var _c = react_1.useState({
min: 0,
max: Math.ceil(window.innerHeight / avgItemHeightInPixels) +
thresholdItemQty
}), scrollIndex = _c[0], setScrollIndex = _c[1];
var scrollerRef = react_1.useRef(null);
var cardCount = props.list.itemIds.length;
// End Performance Improvements
var newCardIsVisible = list.id === showNewItemListId;
var dropPlaceholderClassName = classcat_1.default((_a = {},
_a[styles.dropPreview] = true,
_a[gapBetweenCards] = true,
_a));
var itemList = (
// React.useMemo(() => { return (
React.createElement(react_smooth_dnd_1.Container, __assign({ disableScrollOverlapDetection: true, autoScrollEnabled: true }, props.list, { groupName: "col", onDrop: onDropItem, getChildPayload: function (index) { return list.itemIds[index]; }, dragClass: styles.cardGhost, dropClass: styles.cardGhostDrop, dropPlaceholder: {
animationDuration: itemDropAnimationDuration,
showOnTop: false,
className: dropPlaceholderClassName
}, animationDuration: itemDragAnimationDuration }), items.map(function (item, index) {
var _a;
var isVisible = filter.isFiltered
? Boolean(visibleItems.find(function (visibleItem) {
return visibleItem === item.id;
}))
: true;
var itemDraggableContainerClassName = classcat_1.default((_a = {},
_a[gapBetweenCards] = true,
_a[classNameItem] = Boolean(classNameItem),
_a));
var isVisiblePerformance = scrollIndex.min <= index && index <= scrollIndex.max;
return (React.createElement(Item_1.ItemDraggableContainer, __assign({ key: item.id, index: index, isVisible: isVisible, classNameItem: itemDraggableContainerClassName, events: {
onItemClick: onItemClick,
onItemDelete: handleOnItemDelete
}, newCardIsVisible: newCardIsVisible, Item: Item }, item, { extraProps: extraProps, isVisiblePerformance: isVisiblePerformance })));
})));
// )}, [items, Item])
var laneVisibleItems = filter.isFiltered
? lodash_1.intersection(filter.visibleItems, list.itemIds).length
: list.itemIds.length;
var taskListClassName = getTaskListClassName(laneVisibleItems, scrollbarClassName);
return (
// <LaneScrollContext.Provider value={scrollIndex}>
React.createElement("div", { ref: scrollerRef, className: "itemListInner " + taskListClassName + " " + scrollbarClassName,
// @ts-ignore
onScroll: function (e) {
setScrollIndex(function (prev) {
var _a, _b, _c, _d;
// we're using the async version of hook setting here
// because react synthetic event objects are reused e.target may be null here
if (!e.target) {
return prev;
}
var scrollableLaneHeightInCards = Math.ceil(((_d = (_c = (_b = (_a = scrollerRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect) === null || _b === void 0 ? void 0 : _b.call(_a)) === null || _c === void 0 ? void 0 : _c.height) !== null && _d !== void 0 ? _d : window.innerHeight) /
avgItemHeightInPixels);
var nextBaseIndex = Math.floor(
// @ts-ignore
e.target.scrollTop / avgItemHeightInPixels);
var nextMinIndex = Math.min(Math.max(cardCount -
scrollableLaneHeightInCards -
thresholdItemQty, 0), Math.max(nextBaseIndex - thresholdItemQty, 0));
var nextMaxIndex = nextBaseIndex +
scrollableLaneHeightInCards +
thresholdItemQty;
if (nextMinIndex === prev.min &&
nextMaxIndex === prev.max) {
return prev;
}
return {
min: nextMinIndex,
max: nextMaxIndex
};
});
} },
React.createElement(components_1.NewItemCardStart, { list: props.list, show: newItemPosition === 'start', btnRef: refListStart }),
itemList,
droppableProvidedPlaceholder,
React.createElement(components_1.NewItemCardEnd, { list: props.list, btnRef: refListEnd, show: newItemPosition === 'end' }))
// </LaneScrollContext.Provider>
);
};
var getScrollbarClassName = function (showScrollbar) {
return showScrollbar ? styles.fancyScrollbar : styles.disableScrollbars;
};
var getTaskListClassName = function (itemListCount, scrollbarClassName) {
var taskListClassName = styles.itemList + " " + scrollbarClassName;
return itemListCount > 0
? taskListClassName + " " + styles.itemListWithItems
: taskListClassName + " " + styles.itemListNoItems;
};