mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-09 20:29:36 +02:00
Add dnd-kit package
This commit is contained in:
Generated
+85
@@ -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",
|
||||||
|
|||||||
@@ -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
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user