Skip to content

Commit

Permalink
Merge pull request #6 from JollyGrin/feat/aura
Browse files Browse the repository at this point in the history
Feat/aura
  • Loading branch information
JollyGrin authored Sep 8, 2024
2 parents cbd6575 + 632c1ac commit 0f5c987
Show file tree
Hide file tree
Showing 18 changed files with 992 additions and 87 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
"dependencies": {
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/sortable": "^8.0.0",
"@radix-ui/react-dialog": "^1.1.1",
"@shadow-panda/style-context": "^0.7.1",
"lucide-react": "^0.439.0",
"next": "14.2.8",
"react": "^18",
"react-dom": "^18"
Expand Down
431 changes: 431 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions src/components/atoms/Modal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { DialogProps } from "@radix-ui/react-dialog";
import { ReactNode } from "react";

export const Modal = (props: {
wrapperProps: DialogProps;
trigger?: ReactNode;
title?: string;
content?: ReactNode;
}) => {
return (
<Dialog {...props.wrapperProps}>
<DialogTrigger>{props.trigger}</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>{props.title}</DialogTitle>
<DialogDescription>{props.content}</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
);
};
33 changes: 33 additions & 0 deletions src/components/atoms/card-view/atlas.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Box } from "styled-system/jsx";

export const FullCardAtlas = ({
img = "atlas_rift_valley.webp",
}: {
img?: string;
}) => {
return (
<Box
position="relative"
m="0.5rem auto"
w="inherit"
h="inherit"
borderRadius="1rem"
isolation="isolate"
>
<Box
style={{ backgroundImage: `url(/mock-cards/${img})` }} // bgImage has caching issues
isolation="isolate"
w="100%"
h="100%"
// position="absolute"
backgroundPosition="right"
backgroundSize="cover"
backgroundRepeat="no-repeat"
transform="rotate(90deg)"
bg="gray.400"
borderRadius="1rem"
transition="all 0.25s ease"
/>
</Box>
);
};
37 changes: 37 additions & 0 deletions src/components/atoms/card-view/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Box } from "styled-system/jsx";

export const CardImage = ({
img = "headless_haunt.webp",
position = "top",
}: {
img?: string;
position?: "top" | "bottom";
}) => {
return (
<Box
w="inherit"
h="inherit"
position="relative"
m="0.5rem auto"
borderRadius="1rem"
mb={position === "top" ? "unset" : "unset"}
mt={position === "bottom" ? "-0.25rem" : "unset"}
isolation="isolate"
transform="unset"
opacity="1"
transition="all 0.25s ease"
>
<Box
style={{ backgroundImage: `url(/mock-cards/${img})` }}
w="100%"
h="100%"
minH="300px"
backgroundPosition="top"
backgroundSize="contain"
backgroundRepeat="no-repeat"
transition="all 0.25s ease"
// bg="gray.400"
/>{" "}
</Box>
);
};
3 changes: 2 additions & 1 deletion src/components/atoms/mock-cards/atlas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export const CardAtlas = ({
}
}, [isPressed]);

const show = preview && isHovering; // full preview of the card
// const show = preview && isHovering; // full preview of the card
const show = false;
return (
<Box
position="relative"
Expand Down
4 changes: 3 additions & 1 deletion src/components/atoms/mock-cards/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ export const CardImage = ({
position = "top",
index = 1,
isTapped,
...props
}: {
img?: string;
position?: "top" | "bottom";
index?: number;
isTapped?: boolean;
show?: boolean;
}) => {
const hoverRef = useRef(null);
const isHovering = useHover(hoverRef);
Expand All @@ -25,7 +27,7 @@ export const CardImage = ({
}
}, [isPressed]);

const show = preview && isHovering;
const show = props.show || (preview && isHovering);

return (
<Box
Expand Down
10 changes: 8 additions & 2 deletions src/components/molecules/DragItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useDraggable } from "@dnd-kit/core";
import { ReactNode } from "react";
import { CSSProperties, ReactNode } from "react";

export const DragItem = (props: {
children: ReactNode;
gridIndex: number;
index: number;
style?: CSSProperties;
}) => {
const { attributes, listeners, setNodeRef, transform } = useDraggable({
id: `${props.gridIndex}-${props.index}`,
Expand All @@ -20,7 +21,12 @@ export const DragItem = (props: {
: undefined;

return (
<div ref={setNodeRef} style={style} {...listeners} {...attributes}>
<div
ref={setNodeRef}
style={{ ...style, ...props?.style }}
{...listeners}
{...attributes}
>
{props.children}
</div>
);
Expand Down
7 changes: 6 additions & 1 deletion src/components/molecules/DropGridItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from "react";
import { CSSProperties, ReactNode } from "react";
import { css } from "styled-system/css";
import { Box } from "styled-system/jsx";
import { useDroppable } from "@dnd-kit/core";
Expand All @@ -7,6 +7,7 @@ export const DroppableGridItem = (props: {
children: ReactNode;
id: string;
gridIndex: number;
style?: CSSProperties;
}) => {
const { isOver, setNodeRef } = useDroppable({
id: "droppable-" + props.id,
Expand All @@ -17,11 +18,15 @@ export const DroppableGridItem = (props: {
<div
data-testid={"droppable-" + props.id}
ref={setNodeRef}
style={props.style}
className={css({
h: "100%",
w: "100%",
position: "relative",
})}
onContextMenu={(e) => {
e.preventDefault();
}}
>
{props.children}
<Box
Expand Down
16 changes: 16 additions & 0 deletions src/components/organisms/GameBoard/Auras/AuraDrop.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { DroppableGridItem } from "@/components/molecules/DropGridItem";
import { ReactNode } from "react";

export const AuraDrop = ({
gridIndex,
children,
}: {
gridIndex: number;
children: ReactNode;
}) => {
return (
<DroppableGridItem id={gridIndex.toString()} gridIndex={gridIndex}>
{children}
</DroppableGridItem>
);
};
111 changes: 111 additions & 0 deletions src/components/organisms/GameBoard/Auras/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { Box } from "styled-system/jsx";
import { AuraDrop } from "./AuraDrop";
import { GameStateActions } from "..";
import { DragItem } from "@/components/molecules/DragItem";
import { GameCard } from "@/pages/game";
import { useState } from "react";
import { Modal } from "@/components/atoms/Modal";
import { FullCardAtlas } from "@/components/atoms/card-view/atlas";
import { CardImage as FullCard } from "@/components/atoms/card-view/card";

export const Auras = (props: GameStateActions) => {
return (
<Box position="absolute" w="100%" h="100%">
{Array.from({ length: 12 }).map((_, index) => (
<Aura
key={"aura" + index}
card={props.gridItems?.[21 + index]?.[0]}
gridIndex={21 + index}
index={0}
/>
))}
</Box>
);
};

const Aura = (props: { card: GameCard; gridIndex: number; index: number }) => {
const auraCard = props.card;

const auraIndex = props.gridIndex - 21; // normalize to zero
const topIndex = Math.floor(auraIndex / 4) + 1; // increments every 4
const top = `${topIndex * 25}%`; // in percent
const leftIndex = 1 + (auraIndex % 4); // every 4, resets
const left = `${leftIndex * 20}%`; // in percent

return (
<Box
style={{
top,
left,
}}
position="absolute"
w="75px"
h="75px"
transform="translate(-50%, -50%)" /* Center the box */
_hover={{
border: "solid 5px rgba(0,100,200,0.5)",
borderRadius: "1rem",
}}
>
{!auraCard?.id && (
<AuraDrop gridIndex={props.gridIndex}>
<Box
w="100%"
h="100%"
backgroundSize="cover"
transform="rotate(90deg)"
borderRadius="0.5rem"
/>
</AuraDrop>
)}
{auraCard?.id && (
<DragWrapper gridIndex={props.gridIndex} index={0} card={auraCard} />
)}
</Box>
);
};

const DragWrapper = ({
card,
...props
}: {
gridIndex: number;
index: number;
card: GameCard;
}) => {
const [preview, setPreview] = useState(false);
return (
<div style={{ width: "100%", height: "100%" }}>
<DragItem
gridIndex={props.gridIndex}
index={props.index}
style={{ width: "100%", height: "100%", zIndex: 1000 }}
>
<Box
w="100%"
h="100%"
backgroundSize="200%"
backgroundPosition="10% 20%"
transform={card?.type === "site" ? "rotate(90deg)" : ""}
borderRadius="0.5rem"
style={{
backgroundImage: `url(/mock-cards/${card?.img})`,
}}
onContextMenu={(e) => {
e.preventDefault();
setPreview(true);
}}
/>
</DragItem>
<Modal
wrapperProps={{ open: preview, onOpenChange: setPreview }}
content={
<Box h="600px">
{card?.type === "site" && <FullCardAtlas img={card?.img} />}
{card?.type !== "site" && <FullCard img={card?.img} />}
</Box>
}
/>
</div>
);
};
2 changes: 1 addition & 1 deletion src/components/organisms/GameBoard/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { CardImage } from "@/components/atoms/mock-cards/card";
export const GameFooter = (props: GameStateActions) => {
const gridIndex = 20;
const cardsInHand = props.gridItems[gridIndex] ?? [];
console.log({ cardsInHand });

return (
<div
data-testid="footer"
Expand Down
Loading

0 comments on commit 0f5c987

Please sign in to comment.