mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 04:20:12 +02:00
Add dnd-kit package
This commit is contained in:
Generated
+85
@@ -8,6 +8,8 @@
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "^6.0.5",
|
||||
"@dnd-kit/modifiers": "^6.0.0",
|
||||
"@emotion/react": "^11.9.3",
|
||||
"@jellyfin/client-axios": "^10.7.8",
|
||||
"@mantine/core": "^5.0.0",
|
||||
@@ -790,6 +792,54 @@
|
||||
"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": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz",
|
||||
@@ -23630,6 +23680,41 @@
|
||||
"integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
|
||||
"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": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz",
|
||||
|
||||
@@ -245,6 +245,8 @@
|
||||
"webpack-merge": "^5.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "^6.0.5",
|
||||
"@dnd-kit/modifiers": "^6.0.0",
|
||||
"@emotion/react": "^11.9.3",
|
||||
"@jellyfin/client-axios": "^10.7.8",
|
||||
"@mantine/core": "^5.0.0",
|
||||
|
||||
+32
-3
@@ -1,4 +1,11 @@
|
||||
import { ReactNode, useEffect } from 'react';
|
||||
import {
|
||||
DndContext,
|
||||
MouseSensor,
|
||||
TouchSensor,
|
||||
useSensor,
|
||||
useSensors,
|
||||
} from '@dnd-kit/core';
|
||||
import { MantineProvider } from '@mantine/core';
|
||||
import { useLocalStorage } from '@mantine/hooks';
|
||||
import isElectron from 'is-electron';
|
||||
@@ -27,6 +34,21 @@ export const App = () => {
|
||||
document.body.setAttribute('data-theme', theme);
|
||||
}, [theme]);
|
||||
|
||||
const sensors = useSensors(
|
||||
useSensor(MouseSensor, {
|
||||
activationConstraint: {
|
||||
delay: 200,
|
||||
tolerance: 100,
|
||||
},
|
||||
}),
|
||||
useSensor(TouchSensor, {
|
||||
activationConstraint: {
|
||||
delay: 500,
|
||||
tolerance: 10,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<MantineProvider
|
||||
theme={{
|
||||
@@ -40,15 +62,22 @@ export const App = () => {
|
||||
xl: 18,
|
||||
xs: 10,
|
||||
},
|
||||
|
||||
other: {},
|
||||
spacing: {
|
||||
xs: 2,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<SelectRouter>
|
||||
<AppRouter />
|
||||
</SelectRouter>
|
||||
<DndContext
|
||||
sensors={sensors}
|
||||
onDragEnd={() => console.log('drag end')}
|
||||
onDragStart={() => console.log('drag start')}
|
||||
>
|
||||
<SelectRouter>
|
||||
<AppRouter />
|
||||
</SelectRouter>
|
||||
</DndContext>
|
||||
</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 { motion } from 'framer-motion';
|
||||
import { createPortal } from 'react-dom';
|
||||
import styled from 'styled-components';
|
||||
import { CardRow } from '../../types';
|
||||
import { Draggable } from '../drag-drop/Draggable';
|
||||
import { Text } from '../text/Text';
|
||||
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 cards = [];
|
||||
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
|
||||
useDndMonitor({
|
||||
onDragCancel: () => setIsDragging(false),
|
||||
onDragEnd: () => setIsDragging(false),
|
||||
onDragStart: () => setIsDragging(true),
|
||||
});
|
||||
|
||||
for (let i = startIndex; i <= stopIndex; i += 1) {
|
||||
cards.push(
|
||||
<CardWrapper
|
||||
key={`card-${i}-${index}`}
|
||||
itemGap={itemGap}
|
||||
itemHeight={itemHeight}
|
||||
itemWidth={itemWidth}
|
||||
>
|
||||
<Skeleton visible={!itemData[i]}>
|
||||
<StyledCard>
|
||||
<ImageSection>
|
||||
<Image height={itemWidth} src={itemData[i]?.image}>
|
||||
<ControlsContainer>
|
||||
<GridCardControls
|
||||
cardControls={cardControls}
|
||||
handlePlayQueueAdd={handlePlayQueueAdd}
|
||||
itemData={itemData[i]}
|
||||
/>
|
||||
</ControlsContainer>
|
||||
</Image>
|
||||
</ImageSection>
|
||||
<DetailSection>
|
||||
{cardRows.map((row: CardRow) => (
|
||||
<Row key={`row-${row.prop}`}>
|
||||
<Text overflow="hidden" weight={500}>
|
||||
{itemData[i] && itemData[i][row.prop]}
|
||||
</Text>
|
||||
</Row>
|
||||
))}
|
||||
</DetailSection>
|
||||
</StyledCard>
|
||||
</Skeleton>
|
||||
</CardWrapper>
|
||||
<React.Fragment key={`card-${i}-${index}`}>
|
||||
<Draggable id={`${i}-${index}`}>
|
||||
<CardWrapper
|
||||
itemGap={itemGap}
|
||||
itemHeight={itemHeight}
|
||||
itemWidth={itemWidth}
|
||||
>
|
||||
<Skeleton visible={!itemData[i]}>
|
||||
<StyledCard>
|
||||
<ImageSection>
|
||||
<Image height={itemWidth} src={itemData[i]?.image}>
|
||||
<ControlsContainer>
|
||||
<GridCardControls
|
||||
cardControls={cardControls}
|
||||
handlePlayQueueAdd={handlePlayQueueAdd}
|
||||
itemData={itemData[i]}
|
||||
/>
|
||||
</ControlsContainer>
|
||||
</Image>
|
||||
</ImageSection>
|
||||
<DetailSection>
|
||||
{cardRows.map((row: CardRow) => (
|
||||
<Row key={`row-${row.prop}`}>
|
||||
<Text overflow="hidden" weight={500}>
|
||||
{itemData[i] && itemData[i][row.prop]}
|
||||
</Text>
|
||||
</Row>
|
||||
))}
|
||||
</DetailSection>
|
||||
</StyledCard>
|
||||
</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