UNPKG

lucid-ui

Version:

A UI component library from Xandr.

199 lines 9.48 kB
"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