ehscan-react-components 0.1.43 → 0.1.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Components.d.ts +1 -0
- package/dist/Components.js +1 -0
- package/dist/Window.js +0 -1
- package/dist/dnd/ChecklistItemSquare.d.ts +6 -0
- package/dist/dnd/ChecklistItemSquare.js +11 -0
- package/dist/dnd/DragAndDrop.d.ts +13 -0
- package/dist/dnd/DragAndDrop.js +119 -0
- package/dist/dnd/DragItem.d.ts +12 -0
- package/dist/dnd/DragItem.js +9 -0
- package/dist/style/dnd.module.css +109 -0
- package/dist/tools/Debounce.d.ts +1 -0
- package/dist/tools/Debounce.js +8 -0
- package/package.json +1 -1
package/dist/Components.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export { Window } from './Window';
|
|
|
3
3
|
export { TextArea } from './TextArea';
|
|
4
4
|
export { TextAreaDropDown } from './TextAreaDropDown';
|
|
5
5
|
export { AddBox } from './AddBox';
|
|
6
|
+
export { DragAndDrop } from './dnd/DragAndDrop';
|
|
6
7
|
export { useChangeAddBox } from './tools/useChangeAddBox';
|
package/dist/Components.js
CHANGED
|
@@ -4,4 +4,5 @@ export { Window } from './Window';
|
|
|
4
4
|
export { TextArea } from './TextArea';
|
|
5
5
|
export { TextAreaDropDown } from './TextAreaDropDown';
|
|
6
6
|
export { AddBox } from './AddBox';
|
|
7
|
+
export { DragAndDrop } from './dnd/DragAndDrop';
|
|
7
8
|
export { useChangeAddBox } from './tools/useChangeAddBox';
|
package/dist/Window.js
CHANGED
|
@@ -8,7 +8,6 @@ export const Window = ({ trackMove, open, initialPosition = { x: 600, y: 100 },
|
|
|
8
8
|
const resizeHandleRef = useRef(null);
|
|
9
9
|
const bodyRef = useRef(null);
|
|
10
10
|
const footerRef = useRef(null);
|
|
11
|
-
const [maxHeight] = useState("auto");
|
|
12
11
|
const [bodyPadding] = useState(initialBodyPadding);
|
|
13
12
|
const [windowWidth] = useState(initialWidth);
|
|
14
13
|
useDraggable(open, targetRef, headerRef, bodyRef, resizeHandleRef, bodyPadding, trackMove);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from 'react';
|
|
3
|
+
import styles from '../style/dnd.module.css';
|
|
4
|
+
const ChecklistItemSquare = ({ checked }) => {
|
|
5
|
+
const buttonRef = useRef(null);
|
|
6
|
+
const CheckBoxItemSquare = ({ selected }) => {
|
|
7
|
+
return (_jsx(_Fragment, { children: _jsxs("svg", { className: styles.checkboxSvg, width: "60", height: "60", version: "1.1", viewBox: "0 -960 2400 2400", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("path", { className: styles.checkboxSvgPath, d: "m1200-692.58c-767.96 0-932.58 164.63-932.58 932.58 0 767.98 164.63 932.58 932.58 932.58 767.98 0 932.58-164.63 932.58-932.58 0-767.96-164.63-932.58-932.58-932.58z", fill: "white" }), selected && _jsx("path", { className: styles.checkboxSvgCheck, d: "m1566.4-147.66c-33.43-0.026-66.888 12.734-92.524 38.331l-421.88 421.25-125.8-126.04c-51.193-51.272-133.7-51.348-184.97-0.1555-51.272 51.193-51.348 133.7-0.15551 184.97l218.09 218.48c38.437 38.497 94.554 48.106 141.82 28.846 15.829-6.3918 30.738-15.985 43.618-28.846l514.09-513.39c51.272-51.193 51.348-133.7 0.1554-184.97-25.596-25.636-59.014-38.46-92.446-38.486z", fill: "#666" })] }) }));
|
|
8
|
+
};
|
|
9
|
+
return (_jsx(_Fragment, { children: _jsx("div", { ref: buttonRef, children: _jsx(CheckBoxItemSquare, { selected: checked }) }) }));
|
|
10
|
+
};
|
|
11
|
+
export default ChecklistItemSquare;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface Item {
|
|
3
|
+
id: number;
|
|
4
|
+
label: string;
|
|
5
|
+
selected?: boolean;
|
|
6
|
+
}
|
|
7
|
+
interface Props {
|
|
8
|
+
items: Item[];
|
|
9
|
+
setItems: React.Dispatch<React.SetStateAction<Item[]>>;
|
|
10
|
+
changeItemsAction: (updatedItems: Item[]) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const DragAndDrop: React.FC<Props>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { useState, useRef, useEffect } from 'react';
|
|
12
|
+
import styles from '../style/dnd.module.css';
|
|
13
|
+
import DragItem from './DragItem';
|
|
14
|
+
import { debounce } from "../tools/Debounce";
|
|
15
|
+
export const DragAndDrop = ({ items, setItems, changeItemsAction }) => {
|
|
16
|
+
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
|
|
17
|
+
const [dragPosition, setDragPosition] = useState({ x: 0, y: 0 });
|
|
18
|
+
const [popItem, setPopItem] = useState(null);
|
|
19
|
+
const containerRef = useRef(null);
|
|
20
|
+
const draggingIndexRef = useRef(null);
|
|
21
|
+
const hoverIndexRef = useRef(0);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
console.log(hoverIndexRef.current, draggingIndexRef.current);
|
|
24
|
+
}, [draggingIndexRef, hoverIndexRef]);
|
|
25
|
+
const onMouseDown = (e, index) => {
|
|
26
|
+
const el = document.getElementById(`item-${index}`);
|
|
27
|
+
if (!el)
|
|
28
|
+
return;
|
|
29
|
+
const rect = el.getBoundingClientRect();
|
|
30
|
+
draggingIndexRef.current = index;
|
|
31
|
+
setDragOffset({
|
|
32
|
+
x: e.clientX - rect.left,
|
|
33
|
+
y: e.clientY - rect.top,
|
|
34
|
+
});
|
|
35
|
+
setDragPosition({
|
|
36
|
+
x: rect.left,
|
|
37
|
+
y: rect.top,
|
|
38
|
+
});
|
|
39
|
+
window.addEventListener("mousemove", onMouseMove);
|
|
40
|
+
window.addEventListener("mouseup", onMouseUp);
|
|
41
|
+
};
|
|
42
|
+
const onMouseMove = (e) => {
|
|
43
|
+
setDragPosition({
|
|
44
|
+
x: e.clientX - dragOffset.x,
|
|
45
|
+
y: e.clientY - dragOffset.y,
|
|
46
|
+
});
|
|
47
|
+
const container = containerRef.current;
|
|
48
|
+
if (!container)
|
|
49
|
+
return;
|
|
50
|
+
const rects = Array.from(container.children)
|
|
51
|
+
.filter((_, idx) => idx !== draggingIndexRef.current) // skip placeholder
|
|
52
|
+
.map((child) => child.getBoundingClientRect());
|
|
53
|
+
const mouseY = e.clientY;
|
|
54
|
+
let newHoverIndex = items.length - 1; // default to last
|
|
55
|
+
for (let i = 0; i < rects.length; i++) {
|
|
56
|
+
const r = rects[i];
|
|
57
|
+
if (mouseY < r.top + r.height / 2) {
|
|
58
|
+
newHoverIndex = i;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (newHoverIndex !== hoverIndexRef.current)
|
|
63
|
+
hoverIndexRef.current = newHoverIndex;
|
|
64
|
+
};
|
|
65
|
+
const onMouseUp = () => {
|
|
66
|
+
if (draggingIndexRef.current !== null &&
|
|
67
|
+
hoverIndexRef.current !== null &&
|
|
68
|
+
draggingIndexRef.current !== hoverIndexRef.current) {
|
|
69
|
+
const copy = [...items];
|
|
70
|
+
const dragged = copy[draggingIndexRef.current];
|
|
71
|
+
copy[draggingIndexRef.current] = copy[hoverIndexRef.current];
|
|
72
|
+
copy[hoverIndexRef.current] = dragged;
|
|
73
|
+
setItems(copy);
|
|
74
|
+
changeItemsAction(copy);
|
|
75
|
+
debouncedSave.current(copy); // your existing debounce
|
|
76
|
+
}
|
|
77
|
+
setPopItem(hoverIndexRef.current);
|
|
78
|
+
draggingIndexRef.current = null;
|
|
79
|
+
hoverIndexRef.current = 0;
|
|
80
|
+
setDragPosition({ x: 0, y: 0 });
|
|
81
|
+
setTimeout(() => { setPopItem(null); }, 300);
|
|
82
|
+
window.removeEventListener("mousemove", onMouseMove);
|
|
83
|
+
window.removeEventListener("mouseup", onMouseUp);
|
|
84
|
+
};
|
|
85
|
+
const debouncedSave = useRef(debounce((copy) => {
|
|
86
|
+
const doSave = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
87
|
+
try {
|
|
88
|
+
yield fixRows(copy);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
console.error('Autosave failed:', err);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
doSave();
|
|
95
|
+
}, 800));
|
|
96
|
+
const fixRows = (copy) => __awaiter(void 0, void 0, void 0, function* () {
|
|
97
|
+
const sortedCopy = [...copy]
|
|
98
|
+
.map(item => (Object.assign(Object.assign({}, item), { selected: !!item.selected })))
|
|
99
|
+
.sort((a, b) => Number(b.selected) - Number(a.selected));
|
|
100
|
+
setItems(sortedCopy);
|
|
101
|
+
});
|
|
102
|
+
const clickDragItem = (targetId) => {
|
|
103
|
+
const copy = items.map(item => item.id === targetId ? Object.assign(Object.assign({}, item), { selected: !item.selected }) : item);
|
|
104
|
+
setItems(copy);
|
|
105
|
+
changeItemsAction(copy);
|
|
106
|
+
debouncedSave.current(copy); // your existing debounce
|
|
107
|
+
};
|
|
108
|
+
if (!items)
|
|
109
|
+
return null;
|
|
110
|
+
return (_jsxs("div", { ref: containerRef, className: styles.dndcontainer, children: [items.map((item, index) => {
|
|
111
|
+
const isPoping = index === popItem;
|
|
112
|
+
const isDragging = index === draggingIndexRef.current;
|
|
113
|
+
return (_jsx("div", { style: { width: "100%" }, children: _jsxs("div", { id: `item-${index}`, className: `${styles.listItem} ${isDragging ? styles.placeholder : ''} ${hoverIndexRef.current === index ? styles.hovered : ''} ${isPoping ? styles.pop : ''} ${item.selected ? styles.selected : ''}`, children: [_jsx("div", { className: styles.dragHandle, onMouseDown: (e) => onMouseDown(e, index), children: "\u283F" }), _jsx(DragItem, { item: item, click: clickDragItem })] }) }, item.id));
|
|
114
|
+
}), draggingIndexRef.current !== null && (_jsx("div", { className: styles.dragGhost, style: {
|
|
115
|
+
top: dragPosition.y,
|
|
116
|
+
left: dragPosition.x,
|
|
117
|
+
position: "fixed",
|
|
118
|
+
}, children: items[draggingIndexRef.current].label }))] }));
|
|
119
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type DragItemData = {
|
|
3
|
+
id: number | string;
|
|
4
|
+
label: string;
|
|
5
|
+
selected?: boolean;
|
|
6
|
+
};
|
|
7
|
+
type DragItemProps = {
|
|
8
|
+
item: DragItemData;
|
|
9
|
+
click: (id: number | string) => void;
|
|
10
|
+
};
|
|
11
|
+
declare const DragItem: React.FC<DragItemProps>;
|
|
12
|
+
export default DragItem;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import styles from '../style/dnd.module.css';
|
|
3
|
+
import ChecklistItemSquare from "./ChecklistItemSquare";
|
|
4
|
+
const DragItem = ({ item, click }) => {
|
|
5
|
+
var _a;
|
|
6
|
+
const selected = (_a = item.selected) !== null && _a !== void 0 ? _a : false;
|
|
7
|
+
return (_jsxs("div", { className: styles.itemBody, children: [_jsx("div", { className: styles.dndSelect, onClick: () => click(item.id), children: _jsx(ChecklistItemSquare, { checked: selected }) }), _jsx("div", { children: item.label })] }));
|
|
8
|
+
};
|
|
9
|
+
export default DragItem;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
.dndcontainer {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 10px;
|
|
5
|
+
position: relative;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.horizontal {
|
|
9
|
+
flex-direction: row;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.listItem {
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
background-color: var(--ext-dnd-item-bck-clr, darkblue);
|
|
16
|
+
border-radius: var(--ext-dnd-item-border-radius, 4px);
|
|
17
|
+
padding: var(--ext-dnd-item-padding, 10px);
|
|
18
|
+
transition: transform 0.5s ease;
|
|
19
|
+
color: var(--ext-dnd-item-clr, white);
|
|
20
|
+
height: var(--ext-dnd-item-height, 40px);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
svg.checkboxSvg {
|
|
24
|
+
width: var(--ext-dnd-svg-width, 30px);
|
|
25
|
+
height: var(--ext-dnd-svg-height, 30px);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.checkboxSvgPath {
|
|
29
|
+
fill: var(--ext-dnd-svg-fill, white);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.checkboxSvgCheck {
|
|
33
|
+
fill: var(--ext-dnd-svg-fill-check, lightslategrey);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.listItem:hover {
|
|
37
|
+
filter: brightness(.9);
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.selected {
|
|
42
|
+
background-color: var(--ext-dnd-item-selected-bck-clr,darkviolet);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.hovered {
|
|
46
|
+
background-color: var(--ext-dnd-item-selected-bck-hvr-clr, darkgreen);
|
|
47
|
+
transform: scale(1.03);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.dragHandle {
|
|
51
|
+
cursor: grab;
|
|
52
|
+
padding-right: 5px;
|
|
53
|
+
user-select: none;
|
|
54
|
+
color: var(--ext-dnd-item-handle-clr, #6c8cff);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.dragHandle:active {
|
|
58
|
+
cursor: grabbing;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.itemBody {
|
|
62
|
+
flex: 1;
|
|
63
|
+
display: flex;
|
|
64
|
+
gap: 5px;
|
|
65
|
+
align-items: center;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.dndSelect {
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.placeholder {
|
|
73
|
+
border: 1px dashed #6c8cff;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.dragGhost {
|
|
77
|
+
padding: var(--ext-dnd-item-ghost-padding, 10px);
|
|
78
|
+
background: var(--ext-dnd-item-ghost-bck-clr, white);
|
|
79
|
+
border: var(--ext-dnd-item-ghost-border, 1px solid #6c8cff);
|
|
80
|
+
color: var(--ext-dnd-item-ghost-clr, lightslategrey);
|
|
81
|
+
border-radius: var(--ext-dnd-item-ghost-border-radius, 6px);
|
|
82
|
+
opacity: 0.9;
|
|
83
|
+
pointer-events: none;
|
|
84
|
+
z-index: 9999;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@keyframes popAnimation {
|
|
88
|
+
0% {
|
|
89
|
+
transform: scale(1);
|
|
90
|
+
border-color: #6c8cff;
|
|
91
|
+
box-shadow: 0 0 0 rgba(108, 140, 255, 0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
50% {
|
|
95
|
+
transform: scale(1.05);
|
|
96
|
+
border-color: #5a7fff;
|
|
97
|
+
box-shadow: 0 0 5px rgba(90, 127, 255, 0.3);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
100% {
|
|
101
|
+
transform: scale(1);
|
|
102
|
+
border-color: #6c8cff;
|
|
103
|
+
box-shadow: 0 0 0 rgba(108, 140, 255, 0);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.pop {
|
|
108
|
+
animation: popAnimation 0.2s ease forwards;
|
|
109
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function debounce<T extends (...args: any[]) => void>(func: T, delay: number): T;
|