mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
feat: drag handles
This commit is contained in:
1 parent
cc957466fc
commit
37adc04cda
2 files changed
+72
-124
No files matched your search
@@ -1,20 +1,7 @@
|
||||
import {
|
||||
ChevronUpIcon,
|
||||
DoubleArrowDownIcon,
|
||||
DoubleArrowUpIcon,
|
||||
MinusCircledIcon,
|
||||
} from "@radix-ui/react-icons";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
ChevronDownIcon,
|
||||
Flex,
|
||||
IconButton,
|
||||
Table,
|
||||
} from "@radix-ui/themes";
|
||||
import { Button, Flex, Table } from "@radix-ui/themes";
|
||||
import { useLocale } from "../hooks/useLocale";
|
||||
import { Playlist } from "../stores/playlist";
|
||||
import { TankRowHeaderCell } from "./TankRowHeaderCell";
|
||||
import { PlaylistTankEntry } from "./PlaylistTankEntry";
|
||||
|
||||
export function PlaylistOrder() {
|
||||
const { strings } = useLocale();
|
||||
@@ -47,115 +34,12 @@ export function PlaylistOrder() {
|
||||
|
||||
<Table.Body>
|
||||
{list.map(({ tank, checked }, index) => (
|
||||
<Table.Row key={tank.id}>
|
||||
<Table.Cell
|
||||
onClick={() => {
|
||||
Playlist.mutate((draft) => {
|
||||
draft.list![index].checked = !checked;
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Checkbox variant="classic" checked={checked} />
|
||||
</Table.Cell>
|
||||
|
||||
<TankRowHeaderCell tank={tank} />
|
||||
|
||||
<Table.Cell>
|
||||
<Flex align="center" height="100%" px="2" mb="-1">
|
||||
<IconButton
|
||||
variant="soft"
|
||||
size="1"
|
||||
onClick={() => {
|
||||
Playlist.mutate((draft) => {
|
||||
draft.list!.splice(index, 1);
|
||||
});
|
||||
}}
|
||||
style={{
|
||||
borderTopRightRadius: 0,
|
||||
borderBottomRightRadius: 0,
|
||||
}}
|
||||
>
|
||||
<MinusCircledIcon />
|
||||
</IconButton>
|
||||
|
||||
<IconButton
|
||||
radius="none"
|
||||
disabled={index === list.length - 1}
|
||||
variant="soft"
|
||||
size="1"
|
||||
color="gray"
|
||||
highContrast
|
||||
onClick={() => {
|
||||
const item = list[index];
|
||||
Playlist.mutate((draft) => {
|
||||
draft.list!.splice(index, 1);
|
||||
draft.list!.push(item);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<DoubleArrowDownIcon />
|
||||
</IconButton>
|
||||
|
||||
<IconButton
|
||||
radius="none"
|
||||
disabled={index === 0}
|
||||
variant="soft"
|
||||
size="1"
|
||||
color="gray"
|
||||
onClick={() => {
|
||||
const item = list[index];
|
||||
Playlist.mutate((draft) => {
|
||||
draft.list!.splice(index, 1);
|
||||
draft.list!.unshift(item);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<DoubleArrowUpIcon />
|
||||
</IconButton>
|
||||
|
||||
<IconButton
|
||||
radius="none"
|
||||
disabled={index === list.length - 1}
|
||||
variant="soft"
|
||||
size="1"
|
||||
color="gray"
|
||||
highContrast
|
||||
onClick={() => {
|
||||
const item = list[index];
|
||||
Playlist.mutate((draft) => {
|
||||
const newIndex = index + 1;
|
||||
draft.list!.splice(index, 1);
|
||||
draft.list!.splice(newIndex, 0, item);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<ChevronDownIcon />
|
||||
</IconButton>
|
||||
|
||||
<IconButton
|
||||
disabled={index === 0}
|
||||
variant="soft"
|
||||
size="1"
|
||||
color="gray"
|
||||
highContrast
|
||||
onClick={() => {
|
||||
const item = list[index];
|
||||
Playlist.mutate((draft) => {
|
||||
const newIndex = index - 1;
|
||||
draft.list!.splice(index, 1);
|
||||
draft.list!.splice(newIndex, 0, item);
|
||||
});
|
||||
}}
|
||||
style={{
|
||||
borderTopLeftRadius: 0,
|
||||
borderBottomLeftRadius: 0,
|
||||
}}
|
||||
>
|
||||
<ChevronUpIcon />
|
||||
</IconButton>
|
||||
</Flex>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<PlaylistTankEntry
|
||||
key={tank.id}
|
||||
tank={tank}
|
||||
checked={checked}
|
||||
index={index}
|
||||
/>
|
||||
))}
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import type { TankDefinition } from "@blitzkit/core";
|
||||
import { DragHandleDots2Icon, MinusCircledIcon } from "@radix-ui/react-icons";
|
||||
import { Checkbox, Flex, IconButton, Table, Text } from "@radix-ui/themes";
|
||||
import { Playlist } from "../stores/playlist";
|
||||
import { TankRowHeaderCell } from "./TankRowHeaderCell";
|
||||
|
||||
interface Props {
|
||||
tank: TankDefinition;
|
||||
checked: boolean;
|
||||
index: number;
|
||||
}
|
||||
|
||||
export function PlaylistTankEntry({ tank, checked, index }: Props) {
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell
|
||||
onClick={() => {
|
||||
Playlist.mutate((draft) => {
|
||||
draft.list![index].checked = !checked;
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Checkbox variant="classic" checked={checked} />
|
||||
</Table.Cell>
|
||||
|
||||
<TankRowHeaderCell tank={tank} />
|
||||
|
||||
<Table.Cell>
|
||||
<Flex
|
||||
align="center"
|
||||
height="calc(100% + 2 * var(--space-3) - 2px)"
|
||||
gap="4"
|
||||
pl="2"
|
||||
my="-3"
|
||||
mr="-3"
|
||||
>
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
size="1"
|
||||
onClick={() => {
|
||||
Playlist.mutate((draft) => {
|
||||
draft.list!.splice(index, 1);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<MinusCircledIcon />
|
||||
</IconButton>
|
||||
|
||||
<Flex
|
||||
width="5rem"
|
||||
justify="center"
|
||||
align="center"
|
||||
height="100%"
|
||||
style={{ cursor: "grab", backgroundColor: "var(--gray-1)" }}
|
||||
>
|
||||
<Text color="gray" trim="end">
|
||||
<DragHandleDots2Icon />
|
||||
</Text>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user