Skip to content
This repository has been archived by the owner on Dec 11, 2024. It is now read-only.

feat: create channel form #55

Merged
merged 9 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
3 changes: 3 additions & 0 deletions client/.storybook/preview-body.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<style>
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;600&family=Noto+Sans:wght@400;600&display=swap");
</style>
6 changes: 6 additions & 0 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;600&family=Noto+Sans:wght@400;600&display=swap"
rel="stylesheet"
/>
<title>Vite + React + TS</title>
<script src="/scripts/theme.js"></script>
</head>
Expand Down
4 changes: 4 additions & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@
"build-storybook": "storybook build"
},
"dependencies": {
"@hookform/resolvers": "^3.3.3",
"@radix-ui/react-dialog": "^1.0.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-feather": "^2.0.10",
"react-hook-form": "^7.49.2",
"valibot": "^0.20.1"
},
"devDependencies": {
"@storybook/addon-actions": "^7.6.6",
"@storybook/addon-essentials": "^7.5.1",
"@storybook/addon-interactions": "^7.5.1",
"@storybook/addon-links": "^7.5.1",
Expand Down
203 changes: 175 additions & 28 deletions client/pnpm-lock.yaml

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions client/src/components/loading-overlay/loading-overlay.css.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { vars } from "@/styles/theme.css";
import { vars } from "@/styles";
import { style, createVar } from "@vanilla-extract/css";

const loadingObjectSizeVar = createVar();
Expand All @@ -11,7 +11,7 @@ export const styles = {
width: "100%",
height: "100%",
zIndex: vars.zIndex.modal,
backgroundColor: vars.color.gray[1],
backgroundColor: vars.semantic.background.secondary,
display: "flex",
justifyContent: "center",
alignItems: "center",
Expand Down
35 changes: 35 additions & 0 deletions client/src/components/ui/button/__stories__/button.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Meta } from "@storybook/react";
import { action } from "@storybook/addon-actions";
import { Button } from "..";

const meta = {
title: "Components/UI/Button",
} satisfies Meta;

export default meta;

export const Primary = () => (
<Button variant="primary" onClick={action("onClick")}>
作成
</Button>
);

export const Secondary = () => (
<Button variant="secondary" onClick={action("onClick")}>
一時保存
</Button>
);

export const Text = () => (
<Button variant="text" onClick={action("onClick")}>
キャンセル
</Button>
);

export const Overview = () => (
<div style={{ display: "flex", gap: "1rem" }}>
<Primary />
<Secondary />
<Text />
</div>
);
79 changes: 79 additions & 0 deletions client/src/components/ui/button/button.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { style, styleVariants } from "@vanilla-extract/css";
import { vars } from "@/styles";

export const styles = {
button: style({
display: "inline-flex",
alignItems: "center",
justifyContent: "center",
fontSize: vars.font.size.base,
fontWeight: 600,
borderRadius: vars.spacing[2],
cursor: "pointer",
transition: vars.transition.fastInteraction("background-color"),
userSelect: "none",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
textDecoration: "none",
border: "none",
outline: "none",
}),
buttonVariant: styleVariants({
primary: {
backgroundColor: vars.semantic.button.primary.backgroundColor,
color: vars.semantic.button.primary.color,
transition: vars.transition.normal("opacity"),

selectors: {
"&:hover": {
opacity: 0.8,
},
"&:focus-visible": {
outline: `2px solid ${vars.semantic.border.focus}`,
outlineOffset: "2px",
},
},
},
secondary: {
backgroundColor: vars.semantic.background.primary,
color: vars.semantic.text.secondary,
boxShadow: `0 0 0 1px ${vars.semantic.border.primary} inset`,

selectors: {
"&:hover": {
backgroundColor: vars.semantic.background.primaryHover,
},
"&:focus-visible": {
outline: `2px solid ${vars.semantic.border.focus}`,
outlineOffset: "2px",
},
},
},
text: {
backgroundColor: "transparent",
color: vars.semantic.text.secondary,

selectors: {
"&:hover": {
backgroundColor: vars.semantic.background.primaryHover,
},
"&:focus-visible": {
outline: `2px solid ${vars.semantic.border.focus}`,
outlineOffset: "2px",
},
},
},
}),
buttonSize: styleVariants({
sm: {
fontSize: vars.font.size.sm,
lineHeight: 1,
padding: `${vars.spacing[1]} ${vars.spacing[1]}`,
},
md: {
fontSize: vars.font.size.base,
lineHeight: 1.25,
padding: `${vars.spacing[2]} ${vars.spacing[4]}`,
},
}),
};
23 changes: 23 additions & 0 deletions client/src/components/ui/button/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentProps, forwardRef } from "react";
import { styles } from "./button.css";
import { clsx } from "@/libs/clsx";

interface ButtonProps extends ComponentProps<"button"> {
variant?: "primary" | "secondary" | "text";
size?: "sm" | "md";
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ variant = "primary", size = "md", className, ...props }, ref) => (
<button
ref={ref}
className={clsx(
styles.button,
styles.buttonVariant[variant],
styles.buttonSize[size],
className
)}
{...props}
/>
)
);
1 change: 1 addition & 0 deletions client/src/components/ui/button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./button";
34 changes: 34 additions & 0 deletions client/src/components/ui/dialog/__stories__/dialog.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Meta } from "@storybook/react";
import { action } from "@storybook/addon-actions";
import { Dialog } from "..";
import { Button } from "../../button";

const meta = {
title: "Components/UI/Dialog",
} satisfies Meta;

export default meta;

export const Default = () => (
<Dialog.Root>
<Dialog.Trigger asChild>
<Button onClick={action("onClick")}>ダイアログを開く</Button>
</Dialog.Trigger>
<Dialog.Overlay>
<Dialog.Content>
<Dialog.RightTopClose />
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<p style={{ textAlign: "right" }}>
<Dialog.Close asChild>
<Button variant="secondary">Cancel</Button>
</Dialog.Close>
<span style={{ margin: "0 0.5rem" }} />
<Dialog.Close asChild>
<Button variant="primary">OK</Button>
</Dialog.Close>
</p>
</Dialog.Content>
</Dialog.Overlay>
</Dialog.Root>
);
97 changes: 97 additions & 0 deletions client/src/components/ui/dialog/dialog.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { keyframes, style } from "@vanilla-extract/css";
import { constants, vars } from "@/styles";

const overlayKF = keyframes({
from: {
opacity: 0,
},
to: {
opacity: 0.9,
},
});

const contentKF = keyframes({
from: {
opacity: 0,
transform: "translate(-50%, -48%) scale(0.96)",
},
to: {
opacity: 1,
transform: "translate(-50%, -50%) scale(1)",
},
});

export const styles = {
dialogOverlay: style({
backgroundColor: vars.semantic.background.secondary,
position: "fixed",
inset: 0,
opacity: 0.9,
animation: vars.transition.fastInteraction(overlayKF),
}),
dialogContent: style({
backgroundColor: vars.semantic.background.primary,
border: `1px solid ${vars.color.gray[6]}`,
borderRadius: vars.spacing[2],
position: "fixed",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: `calc(100vw - ${vars.spacing[4]} * 2)`,
maxWidth: constants.sizes.dialogMaxWidth,
maxHeight: "85vh",
padding: vars.spacing[4],
animation: vars.transition.fastInteraction(contentKF),
boxSizing: "border-box",

selectors: {
"&:focus": {
outline: "none",
},
},
}),
dialogTitle: style({
fontSize: vars.font.size.lg,
fontWeight: 600,
marginBottom: vars.spacing[2],
color: vars.color.gray[12],
}),
dialogDescription: style({
fontSize: vars.font.size.sm,
marginBottom: vars.spacing[4],
color: vars.color.gray[11],
}),
dialogClose: style({
position: "absolute",
top: vars.spacing[3],
right: vars.spacing[3],
padding: vars.spacing[1],
border: "none",
borderRadius: vars.spacing[16],
background: "transparent",
cursor: "pointer",
color: vars.color.gray[11],
lineHeight: 0,
transition: vars.transition.normal("background"),

selectors: {
"&:focus": {
outline: "none",
},
"&:hover": {
background: vars.color.gray[4],
},
},
}),
dialogRightTopCloseButton: style({
position: "absolute",
top: vars.spacing[3],
right: vars.spacing[3],
}),
dialogFooter: style({
display: "flex",
justifyContent: "flex-end",
marginTop: vars.spacing[4],
gap: vars.spacing[4],
}),
};
45 changes: 45 additions & 0 deletions client/src/components/ui/dialog/dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as D from "@radix-ui/react-dialog";
import { ComponentProps } from "react";
import { styles } from "./dialog.css";
import { clsx } from "@/libs/clsx";
import { Button } from "../button";
import { X } from "react-feather";

export const Dialog = {
Root: D.Root,
Trigger: D.Trigger,
Portal: D.Portal,
Overlay: ({ className, ...props }: ComponentProps<typeof D.Overlay>) => (
<D.Overlay className={clsx(styles.dialogOverlay, className)} {...props} />
),
Content: ({ className, ...props }: ComponentProps<typeof D.Content>) => (
<D.Content className={clsx(styles.dialogContent, className)} {...props} />
),
Title: ({ className, ...props }: ComponentProps<typeof D.Title>) => (
<D.Title className={clsx(styles.dialogTitle, className)} {...props} />
),
Description: ({
className,
...props
}: ComponentProps<typeof D.Description>) => (
<D.Description
className={clsx(styles.dialogDescription, className)}
{...props}
/>
),
RightTopClose: (props: ComponentProps<typeof D.Close>) => (
<Dialog.Close asChild {...props}>
<Button
variant="text"
size="sm"
className={styles.dialogRightTopCloseButton}
>
<X />
</Button>
</Dialog.Close>
),
Footer: ({ className, ...props }: ComponentProps<"div">) => (
<div className={clsx(styles.dialogFooter, className)} {...props} />
),
Close: D.Close,
};
1 change: 1 addition & 0 deletions client/src/components/ui/dialog/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./dialog";
Loading
Loading