Skip to content
Merged
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
22 changes: 22 additions & 0 deletions apps/web/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,27 @@ const config: StorybookConfig = {
options: {},
},
staticDirs: ["../public"],
// biome-ignore lint/suspicious/noExplicitAny:
webpackFinal: (config: any) => {
const imageRule = config.module.rules.find(rule => {
const test = (rule as { test: RegExp }).test;

if (!test) {
return false;
}

return test.test(".svg");
// biome-ignore lint/suspicious/noExplicitAny:
}) as { [key: string]: any };

imageRule.exclude = /\.svg$/;

config.module.rules.push({
test: /\.svg$/,
use: ["@svgr/webpack"],
});

return config;
},
};
export default config;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "@/shared/style/index.css";

import type { Preview } from "@storybook/nextjs-vite";
import React from "react";

const preview: Preview = {
parameters: {
Expand All @@ -18,6 +18,17 @@ const preview: Preview = {
test: "todo",
},
},
decorators: [
Story => {
if (!document.getElementById("toast-portal")) {
const portalDiv = document.createElement("div");
portalDiv.id = "toast-portal";
document.body.appendChild(portalDiv);
}

return <Story />;
},
],
};

export default preview;
8 changes: 8 additions & 0 deletions apps/web/next.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "standalone",
turbopack: {
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js'
}
}
}
Comment thread
widse marked this conversation as resolved.
Comment on lines +4 to +11

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prλ³Έλ¬Έμ—μ„œ 레퍼런슀 ν™•μΈν•˜μ˜€μŠ΅λ‹ˆλ‹€πŸ‘

};

export default nextConfig;
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@storybook/addon-vitest": "^9.1.7",
"@storybook/nextjs": "^9.1.7",
"@storybook/nextjs-vite": "^9.1.7",
"@svgr/webpack": "^8.1.0",
"@types/node": "^22.15.3",
"@types/react": "19.1.0",
"@types/react-dom": "19.1.1",
Expand Down
120 changes: 120 additions & 0 deletions apps/web/src/shared/components/Toast/Toast.Animation.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* Toast Keyframe Animations */

@keyframes toast-enter-top {
0% {
transform: translate3d(0, -200%, 0) scale(0.6);
opacity: 0.5;
}
100% {
transform: translate3d(0, 0, 0) scale(1);
opacity: 1;
}
}

@keyframes toast-exit-top {
0% {
transform: translate3d(0, 0, -1px) scale(1);
opacity: 1;
}
100% {
transform: translate3d(0, -150%, -1px) scale(0.6);
opacity: 0;
}
}

@keyframes toast-enter-bottom {
0% {
transform: translate3d(0, 200%, 0) scale(0.6);
opacity: 0.5;
}
100% {
transform: translate3d(0, 0, 0) scale(1);
opacity: 1;
}
}

@keyframes toast-exit-bottom {
0% {
transform: translate3d(0, 0, -1px) scale(1);
opacity: 1;
}
100% {
transform: translate3d(0, 150%, -1px) scale(0.6);
opacity: 0;
}
}

@keyframes toast-fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

@keyframes toast-fade-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}

@media (prefers-reduced-motion: reduce) {
@keyframes toast-enter-top {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

@keyframes toast-exit-top {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}

@keyframes toast-enter-bottom {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

@keyframes toast-exit-bottom {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}

@keyframes toast-fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

@keyframes toast-fade-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
}

154 changes: 154 additions & 0 deletions apps/web/src/shared/components/Toast/Toast.stlye.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { css, cva } from "../../../../styled-system/css";

// Toast Content μŠ€νƒ€μΌ (positionκ³Ό visible variants 포함)
export const toastContent = cva({
base: {
opacity: 0,
display: "flex",
position: "relative",
boxSizing: "border-box",
alignItems: "center",
justifyContent: "space-between",
gap: "8px",
borderRadius: "4px",
minHeight: "48px",
padding: "0 14px",
background: "#3D3D3D",
color: "#FFFFFF",
boxShadow: "0 3px 10px rgba(0, 0, 0, 0.1), 0 3px 3px rgba(0, 0, 0, 0.05)",
pointerEvents: "auto",
willChange: "transform",
transition: "transform 0.23s cubic-bezier(0.21, 1.02, 0.73, 1)",
},
compoundVariants: [
{
position: "top",
visible: true,
css: {
animation: "toast-enter-top 0.35s cubic-bezier(0.21, 1.02, 0.73, 1) forwards",
"@media (prefers-reduced-motion: reduce)": {
animation: "toast-fade-in 0.35s ease-in forwards",
},
},
},
{
position: "top",
visible: false,
css: {
animation: "toast-exit-top 0.4s cubic-bezier(0.06, 0.71, 0.55, 1) forwards",
"@media (prefers-reduced-motion: reduce)": {
animation: "toast-fade-out 0.4s ease-out forwards",
},
},
},
{
position: "bottom",
visible: true,
css: {
animation: "toast-enter-bottom 0.35s cubic-bezier(0.21, 1.02, 0.73, 1) forwards",
"@media (prefers-reduced-motion: reduce)": {
animation: "toast-fade-in 0.35s ease-in forwards",
},
},
},
{
position: "bottom",
visible: false,
css: {
animation: "toast-exit-bottom 0.4s cubic-bezier(0.06, 0.71, 0.55, 1) forwards",
"@media (prefers-reduced-motion: reduce)": {
animation: "toast-fade-out 0.4s ease-out forwards",
},
},
},
],
});

export const toastTypeMessage = css({
display: "flex",
alignItems: "center",
gap: "8px",
});

export const toastTypeIcon = css({
display: "flex",
alignItems: "center",
'&[data-toast-type="default"]': {
display: "none",
},
});

export const toastMessage = css({
fontSize: "14px",
fontWeight: "400",
color: "#FFFFFF",
lineHeight: "20px",
});

export const toastActionLink = css({
flexShrink: 0,
fontSize: "12px",
fontWeight: "400",
color: "#FFFFFF",
textDecoration: "underline",
textUnderlineOffset: "2px",
cursor: "pointer",
});

export const toastActionButton = css({
display: "flex",
flexShrink: 0,
alignItems: "center",
justifyContent: "center",
padding: "4px 6px",
backgroundColor: "#FF8A00",
borderRadius: "4px",
fontSize: "12px",
fontWeight: "400",
color: "#FFFFFF",
cursor: "pointer",
});

export const toasterContent = css({
position: "fixed",
zIndex: 9999,
top: 0,
left: 0,
right: 0,
bottom: 0,
pointerEvents: "none",
});

export const toastWrapper = cva({
base: {
position: "absolute",
"& > *": {
transition: "all 0.23s cubic-bezier(0.21, 1.02, 0.73, 1)",
},
},
variants: {
position: {
"top-right": {
right: 0,
},
"top-left": {
left: 0,
},
"top-center": {
left: "50%",
},
"bottom-right": {
bottom: 0,
right: 0,
},
"bottom-left": {
bottom: 0,
left: 0,
},
"bottom-center": {
bottom: 0,
left: "50%",
},
},
},
});
Loading