mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +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 {
|
import { Button, Flex, Table } from "@radix-ui/themes";
|
||||||
ChevronUpIcon,
|
|
||||||
DoubleArrowDownIcon,
|
|
||||||
DoubleArrowUpIcon,
|
|
||||||
MinusCircledIcon,
|
|
||||||
} from "@radix-ui/react-icons";
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Checkbox,
|
|
||||||
ChevronDownIcon,
|
|
||||||
Flex,
|
|
||||||
IconButton,
|
|
||||||
Table,
|
|
||||||
} from "@radix-ui/themes";
|
|
||||||
import { useLocale } from "../hooks/useLocale";
|
import { useLocale } from "../hooks/useLocale";
|
||||||
import { Playlist } from "../stores/playlist";
|
import { Playlist } from "../stores/playlist";
|
||||||
import { TankRowHeaderCell } from "./TankRowHeaderCell";
|
import { PlaylistTankEntry } from "./PlaylistTankEntry";
|
||||||
|
|
||||||
export function PlaylistOrder() {
|
export function PlaylistOrder() {
|
||||||
const { strings } = useLocale();
|
const { strings } = useLocale();
|
||||||
@@ -47,115 +34,12 @@ export function PlaylistOrder() {
|
|||||||
|
|
||||||
<Table.Body>
|
<Table.Body>
|
||||||
{list.map(({ tank, checked }, index) => (
|
{list.map(({ tank, checked }, index) => (
|
||||||
<Table.Row key={tank.id}>
|
<PlaylistTankEntry
|
||||||
<Table.Cell
|
key={tank.id}
|
||||||
onClick={() => {
|
tank={tank}
|
||||||
Playlist.mutate((draft) => {
|
checked={checked}
|
||||||
draft.list![index].checked = !checked;
|
index={index}
|
||||||
});
|
/>
|
||||||
}}
|
|
||||||
>
|
|
||||||
<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>
|
|
||||||
))}
|
))}
|
||||||
</Table.Body>
|
</Table.Body>
|
||||||
</Table.Root>
|
</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