Use in the DropdownMenu
tsx
//https://github.com/semrush/intergalactic/tree/master/website/docs/components/drag-and-drop/examples/list.tsx
import React from 'react';
import Select from '@semcore/ui/select';
import DnD from '@semcore/ui/drag-and-drop';
const initialOptions = Array(6)
.fill(0)
.map((i, idx) => ({
value: idx,
title: `Awesome option ${idx}`,
}));
const Demo = () => {
const [options, setOptions] = React.useState(initialOptions);
const handleDnD = React.useCallback(
({ fromIndex, toIndex }: { fromIndex: number; toIndex: number }) => {
setOptions((options) => {
const newOptions = [...options];
const swap = newOptions[fromIndex];
newOptions[fromIndex] = newOptions[toIndex];
newOptions[toIndex] = swap;
return newOptions;
});
},
[options],
);
return (
<Select multiselect>
<Select.Trigger />
<Select.Menu>
{({ highlightedIndex }) => {
return (
<DnD onDnD={handleDnD} customFocus={highlightedIndex}>
{options.map((option, idx) => {
const { value, title } = option;
return (
<DnD.Draggable tag={Select.Option} value={value} key={idx} pr={5}>
{title}
</DnD.Draggable>
);
})}
</DnD>
);
}}
</Select.Menu>
</Select>
);
};
//https://github.com/semrush/intergalactic/tree/master/website/docs/components/drag-and-drop/examples/list.tsx
import React from 'react';
import Select from '@semcore/ui/select';
import DnD from '@semcore/ui/drag-and-drop';
const initialOptions = Array(6)
.fill(0)
.map((i, idx) => ({
value: idx,
title: `Awesome option ${idx}`,
}));
const Demo = () => {
const [options, setOptions] = React.useState(initialOptions);
const handleDnD = React.useCallback(
({ fromIndex, toIndex }: { fromIndex: number; toIndex: number }) => {
setOptions((options) => {
const newOptions = [...options];
const swap = newOptions[fromIndex];
newOptions[fromIndex] = newOptions[toIndex];
newOptions[toIndex] = swap;
return newOptions;
});
},
[options],
);
return (
<Select multiselect>
<Select.Trigger />
<Select.Menu>
{({ highlightedIndex }) => {
return (
<DnD onDnD={handleDnD} customFocus={highlightedIndex}>
{options.map((option, idx) => {
const { value, title } = option;
return (
<DnD.Draggable tag={Select.Option} value={value} key={idx} pr={5}>
{title}
</DnD.Draggable>
);
})}
</DnD>
);
}}
</Select.Menu>
</Select>
);
};
Use in TabPanel
tsx
import React from 'react';
import DnD from '@semcore/ui/drag-and-drop';
import Badge from '@semcore/ui/badge';
import LinkedInM from '@semcore/ui/icon/LinkedIn/m';
import TabPanel from '@semcore/ui/tab-panel';
const icons = {
social: (
<TabPanel.Item.Addon>
<LinkedInM />
</TabPanel.Item.Addon>
),
issues: (
<TabPanel.Item.Addon>
<Badge bg='red'>new</Badge>
</TabPanel.Item.Addon>
),
};
const titles = {
overview: 'Overview',
issues: 'Issues',
social: 'LinkedIn',
};
const Demo = () => {
const [tabs, setTabs] = React.useState(['overview', 'issues', 'social']);
const [currentTab, setCurrentTab] = React.useState('overview');
const handleDnD = React.useCallback(({ fromIndex, toIndex }) => {
setTabs((tabs) => {
const from = tabs[fromIndex];
tabs[fromIndex] = tabs[toIndex];
tabs[toIndex] = from;
return [...tabs];
});
}, []);
return (
<DnD
tag={TabPanel}
value={currentTab}
onChange={(tab) => setCurrentTab(tab as string)}
onDnD={handleDnD}
>
{tabs.map((tab) => (
<DnD.Draggable placement='bottom' tag={TabPanel.Item} value={tab} key={tab} pb={0}>
{icons[tab] ?? null}
<TabPanel.Item.Text>{titles[tab]}</TabPanel.Item.Text>
</DnD.Draggable>
))}
</DnD>
);
};
import React from 'react';
import DnD from '@semcore/ui/drag-and-drop';
import Badge from '@semcore/ui/badge';
import LinkedInM from '@semcore/ui/icon/LinkedIn/m';
import TabPanel from '@semcore/ui/tab-panel';
const icons = {
social: (
<TabPanel.Item.Addon>
<LinkedInM />
</TabPanel.Item.Addon>
),
issues: (
<TabPanel.Item.Addon>
<Badge bg='red'>new</Badge>
</TabPanel.Item.Addon>
),
};
const titles = {
overview: 'Overview',
issues: 'Issues',
social: 'LinkedIn',
};
const Demo = () => {
const [tabs, setTabs] = React.useState(['overview', 'issues', 'social']);
const [currentTab, setCurrentTab] = React.useState('overview');
const handleDnD = React.useCallback(({ fromIndex, toIndex }) => {
setTabs((tabs) => {
const from = tabs[fromIndex];
tabs[fromIndex] = tabs[toIndex];
tabs[toIndex] = from;
return [...tabs];
});
}, []);
return (
<DnD
tag={TabPanel}
value={currentTab}
onChange={(tab) => setCurrentTab(tab as string)}
onDnD={handleDnD}
>
{tabs.map((tab) => (
<DnD.Draggable placement='bottom' tag={TabPanel.Item} value={tab} key={tab} pb={0}>
{icons[tab] ?? null}
<TabPanel.Item.Text>{titles[tab]}</TabPanel.Item.Text>
</DnD.Draggable>
))}
</DnD>
);
};
Example with use of the drop zone
tsx
import React from 'react';
import DnD from '@semcore/ui/drag-and-drop';
import Card from '@semcore/ui/card';
import { Row, Col } from '@semcore/ui/grid';
const titles = { backlink: 'Backlink', keyword: 'Keyword', seo: 'On Page SEO' };
const Demo = () => {
const [items, setItems] = React.useState(['backlink', 'keyword', 'seo']);
const [saved, setSaved] = React.useState({});
const handleDnD = React.useCallback(({ fromId, toId }) => {
if (toId === 'drop-zone') {
setSaved((saved) => ({ ...saved, [fromId]: true }));
} else {
setItems((items) => {
const newItems = [...items];
const fromIndex = items.indexOf(fromId);
const toIndex = items.indexOf(toId);
newItems[fromIndex] = items[toIndex];
newItems[toIndex] = items[fromIndex];
return newItems;
});
}
}, []);
return (
<DnD tag={Row} gutter={4} onDnD={handleDnD}>
<Col span={12} mb={4}>
<DnD.DropZone h={73} style={{ display: 'flex' }} id='drop-zone'>
{items
.filter((item) => saved[item])
.map((item) => (
<Card key={item} mr={4}>
<Card.Title tag='h4' inline my={0}>
{titles[item]}
</Card.Title>
</Card>
))}
</DnD.DropZone>
</Col>
{items
.filter((item) => !saved[item])
.map((item) => (
<Col span={4} mb={4} key={item}>
<DnD.Draggable placement='top' id={item}>
<Card>
<Card.Title tag='h4' inline my={0}>
{titles[item]}
</Card.Title>
</Card>
</DnD.Draggable>
</Col>
))}
</DnD>
);
};
import React from 'react';
import DnD from '@semcore/ui/drag-and-drop';
import Card from '@semcore/ui/card';
import { Row, Col } from '@semcore/ui/grid';
const titles = { backlink: 'Backlink', keyword: 'Keyword', seo: 'On Page SEO' };
const Demo = () => {
const [items, setItems] = React.useState(['backlink', 'keyword', 'seo']);
const [saved, setSaved] = React.useState({});
const handleDnD = React.useCallback(({ fromId, toId }) => {
if (toId === 'drop-zone') {
setSaved((saved) => ({ ...saved, [fromId]: true }));
} else {
setItems((items) => {
const newItems = [...items];
const fromIndex = items.indexOf(fromId);
const toIndex = items.indexOf(toId);
newItems[fromIndex] = items[toIndex];
newItems[toIndex] = items[fromIndex];
return newItems;
});
}
}, []);
return (
<DnD tag={Row} gutter={4} onDnD={handleDnD}>
<Col span={12} mb={4}>
<DnD.DropZone h={73} style={{ display: 'flex' }} id='drop-zone'>
{items
.filter((item) => saved[item])
.map((item) => (
<Card key={item} mr={4}>
<Card.Title tag='h4' inline my={0}>
{titles[item]}
</Card.Title>
</Card>
))}
</DnD.DropZone>
</Col>
{items
.filter((item) => !saved[item])
.map((item) => (
<Col span={4} mb={4} key={item}>
<DnD.Draggable placement='top' id={item}>
<Card>
<Card.Title tag='h4' inline my={0}>
{titles[item]}
</Card.Title>
</Card>
</DnD.Draggable>
</Col>
))}
</DnD>
);
};