Add dnd-kit package

This commit is contained in:
jeffvli
2022-07-31 02:14:54 -07:00
parent e1977b291e
commit 9c9cf3a978
5 changed files with 186 additions and 34 deletions
+85
View File
@@ -8,6 +8,8 @@
"hasInstallScript": true, "hasInstallScript": true,
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"@dnd-kit/core": "^6.0.5",
"@dnd-kit/modifiers": "^6.0.0",
"@emotion/react": "^11.9.3", "@emotion/react": "^11.9.3",
"@jellyfin/client-axios": "^10.7.8", "@jellyfin/client-axios": "^10.7.8",
"@mantine/core": "^5.0.0", "@mantine/core": "^5.0.0",
@@ -790,6 +792,54 @@
"node": ">=10.0.0" "node": ">=10.0.0"
} }
}, },
"node_modules/@dnd-kit/accessibility": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz",
"integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==",
"dependencies": {
"tslib": "^2.0.0"
},
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/@dnd-kit/core": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.5.tgz",
"integrity": "sha512-3nL+Zy5cT+1XwsWdlXIvGIFvbuocMyB4NBxTN74DeBaBqeWdH9JsnKwQv7buZQgAHmAH+eIENfS1ginkvW6bCw==",
"dependencies": {
"@dnd-kit/accessibility": "^3.0.0",
"@dnd-kit/utilities": "^3.2.0",
"tslib": "^2.0.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@dnd-kit/modifiers": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-6.0.0.tgz",
"integrity": "sha512-V3+JSo6/BTcgPRHiNUTSKgqVv/doKXg+T4Z0QvKiiXp+uIyJTUtPkQOBRQApUWi3ApBhnoWljyt/3xxY4fTd0Q==",
"dependencies": {
"@dnd-kit/utilities": "^3.2.0",
"tslib": "^2.0.0"
},
"peerDependencies": {
"@dnd-kit/core": "^6.0.0"
}
},
"node_modules/@dnd-kit/utilities": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.0.tgz",
"integrity": "sha512-h65/pn2IPCCIWwdlR2BMLqRkDxpTEONA+HQW3n765HBijLYGyrnTCLa2YQt8VVjjSQD6EfFlTE6aS2Q/b6nb2g==",
"dependencies": {
"tslib": "^2.0.0"
},
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/@electron/get": { "node_modules/@electron/get": {
"version": "1.14.1", "version": "1.14.1",
"resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz", "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz",
@@ -23630,6 +23680,41 @@
"integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
"dev": true "dev": true
}, },
"@dnd-kit/accessibility": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz",
"integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==",
"requires": {
"tslib": "^2.0.0"
}
},
"@dnd-kit/core": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.5.tgz",
"integrity": "sha512-3nL+Zy5cT+1XwsWdlXIvGIFvbuocMyB4NBxTN74DeBaBqeWdH9JsnKwQv7buZQgAHmAH+eIENfS1ginkvW6bCw==",
"requires": {
"@dnd-kit/accessibility": "^3.0.0",
"@dnd-kit/utilities": "^3.2.0",
"tslib": "^2.0.0"
}
},
"@dnd-kit/modifiers": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-6.0.0.tgz",
"integrity": "sha512-V3+JSo6/BTcgPRHiNUTSKgqVv/doKXg+T4Z0QvKiiXp+uIyJTUtPkQOBRQApUWi3ApBhnoWljyt/3xxY4fTd0Q==",
"requires": {
"@dnd-kit/utilities": "^3.2.0",
"tslib": "^2.0.0"
}
},
"@dnd-kit/utilities": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.0.tgz",
"integrity": "sha512-h65/pn2IPCCIWwdlR2BMLqRkDxpTEONA+HQW3n765HBijLYGyrnTCLa2YQt8VVjjSQD6EfFlTE6aS2Q/b6nb2g==",
"requires": {
"tslib": "^2.0.0"
}
},
"@electron/get": { "@electron/get": {
"version": "1.14.1", "version": "1.14.1",
"resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz", "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz",
+2
View File
@@ -245,6 +245,8 @@
"webpack-merge": "^5.8.0" "webpack-merge": "^5.8.0"
}, },
"dependencies": { "dependencies": {
"@dnd-kit/core": "^6.0.5",
"@dnd-kit/modifiers": "^6.0.0",
"@emotion/react": "^11.9.3", "@emotion/react": "^11.9.3",
"@jellyfin/client-axios": "^10.7.8", "@jellyfin/client-axios": "^10.7.8",
"@mantine/core": "^5.0.0", "@mantine/core": "^5.0.0",
+32 -3
View File
@@ -1,4 +1,11 @@
import { ReactNode, useEffect } from 'react'; import { ReactNode, useEffect } from 'react';
import {
DndContext,
MouseSensor,
TouchSensor,
useSensor,
useSensors,
} from '@dnd-kit/core';
import { MantineProvider } from '@mantine/core'; import { MantineProvider } from '@mantine/core';
import { useLocalStorage } from '@mantine/hooks'; import { useLocalStorage } from '@mantine/hooks';
import isElectron from 'is-electron'; import isElectron from 'is-electron';
@@ -27,6 +34,21 @@ export const App = () => {
document.body.setAttribute('data-theme', theme); document.body.setAttribute('data-theme', theme);
}, [theme]); }, [theme]);
const sensors = useSensors(
useSensor(MouseSensor, {
activationConstraint: {
delay: 200,
tolerance: 100,
},
}),
useSensor(TouchSensor, {
activationConstraint: {
delay: 500,
tolerance: 10,
},
})
);
return ( return (
<MantineProvider <MantineProvider
theme={{ theme={{
@@ -40,15 +62,22 @@ export const App = () => {
xl: 18, xl: 18,
xs: 10, xs: 10,
}, },
other: {}, other: {},
spacing: { spacing: {
xs: 2, xs: 2,
}, },
}} }}
> >
<SelectRouter> <DndContext
<AppRouter /> sensors={sensors}
</SelectRouter> onDragEnd={() => console.log('drag end')}
onDragStart={() => console.log('drag start')}
>
<SelectRouter>
<AppRouter />
</SelectRouter>
</DndContext>
</MantineProvider> </MantineProvider>
); );
}; };
@@ -0,0 +1,14 @@
import { useDraggable } from '@dnd-kit/core';
export const Draggable = ({ element, id, children, key }: any) => {
const Element = element || 'div';
const { attributes, listeners, setNodeRef } = useDraggable({
id,
});
return (
<Element key={key} ref={setNodeRef} {...listeners} {...attributes}>
{children}
</Element>
);
};
@@ -1,7 +1,12 @@
import React, { useState } from 'react';
import { DragOverlay, useDndMonitor } from '@dnd-kit/core';
import { snapCenterToCursor } from '@dnd-kit/modifiers';
import { Card, Skeleton } from '@mantine/core'; import { Card, Skeleton } from '@mantine/core';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { createPortal } from 'react-dom';
import styled from 'styled-components'; import styled from 'styled-components';
import { CardRow } from '../../types'; import { CardRow } from '../../types';
import { Draggable } from '../drag-drop/Draggable';
import { Text } from '../text/Text'; import { Text } from '../text/Text';
import { GridCardControls } from './GridCardControls'; import { GridCardControls } from './GridCardControls';
@@ -98,39 +103,56 @@ export const GridCard = ({ data, index, style }: any) => {
const stopIndex = Math.min(itemCount - 1, startIndex + columnCount - 1); const stopIndex = Math.min(itemCount - 1, startIndex + columnCount - 1);
const cards = []; const cards = [];
const [isDragging, setIsDragging] = useState(false);
useDndMonitor({
onDragCancel: () => setIsDragging(false),
onDragEnd: () => setIsDragging(false),
onDragStart: () => setIsDragging(true),
});
for (let i = startIndex; i <= stopIndex; i += 1) { for (let i = startIndex; i <= stopIndex; i += 1) {
cards.push( cards.push(
<CardWrapper <React.Fragment key={`card-${i}-${index}`}>
key={`card-${i}-${index}`} <Draggable id={`${i}-${index}`}>
itemGap={itemGap} <CardWrapper
itemHeight={itemHeight} itemGap={itemGap}
itemWidth={itemWidth} itemHeight={itemHeight}
> itemWidth={itemWidth}
<Skeleton visible={!itemData[i]}> >
<StyledCard> <Skeleton visible={!itemData[i]}>
<ImageSection> <StyledCard>
<Image height={itemWidth} src={itemData[i]?.image}> <ImageSection>
<ControlsContainer> <Image height={itemWidth} src={itemData[i]?.image}>
<GridCardControls <ControlsContainer>
cardControls={cardControls} <GridCardControls
handlePlayQueueAdd={handlePlayQueueAdd} cardControls={cardControls}
itemData={itemData[i]} handlePlayQueueAdd={handlePlayQueueAdd}
/> itemData={itemData[i]}
</ControlsContainer> />
</Image> </ControlsContainer>
</ImageSection> </Image>
<DetailSection> </ImageSection>
{cardRows.map((row: CardRow) => ( <DetailSection>
<Row key={`row-${row.prop}`}> {cardRows.map((row: CardRow) => (
<Text overflow="hidden" weight={500}> <Row key={`row-${row.prop}`}>
{itemData[i] && itemData[i][row.prop]} <Text overflow="hidden" weight={500}>
</Text> {itemData[i] && itemData[i][row.prop]}
</Row> </Text>
))} </Row>
</DetailSection> ))}
</StyledCard> </DetailSection>
</Skeleton> </StyledCard>
</CardWrapper> </Skeleton>
</CardWrapper>
</Draggable>
{createPortal(
<DragOverlay dropAnimation={null} modifiers={[snapCenterToCursor]}>
{isDragging ? <div>OVERLAY</div> : null}
</DragOverlay>,
document.body
)}
</React.Fragment>
); );
} }