drag drop

This commit is contained in:
Gabriele Cannata 2023-08-25 16:16:03 +02:00
parent d17a7542cd
commit 94a0e4d4ea
7 changed files with 121 additions and 54 deletions

9
package-lock.json generated
View file

@ -10,6 +10,7 @@
"license": "MIT",
"dependencies": {
"@jalik/observer": "github:jalik/js-observer",
"@thisbeyond/solid-dnd": "^0.7.4",
"babel-preset-solid": "^1.7.7",
"solid-js": "^1.7.11"
},
@ -1309,6 +1310,14 @@
"@svgr/core": "^6.0.0"
}
},
"node_modules/@thisbeyond/solid-dnd": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/@thisbeyond/solid-dnd/-/solid-dnd-0.7.4.tgz",
"integrity": "sha512-jgV9EtR3gAtVsILG8p1OAGrhHIgnK4W04YxpyLgJRCDKEFYQWuDrMdUe8F5Kc6pcVXlC4IMXr4cB8fS2Ut3/Ow==",
"peerDependencies": {
"solid-js": "^1.5"
}
},
"node_modules/@types/codemirror": {
"version": "5.60.8",
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.8.tgz",

View file

@ -28,6 +28,7 @@
},
"dependencies": {
"@jalik/observer": "github:jalik/js-observer",
"@thisbeyond/solid-dnd": "^0.7.4",
"babel-preset-solid": "^1.7.7",
"solid-js": "^1.7.11"
}

3
src/Globals.d.ts vendored
View file

@ -9,6 +9,9 @@ declare module "solid-js" {
interface Directives {
// use:clickOutside
clickOutside: ()=>void;
draggable: boolean;
sortable: boolean;
}
}
}

View file

@ -5,6 +5,8 @@ import { ObjectData } from "src/Data/ObjectData";
import { Cell } from "./Cell";
import { Header } from "./Header";
import { useGrid } from "./GridProvider";
import { DragDropProvider, DragDropSensors } from "@thisbeyond/solid-dnd";
import HeaderRow from "./HeaderRow";
// TODO: use https://github.com/minht11/solid-virtual-container
@ -29,14 +31,9 @@ const GridView: Component<{ data: ObjectData[], attributes: AttributeDefinition[
return <div
class="sets-codeblock sets-gridview"
>
<div class="sets-headers-row" style={{ "grid-template-columns": colSizes() }}>
<For each={orderedAttributes()}>{
(attribute, i) => <Header name={attribute.displayName()} key={attribute.key} />
}
</For>
</div>
<HeaderRow colSizes={colSizes()} attributes={orderedAttributes()} />
<div class="sets-gridview-body">
<div class="sets-gridview-grid" >
<For each={props.data}>{(item, i) =>
@ -53,3 +50,6 @@ const GridView: Component<{ data: ObjectData[], attributes: AttributeDefinition[
}
export default GridView;

View file

@ -1,9 +1,14 @@
import { Component } from "solid-js";
import { useGrid } from "./GridProvider";
import {
createSortable,
} from "@thisbeyond/solid-dnd";
export const Header: Component<{ name: string; key: string; }> = (props) => {
const gridContext = useGrid();
const { state, onHover, onExit, shift } = gridContext!;
const sortable = createSortable(props.key);
const onMouseOver = (e) => {
if (gridContext !== undefined) {
@ -21,48 +26,24 @@ export const Header: Component<{ name: string; key: string; }> = (props) => {
const isHovering = () => {
return state?.().hovering === props.key;
}
const drag = (e:DragEvent) => {
if(e.dataTransfer){
e.dataTransfer.setData("text", props.key);
}
}
const dragover = (e:DragEvent) => {
if(e.dataTransfer){
e.dataTransfer.dropEffect = "move";
const data = e.dataTransfer?.getData("text");
if(data !== props.key){
e.preventDefault();
} else {
console.log(data, props.key)
}
}
}
const drop = (e:DragEvent) => {
const data = e.dataTransfer?.getData("text");
e.preventDefault();
data && shift(data, props.key)
}
return (
return (<div class="sets-header-cell"
draggable={true}
classList={{
hovered: isHovering()
}}
ondragover={dragover}
ondragstart={drag}
onmouseover={onMouseOver}
onmouseleave={onMouseLeave}
ondrop={drop}
>
<div class="sets-cell-content">
<div>{props.name}</div>
<div class="sets-column-resizer"></div>
</div>
</div>);
<div class="sets-header-cell"
classList={{
hovered: isHovering()
}}
// use: draggable
use:sortable
onmouseover={onMouseOver}
onmouseleave={onMouseLeave}
>
<div class="sets-cell-content">
<div>{props.name}</div>
<div class="sets-column-resizer"></div>
</div>
</div>
);
};

View file

@ -0,0 +1,66 @@
import { Component, For, createSignal } from "solid-js";
import { Header } from "./Header";
import { AttributeDefinition } from "src/Data/AttributeDefinition";
import { DragDropProvider, DragDropSensors, DragOverlay,SortableProvider,closestCenter
} from "@thisbeyond/solid-dnd";
const HeaderRow:Component<{colSizes: string, attributes: AttributeDefinition[]}> = (props) => {
const [activeItem, setActiveItem] = createSignal(null);
const onDragStart = ({ draggable }) => {
// console.log(`dragStart`, draggable);
setActiveItem(draggable.id);
}
const onDragEnd = ({ draggable, droppable }) => {
if (draggable && droppable) {
const currentItems = props.attributes;
const fromIndex = currentItems.indexOf(draggable.id);
const toIndex = currentItems.indexOf(droppable.id);
console.log(`reorder`,draggable, droppable);
if (fromIndex !== toIndex) {
// const updatedItems = currentItems.slice();
// updatedItems.splice(toIndex, 0, ...updatedItems.splice(fromIndex, 1));
// setItems(updatedItems);
}
}
setActiveItem(null);
};
const activeHeader = () => {
const activeKey = activeItem();
const attr = props.attributes.find(attr => attr.key === activeKey);
return attr?.displayName()
}
const ids = () => props.attributes.map(at => at.key)
return (
<DragDropProvider
onDragStart={onDragStart}
onDragEnd={onDragEnd}
collisionDetector={closestCenter}
>
<DragDropSensors />
<div class="sets-headers-row" style={{ "grid-template-columns": props.colSizes }}>
<SortableProvider ids={ids()}>
<For each={props.attributes}>{(attribute, i) => <Header name={attribute.displayName()} key={attribute.key} />}
</For>
</SortableProvider>
<DragOverlay>
{/* <Header name={"TODO"} key={activeItem()||""} /> */}
{/* <div class="sortable">{activeItem()}</div> */}
<div class="sets-header-draggable">
<div class="sets-cell-content">{activeHeader()}</div>
</div>
</DragOverlay>
</div>
</DragDropProvider>
);
}
export default HeaderRow;

View file

@ -3,6 +3,15 @@
box-shadow: initial;
}
.sets-header-draggable {
text-align: center;
background-color: var(--background-modifier-hover);
height: 36px;
font-family: var(--font-text);
line-height: var(--line-height-normal);
font-size: var(--font-text-size);
}
.sets-codeblock {
padding: 12px;
user-select: none;
@ -31,14 +40,12 @@
margin-left: 16px;
margin-right: 16px;
.sets-header-cell {
text-align: center;
cursor: grab;
// margin-left: 2px;
&:first-child {
// margin-left: 2px;
}
&.hovered {
background-color: var(--background-modifier-hover);