Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] feat: add Bars components #351

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ const config: StorybookConfig = {
const fileLoaderRules = config.module?.rules?.filter(
(rule) =>
rule !== "..." &&
rule.test &&
rule &&
rule.test instanceof RegExp &&
rule.test.test(".svg")
);

fileLoaderRules?.forEach((rule) => {
if (rule !== "...") rule.exclude = /\.svg$/;
if (rule && rule !== "...") rule.exclude = /\.svg$/;
});

config.module?.rules?.push({
Expand Down
7 changes: 6 additions & 1 deletion .storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ const preview: Preview = {
parameters: {
backgrounds: {
default: "Dark",
values: [{ name: "Dark", value: "#1E1F22" }],
values: [
{
name: "Dark",
value: "linear-gradient(145.51deg, #06020B -7.4%, #2C1B47 154.79%)",
},
],
},
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
Expand Down
2 changes: 1 addition & 1 deletion components/shared/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default function Avatar({

const avatarSizeVariants = {
default: `w-[34px] h-[34px]`,
small: `w-[28px] h-[28px]`,
small: `w-[24px] h-[24px]`,
large: `w-[40px] h-[40px]`,
};

Expand Down
20 changes: 20 additions & 0 deletions components/shared/Bars/v2/MenuBar/MenuBar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Meta, StoryObj } from "@storybook/react";

import MenuBar from "./index";

const meta: Meta<typeof MenuBar> = {
title: "Bars/MenuBar",
component: MenuBar,
tags: ["autodocs"],
argTypes: {},
};

export default meta;

type PlaygroudStory = StoryObj<typeof MenuBar>;

export const Playgroud: PlaygroudStory = {
render: (args) => <MenuBar {...args}></MenuBar>,
};

Playgroud.args = {};
13 changes: 13 additions & 0 deletions components/shared/Bars/v2/MenuBar/MenuBar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { cleanup, render, screen } from "@testing-library/react";
import MenuBar from "./MenuBar";
import "@testing-library/jest-dom";
import React from "react";

describe("MenuBar", () => {
afterEach(cleanup);

it("MenuBar", () => {
render(<MenuBar />);
expect(screen.getByText("遊戲微服務大平台")).toBeInTheDocument();
});
});
25 changes: 25 additions & 0 deletions components/shared/Bars/v2/MenuBar/MenuBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { PropsWithChildren } from "react";
import Icon from "@/components/shared/Icon";

interface TagProps extends React.ComponentPropsWithoutRef<"div"> {}

const NavBar = ({}: PropsWithChildren<TagProps>) => {
return (
<div
className={
"flex items-start justify-center w-[72px] h-[648px] px-1 pt-6 pb-14 rounded-[16px] gradient-black"
}
>
<div id={"btn-group"} className={"flex flex-col"}>
<div className={"w-12 h-12 p-3"}>
<Icon name="chat" className="w-6 h-6 stroke-gray-500" />
</div>
<div className={"w-12 h-12 p-3 mt-4"}>
<Icon name="notification" className="w-6 h-6 stroke-gray-500" />
</div>
</div>
</div>
);
};

export default NavBar;
5 changes: 5 additions & 0 deletions components/shared/Bars/v2/MenuBar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import NarBar from "./MenuBar";

export * from "./MenuBar";

export default NarBar;
20 changes: 20 additions & 0 deletions components/shared/Bars/v2/NavBar/NavBar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Meta, StoryObj } from "@storybook/react";

import NavBar from "./index";

const meta: Meta<typeof NavBar> = {
title: "Bars/NavBar",
component: NavBar,
tags: ["autodocs"],
argTypes: {},
};

export default meta;

type PlaygroudStory = StoryObj<typeof NavBar>;

export const Playgroud: PlaygroudStory = {
render: (args) => <NavBar {...args}></NavBar>,
};

Playgroud.args = {};
13 changes: 13 additions & 0 deletions components/shared/Bars/v2/NavBar/NavBar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { cleanup, render, screen } from "@testing-library/react";
import NavBar from "./NavBar";
import "@testing-library/jest-dom";
import React from "react";

describe("NavBar", () => {
afterEach(cleanup);

it("NavBar", () => {
render(<NavBar />);
expect(screen.getByText("遊戲微服務大平台")).toBeInTheDocument();
});
});
37 changes: 37 additions & 0 deletions components/shared/Bars/v2/NavBar/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { PropsWithChildren } from "react";
import Icon from "@/components/shared/Icon";

interface TagProps extends React.ComponentPropsWithoutRef<"div"> {}

const NavBar = ({}: PropsWithChildren<TagProps>) => {
return (
<div
className={
"flex items-center justify-between h-14 pl-2 pr-4 py-1 gradient-black"
}
>
<div id={"logo"} className={"flex px-2.5 items-center"}>
<div
id={"leading-icon"}
className={"flex flex-col w-12 h-12 p-2 items-center justify-center"}
>
<Icon name="logo" className="w-6 h-6" />
</div>
<div className={"ml-1 text-primary-100"}>遊戲微服務大平台</div>
</div>
<div id={"btn-group"} className={"flex"}>
<div className={"w-12 h-12 p-3"}>
<Icon name="chat" className="w-6 h-6 stroke-gray-500" />
</div>
<div className={"w-12 h-12 p-3 ml-3"}>
<Icon name="notification" className="w-6 h-6 stroke-gray-500" />
</div>
<div className={"w-12 h-12 p-3 ml-3"}>
<Icon name="player" className="w-6 h-6 stroke-gray-500" />
</div>
</div>
</div>
);
};

export default NavBar;
5 changes: 5 additions & 0 deletions components/shared/Bars/v2/NavBar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import NarBar from "./NavBar";

export * from "./NavBar";

export default NarBar;
22 changes: 22 additions & 0 deletions components/shared/Bars/v2/SearchBar/NavHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Icon from "@/components/shared/Icon";
import { IconName } from "@/components/shared/Icon/icons";

type Props = {
svg: IconName;
text: string;
};

const NavHeader = ({ svg, text }: Readonly<Props>) => {
return (
<div className="self-stretch h-14 rounded-[100px] justify-start items-center gap-3 inline-flex">
<div className="grow shrink basis-0 self-stretch px-6 py-4 justify-start items-center gap-3 flex">
<Icon name={svg} className="w-6 h-6 stroke-white"></Icon>
<div className="grow shrink basis-0 text-violet-200 text-sm font-medium font-['Noto Sans TC'] leading-[21px]">
{text}
</div>
</div>
</div>
);
};

export default NavHeader;
17 changes: 17 additions & 0 deletions components/shared/Bars/v2/SearchBar/NavItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
type Props = {
text: string;
};

const NavItem = ({ text }: Readonly<Props>) => {
return (
<button className="self-stretch h-14 hover:bg-white hover:bg-opacity-10 active:bg-violet-300 active:bg-opacity-20 rounded-[100px] justify-start items-center gap-3 inline-flex">
<div className="grow shrink basis-0 self-stretch px-6 py-4 justify-start items-center gap-3 flex">
<div className="grow shrink basis-0 text-start text-violet-200 text-sm font-medium font-['Noto Sans TC'] leading-[21px]">
{text}
</div>
</div>
</button>
);
};

export default NavItem;
20 changes: 20 additions & 0 deletions components/shared/Bars/v2/SearchBar/SearchBar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Meta, StoryObj } from "@storybook/react";

import SearchBar from "./index";

const meta: Meta<typeof SearchBar> = {
title: "Bars/SearchBar",
component: SearchBar,
tags: ["autodocs"],
argTypes: {},
};

export default meta;

type PlaygroudStory = StoryObj<typeof SearchBar>;

export const Playgroud: PlaygroudStory = {
render: (args) => <SearchBar {...args}></SearchBar>,
};

Playgroud.args = {};
13 changes: 13 additions & 0 deletions components/shared/Bars/v2/SearchBar/SearchBar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { cleanup, render, screen } from "@testing-library/react";
import SearchBar from "./SearchBar";
import "@testing-library/jest-dom";
import React from "react";

describe("SearchBar", () => {
afterEach(cleanup);

it("SearchBar", () => {
render(<SearchBar />);
expect(screen.getByText("遊戲微服務大平台")).toBeInTheDocument();
});
});
34 changes: 34 additions & 0 deletions components/shared/Bars/v2/SearchBar/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from "react";
import SearchBarDumb from "./SearchBarDumb";
import SearchDrawer from "./SearchDrawer";

interface Props extends React.ComponentPropsWithoutRef<"div"> {}

const SearchBar = ({}: Readonly<Props>) => {
const [showDrawer, setShowDrawer] = React.useState(false);

const handleClick = () => {
setShowDrawer(!showDrawer);
};

const category = {
action: ["格鬥和武術", "第一人稱射擊", "第三人稱射擊", "街機和節奏"],
adventure: ["休閒", "劇情豐富", "視覺小說"],
simulation: ["太空和飛行", "建造和自動化", "戀愛", "沙盒和物理"],
strategy: ["卡牌和棋盤", "即時策略", "回合制策略"],
};

return (
<div>
<SearchBarDumb onClick={handleClick}></SearchBarDumb>
{showDrawer ? (
<SearchDrawer
category={category}
className="absolute mt-6"
></SearchDrawer>
) : null}
</div>
);
};

export default SearchBar;
43 changes: 43 additions & 0 deletions components/shared/Bars/v2/SearchBar/SearchBarDumb.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Icon from "@/components/shared/Icon";

type Props = {
onClick: () => void;
};

const SearchBarDumb = ({ onClick }: Readonly<Props>) => {
const clickButton = () => () => onClick();

return (
<div
className={
"flex items-start justify-center w-[484px] p-1 pl-4 rounded-[40px] bg-white/8 backdrop-blur-[20px]"
}
>
<button
className={
"flex flex-grow flex-shrink-0 flex-basis-0 items-center justify-center px-3 py-2.5 rounded-[100px] text-primary-300 hover:bg-white/8 active:bg-[#CEBFEF] active:bg-white/20"
}
onClick={clickButton()}
>
類型
</button>
<div
id={"search-bar"}
className={
"flex flex-grow flex-shrink-0 flex-basis-0 items-center h-11 pl-4 pr-1 ml-4 rounded-[28px] text-gray-500 bg-white/8 backdrop-blur-[60px]"
}
>
<input
type={"text"}
className={"w-[324px] bg-transparent"}
placeholder={"在此輸入今天想玩的遊戲"}
/>
<div className={"w-11 h-11 p-2.5 ml-1"}>
<Icon name="search" className="w-6 h-6 [&_*]:stroke-white" />
</div>
</div>
</div>
);
};

export default SearchBarDumb;
55 changes: 55 additions & 0 deletions components/shared/Bars/v2/SearchBar/SearchDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { cn } from "@/lib/utils";
import NavHeader from "@/components/shared/Bars/v2/SearchBar/NavHeader";
import NavItem from "@/components/shared/Bars/v2/SearchBar/NavItem";

type Props = {
className?: string;
category: {
action: string[];
adventure: string[];
simulation: string[];
strategy: string[];
};
};

const SearchDrawer = ({ className, category }: Readonly<Props>) => {
return (
<div
className={cn(
"w-[484px] pb-2 bg-zinc-950 bg-opacity-40 rounded-2xl shadow border border-slate-500 backdrop-blur-[104.20px] flex-col justify-start items-center inline-flex",
className
)}
>
<div className="w-[484px] p-3 rounded-2xl justify-start items-center gap-4 inline-flex bg-opacity-4">
<div className="w-[220px] flex-col justify-start items-start inline-flex">
<NavHeader svg="archery" text="動作"></NavHeader>
{category.action.map((text, index) => {
return <NavItem key={index} text={text}></NavItem>;
})}
<div className="self-stretch h-px px-4 flex-col justify-center items-start flex">
<div className="self-stretch h-[0px] border border-slate-500"></div>
</div>
<NavHeader svg="explore" text="冒險"></NavHeader>
{category.adventure.map((text, index) => {
return <NavItem key={index} text={text}></NavItem>;
})}
</div>
<div className="w-[220px] flex-col justify-start items-start inline-flex">
<NavHeader svg="hotAirBalloon" text="模擬"></NavHeader>
{category.simulation.map((text, index) => {
return <NavItem key={index} text={text}></NavItem>;
})}
<div className="self-stretch h-px px-4 flex-col justify-center items-start flex">
<div className="self-stretch h-[0px] border border-slate-500"></div>
</div>
<NavHeader svg="chessRook" text="策略"></NavHeader>
{category.strategy.map((text, index) => {
return <NavItem key={index} text={text}></NavItem>;
})}
</div>
</div>
</div>
);
};

export default SearchDrawer;
Loading
Loading