lucid-ui
Version:
A UI component library from Xandr.
199 lines • 9.48 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);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DraggableListDumb = void 0;
var lodash_1 = __importDefault(require("lodash"));
var react_1 = __importStar(require("react"));
var prop_types_1 = __importDefault(require("prop-types"));
var style_helpers_1 = require("../../util/style-helpers");
var state_management_1 = require("../../util/state-management");
var DotsIcon_1 = __importDefault(require("../Icon/DotsIcon/DotsIcon"));
var reducers = __importStar(require("./DraggableList.reducers"));
var component_types_1 = require("../../util/component-types");
var cx = style_helpers_1.lucidClassNames.bind('&-DraggableList');
var bool = prop_types_1.default.bool, func = prop_types_1.default.func, object = prop_types_1.default.object, number = prop_types_1.default.number, string = prop_types_1.default.string;
var DraggableListItem = function (_props) { return null; };
DraggableListItem.displayName = 'DraggableList.Item';
DraggableListItem.peek = {
description: "\n\tRenders a `<div>` that acts as an item in the list\n\t",
};
DraggableListItem.propName = 'Item';
DraggableListItem.propTypes = {
children: prop_types_1.default.node /**/,
};
/** Verifies its ok to drop an item given the current drag indexes and
* provides a typeguard that dragIndex and dragOverIndex aren't undefined
*/
var isValidDropIndex = function (dragIndexes) {
var dragOverIndex = dragIndexes.dragOverIndex, dragIndex = dragIndexes.dragIndex;
return (lodash_1.default.isNumber(dragOverIndex) &&
lodash_1.default.isNumber(dragIndex) &&
(dragOverIndex < dragIndex || dragOverIndex > dragIndex + 1));
};
var DraggableList = function (props) {
var style = props.style, className = props.className, dragIndex = props.dragIndex, dragOverIndex = props.dragOverIndex, _a = props.hasDragHandle, hasDragHandle = _a === void 0 ? true : _a, _b = props.onDragStart, onDragStart = _b === void 0 ? lodash_1.default.noop : _b, _c = props.onDragEnd, onDragEnd = _c === void 0 ? lodash_1.default.noop : _c, _d = props.onDragOver, onDragOver = _d === void 0 ? lodash_1.default.noop : _d, _e = props.onDrop, onDrop = _e === void 0 ? lodash_1.default.noop : _e, passThroughs = __rest(props, ["style", "className", "dragIndex", "dragOverIndex", "hasDragHandle", "onDragStart", "onDragEnd", "onDragOver", "onDrop"]);
var lastItemEl = (0, react_1.useRef)(null);
//This object helps handle 'undefined' indexes in a way that makes typescript happy
var dragIndexes = { dragIndex: dragIndex, dragOverIndex: dragOverIndex };
var handleDragStart = function (index) {
return function (event) {
var dataTransfer = event.dataTransfer;
dataTransfer.effectAllowed = 'move';
dataTransfer.dropEffect = 'move';
dataTransfer.setData('drag', 'drag');
onDragStart(index, { event: event, props: props });
};
};
var handleDragEnd = function (event) {
onDragEnd({ event: event, props: props });
if (isValidDropIndex(dragIndexes)) {
onDrop({
oldIndex: dragIndex,
newIndex: dragIndexes.dragOverIndex > dragIndexes.dragIndex
? dragIndexes.dragOverIndex - 1
: dragOverIndex,
}, { event: event, props: props });
}
};
var handleDragOver = function (index) {
return function (event) {
event.preventDefault();
if (dragOverIndex !== index) {
onDragOver(index, { event: event, props: props });
}
};
};
var handleDragLeave = function (event) {
var childCount = (0, component_types_1.findTypes)(props, DraggableList.Item).length;
var currentLastItemEl = lastItemEl.current;
if (currentLastItemEl !== null) {
//@ts-ignore
var bottom = currentLastItemEl.getBoundingClientRect().bottom;
if (lodash_1.default.isFinite(dragIndex) && event.clientY > bottom) {
onDragOver(childCount, { event: event, props: props });
}
}
};
var itemChildProps = lodash_1.default.map((0, component_types_1.findTypes)(props, DraggableList.Item), 'props');
var dividerIndex = isValidDropIndex(dragIndexes)
? dragIndexes.dragOverIndex
: -1;
return (react_1.default.createElement("div", __assign({}, passThroughs, { className: cx('&', {
'&-is-dragging': lodash_1.default.isNumber(dragIndex),
}, className), style: style, onDragLeave: handleDragLeave }),
lodash_1.default.map(itemChildProps, function (itemChildProp, index) {
return (react_1.default.createElement("div", { key: index },
react_1.default.createElement("hr", { className: cx('&-Divider', {
'&-Divider-is-visible': dividerIndex === index,
}) }),
react_1.default.createElement("div", { className: cx('&-Item', {
'&-Item-is-dragging': dragIndex === index,
'&-Item-is-drag-over': dragOverIndex === index,
}, itemChildProp.className), draggable: true, onDragStart: handleDragStart(index), onDragEnd: handleDragEnd, onDragOver: handleDragOver(index) },
react_1.default.createElement("div", __assign({}, itemChildProp, { className: cx('&-Item-content'), ref: index === itemChildProps.length - 1 ? lastItemEl : null })),
hasDragHandle && (react_1.default.createElement("span", { className: cx('&-Item-handle') },
react_1.default.createElement(DotsIcon_1.default, { size: 8 }),
react_1.default.createElement(DotsIcon_1.default, { size: 8 }))))));
}),
react_1.default.createElement("hr", { key: 'divider', className: cx('&-Divider', {
'&-Divider-is-visible': dividerIndex >= itemChildProps.length,
}) })));
};
exports.DraggableListDumb = DraggableList;
DraggableList.Item = DraggableListItem;
DraggableList.displayName = 'DraggableList';
DraggableList.peek = {
description: "A container that renders `divs` in a list that can be drag-and-drop reordered.",
categories: ['controls'],
};
DraggableList.propTypes = {
/**
Appended to the component-specific class names set on the root element.
*/
className: string,
/**
Passed through to the root element.
*/
style: object,
/**
Render a drag handle on list items
*/
hasDragHandle: bool,
/**
Index of the item the drag was started on
*/
dragIndex: number,
/**
Index of the item the dragged item is hovered over
*/
dragOverIndex: number,
/**
Called when the user starts to drag an item.
Signature: \`(dragIndex, { event, props }) => {}\`
*/
onDragStart: func,
/**
Called when the user stops to dragging an item.
Signature: \`({ event, props }) => {}\`
*/
onDragEnd: func,
/**
Called when the user drags an item over another item.
Signature: \`(dragOverIndex, { event, props }) => {}\`
*/
onDragOver: func,
/**
Called when the user drops an item in the list
Signature: \`({oldIndex, newIndex}, { event, props }) => {}\`
*/
onDrop: func,
/**
Props for DraggableList.Item
*/
Item: prop_types_1.default.any,
};
exports.default = (0, state_management_1.buildModernHybridComponent)(DraggableList, { reducers: reducers });
//# sourceMappingURL=DraggableList.js.map