diff --git a/CLAUDE.md b/CLAUDE.md index 49ed522c..c621a3e6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,10 +10,10 @@ GitAnimals is a monorepo that allows users to raise virtual pets through GitHub **Monorepo Structure:** - `apps/web` - Next.js 14 web application (main frontend) -- `apps/admin` - Remix admin dashboard +- `apps/admin-main` - Admin dashboard (Vite) - `apps/webview` - Vite + React Router webview for mobile integration - `apps/webview-history` - Legacy Next.js webview (being migrated) -- `packages/ui/panda` - Component library using PandaCSS +- `packages/ui/tailwind` - Component library (Tailwind + Radix) - `packages/ui/icon` - Icon components - `packages/ui/token` - Design tokens - `packages/api` - Shared API client with interceptors @@ -52,7 +52,7 @@ src/ ```bash # Development servers pnpm dev:web # Start web app dev server (Next.js) -pnpm dev:admin # Start admin app dev server (Remix) +pnpm dev:admin # Start admin app dev server (admin-main) pnpm dev:webview # Start webview dev server (Vite) # Build commands @@ -66,13 +66,12 @@ pnpm lint # Lint all workspaces pnpm format # Format code with Prettier # UI Development -pnpm sb:panda # Start Storybook for UI components +pnpm sb:tailwind # Start Storybook for @gitanimals/ui-tailwind ``` **Workspace-specific commands:** ```bash # Web app (apps/web) -pnpm --filter @gitanimals/web prepare # PandaCSS codegen pnpm --filter @gitanimals/web type-check # TypeScript validation pnpm --filter @gitanimals/web lint:fix # Fix ESLint issues @@ -80,8 +79,8 @@ pnpm --filter @gitanimals/web lint:fix # Fix ESLint issues pnpm --filter @gitanimals/webview dev # Vite dev server on port 3000 pnpm --filter @gitanimals/webview type-check # TypeScript validation -# UI components (packages/ui/panda) -pnpm --filter @gitanimals/ui-panda storybook # Start Storybook +# UI components (packages/ui/tailwind) +pnpm --filter @gitanimals/ui-tailwind storybook # Start Storybook (port 6002) ``` ## Code Patterns & Conventions @@ -178,14 +177,14 @@ pnpm --filter @gitanimals/ui-panda storybook # Start Storybook - `turbo.json` - Build pipeline configuration - `pnpm-workspace.yaml` - Workspace definition - `apps/web/ARCHITECTURE.md` - **FSD 아키텍처 상세 가이드 (필독)** -- `packages/ui/panda/src/theme/` - Design system tokens and styles +- `packages/ui/tailwind/src/theme/` - Design system tokens (Tailwind preset) ## Build Pipeline Dependencies The build system has specific dependency chains: -- Most builds depend on `^build` and `^prepare` -- `prepare` tasks generate PandaCSS styled-system -- Admin uses different output patterns (dist/**) vs others (.next/**) +- Most builds depend on `^build` and `^prepare` where applicable +- Some packages use `prepare` for codegen (e.g. legacy styled-system); web/webview rely on Tailwind +- Admin-main and webview use `dist/**`; web uses `.next/**` ## Notes for Development diff --git a/apps/admin/.eslintrc.cjs b/apps/admin/.eslintrc.cjs deleted file mode 100644 index 69f9fe0d..00000000 --- a/apps/admin/.eslintrc.cjs +++ /dev/null @@ -1,26 +0,0 @@ -/** - * This is intended to be a basic starting point for linting in your app. - * It relies on recommended configs out of the box for simplicity, but you can - * and should modify this configuration to best suit your team's needs. - */ - -/** @type {import('eslint').Linter.Config} */ -module.exports = { - root: true, - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - env: { - browser: true, - commonjs: true, - es6: true, - }, - ignorePatterns: ['!**/.server', '!**/.client'], - - extends: ['@gitanimals/eslint-config/library.js'], - parser: '@typescript-eslint/parser', -}; diff --git a/apps/admin/.gitignore b/apps/admin/.gitignore deleted file mode 100644 index c78de0eb..00000000 --- a/apps/admin/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -node_modules - -/.cache -/build -.env - -## Panda -styled-system -styled-system-studio \ No newline at end of file diff --git a/apps/admin/README.md b/apps/admin/README.md deleted file mode 100644 index 6c4d2168..00000000 --- a/apps/admin/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Welcome to Remix! - -- 📖 [Remix docs](https://remix.run/docs) - -## Development - -Run the dev server: - -```shellscript -npm run dev -``` - -## Deployment - -First, build your app for production: - -```sh -npm run build -``` - -Then run the app in production mode: - -```sh -npm start -``` - -Now you'll need to pick a host to deploy it to. - -### DIY - -If you're familiar with deploying Node applications, the built-in Remix app server is production-ready. - -Make sure to deploy the output of `npm run build` - -- `build/server` -- `build/client` - -## Styling - -This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever css framework you prefer. See the [Vite docs on css](https://vitejs.dev/guide/features.html#css) for more information. diff --git a/apps/admin/app/QueryClientProvider.tsx b/apps/admin/app/QueryClientProvider.tsx deleted file mode 100644 index 33d84158..00000000 --- a/apps/admin/app/QueryClientProvider.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import type { PropsWithChildren } from 'react'; -import { useState } from 'react'; -import type { QueryClientConfig } from '@tanstack/react-query'; -import { QueryClient, QueryClientProvider as BaseQueryClientProvider } from '@tanstack/react-query'; - -const queryClientOption: QueryClientConfig = { - defaultOptions: { - queries: { - retry: false, - refetchOnMount: false, - refetchOnWindowFocus: false, - }, - }, -}; - -const QueryClientProvider = ({ children }: PropsWithChildren) => { - const [queryClient] = useState(() => new QueryClient(queryClientOption)); - - return {children}; -}; - -export default QueryClientProvider; diff --git a/apps/admin/app/components/Auction/AllBuy/ProductTable.tsx b/apps/admin/app/components/Auction/AllBuy/ProductTable.tsx deleted file mode 100644 index 84cbb857..00000000 --- a/apps/admin/app/components/Auction/AllBuy/ProductTable.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import * as React from 'react'; -import { - ColumnDef, - ColumnFiltersState, - SortingState, - VisibilityState, - flexRender, - getCoreRowModel, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable, -} from '@tanstack/react-table'; -import { ChevronDown } from 'lucide-react'; -import { Button } from '@/components/ui/button'; -import { Checkbox } from '@/components/ui/checkbox'; -import { - DropdownMenu, - DropdownMenuCheckboxItem, - DropdownMenuContent, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu'; -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; -import { STATIC_IMAGE_URL } from '@/constants/outlink'; -import { BuyProductRequest, buyProductWithToken, Product } from '@gitanimals/api'; -import { Box, Flex } from '_panda/jsx'; -import { icon } from '_panda/recipes'; -import { getToken } from '@/utils/token'; -import { useMutation } from '@tanstack/react-query'; -import { token } from '_panda/tokens'; - -function ProductBuyButton({ productId }: { productId: string }) { - const { mutate, isSuccess, isPending } = useMutation({ - mutationFn: (request: BuyProductRequest) => { - const token = getToken(); - if (!token) throw new Error('Token not found'); - - return buyProductWithToken({ ...request, token }); - }, - }); - const onClick = async () => { - mutate({ productId }); - }; - - return ( - - ); -} - -export const columns: ColumnDef[] = [ - { - id: 'select', - header: ({ table }) => ( - table.toggleAllPageRowsSelected(!!value)} - aria-label="Select all" - /> - ), - cell: ({ row }) => ( - row.toggleSelected(!!value)} - aria-label="Select row" - /> - ), - enableSorting: false, - enableHiding: false, - }, - - { - // persona - accessorKey: 'personaType', - accessorFn: (info) => info.persona.personaType, - header: 'Image', - cell: ({ row }) => ( -
- {row.getValue('personaType')} -
- ), - }, - { - accessorKey: 'personaLevel', - accessorFn: (info) => info.persona.personaLevel, - header: 'Level', - cell: ({ row }) =>
level {row.getValue('personaLevel')}
, - }, - { - accessorKey: 'price', - header: 'Price', - cell: ({ row }) =>
{row.getValue('price')}
, - }, - { - accessorKey: 'paymentState', - header: 'Payment State', - cell: ({ row }) =>
{row.getValue('paymentState')}
, - }, - { - accessorKey: 'actions', - header: () => Actions, - cell: ({ row }) => , - }, -]; - -function ProductDataTable({ data }: { data: Product[] }) { - const [sorting, setSorting] = React.useState([]); - const [columnFilters, setColumnFilters] = React.useState([]); - const [columnVisibility, setColumnVisibility] = React.useState({}); - const [rowSelection, setRowSelection] = React.useState({}); - - const table = useReactTable({ - data, - columns, - onSortingChange: setSorting, - onColumnFiltersChange: setColumnFilters, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getSortedRowModel: getSortedRowModel(), - getFilteredRowModel: getFilteredRowModel(), - onColumnVisibilityChange: setColumnVisibility, - onRowSelectionChange: setRowSelection, - state: { - sorting, - columnFilters, - columnVisibility, - rowSelection, - }, - initialState: { - pagination: { - pageSize: 5, - }, - }, - }); - - return ( - - - - - - - - {table - .getAllColumns() - .filter((column) => column.getCanHide()) - .map((column) => { - return ( - column.toggleVisibility(!!value)} - > - {column.id} - - ); - })} - - - - - - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - return ( - - {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} - - ); - })} - - ))} - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - {flexRender(cell.column.columnDef.cell, cell.getContext())} - ))} - - )) - ) : ( - - - No results. - - - )} - -
-
- - - {table.getFilteredSelectedRowModel().rows.length} of {table.getFilteredRowModel().rows.length} row(s) - selected. - - - - - - -
- ); -} - -export default ProductDataTable; diff --git a/apps/admin/app/components/Auction/AllBuy/SortFilter.tsx b/apps/admin/app/components/Auction/AllBuy/SortFilter.tsx deleted file mode 100644 index 05451d70..00000000 --- a/apps/admin/app/components/Auction/AllBuy/SortFilter.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { Link } from '@remix-run/react'; -import { GetProductsRequest } from '@gitanimals/api'; -import { Button } from '@/components/ui/button'; -import { Grid } from '_panda/jsx'; - -const SORT_OPTION: { - label: string; - options?: Partial; -}[] = [ - { - label: '오래된 순', - options: { sortDirection: 'ASC', orderType: 'CREATED_AT' }, - }, - { - label: '가격 낮은 순', - options: { orderType: 'PRICE', sortDirection: 'ASC' }, - }, - { - label: '가격 높은 순', - options: { orderType: 'PRICE', sortDirection: 'DESC' }, - }, -]; - -const PAGE_SIZE = [20, 40, 100]; - -function SortFilter({ tableParams }: { tableParams: Record }) { - return ( - - {SORT_OPTION.map((option) => ( - - - - ))} - - {PAGE_SIZE.map((size) => ( - - - - ))} - - ); -} - -export default SortFilter; - -const getNewTableUrl = ({ - baseUrl, - newParams, - oldParams = {}, -}: { - baseUrl: string; - oldParams?: Record; - newParams: Record; -}) => { - let params = new URLSearchParams(); - - for (const [key, value] of Object.entries({ ...oldParams, ...newParams })) { - params.append(key, String(value)); - } - - return `${baseUrl}?${params.toString()}`; -}; diff --git a/apps/admin/app/components/layout/Header/Header.tsx b/apps/admin/app/components/layout/Header/Header.tsx deleted file mode 100644 index 87a1e20a..00000000 --- a/apps/admin/app/components/layout/Header/Header.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { css } from '_panda/css'; -import Nav from './Nav'; -import { Avatar, AvatarImage } from '@radix-ui/react-avatar'; - -const PROFILE_IMG = 'https://avatars.githubusercontent.com/u/171903401?s=200&v=4'; -function Header() { - return ( -
-
- ); -} - -export default Header; - -const containerStyle = css({ - h: '16px', - bg: 'background', - shadow: 'md', - zIndex: 'sticky', - px: '4px', - py: '3px', - - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', -}); - -const avatarStyle = css({ - overflow: 'hidden', - borderRadius: '50%', - height: '100%', - background: 'muted', - '& span': { - height: '100%', - display: 'block', - '& img': { - borderRadius: '50%', - height: '100%', - width: 'auto', - }, - }, -}); diff --git a/apps/admin/app/components/layout/Header/Nav.tsx b/apps/admin/app/components/layout/Header/Nav.tsx deleted file mode 100644 index 251879c0..00000000 --- a/apps/admin/app/components/layout/Header/Nav.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { - NavigationMenu, - NavigationMenuContent, - NavigationMenuItem, - NavigationMenuLink, - NavigationMenuList, - NavigationMenuTrigger, -} from '@/components/ui/navigation-menu'; -import ListItem from './NavItem'; -import { css } from '_panda/css'; -import { MENU } from './menu.constants'; - -export default function Example() { - return ( - - - - - Home - - - {MENU.map((menu) => ( - - {menu.title} - -
    - {menu.items.map((component) => ( - - {component.description} - - ))} -
-
-
- ))} -
-
- ); -} - -const listStyle = css({ - display: 'flex', - flexDirection: 'column', - gap: '3px', - p: '6px', - md: { - w: '400px', - }, - lg: { - w: '500px', - gridTemplateColumns: '.75fr 1fr', - }, -}); diff --git a/apps/admin/app/components/layout/Header/NavItem.tsx b/apps/admin/app/components/layout/Header/NavItem.tsx deleted file mode 100644 index 6f3d2573..00000000 --- a/apps/admin/app/components/layout/Header/NavItem.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { NavigationMenuLink } from '@radix-ui/react-navigation-menu'; -import { cx, css } from '_panda/css'; -import { forwardRef, ElementRef, ComponentPropsWithoutRef } from 'react'; - -const ListItem = forwardRef, ComponentPropsWithoutRef<'a'>>( - ({ className, title, children, ...props }, ref) => { - return ( -
  • - - -
    {title}
    -

    {children}

    -
    -
    -
  • - ); - }, -); - -ListItem.displayName = 'ListItem'; - -export default ListItem; - -const anchorStyle = css({ - display: 'block', - userSelect: 'none', - spaceY: '1', - rounded: 'md', - p: '3', - leading: 'none', - textDecoration: 'none', - outline: 'none', - transition: 'colors', - _hover: { - bg: 'accent', - color: 'accent.foreground', - }, - _focus: { - bg: 'accent', - color: 'accent.foreground', - }, -}); - -const titleStyle = css({ - textStyle: 'sm', - fontWeight: 'medium', - leading: 'none', -}); - -const descriptionStyle = css({ - lineClamp: '2', - textStyle: 'sm', - leading: 'snug', - color: 'muted.foreground', -}); diff --git a/apps/admin/app/components/layout/Header/index.ts b/apps/admin/app/components/layout/Header/index.ts deleted file mode 100644 index 6a0251df..00000000 --- a/apps/admin/app/components/layout/Header/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -import Header from './Header'; -export { Header }; diff --git a/apps/admin/app/components/layout/Header/menu.constants.ts b/apps/admin/app/components/layout/Header/menu.constants.ts deleted file mode 100644 index 44cdf0ce..00000000 --- a/apps/admin/app/components/layout/Header/menu.constants.ts +++ /dev/null @@ -1,31 +0,0 @@ -interface MenuItem { - title: string; - href: string; - description: string; -} - -export const MENU: { - title: string; - items: MenuItem[]; -}[] = [ - { - title: '경매장', - items: [ - { - title: '경매장 일괄 구매', - href: '/auction/all-buy', - description: '시장경제를 위해 경매장에서 일괄 구매할 수 있습니다.', - }, - ], - }, - { - title: '상점', - items: [ - { - title: '펫 판매', - href: '/shop/drop-pet', - description: '펫을 판매할 수 있습니다.', - }, - ], - }, -]; diff --git a/apps/admin/app/components/layout/Main/Heading.tsx b/apps/admin/app/components/layout/Main/Heading.tsx deleted file mode 100644 index bb8ae24a..00000000 --- a/apps/admin/app/components/layout/Main/Heading.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { cva } from '_panda/css'; -import { styled } from '_panda/jsx'; - -const mainHeadingRecipe = cva({ - base: { - display: 'block', - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - width: '100%', - maxWidth: '100%', - textStyle: 'glyph24.bold', - }, -}); - -const MainHeading = styled('h1', mainHeadingRecipe); - -export default MainHeading; diff --git a/apps/admin/app/components/layout/Main/Main.tsx b/apps/admin/app/components/layout/Main/Main.tsx deleted file mode 100644 index 16517232..00000000 --- a/apps/admin/app/components/layout/Main/Main.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { css } from '_panda/css'; -import React, { PropsWithChildren } from 'react'; - -function Main({ children }: PropsWithChildren<{}>) { - return
    {children}
    ; -} - -export default Main; - -const containerStyle = css({ - p: '8px', -}); diff --git a/apps/admin/app/components/layout/Main/index.tsx b/apps/admin/app/components/layout/Main/index.tsx deleted file mode 100644 index 05fcce78..00000000 --- a/apps/admin/app/components/layout/Main/index.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import Main from './Main'; -import MainHeading from './Heading'; - -export { Main, MainHeading }; diff --git a/apps/admin/app/components/shop/drop-pet/ProductTable.tsx b/apps/admin/app/components/shop/drop-pet/ProductTable.tsx deleted file mode 100644 index 5c5477ac..00000000 --- a/apps/admin/app/components/shop/drop-pet/ProductTable.tsx +++ /dev/null @@ -1,182 +0,0 @@ -import * as React from 'react'; -import { - ColumnDef, - ColumnFiltersState, - SortingState, - VisibilityState, - flexRender, - getCoreRowModel, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable, -} from '@tanstack/react-table'; -import { Button } from '@/components/ui/button'; -import { Checkbox } from '@/components/ui/checkbox'; - -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; -import { STATIC_IMAGE_URL } from '@/constants/outlink'; -import { BuyProductRequest, buyProductWithToken, Persona } from '@gitanimals/api'; -import { Box, Flex } from '_panda/jsx'; -import { getToken } from '@/utils/token'; -import { useMutation } from '@tanstack/react-query'; - -function ProductBuyButton({ productId }: { productId: string }) { - const { mutate, isSuccess, isPending } = useMutation({ - mutationFn: (request: BuyProductRequest) => { - const token = getToken(); - if (!token) throw new Error('Token not found'); - - return buyProductWithToken({ ...request, token }); - }, - }); - - const onClick = async () => { - mutate({ productId }); - }; - - return ( - - ); -} - -export const columns: ColumnDef[] = [ - { - id: 'select', - header: ({ table }) => ( - table.toggleAllPageRowsSelected(!!value)} - aria-label="Select all" - /> - ), - cell: ({ row }) => ( - row.toggleSelected(!!value)} - aria-label="Select row" - /> - ), - enableSorting: false, - enableHiding: false, - }, - { - // persona - accessorKey: 'type', - header: 'type', - cell: ({ row }) => ( -
    - {row.getValue('type')} -
    - ), - }, - { - accessorKey: 'level', - header: 'level', - cell: ({ row }) =>
    level {row.getValue('level')}
    , - }, - { - accessorKey: 'dropRate', - header: 'dropRate', - cell: ({ row }) =>
    {row.getValue('dropRate')}
    , - }, - { - accessorKey: 'actions', - header: () => Actions, - cell: ({ row }) => , - }, -]; - -function ProductDataTable({ data }: { data: Persona[] }) { - const [sorting, setSorting] = React.useState([]); - const [columnFilters, setColumnFilters] = React.useState([]); - const [columnVisibility, setColumnVisibility] = React.useState({}); - const [rowSelection, setRowSelection] = React.useState({}); - - const table = useReactTable({ - data, - columns, - onSortingChange: setSorting, - onColumnFiltersChange: setColumnFilters, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getSortedRowModel: getSortedRowModel(), - getFilteredRowModel: getFilteredRowModel(), - onColumnVisibilityChange: setColumnVisibility, - onRowSelectionChange: setRowSelection, - state: { - sorting, - columnFilters, - columnVisibility, - rowSelection, - }, - initialState: { - pagination: { - pageSize: 5, - }, - }, - }); - - return ( - - - - - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - return ( - - {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} - - ); - })} - - ))} - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - {flexRender(cell.column.columnDef.cell, cell.getContext())} - ))} - - )) - ) : ( - - - No results. - - - )} - -
    -
    - - - {table.getFilteredSelectedRowModel().rows.length} of {table.getFilteredRowModel().rows.length} row(s) - selected. - - - - - - -
    - ); -} - -export default ProductDataTable; diff --git a/apps/admin/app/components/ui/avatar/index.tsx b/apps/admin/app/components/ui/avatar/index.tsx deleted file mode 100644 index 4b2ef4a2..00000000 --- a/apps/admin/app/components/ui/avatar/index.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import * as AvatarPrimitive from '@radix-ui/react-avatar'; -import { createStyleContext } from '@shadow-panda/style-context'; -import { styled } from '_panda/jsx'; -import { avatar } from '_panda/recipes'; - -const { withProvider, withContext } = createStyleContext(avatar); - -export const Avatar = withProvider(styled(AvatarPrimitive.Root), 'root'); -export const AvatarImage = withContext(styled(AvatarPrimitive.Image), 'image'); -export const AvatarFallback = withContext(styled(AvatarPrimitive.Fallback), 'fallback'); diff --git a/apps/admin/app/components/ui/badge/index.tsx b/apps/admin/app/components/ui/badge/index.tsx deleted file mode 100644 index 49df8613..00000000 --- a/apps/admin/app/components/ui/badge/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { HTMLStyledProps, styled } from '_panda/jsx'; -import { badge } from '_panda/recipes'; - -export const Badge = styled('div', badge); - -export type BadgeProps = HTMLStyledProps; diff --git a/apps/admin/app/components/ui/button/index.tsx b/apps/admin/app/components/ui/button/index.tsx deleted file mode 100644 index 2694e52b..00000000 --- a/apps/admin/app/components/ui/button/index.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { styled } from '_panda/jsx'; -import { button, icon } from '_panda/recipes'; -import { HTMLStyledProps } from '_panda/types'; -import * as React from 'react'; -import { Slot } from '@radix-ui/react-slot'; -import { cx, css } from '_panda/css'; -import { Loader2 } from 'lucide-react'; - -const BaseButton = React.forwardRef< - HTMLButtonElement, - React.ButtonHTMLAttributes & { asChild?: boolean; children?: React.ReactNode; isLoading?: boolean } ->(({ asChild = false, isLoading = false, ...props }, ref) => { - const Comp = asChild ? Slot : 'button'; - - if (isLoading) { - return ( - - - Loading... - - ); - } - return ; -}); -BaseButton.displayName = 'Button'; - -export const Button = styled(BaseButton, button); -export type ButtonProps = HTMLStyledProps; diff --git a/apps/admin/app/components/ui/card/index.tsx b/apps/admin/app/components/ui/card/index.tsx deleted file mode 100644 index d754135d..00000000 --- a/apps/admin/app/components/ui/card/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { styled } from '_panda/jsx'; -import { card, cardHeader, cardTitle, cardDescription, cardContent, cardFooter } from '_panda/recipes'; - -export const Card = styled('div', card); -export const CardHeader = styled('div', cardHeader); -export const CardTitle = styled('h3', cardTitle); -export const CardDescription = styled('p', cardDescription); -export const CardContent = styled('div', cardContent); -export const CardFooter = styled('div', cardFooter); diff --git a/apps/admin/app/components/ui/checkbox/index.tsx b/apps/admin/app/components/ui/checkbox/index.tsx deleted file mode 100644 index b7487468..00000000 --- a/apps/admin/app/components/ui/checkbox/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import * as React from 'react'; -import * as CheckboxPrimitive from '@radix-ui/react-checkbox'; -import { cx } from '_panda/css'; -import { styled } from '_panda/jsx'; -import { checkbox, icon } from '_panda/recipes'; -import { Check } from 'lucide-react'; - -const BaseCheckbox = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => { - const styles = checkbox(); - - return ( - - - - - - ); -}); -BaseCheckbox.displayName = CheckboxPrimitive.Root.displayName; - -export const Checkbox = styled(BaseCheckbox); diff --git a/apps/admin/app/components/ui/dropdown-menu/index.tsx b/apps/admin/app/components/ui/dropdown-menu/index.tsx deleted file mode 100644 index fa979641..00000000 --- a/apps/admin/app/components/ui/dropdown-menu/index.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import * as React from 'react'; -import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'; -import { Check, ChevronRight, Circle } from 'lucide-react'; -import { cx, css } from '_panda/css'; -import { styled } from '_panda/jsx'; -import { dropdownMenu, icon } from '_panda/recipes'; -import { createStyleContext } from '@shadow-panda/style-context'; - -const { withProvider, withContext } = createStyleContext(dropdownMenu); - -const SubTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - insetLeft?: boolean; - } ->(({ className, insetLeft, children, ...props }, ref) => ( - - {children} - - -)); -SubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName; - -const Content = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ sideOffset = 4, ...props }, ref) => ( - - - -)); -Content.displayName = DropdownMenuPrimitive.Content.displayName; - -const Item = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - insetLeft?: boolean; - } ->(({ className, insetLeft, ...props }, ref) => ( - -)); -Item.displayName = DropdownMenuPrimitive.Item.displayName; - -const ItemIndicator = withContext(styled(DropdownMenuPrimitive.ItemIndicator), 'itemIndicator'); - -const CheckboxItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( - - - - - {children} - -)); -CheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName; - -const RadioItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( - - - - - {children} - -)); -RadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName; - -const Label = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - insetLeft?: boolean; - } ->(({ className, insetLeft, ...props }, ref) => ( - -)); -Label.displayName = DropdownMenuPrimitive.Label.displayName; - -export const DropdownMenu = withProvider(styled(DropdownMenuPrimitive.Root), 'root'); -export const DropdownMenuTrigger = withContext(styled(DropdownMenuPrimitive.Trigger), 'trigger'); -export const DropdownMenuGroup = withContext(styled(DropdownMenuPrimitive.Group), 'group'); -export const DropdownMenuPortal = withContext(styled(DropdownMenuPrimitive.Portal), 'portal'); -export const DropdownMenuSub = withContext(styled(DropdownMenuPrimitive.Sub), 'sub'); -export const DropdownMenuRadioGroup = withContext(styled(DropdownMenuPrimitive.RadioGroup), 'radioGroup'); -export const DropdownMenuSubTrigger = withContext(styled(SubTrigger), 'subTrigger'); -export const DropdownMenuSubContent = withContext(styled(DropdownMenuPrimitive.SubContent), 'subContent'); -export const DropdownMenuContent = withContext(styled(Content), 'content'); -export const DropdownMenuItem = withContext(styled(Item), 'item'); -export const DropdownMenuCheckboxItem = withContext(styled(CheckboxItem), 'checkboxItem'); -export const DropdownMenuRadioItem = withContext(styled(RadioItem), 'radioItem'); -export const DropdownMenuLabel = withContext(styled(Label), 'label'); -export const DropdownMenuSeparator = withContext(styled(DropdownMenuPrimitive.Separator), 'separator'); -export const DropdownMenuShortcut = withContext(styled('span'), 'shortcut'); diff --git a/apps/admin/app/components/ui/input/index.tsx b/apps/admin/app/components/ui/input/index.tsx deleted file mode 100644 index f1bb431a..00000000 --- a/apps/admin/app/components/ui/input/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { styled } from '_panda/jsx'; -import { input } from '_panda/recipes'; -import { HTMLStyledProps } from '_panda/types'; - -export const Input = styled('input', input); -export type InputProps = HTMLStyledProps; diff --git a/apps/admin/app/components/ui/navigation-menu/index.tsx b/apps/admin/app/components/ui/navigation-menu/index.tsx deleted file mode 100644 index 947880db..00000000 --- a/apps/admin/app/components/ui/navigation-menu/index.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import * as React from 'react'; -import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu'; -import { createStyleContext } from '@shadow-panda/style-context'; -import { cx } from '_panda/css'; -import { styled } from '_panda/jsx'; -import { navigationMenu } from '_panda/recipes'; -import { ChevronDown } from 'lucide-react'; - -const { withProvider, withContext } = createStyleContext(navigationMenu); - -const BaseNavigationMenu = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( - - {children} - - -)); -BaseNavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName; - -const BaseNavigationMenuTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( - - {children} -)); -BaseNavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName; - -const ViewportWrapper = withContext(styled('div'), 'viewportWrapper'); - -const BaseNavigationMenuViewport = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - -)); -BaseNavigationMenuViewport.displayName = NavigationMenuPrimitive.Viewport.displayName; - -export const NavigationMenu = withProvider(styled(BaseNavigationMenu), 'root'); -export const NavigationMenuList = withContext(styled(NavigationMenuPrimitive.List), 'list'); -export const NavigationMenuItem = withContext(styled(NavigationMenuPrimitive.Item), 'item'); -export const NavigationMenuTrigger = withContext(styled(BaseNavigationMenuTrigger), 'trigger'); -export const NavigationMenuContent = withContext(styled(NavigationMenuPrimitive.Content), 'content'); -export const NavigationMenuLink = withContext(styled(NavigationMenuPrimitive.Link), 'link'); -export const NavigationMenuViewport = withContext(styled(BaseNavigationMenuViewport), 'viewport'); -export const NavigationMenuIndicator = withContext(styled(NavigationMenuPrimitive.Indicator), 'indicator', { - children:
    , -}); diff --git a/apps/admin/app/components/ui/table/index.tsx b/apps/admin/app/components/ui/table/index.tsx deleted file mode 100644 index 5323cb6e..00000000 --- a/apps/admin/app/components/ui/table/index.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { styled } from '_panda/jsx'; -import { - tableContainer, - table, - tableHeader, - tableBody, - tableFooter, - tableHead, - tableRow, - tableCell, - tableCaption, -} from '_panda/recipes'; -import { forwardRef, HTMLAttributes } from 'react'; - -const TableContainer = styled('div', tableContainer); - -const BaseTable = forwardRef>((props, ref) => ( - - - -)); -BaseTable.displayName = 'Table'; - -export const Table = styled(BaseTable, table); -export const TableHeader = styled('thead', tableHeader); -export const TableBody = styled('tbody', tableBody); -export const TableFooter = styled('tfoot', tableFooter); -export const TableHead = styled('th', tableHead); -export const TableRow = styled('tr', tableRow); -export const TableCell = styled('td', tableCell); -export const TableCaption = styled('caption', tableCaption); diff --git a/apps/admin/app/components/ui/tabs/index.tsx b/apps/admin/app/components/ui/tabs/index.tsx deleted file mode 100644 index db667ec4..00000000 --- a/apps/admin/app/components/ui/tabs/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import * as TabsPrimitive from '@radix-ui/react-tabs'; -import { createStyleContext } from '@shadow-panda/style-context'; -import { styled } from '_panda/jsx'; -import { tabs } from '_panda/recipes'; - -const { withProvider, withContext } = createStyleContext(tabs); - -export const Tabs = withProvider(styled(TabsPrimitive.Root), 'root'); -export const TabsList = withContext(styled(TabsPrimitive.List), 'list'); -export const TabsTrigger = withContext(styled(TabsPrimitive.Trigger), 'trigger'); -export const TabsContent = withContext(styled(TabsPrimitive.Content), 'content'); diff --git a/apps/admin/app/constants/outlink.ts b/apps/admin/app/constants/outlink.ts deleted file mode 100644 index e8d5d51a..00000000 --- a/apps/admin/app/constants/outlink.ts +++ /dev/null @@ -1 +0,0 @@ -export const STATIC_IMAGE_URL = 'https://static.gitanimals.org/personas'; diff --git a/apps/admin/app/cookies.server.ts b/apps/admin/app/cookies.server.ts deleted file mode 100644 index 868527e7..00000000 --- a/apps/admin/app/cookies.server.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createCookie } from '@remix-run/node'; // or cloudflare/deno - -export const userToken = createCookie('user-token', { - maxAge: 604_800, // one week -}); diff --git a/apps/admin/app/entry.client.tsx b/apps/admin/app/entry.client.tsx deleted file mode 100644 index 94d5dc0d..00000000 --- a/apps/admin/app/entry.client.tsx +++ /dev/null @@ -1,18 +0,0 @@ -/** - * By default, Remix will handle hydrating your app on the client for you. - * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ - * For more information, see https://remix.run/file-conventions/entry.client - */ - -import { RemixBrowser } from "@remix-run/react"; -import { startTransition, StrictMode } from "react"; -import { hydrateRoot } from "react-dom/client"; - -startTransition(() => { - hydrateRoot( - document, - - - - ); -}); diff --git a/apps/admin/app/entry.server.tsx b/apps/admin/app/entry.server.tsx deleted file mode 100644 index 45db3229..00000000 --- a/apps/admin/app/entry.server.tsx +++ /dev/null @@ -1,140 +0,0 @@ -/** - * By default, Remix will handle generating the HTTP Response for you. - * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ - * For more information, see https://remix.run/file-conventions/entry.server - */ - -import { PassThrough } from "node:stream"; - -import type { AppLoadContext, EntryContext } from "@remix-run/node"; -import { createReadableStreamFromReadable } from "@remix-run/node"; -import { RemixServer } from "@remix-run/react"; -import { isbot } from "isbot"; -import { renderToPipeableStream } from "react-dom/server"; - -const ABORT_DELAY = 5_000; - -export default function handleRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext, - // This is ignored so we can keep it in the template for visibility. Feel - // free to delete this parameter in your app if you're not using it! - // eslint-disable-next-line @typescript-eslint/no-unused-vars - loadContext: AppLoadContext -) { - return isbot(request.headers.get("user-agent") || "") - ? handleBotRequest( - request, - responseStatusCode, - responseHeaders, - remixContext - ) - : handleBrowserRequest( - request, - responseStatusCode, - responseHeaders, - remixContext - ); -} - -function handleBotRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext -) { - return new Promise((resolve, reject) => { - let shellRendered = false; - const { pipe, abort } = renderToPipeableStream( - , - { - onAllReady() { - shellRendered = true; - const body = new PassThrough(); - const stream = createReadableStreamFromReadable(body); - - responseHeaders.set("Content-Type", "text/html"); - - resolve( - new Response(stream, { - headers: responseHeaders, - status: responseStatusCode, - }) - ); - - pipe(body); - }, - onShellError(error: unknown) { - reject(error); - }, - onError(error: unknown) { - responseStatusCode = 500; - // Log streaming rendering errors from inside the shell. Don't log - // errors encountered during initial shell rendering since they'll - // reject and get logged in handleDocumentRequest. - if (shellRendered) { - console.error(error); - } - }, - } - ); - - setTimeout(abort, ABORT_DELAY); - }); -} - -function handleBrowserRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext -) { - return new Promise((resolve, reject) => { - let shellRendered = false; - const { pipe, abort } = renderToPipeableStream( - , - { - onShellReady() { - shellRendered = true; - const body = new PassThrough(); - const stream = createReadableStreamFromReadable(body); - - responseHeaders.set("Content-Type", "text/html"); - - resolve( - new Response(stream, { - headers: responseHeaders, - status: responseStatusCode, - }) - ); - - pipe(body); - }, - onShellError(error: unknown) { - reject(error); - }, - onError(error: unknown) { - responseStatusCode = 500; - // Log streaming rendering errors from inside the shell. Don't log - // errors encountered during initial shell rendering since they'll - // reject and get logged in handleDocumentRequest. - if (shellRendered) { - console.error(error); - } - }, - } - ); - - setTimeout(abort, ABORT_DELAY); - }); -} diff --git a/apps/admin/app/index.css b/apps/admin/app/index.css deleted file mode 100644 index e27a23b7..00000000 --- a/apps/admin/app/index.css +++ /dev/null @@ -1 +0,0 @@ -@layer reset, base, tokens, recipes, utilities; diff --git a/apps/admin/app/root.tsx b/apps/admin/app/root.tsx deleted file mode 100644 index cb8f1873..00000000 --- a/apps/admin/app/root.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import type { LinksFunction, LoaderFunction } from '@remix-run/node'; -import { Links, Meta, Outlet, Scripts, ScrollRestoration, redirect, useLoaderData } from '@remix-run/react'; - -import styles from './index.css?url'; -import { Header } from './components/layout/Header'; -import QueryClientProvider from './QueryClientProvider'; -import { userToken } from './cookies.server'; - -export const links: LinksFunction = () => [{ rel: 'stylesheet', href: styles }]; - -export const loader: LoaderFunction = async ({ request }) => { - if (request.url.includes('/auth-main')) { - return { noHeader: true }; - } - - if (request.url.includes('/auth')) { - return null; - } - - const cookieHeader = request.headers.get('Cookie'); - const cookie = (await userToken.parse(cookieHeader)) || {}; - - if (!cookie.token) { - return redirect('/auth-main'); - } - - return null; -}; -export default function App() { - const isAuthMain = useLoaderData()?.noHeader; - - return ( - - - - - - - - - - {!isAuthMain &&
    } - - - - - {/* */} - - - ); -} diff --git a/apps/admin/app/routes/_index.tsx b/apps/admin/app/routes/_index.tsx deleted file mode 100644 index 3c21d493..00000000 --- a/apps/admin/app/routes/_index.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { Main, MainHeading } from '@/components/layout/Main'; -import { Button } from '@/components/ui/button'; -import { Input } from '@/components/ui/input'; -import { userToken } from '@/cookies.server'; - -import { ActionFunctionArgs, redirect, type MetaFunction } from '@remix-run/node'; -import { Form, Link } from '@remix-run/react'; -import { css } from '_panda/css'; -import { Box } from '_panda/jsx'; -import { useState } from 'react'; - -export const meta: MetaFunction = () => { - return [ - { title: 'GitAnimals Admin' }, - { name: 'description', content: 'GitAnimals 관리를 위한 admin 페이지입니다. ' }, - { - property: 'og:title', - content: 'GitAnimals Admin', - }, - { - property: 'og:description', - content: 'GitAnimals 관리를 위한 admin 페이지입니다. ', - }, - { - property: 'og:image', - content: '/og-image.png', - }, - ]; -}; - -export async function action() { - return {}; -} - -export default function Index() { - return ( -
    - Home -

    Gitanimals Admin 페이지입니다.

    -
    -
    - -
    - ); -} diff --git a/apps/admin/app/routes/auction.all-buy.tsx b/apps/admin/app/routes/auction.all-buy.tsx deleted file mode 100644 index 0d589759..00000000 --- a/apps/admin/app/routes/auction.all-buy.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import ProductDataTable from '@/components/Auction/AllBuy/ProductTable'; -import SortFilter from '@/components/Auction/AllBuy/SortFilter'; -import { Button } from '@/components/ui/button'; -import { Card, CardHeader, CardTitle, CardContent, CardDescription } from '@/components/ui/card'; -import { userToken } from '@/cookies.server'; -import { GetProductsResponse, Product, buyProductWithToken, getProducts } from '@gitanimals/api'; -import { ActionFunctionArgs, LoaderFunction, json, redirect } from '@remix-run/node'; -import { Form, useLoaderData, useSubmit } from '@remix-run/react'; - -import { Flex } from '_panda/jsx'; -import { useEffect, useState } from 'react'; - -const INIT_COUNT = 20; - -const getProductParams = (query: URLSearchParams) => { - return Object.fromEntries( - Object.entries({ - pageNumber: query.get('pageNumber'), - personaType: query.get('personaType'), - count: query.get('count') ?? INIT_COUNT, - orderType: query.get('orderType') ?? 'PRICE', - sortDirection: query.get('sortDirection') ?? 'ASC', - }).filter(([, v]) => v != null), - ); -}; - -export const loader: LoaderFunction = async ({ request }) => { - const query = new URL(request.url).searchParams; - - const alertQuery = { alert: query.get('alert'), failed: query.get('failed') }; - - const params = getProductParams(query); - - const data: GetProductsResponse = await getProducts(params); - return json({ products: data.products, tableParams: params, query: alertQuery }); -}; - -export async function action({ request }: ActionFunctionArgs) { - const cookieHeader = request.headers.get('Cookie'); - const { token } = (await userToken.parse(cookieHeader)) || {}; - - let formData = await request.formData(); - let items = formData.get('products'); - let itemsArray = items ? JSON.parse(items as string) : []; - - try { - const promises = itemsArray.map((id: string) => buyProductWithToken({ productId: id, token })); - const results = await Promise.allSettled(promises); - - const failed = results.filter((result) => result.status === 'rejected'); - if (failed.length === itemsArray.length) { - throw new Error(`Failed to buy ${failed.length} products`); - } - - console.info('buy product success'); - - return redirect(`/auction/all-buy?alert=success&failed=${failed.length}`); - } catch (error) { - console.error('buy products error'); - return redirect('/auction/all-buy?alert=error'); - } -} - -function ActionAllBuyPage() { - const { products, tableParams, query } = useLoaderData(); - - const submit = useSubmit(); - - const [isLoading, setIsLoading] = useState(false); - - useEffect(() => { - setIsLoading(false); - }, [query]); - - return ( - - - - 경매장 일괄 구매 - 시장 경제 손보다가, 손이 빠질 것 같아여....... - -
    { - submit(tableParams, { method: 'post', encType: 'application/json' }); - setIsLoading(true); - }} - > - item.id))} /> - - - -
    - - - {products && } - -
    -
    - ); -} - -export default ActionAllBuyPage; - -const getProductAveragePrice = (products: Product[]) => { - const total = products.reduce((acc, product) => acc + Number(product.price), 0); - return total / products.length; -}; diff --git a/apps/admin/app/routes/auth-main.tsx b/apps/admin/app/routes/auth-main.tsx deleted file mode 100644 index b7359919..00000000 --- a/apps/admin/app/routes/auth-main.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { Link } from '@remix-run/react'; -import { css } from '_panda/css'; -import { Center, Flex, Grid } from '_panda/jsx'; -import { h2, p } from '_panda/recipes'; -import React from 'react'; - -function AuthMainPage() { - return ( - - -

    - GitAnimals -

    -

    - Have pet in your github
    -

    -
    -
    -

    GitAnimals Admin

    -

    Please Github OAuth Login

    - - - - -
    -
    - ); -} - -export default AuthMainPage; diff --git a/apps/admin/app/routes/auth.tsx b/apps/admin/app/routes/auth.tsx deleted file mode 100644 index 8dc7af9b..00000000 --- a/apps/admin/app/routes/auth.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { userToken } from '@/cookies.server'; -import { LoaderFunction, redirect } from '@remix-run/node'; -import { useLoaderData } from '@remix-run/react'; - -export let loader: LoaderFunction = async ({ request }) => { - const query = new URL(request.url).searchParams; - const authToken = query.get('jwt'); - - if (authToken) { - const cookieHeader = request.headers.get('Cookie'); - const cookie = (await userToken.parse(cookieHeader)) || {}; - - cookie.token = authToken.split(' ')[1]; - - return redirect('/', { - headers: { - 'Set-Cookie': await userToken.serialize(cookie), - }, - }); - } - - const res = await fetch('https://api.gitanimals.org/logins/oauth/github', { - headers: { - 'Redirect-When-Success': process.env.NODE_ENV === 'production' ? 'ADMIN' : 'LOCAL_ADMIN', - }, - }); - - return redirect(res.url); -}; - -function AuthPage() { - useLoaderData(); - - return
    ; -} - -export default AuthPage; diff --git a/apps/admin/app/routes/shop.drop-pet.tsx b/apps/admin/app/routes/shop.drop-pet.tsx deleted file mode 100644 index 37e1fb3a..00000000 --- a/apps/admin/app/routes/shop.drop-pet.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import ProductDataTable from '@/components/shop/drop-pet/ProductTable'; -import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; -import { Persona, getAllMyPersonas } from '@gitanimals/api'; -import { LoaderFunction, json } from '@remix-run/node'; -import { useLoaderData } from '@remix-run/react'; -import { Flex } from '_panda/jsx'; - -export const loader: LoaderFunction = async ({ request }) => { - const { personas } = await getAllMyPersonas('git-good-w'); - return json({ personas }); -}; - -function ShopDropPetPage() { - const data = useLoaderData(); - - const personas: Persona[] = data.personas; - - return ( - - - - 상점 펫 판매 - - - - - - - ); -} - -export default ShopDropPetPage; diff --git a/apps/admin/app/utils/token.ts b/apps/admin/app/utils/token.ts deleted file mode 100644 index 383d4e45..00000000 --- a/apps/admin/app/utils/token.ts +++ /dev/null @@ -1,13 +0,0 @@ -const ADMIN_TOKEN = 'gitanimals-admin-token'; - -export const getToken = () => { - if (typeof window === 'undefined' || !window.localStorage) return; - - return window.localStorage.getItem(ADMIN_TOKEN); -}; - -export const setToken = (token: string) => { - if (typeof window === 'undefined' || !window.localStorage) return; - - window.localStorage.setItem(ADMIN_TOKEN, token); -}; diff --git a/apps/admin/package.json b/apps/admin/package.json deleted file mode 100644 index c699af9d..00000000 --- a/apps/admin/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "@gitanimals/admin", - "version": "0.1.0", - "private": true, - "sideEffects": false, - "type": "module", - "scripts": { - "prepare": "panda codegen", - "build": "remix vite:build", - "dev": "remix vite:dev", - "lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .", - "start": "remix-serve ./build/server/index.js", - "typecheck": "tsc" - }, - "dependencies": { - "@gitanimals/api": "workspace:*", - "@gitanimals/asset-font": "workspace:*", - "@gitanimals/exception": "workspace:*", - "@gitanimals/ui-panda": "workspace:*", - "@radix-ui/react-avatar": "^1.1.0", - "@radix-ui/react-checkbox": "^1.1.1", - "@radix-ui/react-dropdown-menu": "^2.1.1", - "@radix-ui/react-navigation-menu": "^1.2.0", - "@radix-ui/react-slot": "^1.1.0", - "@radix-ui/react-tabs": "^1.1.0", - "@remix-run/node": "^2.10.2", - "@remix-run/react": "^2.10.2", - "@remix-run/serve": "^2.10.2", - "@shadow-panda/style-context": "^0.7.1", - "@tanstack/react-query": "*", - "@tanstack/react-table": "^8.19.3", - "isbot": "^4.1.0", - "lucide-react": "^0.408.0", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@gitanimals/eslint-config": "workspace:*", - "@gitanimals/typescript-config": "workspace:*", - "@pandacss/dev": "^0.41.0", - "@remix-run/dev": "^2.10.2", - "@shadow-panda/preset": "^0.7.1", - "@types/react": "*", - "@types/react-dom": "^18.2.7", - "@typescript-eslint/eslint-plugin": "^6.7.4", - "@typescript-eslint/parser": "^6.7.4", - "eslint": "^8.38.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.6.0", - "typescript": "^5.1.6", - "vite": "^5.1.0", - "vite-tsconfig-paths": "^4.2.1" - }, - "engines": { - "node": ">=20.0.0" - } -} \ No newline at end of file diff --git a/apps/admin/panda.config.ts b/apps/admin/panda.config.ts deleted file mode 100644 index 0488d24e..00000000 --- a/apps/admin/panda.config.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { semanticTokens, textStyles, tokens } from '@gitanimals/ui-panda'; -import { defineConfig } from '@pandacss/dev'; - -export default defineConfig({ - presets: ['@shadow-panda/preset'], - - // Whether to use css reset - preflight: true, - - // Where to look for your css declarations - include: [ - './app/routes/**/*.{ts,tsx,js,jsx}', - './app/components/**/*.{ts,tsx,js,jsx}', - '../../packages/ui/panda/src/**/*.{ts,tsx}', - ], - - // Files to exclude - exclude: [], - - // Useful for theme customization - theme: { - extend: { - tokens, - semanticTokens, - textStyles, - }, - }, - jsxFramework: 'react', - - // The output directory for your css system - // outdir: 'styled-system', - outdir: 'styled-system', -}); diff --git a/apps/admin/postcss.config.cjs b/apps/admin/postcss.config.cjs deleted file mode 100644 index ee939cb0..00000000 --- a/apps/admin/postcss.config.cjs +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - plugins: { - '@pandacss/dev/postcss': {}, - }, -}; diff --git a/apps/admin/public/favicon.ico b/apps/admin/public/favicon.ico deleted file mode 100644 index 8830cf68..00000000 Binary files a/apps/admin/public/favicon.ico and /dev/null differ diff --git a/apps/admin/public/og-image.png b/apps/admin/public/og-image.png deleted file mode 100644 index f0e92e46..00000000 Binary files a/apps/admin/public/og-image.png and /dev/null differ diff --git a/apps/admin/tsconfig.json b/apps/admin/tsconfig.json deleted file mode 100644 index a44c933d..00000000 --- a/apps/admin/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "extends": "@gitanimals/typescript-config/react-library.json", - "include": [ - "**/*.ts", - "**/*.tsx", - "**/.server/**/*.ts", - "**/.server/**/*.tsx", - "**/.client/**/*.ts", - "**/.client/**/*.tsx", - "styled-system" - ], - "compilerOptions": { - "lib": ["DOM", "DOM.Iterable", "ES2022"], - "types": ["@remix-run/node", "vite/client"], - "isolatedModules": true, - "esModuleInterop": true, - "jsx": "react-jsx", - "module": "ESNext", - "moduleResolution": "Bundler", - "resolveJsonModule": true, - "target": "ES2022", - "strict": true, - "allowJs": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "baseUrl": ".", - "paths": { - "@/*": ["./app/*"], - "_panda/*": ["./styled-system/*"] - }, - - // Vite takes care of building everything, not tsc. - "noEmit": true - } -} diff --git a/apps/admin/vite.config.ts b/apps/admin/vite.config.ts deleted file mode 100644 index 54066fb7..00000000 --- a/apps/admin/vite.config.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { vitePlugin as remix } from "@remix-run/dev"; -import { defineConfig } from "vite"; -import tsconfigPaths from "vite-tsconfig-paths"; - -export default defineConfig({ - plugins: [ - remix({ - future: { - v3_fetcherPersist: true, - v3_relativeSplatPath: true, - v3_throwAbortReason: true, - }, - }), - tsconfigPaths(), - ], -}); diff --git a/apps/web/.eslintrc.json b/apps/web/.eslintrc.json index e0d99364..e6aa9deb 100644 --- a/apps/web/.eslintrc.json +++ b/apps/web/.eslintrc.json @@ -13,7 +13,7 @@ "paths": [ { "name": "styled-jsx/css", - "message": "Please use panda/css instead." + "message": "Please use Tailwind / @gitanimals/ui-tailwind instead." } ] } diff --git a/apps/web/package.json b/apps/web/package.json index d4087609..48755704 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -21,7 +21,6 @@ "@gitanimals/react": "workspace:*", "@gitanimals/react-query": "workspace:*", "@gitanimals/ui-icon": "workspace:*", - "@gitanimals/ui-panda": "workspace:*", "@gitanimals/ui-tailwind": "workspace:*", "@gitanimals/util-common": "workspace:*", "@next/third-parties": "^14.2.5", @@ -30,7 +29,6 @@ "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.6", - "@shadow-panda/style-context": "^0.7.1", "@supabase/supabase-js": "^2.75.0", "@suspensive/react": "^2.17.1", "@tanstack/react-query": "*", @@ -62,8 +60,6 @@ "@gitanimals/typescript-config": "workspace:*", "@gitanimals/util-common": "workspace:*", "@next/bundle-analyzer": "^14.2.5", - "@pandacss/dev": "^0.41.0", - "@shadow-panda/preset": "^0.7.1", "@storybook/addon-essentials": "^8.0.9", "@storybook/addon-interactions": "^8.0.9", "@storybook/addon-links": "^8.0.9", diff --git a/package.json b/package.json index cb8dfbe7..0cb258cc 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "build:webview": "turbo build --filter=@gitanimals/webview", "lint": "turbo lint", "format": "prettier --write \"**/*.{ts,tsx,md}\"", - "sb:panda": "turbo run storybook --filter=@gitanimals/ui-panda", "sb:tailwind": "turbo run storybook --filter=@gitanimals/ui-tailwind", "dev:ui-tailwind": "turbo build --filter=@gitanimals/ui-tailwind dev", "lint-staged": "lint-staged", diff --git a/packages/ui/panda/.eslintrc.js b/packages/ui/panda/.eslintrc.js deleted file mode 100644 index 0f55f417..00000000 --- a/packages/ui/panda/.eslintrc.js +++ /dev/null @@ -1,6 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - root: true, - extends: ['@gitanimals/eslint-config/react-internal.js', 'plugin:storybook/recommended'], - parser: '@typescript-eslint/parser', -}; diff --git a/packages/ui/panda/.storybook/globals.css b/packages/ui/panda/.storybook/globals.css deleted file mode 100644 index ade60433..00000000 --- a/packages/ui/panda/.storybook/globals.css +++ /dev/null @@ -1,37 +0,0 @@ -@layer reset, base, tokens, recipes, utilities; -@layer reset { - *, - *::before, - *::after { - box-sizing: border-box; - } - - body { - position: relative; - } - - button { - cursor: pointer; - border: transparent; - background-color: transparent; - padding: 0; - outline: none; - } - - @media (max-width: 768px) { - .mobile { - display: block; - } - - .desktop { - display: none; - } - } -} - -.sb-show-main, -.docs-story { - background-color: #2c2929; - color: white; - min-width: 400px; -} diff --git a/packages/ui/panda/.storybook/main.ts b/packages/ui/panda/.storybook/main.ts deleted file mode 100644 index 3ed62a30..00000000 --- a/packages/ui/panda/.storybook/main.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { StorybookConfig } from '@storybook/nextjs'; - -const config: StorybookConfig = { - stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], - addons: [ - '@storybook/addon-links', - '@storybook/addon-essentials', - '@storybook/addon-onboarding', - '@storybook/addon-interactions', - ], - framework: { - name: '@storybook/nextjs', - options: {}, - }, - docs: { - autodocs: 'tag', - }, - webpackFinal: async (config) => { - if (config.resolve) { - // _panda 경로 매핑 추가 - config.resolve.alias = { - ...config.resolve.alias, - _panda: '../styled-system', // 상대 경로 사용 - }; - } - return config; - }, - staticDirs: ['../public'], -}; - -export default config; diff --git a/packages/ui/panda/.storybook/preview.ts b/packages/ui/panda/.storybook/preview.ts deleted file mode 100644 index e03ba0d3..00000000 --- a/packages/ui/panda/.storybook/preview.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { Preview } from '@storybook/react'; -import './globals.css'; - -const preview: Preview = { - parameters: { - actions: { argTypesRegex: '^on[A-Z].*' }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, -}; - -export default preview; diff --git a/packages/ui/panda/package.json b/packages/ui/panda/package.json deleted file mode 100644 index 64ee05f1..00000000 --- a/packages/ui/panda/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@gitanimals/ui-panda", - "version": "0.0.0", - "private": true, - "main": "src/index.ts", - "scripts": { - "prepare": "panda codegen", - "lint": "eslint . ", - "generate:component": "turbo gen react-component", - "storybook": "panda codegen && storybook dev -p 6001", - "build-storybook": "panda codegen && storybook build" - }, - "dependencies": { - "@gitanimals/react": "workspace:*", - "@radix-ui/react-accordion": "^1.2.1", - "@radix-ui/react-checkbox": "^1.1.1", - "@radix-ui/react-dialog": "^1.1.2", - "@radix-ui/react-dropdown-menu": "^2.1.1", - "@radix-ui/react-label": "^2.1.1", - "@radix-ui/react-scroll-area": "^1.2.10", - "@radix-ui/react-select": "^2.1.2", - "@radix-ui/react-tooltip": "^1.1.6", - "@react-spring/web": "^9.7.5", - "@shadow-panda/style-context": "^0.7.1", - "lucide-react": "^0.408.0" - }, - "devDependencies": { - "@chromatic-com/storybook": "^1.9.0", - "@gitanimals/eslint-config": "workspace:*", - "@gitanimals/typescript-config": "workspace:*", - "@gitanimals/ui-token": "workspace:*", - "@gitanimals/util-typescript": "workspace:*", - "@pandacss/dev": "^0.41.0", - "@shadow-panda/preset": "^0.7.1", - "@storybook/addon-essentials": "^8.0.9", - "@storybook/addon-interactions": "^8.0.9", - "@storybook/addon-links": "^8.0.9", - "@storybook/addon-onboarding": "^8.0.9", - "@storybook/blocks": "^8.0.9", - "@storybook/nextjs": "^8.0.9", - "@storybook/react": "^8.0.9", - "@storybook/test": "^8.0.9", - "@turbo/gen": "^1.12.4", - "@types/eslint": "^8.56.5", - "@types/node": "^20.11.24", - "@types/react": "*", - "@types/react-dom": "^18.2.19", - "eslint": "^8.57.0", - "eslint-plugin-storybook": "^0.8.0", - "react": "*", - "storybook": "^8.0.9", - "typescript": "*" - } -} diff --git a/packages/ui/panda/panda.config.ts b/packages/ui/panda/panda.config.ts deleted file mode 100644 index 3a942429..00000000 --- a/packages/ui/panda/panda.config.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { defineConfig } from '@pandacss/dev'; -import { tokens, semanticTokens, textStyles, media } from './src/theme'; - -export default defineConfig({ - // Whether to use css reset - preflight: true, - - // Where to look for your css declarations - include: ['./src/**/*.{ts,tsx}'], - - // Files to exclude - exclude: [], - - // Useful for theme customization - theme: { - extend: { - tokens, - semanticTokens, - textStyles, - }, - }, - conditions: { - extend: { - mobile: media.mobile, - desktop: media.desktop, - }, - }, - - // utilities: { - // extend: utilities, - // }, - outExtension: 'js', - jsxFramework: 'react', - - // The output directory for your css system - outdir: 'styled-system', - - // delete default presets - presets: ['@shadow-panda/preset'], -}); diff --git a/packages/ui/panda/postcss.config.cjs b/packages/ui/panda/postcss.config.cjs deleted file mode 100644 index 573efad2..00000000 --- a/packages/ui/panda/postcss.config.cjs +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - plugins: { - '@pandacss/dev/postcss': {}, - }, -} \ No newline at end of file diff --git a/packages/ui/panda/public/animal-card/card-back-A_PLUS.webp b/packages/ui/panda/public/animal-card/card-back-A_PLUS.webp deleted file mode 100644 index 7b0e3d8c..00000000 Binary files a/packages/ui/panda/public/animal-card/card-back-A_PLUS.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-back-B_MINUS.webp b/packages/ui/panda/public/animal-card/card-back-B_MINUS.webp deleted file mode 100644 index 2e09dbc1..00000000 Binary files a/packages/ui/panda/public/animal-card/card-back-B_MINUS.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-back-EX.webp b/packages/ui/panda/public/animal-card/card-back-EX.webp deleted file mode 100644 index 1932e47b..00000000 Binary files a/packages/ui/panda/public/animal-card/card-back-EX.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-back-S_PLUS.webp b/packages/ui/panda/public/animal-card/card-back-S_PLUS.webp deleted file mode 100644 index adacfbfd..00000000 Binary files a/packages/ui/panda/public/animal-card/card-back-S_PLUS.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-bg-A_PLUS.webp b/packages/ui/panda/public/animal-card/card-bg-A_PLUS.webp deleted file mode 100644 index 4ae031f8..00000000 Binary files a/packages/ui/panda/public/animal-card/card-bg-A_PLUS.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-bg-B_MINUS.webp b/packages/ui/panda/public/animal-card/card-bg-B_MINUS.webp deleted file mode 100644 index c47b2083..00000000 Binary files a/packages/ui/panda/public/animal-card/card-bg-B_MINUS.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-bg-EVOLUTION.webp b/packages/ui/panda/public/animal-card/card-bg-EVOLUTION.webp deleted file mode 100644 index 7e341862..00000000 Binary files a/packages/ui/panda/public/animal-card/card-bg-EVOLUTION.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-bg-EX.webp b/packages/ui/panda/public/animal-card/card-bg-EX.webp deleted file mode 100644 index 5cb77b79..00000000 Binary files a/packages/ui/panda/public/animal-card/card-bg-EX.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-bg-S_PLUS.webp b/packages/ui/panda/public/animal-card/card-bg-S_PLUS.webp deleted file mode 100644 index 92905b0c..00000000 Binary files a/packages/ui/panda/public/animal-card/card-bg-S_PLUS.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-thumbnail-A_PLUS.webp b/packages/ui/panda/public/animal-card/card-thumbnail-A_PLUS.webp deleted file mode 100644 index 93d89424..00000000 Binary files a/packages/ui/panda/public/animal-card/card-thumbnail-A_PLUS.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-thumbnail-B_MINUS.webp b/packages/ui/panda/public/animal-card/card-thumbnail-B_MINUS.webp deleted file mode 100644 index 7fdab3a3..00000000 Binary files a/packages/ui/panda/public/animal-card/card-thumbnail-B_MINUS.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-thumbnail-EVOLUTION.webp b/packages/ui/panda/public/animal-card/card-thumbnail-EVOLUTION.webp deleted file mode 100644 index 64838232..00000000 Binary files a/packages/ui/panda/public/animal-card/card-thumbnail-EVOLUTION.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-thumbnail-EX.webp b/packages/ui/panda/public/animal-card/card-thumbnail-EX.webp deleted file mode 100644 index 52dd0437..00000000 Binary files a/packages/ui/panda/public/animal-card/card-thumbnail-EX.webp and /dev/null differ diff --git a/packages/ui/panda/public/animal-card/card-thumbnail-S_PLUS.webp b/packages/ui/panda/public/animal-card/card-thumbnail-S_PLUS.webp deleted file mode 100644 index 6d62ef20..00000000 Binary files a/packages/ui/panda/public/animal-card/card-thumbnail-S_PLUS.webp and /dev/null differ diff --git a/packages/ui/panda/src/animation/SplitText/SplitText.stories.tsx b/packages/ui/panda/src/animation/SplitText/SplitText.stories.tsx deleted file mode 100644 index b586c7a6..00000000 --- a/packages/ui/panda/src/animation/SplitText/SplitText.stories.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import SplitText from './SplitText'; - -const meta: Meta = { - title: 'Animation/SplitText', - component: SplitText, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], - argTypes: { - text: { control: 'text' }, - delay: { control: { type: 'number', min: 0, max: 500, step: 10 } }, - textAlign: { - control: { type: 'radio' }, - options: ['left', 'center', 'right', 'justify'], - }, - threshold: { control: { type: 'number', min: 0, max: 1, step: 0.1 } }, - onLetterAnimationComplete: { action: 'animationComplete' }, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - args: { - text: 'Hello, World!', - delay: 100, - textAlign: 'center', - threshold: 0.1, - rootMargin: '-10px', - }, -}; - -export const LongText: Story = { - args: { - text: 'This is a longer text example to show how SplitText handles multiple words', - delay: 50, - textAlign: 'left', - }, -}; - -export const SlowAnimation: Story = { - args: { - text: 'Slow Animation', - delay: 300, - textAlign: 'center', - }, -}; diff --git a/packages/ui/panda/src/animation/SplitText/SplitText.tsx b/packages/ui/panda/src/animation/SplitText/SplitText.tsx deleted file mode 100644 index bf0d03bd..00000000 --- a/packages/ui/panda/src/animation/SplitText/SplitText.tsx +++ /dev/null @@ -1,145 +0,0 @@ -'use client'; - -import { useSprings, animated } from '@react-spring/web'; -import { css } from '_panda/css'; -import { useEffect, useRef, useState } from 'react'; - -interface SplitTextProps { - text?: string; - className?: string; - delay?: number; - animationFrom?: { - opacity: number; - transform: string; - }; - animationTo?: { - opacity: number; - transform: string; - }; - easing?: string; - threshold?: number; - rootMargin?: string; - textAlign?: 'left' | 'center' | 'right' | 'justify'; - onLetterAnimationComplete?: () => void; - style?: React.CSSProperties; -} - -/** - * @example - * - * - * @see https://www.reactbits.dev/text-animations/split-text - */ -const SplitText = ({ - text = '', - className = '', - delay = 100, - animationFrom = { opacity: 0, transform: 'translate3d(0,40px,0)' }, - animationTo = { opacity: 1, transform: 'translate3d(0,0,0)' }, - easing = 'easeOutCubic', - threshold = 0.1, - rootMargin = '-50px', - textAlign = 'center', - onLetterAnimationComplete, - style, -}: SplitTextProps) => { - const words = text.split(' ').map((word) => word.split('')); - - const letters = words.flat(); - const [inView, setInView] = useState(false); - const ref = useRef(null); - const animatedCount = useRef(0); - - useEffect(() => { - if (!ref.current) return; - - const observer = new IntersectionObserver( - ([entry]) => { - if (entry.isIntersecting) { - setInView(true); - if (ref.current) { - observer.unobserve(ref.current); - } - } - }, - { - threshold, - rootMargin, - // delay: 100, - }, - ); - - observer.observe(ref.current); - - return () => observer.disconnect(); - }, [threshold, rootMargin]); - - const springs = useSprings( - letters.length, - letters.map((_, i) => ({ - from: animationFrom, - to: inView - ? async (next: any) => { - await next(animationTo); - animatedCount.current += 1; - if (animatedCount.current === letters.length && onLetterAnimationComplete) { - onLetterAnimationComplete(); - } - } - : animationFrom, - delay: i * delay, - easing: easing, - })), - ); - - return ( -

    - {words.map((word, wordIndex) => ( - - {word.map((letter, letterIndex) => { - const index = words.slice(0, wordIndex).reduce((acc, w) => acc + w.length, 0) + letterIndex; - - return ( - - {letter} - - ); - })} -   - - ))} -

    - ); -}; - -// Panda CSS styles -const splitParentStyle = css({ - overflow: 'hidden', - display: 'inline', - whiteSpace: 'normal', - wordWrap: 'break-word', - backfaceVisibility: 'hidden', - fontSmoothing: 'antialiased', -}); - -const wordStyle = css({ - display: 'inline', - whiteSpace: 'nowrap', - backfaceVisibility: 'hidden', - fontSmoothing: 'antialiased', -}); - -const spaceStyle = css({ - display: 'inline', - width: '0.3em', -}); - -export default SplitText; diff --git a/packages/ui/panda/src/animation/SplitText/index.ts b/packages/ui/panda/src/animation/SplitText/index.ts deleted file mode 100644 index 24d97fcd..00000000 --- a/packages/ui/panda/src/animation/SplitText/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './SplitText'; diff --git a/packages/ui/panda/src/animation/index.ts b/packages/ui/panda/src/animation/index.ts deleted file mode 100644 index 24d97fcd..00000000 --- a/packages/ui/panda/src/animation/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './SplitText'; diff --git a/packages/ui/panda/src/components/Accordion/Accordion.tsx b/packages/ui/panda/src/components/Accordion/Accordion.tsx deleted file mode 100644 index 2e13ec6b..00000000 --- a/packages/ui/panda/src/components/Accordion/Accordion.tsx +++ /dev/null @@ -1,40 +0,0 @@ -'use client'; - -import * as React from 'react'; -import * as AccordionPrimitive from '@radix-ui/react-accordion'; -import { ChevronDown } from 'lucide-react'; -import { createStyleContext } from '@shadow-panda/style-context'; -import { styled } from '_panda/jsx'; -import { accordion } from '_panda/recipes'; - -const { withProvider, withContext } = createStyleContext(accordion); - -const Header = withContext(styled(AccordionPrimitive.Header), 'header'); - -const Trigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( -
    - - {children} - - -
    -)); -Trigger.displayName = AccordionPrimitive.Trigger.displayName; - -const Content = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( - -
    {children}
    -
    -)); -Content.displayName = AccordionPrimitive.Content.displayName; - -export const Accordion = withProvider(styled(AccordionPrimitive.Root), 'root'); -export const AccordionItem = withContext(styled(AccordionPrimitive.Item), 'item'); -export const AccordionTrigger = withContext(styled(Trigger), 'trigger'); -export const AccordionContent = withContext(styled(Content), 'content'); diff --git a/packages/ui/panda/src/components/Accordion/index.ts b/packages/ui/panda/src/components/Accordion/index.ts deleted file mode 100644 index 63f62bc6..00000000 --- a/packages/ui/panda/src/components/Accordion/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Accordion'; diff --git a/packages/ui/panda/src/components/Banner/Banner.tsx b/packages/ui/panda/src/components/Banner/Banner.tsx deleted file mode 100644 index bd3fc5a2..00000000 --- a/packages/ui/panda/src/components/Banner/Banner.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { ReactNode } from 'react'; -import { bannerStyle, BannerStyleProps } from './cva'; -import { css, cx } from '_panda/css'; -import { skeletonStyle } from '../Skeleton'; -import { Loader } from 'lucide-react'; - -type BannerProps = BannerStyleProps & { - label?: string; - image: string | ReactNode; - loading?: boolean; - className?: string; -}; - -export function Banner({ image, label, loading, ...styleProps }: BannerProps) { - const { className, ...rest } = styleProps; - return ( -
    - {typeof image === 'string' ? {image} : image} - {label &&

    {label}

    } - {loading && ( -
    - -
    - )} -
    - ); -} - -const loadingStyle = css({ - position: 'absolute', - top: 0, - left: 0, - width: '100%', - height: '100%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - backgroundColor: 'white.white_25', - borderColor: 'white.white_50', -}); - -const labelStyle = css({ - textStyle: 'glyph16.regular', - color: 'white', - maxWidth: '80px', - textAlign: 'center', - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', -}); - -export function BannerSkeleton(props: BannerStyleProps) { - return
    ; -} - -export function BannerSkeletonList({ length, ...props }: BannerStyleProps & { length: number }) { - return ( - <> - {Array.from({ length }).map((_, index) => ( - - ))} - - ); -} diff --git a/packages/ui/panda/src/components/Banner/BannerPetSelect.tsx b/packages/ui/panda/src/components/Banner/BannerPetSelect.tsx deleted file mode 100644 index 7e5673cc..00000000 --- a/packages/ui/panda/src/components/Banner/BannerPetSelect.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { css } from '_panda/css'; -import { bannerStyle } from './cva'; - -interface BannerPetSelectMediumProps { - name: string; - count: string; - image: string; - status?: 'selected' | 'gradient' | 'default'; -} - -export function BannerPetSelectMedium({ name, count, image, status = 'default' }: BannerPetSelectMediumProps) { - return ( -
    - {name} -

    {name}

    -

    {count}

    -
    - ); -} - -const nameStyle = css({ - textStyle: 'glyph16.regular', - color: 'white', -}); - -const countStyle = css({ - textStyle: 'glyph14.regular', - color: 'white.white_50', -}); diff --git a/packages/ui/panda/src/components/Banner/LevelBanner.tsx b/packages/ui/panda/src/components/Banner/LevelBanner.tsx deleted file mode 100644 index 113adb4c..00000000 --- a/packages/ui/panda/src/components/Banner/LevelBanner.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { ReactNode } from 'react'; -import { bannerStyle, BannerStyleProps } from './cva'; -import { css, cx } from '_panda/css'; - -type Props = BannerStyleProps & { - image: string | ReactNode; - level: number; - className?: string; -}; - -export function LevelBanner({ image, level, className, ...styleProps }: Props) { - return ( -
    - {typeof image === 'string' ? {image} : image} -

    Lv.{level}

    -
    - ); -} - -const levelTagStyle = css({ - borderRadius: '12px', - background: 'black.black_25', - padding: '0 8px', - color: 'white.white_75', - textStyle: 'glyph12.regular', - fontSize: '10px', - lineHeight: '20px', - position: 'absolute', - bottom: '3px', - right: '3px', -}); diff --git a/packages/ui/panda/src/components/Banner/cva.ts b/packages/ui/panda/src/components/Banner/cva.ts deleted file mode 100644 index edd3dedb..00000000 --- a/packages/ui/panda/src/components/Banner/cva.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { cva, RecipeVariantProps } from '_panda/css'; - -export const bannerStyle = cva({ - base: { - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - justifyContent: 'center', - borderRadius: '12px', - transition: 'border 0.3s, background-color 0.3s', - position: 'relative', - borderColor: 'transparent', - overflow: 'hidden', - }, - variants: { - status: { - selected: { - border: '2px solid', - borderColor: 'white.white_50', - backgroundColor: 'white.white_25', - }, - gradient: { - background: - 'linear-gradient(133deg, rgba(255, 253, 201, 0.40) 2.19%, rgba(150, 230, 216, 0.40) 49.24%, rgba(125, 171, 241, 0.40) 98.21%)', - }, - default: { - backgroundColor: 'white.white_10', - }, - }, - size: { - small: { - width: '80px', - height: '80px', - '& img': { - width: '100%', - height: '100%', - objectFit: 'contain', - }, - - _mobile: { - width: '52px', - height: '52px', - borderRadius: '5px', - }, - }, - medium: { - width: '120px', - padding: '12px 20px', - height: '149px', - }, - full: { - width: '100%', - height: '100%', - '& img': { - width: '100%', - height: '100%', - objectFit: 'contain', - }, - }, - }, - }, - - defaultVariants: { - size: 'medium', - status: 'default', - }, -}); - -export type BannerStyleProps = RecipeVariantProps; diff --git a/packages/ui/panda/src/components/Banner/index.ts b/packages/ui/panda/src/components/Banner/index.ts deleted file mode 100644 index ce1d283c..00000000 --- a/packages/ui/panda/src/components/Banner/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { Banner, BannerSkeleton, BannerSkeletonList } from './Banner'; -export { LevelBanner } from './LevelBanner'; -export { BannerPetSelectMedium } from './BannerPetSelect'; diff --git a/packages/ui/panda/src/components/Button/Button.stories.tsx b/packages/ui/panda/src/components/Button/Button.stories.tsx deleted file mode 100644 index 5173e23b..00000000 --- a/packages/ui/panda/src/components/Button/Button.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { Button } from './Button'; - -// 메타데이터 정의 -const meta = { - title: 'Components/Button', - component: Button, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], - argTypes: { - disabled: { - control: 'boolean', - description: '버튼 비활성화 상태', - }, - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -// 기본 버튼 스토리 -export const 기본: Story = { - args: { - children: '버튼', - variant: 'primary', - size: 'm', - colorScheme: 'primary', - }, -}; diff --git a/packages/ui/panda/src/components/Button/Button.tsx b/packages/ui/panda/src/components/Button/Button.tsx deleted file mode 100644 index 54fe4a7c..00000000 --- a/packages/ui/panda/src/components/Button/Button.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { styled } from '_panda/jsx'; -import { buttonStyle } from './cva'; - -export const Button = styled('button', buttonStyle); -export const AnchorButton = styled('a', buttonStyle); diff --git a/packages/ui/panda/src/components/Button/cva.ts b/packages/ui/panda/src/components/Button/cva.ts deleted file mode 100644 index 35f9fee4..00000000 --- a/packages/ui/panda/src/components/Button/cva.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { cva } from '_panda/css'; - -export const buttonStyle = cva({ - base: { - padding: '8px 42px', - borderRadius: '6px', - border: '1px solid black', - fontFamily: 'Product Sans', - fontSize: '16px', - fontStyle: 'normal', - fontWeight: '400', - lineHeight: '150%', - letterSpacing: '-0.3px', - transition: 'filter 0.2s, box-shadow 0.2s', - backgroundColor: 'brand.canary', - boxShadow: '0px 4px 4px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #c4c382 inset, 0px 3px 0px 0px #fdfed2 inset', - color: '#000', - - _disabled: { - cursor: 'not-allowed', - }, - }, - variants: { - size: { - s: { - padding: '0 24px', - fontSize: '14px', - minHeight: '32px', - }, - m: { - padding: '0 30px', - fontSize: '16px', - minHeight: '40px', - height: '40px', - }, - l: { - padding: '25px 76px', - fontSize: '20px', - minHeight: '76px', - }, - }, - floating: { - true: { - width: '100%', - maxWidth: 'calc(100% - 32px)', - position: 'fixed', - bottom: '16px', - left: '50%', - transform: 'translateX(-50%)', - }, - }, - variant: { - primary: { - background: 'brand.canary', - boxShadow: '0px 4px 4px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #c4c382 inset, 0px 3px 0px 0px #fdfed2 inset', - color: '#000', - - _hover: { - backgroundColor: '#EAE78A', - boxShadow: - '0px 4px 16px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #C4C382 inset, 0px 3px 0px 0px #fdfed2 inset', - }, - _active: { - boxShadow: - '0px 4px 16px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #C4C382 inset, 0px 3px 0px 0px #fdfed2 inset', - }, - - _disabled: { - border: '1px solid #000', - backgroundColor: 'gray.gray_800', - boxShadow: - '0px 4px 4px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #a3a3a3 inset, 0px 3px 0px 0px #dbdbdb inset', - - _hover: { - backgroundColor: 'gray.gray_800', - boxShadow: - '0px 4px 4px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #a3a3a3 inset, 0px 3px 0px 0px #dbdbdb inset', - }, - _active: { - backgroundColor: 'gray.gray_800', - boxShadow: - '0px 4px 4px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #a3a3a3 inset, 0px 3px 0px 0px #dbdbdb inset', - }, - }, - }, - secondary: { - borderRadius: '6px', - border: '1px solid #000', - backgroundColor: '#FFF', - boxShadow: '0px 4px 4px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #A1A1B1 inset, 0px 3px 0px 0px #D2DCFE inset', - - _hover: { - backgroundColor: 'gray.gray_900', - boxShadow: - '0px 4px 16px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #A1A1B1 inset, 0px 3px 0px 0px #D2DCFE inset', - }, - - _disabled: { - backgroundColor: 'gray.gray_800', - boxShadow: - '0px 4px 4px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #A3A3A3 inset, 0px 3px 0px 0px #DBDBDB inset', - _hover: { - backgroundColor: 'gray.gray_800', - boxShadow: - '0px 4px 4px 0px rgba(0, 0, 0, 0.25), 0px -3px 0px 0px #A3A3A3 inset, 0px 3px 0px 0px #DBDBDB inset', - }, - }, - }, - }, - }, - defaultVariants: { - variant: 'primary', - size: 'm', - floating: false, - }, -}); diff --git a/packages/ui/panda/src/components/Button/index.ts b/packages/ui/panda/src/components/Button/index.ts deleted file mode 100644 index 8b166a86..00000000 --- a/packages/ui/panda/src/components/Button/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Button'; diff --git a/packages/ui/panda/src/components/Card/CardBack.tsx b/packages/ui/panda/src/components/Card/CardBack.tsx deleted file mode 100644 index 9ec41148..00000000 --- a/packages/ui/panda/src/components/Card/CardBack.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { css } from '_panda/css'; -import { ANIMAL_CARD_IMAGE_BASE_URL } from './constants'; - -interface Props { - tier: 'EX' | 'S_PLUS' | 'A_PLUS' | 'B_MINUS'; -} - -export function CardBack(props: Props) { - const { bg } = getTierToCardBackInfo(props.tier); - - return ( -
    - {props.tier} -
    - ); -} - -const bgStyle = css({ - width: '100%', -}); - -const getTierToCardBackInfo = (tier: Props['tier']): { bg: string } => { - switch (tier) { - case 'EX': - return { - bg: 'card-back-EX.webp', - }; - case 'S_PLUS': - return { - bg: 'card-back-S_PLUS.webp', - }; - case 'A_PLUS': - return { - bg: 'card-back-A_PLUS.webp', - }; - case 'B_MINUS': - return { - bg: 'card-back-B_MINUS.webp', - }; - } -}; diff --git a/packages/ui/panda/src/components/Card/GameCard.stories.tsx b/packages/ui/panda/src/components/Card/GameCard.stories.tsx deleted file mode 100644 index 224ed662..00000000 --- a/packages/ui/panda/src/components/Card/GameCard.stories.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { GameCard } from './GameCard'; -import { css } from '_panda/css'; - -const meta: Meta = { - title: 'Components/GameCard', - component: GameCard, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -}; - -export default meta; - -type Story = StoryObj; - -export const GameCardDefault: Story = { - args: { - title: 'QUOKKA', - percentage: '10%', - tier: 'A_PLUS', - size: 'medium', - imageUrl: 'https://static.gitanimals.org/personas/QUOKKA', - }, -}; - -export const AllCards = () => { - return ( -
    -

    Responsive Game Cards

    - -
    - - - - - -
    - -
    -

    Responsive Sizing

    -
    -
    - -
    -
    - -
    -
    -
    -
    - ); -}; - -const mainStyle = css({ - display: 'flex', - minHeight: '100vh', - flexDirection: 'column', - alignItems: 'center', - justifyContent: 'center', - padding: '1rem', - gap: '2rem', -}); - -const headingStyle = css({ - fontSize: '1.5rem', - fontWeight: 'bold', - marginBottom: '1rem', -}); - -const cardGridStyle = css({ - display: 'grid', - gridTemplateColumns: 'repeat(1, 1fr)', - gap: '1.5rem', - width: '100%', - maxWidth: '64rem', - '@media (min-width: 640px)': { - gridTemplateColumns: 'repeat(2, 1fr)', - }, - '@media (min-width: 768px)': { - gridTemplateColumns: 'repeat(3, 1fr)', - }, -}); - -const responsiveDemoStyle = css({ - width: '100%', - maxWidth: '64rem', - marginTop: '2rem', -}); - -const subheadingStyle = css({ - fontSize: '1.25rem', - fontWeight: 'bold', - marginBottom: '1rem', -}); - -const responsiveGridStyle = css({ - display: 'grid', - gridTemplateColumns: 'repeat(1, 1fr)', - gap: '1.5rem', - '@media (min-width: 640px)': { - gridTemplateColumns: 'repeat(3, 1fr)', - }, -}); - -const fullWidthStyle = css({ - width: '100%', -}); - -const largeCardContainerStyle = css({ - width: '100%', - '@media (min-width: 640px)': { - gridColumn: 'span 2', - }, -}); diff --git a/packages/ui/panda/src/components/Card/GameCard.tsx b/packages/ui/panda/src/components/Card/GameCard.tsx deleted file mode 100644 index 20eaa8e0..00000000 --- a/packages/ui/panda/src/components/Card/GameCard.tsx +++ /dev/null @@ -1,172 +0,0 @@ -'use client'; - -import { css, cva } from '_panda/css'; -import { useRef, useState, useEffect } from 'react'; -import { ANIMAL_CARD_IMAGE_BASE_URL, CARD_INFO, CardTierType } from './constants'; - -interface GameCardProps { - tier: CardTierType; - title: string; - percentage: string; - imageUrl: string; - size?: 'small' | 'medium' | 'large' | 'responsive'; -} - -export function GameCard({ title, percentage, tier, imageUrl, size = 'medium' }: GameCardProps) { - const svgRef = useRef(null); - const [fontSize, setFontSize] = useState({ - title: 16, - percentage: 16, - rating: 16, - }); - const [positions, setPositions] = useState('1rem'); - - useEffect(() => { - if (!svgRef.current) return; - - const resizeObserver = new ResizeObserver((entries) => { - const width = entries[0].contentRect.width; - - setFontSize({ - title: width * 0.08, - percentage: width * 0.08, - rating: width * 0.1, - }); - - const paddingX = Math.max(12, width * 0.075); - const paddingY = Math.max(14.4, width * 0.09); - - setPositions(`${paddingY}px ${paddingX}px`); - }); - - resizeObserver.observe(svgRef.current); - return () => resizeObserver.disconnect(); - }, [size]); - - const { bg, thumbnail } = CARD_INFO[tier]; - - return ( -
    -
    - {'A_PLUS'} -
    - -
    -
    - {title} -
    -
    - {title} -
    -
    - -
    -
    {title}
    - -
    {percentage}%
    -
    -
    - ); -} - -const bgImageStyle = css({ - width: '100%', - height: '100%', -}); - -const imageContainerStyle = css({ - position: 'absolute', - inset: '0', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - top: '0', - left: '0', - right: '0', - width: '100%', - aspectRatio: '1/1', -}); - -const imageWrapperStyle = css({ - position: 'relative', - width: '90%', - aspectRatio: '1/1', -}); - -const imageStyle = css({ - width: '90%', - aspectRatio: '1/1', - position: 'absolute', - top: '50%', - left: '50%', - transform: 'translate(-50%, -50%)', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - '& > img': { - width: '100%', - height: '100%', - objectFit: 'contain', - }, -}); - -const textWrapperStyle = css({ - position: 'absolute', - bottom: '0', - left: '0', - right: '0', - padding: '1rem', - fontWeight: 'bold', - color: '#000000', - display: 'flex', - justifyContent: 'space-between', -}); - -const titleStyle = css({ - fontWeight: 'bold', - color: '#000000', - flex: 1, - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis', - textAlign: 'left', -}); - -const percentageStyle = css({ - fontWeight: 'bold', - color: '#000000', - textAlign: 'right', -}); - -const cardCva = cva({ - base: { - position: 'relative', - display: 'inline-block', - width: '100%', - maxWidth: '300px', - aspectRatio: '220/272', - }, - variants: { - size: { - small: { - maxWidth: '150px', - }, - medium: { - maxWidth: '200px', - }, - large: { - maxWidth: '300px', - }, - responsive: { - maxWidth: '100%', - }, - }, - }, -}); diff --git a/packages/ui/panda/src/components/Card/NoRatingCard.tsx b/packages/ui/panda/src/components/Card/NoRatingCard.tsx deleted file mode 100644 index 8445e01a..00000000 --- a/packages/ui/panda/src/components/Card/NoRatingCard.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { cx, css } from '_panda/css'; -import { flex } from '_panda/patterns'; - -// TODO : 아예 외부 경로로 옮겨도 괜찮을것 같다. - -type CardTierType = 'EX' | 'S_PLUS' | 'A_PLUS' | 'B_MINUS'; - -interface Props { - tier: CardTierType; - type: string; - personaImage: string; - bgUrl: string; - thumbnailUrl: string; - rightTextEl: React.ReactNode; -} - -export function NoRatingCard(props: Props) { - return ( -
    -
    - {props.tier} -
    -
    - {props.tier} -
    -
    - {props.type} -
    -
    -

    {snakeToTitleCase(props.type)}

    -

    {props.rightTextEl}

    -
    -
    - ); -} - -/** - * 스네이크 케이스 문자열을 타이틀 케이스로 변환합니다. - * @param str - 변환할 스네이크 케이스 문자열 - * @returns 타이틀 케이스로 변환된 문자열 - * @example - * snakeToTitleCase('SUMI_MA') => 'Sumi Ma' - */ -export const snakeToTitleCase = (str: string): string => { - return str - .toLowerCase() - .split('_') - .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) - .join(' '); -}; - -export const container = css({ - position: 'relative', - width: '265px', - height: '328px', -}); - -export const bgImage = css({ - position: 'absolute', - top: 0, - left: 0, - width: '100%', - height: '100%', - zIndex: 0, -}); - -export const thumbnailImage = css({ - position: 'absolute', - top: '16px', - left: '16px', - right: '16px', - - zIndex: 1, -}); - -export const infoWrapper = flex({ - position: 'absolute', - bottom: '20px', - left: '20px', - right: '20px', - justifyContent: 'space-between', - gap: '8px', -}); - -export const typeText = css({ - textStyle: 'glyph24.bold', - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', - overflow: 'hidden', - lineHeight: '40px', -}); - -export const ratingText = css({ - textStyle: 'glyph22.regular', - lineHeight: '40px', -}); diff --git a/packages/ui/panda/src/components/Card/constants.ts b/packages/ui/panda/src/components/Card/constants.ts deleted file mode 100644 index 3937be9e..00000000 --- a/packages/ui/panda/src/components/Card/constants.ts +++ /dev/null @@ -1,26 +0,0 @@ -export type CardTierType = 'EX' | 'S_PLUS' | 'A_PLUS' | 'B_MINUS' | 'EVOLUTION'; - -export const CARD_INFO: Record = { - EX: { - bg: 'card-bg-EX.webp', - thumbnail: 'card-thumbnail-EX.webp', - }, - S_PLUS: { - bg: 'card-bg-S_PLUS.webp', - thumbnail: 'card-thumbnail-S_PLUS.webp', - }, - A_PLUS: { - bg: 'card-bg-A_PLUS.webp', - thumbnail: 'card-thumbnail-A_PLUS.webp', - }, - B_MINUS: { - bg: 'card-bg-B_MINUS.webp', - thumbnail: 'card-thumbnail-B_MINUS.webp', - }, - EVOLUTION: { - bg: 'card-bg-EVOLUTION.webp', - thumbnail: 'card-thumbnail-EVOLUTION.webp', - }, -}; - -export const ANIMAL_CARD_IMAGE_BASE_URL = '/assets/animal-card/'; diff --git a/packages/ui/panda/src/components/Card/index.ts b/packages/ui/panda/src/components/Card/index.ts deleted file mode 100644 index 55c84945..00000000 --- a/packages/ui/panda/src/components/Card/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { CardBack } from './CardBack'; -export { NoRatingCard } from './NoRatingCard'; -export { GameCard } from './GameCard'; diff --git a/packages/ui/panda/src/components/CheckBox/CheckBox.tsx b/packages/ui/panda/src/components/CheckBox/CheckBox.tsx deleted file mode 100644 index 769556ef..00000000 --- a/packages/ui/panda/src/components/CheckBox/CheckBox.tsx +++ /dev/null @@ -1,35 +0,0 @@ -'use client'; - -import * as React from 'react'; -import * as CheckboxPrimitive from '@radix-ui/react-checkbox'; -import { Check } from 'lucide-react'; -import { css, cx } from '_panda/css'; -import { styled } from '_panda/jsx'; -import { checkbox, icon } from '_panda/recipes'; - -const BaseCheckbox = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => { - const styles = checkbox(); - - return ( - - - - - - ); -}); -BaseCheckbox.displayName = CheckboxPrimitive.Root.displayName; - -export const Checkbox = styled(BaseCheckbox); - -const checkboxLightStyle = css({ - borderColor: '#fafafa', - - '&[data-state="checked"]': { - backgroundColor: '#fafafa', - color: '#000', - }, -}); diff --git a/packages/ui/panda/src/components/CheckBox/index.ts b/packages/ui/panda/src/components/CheckBox/index.ts deleted file mode 100644 index 9c857f3d..00000000 --- a/packages/ui/panda/src/components/CheckBox/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Checkbox } from './CheckBox'; diff --git a/packages/ui/panda/src/components/Chip/CombineChip.stories.tsx b/packages/ui/panda/src/components/Chip/CombineChip.stories.tsx deleted file mode 100644 index aca529ad..00000000 --- a/packages/ui/panda/src/components/Chip/CombineChip.stories.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { CombineChip } from './CombineChip'; - -const meta: Meta = { - title: 'Components/CombineChip', - component: CombineChip, - tags: ['autodocs'], - parameters: { - layout: 'centered', - }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - render: () => ( - - - - - - - 옵션 - 옵션 1 - 옵션 2 - 옵션 3 - - - - ), -}; - -export const SmallSize: Story = { - render: () => ( - - - - - - - 옵션 - 옵션 1 - 옵션 2 - - - - ), -}; diff --git a/packages/ui/panda/src/components/Chip/CombineChip.tsx b/packages/ui/panda/src/components/Chip/CombineChip.tsx deleted file mode 100644 index 6ab7cdd1..00000000 --- a/packages/ui/panda/src/components/Chip/CombineChip.tsx +++ /dev/null @@ -1,139 +0,0 @@ -'use client'; - -import * as React from 'react'; -import * as ChipPrimitive from '@radix-ui/react-select'; -import { Check, ChevronDown } from 'lucide-react'; -import { createStyleContext } from '@shadow-panda/style-context'; -import { styled } from '_panda/jsx'; -import { select, icon } from '_panda/recipes'; -import { css, cva, cx, RecipeVariantProps } from '_panda/css'; - -const chipTriggerStyle = cva({ - base: { - width: 'fit-content', - padding: '6px 12px 6px 8px', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - }, - - variants: { - size: { - small: { - height: '30px', - color: 'white.white_50', - borderRadius: '6px', - textStyle: 'glyph12.regular', - borderColor: 'white.white_5', - backgroundColor: 'white.white_5', - gap: '1px', - }, - medium: { - height: '36px', - color: 'white.white_90', - textStyle: 'glyph16.regular', - borderColor: 'white.white_25', - backgroundColor: 'white.white_25', - borderRadius: '8px', - gap: '2px', - }, - }, - }, - defaultVariants: { - size: 'medium', - }, -}); - -type ChipTriggerStyleProps = RecipeVariantProps; - -const chipContentStyle = css({ - backgroundColor: 'black.black_75', - borderRadius: 10, - border: '1px solid', - borderColor: 'black.black_50', - color: 'white', - zIndex: 9999, - pointerEvents: 'auto', -}); - -const chipItemStyle = css({ - color: 'white', - textStyle: 'glyph16.regular', - - _hover: { - backgroundColor: 'white.white_5', - }, - _focus: { - backgroundColor: 'white.white_5', - }, -}); - -const { withProvider, withContext } = createStyleContext(select); - -const Trigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & ChipTriggerStyleProps ->(({ children, ...props }, ref) => ( - - {children} - - - - -)); -Trigger.displayName = ChipPrimitive.Trigger.displayName; - -const Viewport = withContext(ChipPrimitive.Viewport, 'viewport'); - -const Content = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, position = 'popper', ...props }, ref) => ( - - - {children} - - -)); -Content.displayName = ChipPrimitive.Content.displayName; - -const ItemIndicator = withContext(styled(ChipPrimitive.ItemIndicator), 'itemIndicator'); - -const Item = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( - - - - - - {children} - -)); -Item.displayName = ChipPrimitive.Item.displayName; - -const ChipRoot = withProvider(styled(ChipPrimitive.Root), 'root'); -const ChipGroup = withContext(styled(ChipPrimitive.Group), 'group'); -const ChipValue = withContext(styled(ChipPrimitive.Value), 'value'); -const ChipTrigger = withContext(styled(Trigger), 'trigger'); -const ChipContent = withContext(styled(Content), 'content'); -const ChipLabel = withContext(styled(ChipPrimitive.Label), 'label'); -const ChipItem = withContext(styled(Item), 'item'); -const ChipSeparator = withContext(styled(ChipPrimitive.Separator), 'separator'); - -export const CombineChip = Object.assign(ChipRoot, { - Group: ChipGroup, - Value: ChipValue, - Trigger: ChipTrigger, - Content: ChipContent, - Label: ChipLabel, - Item: ChipItem, - Separator: ChipSeparator, -}); diff --git a/packages/ui/panda/src/components/Chip/index.ts b/packages/ui/panda/src/components/Chip/index.ts deleted file mode 100644 index f84225b8..00000000 --- a/packages/ui/panda/src/components/Chip/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './CombineChip'; diff --git a/packages/ui/panda/src/components/Dialog/CommonDialog.tsx b/packages/ui/panda/src/components/Dialog/CommonDialog.tsx deleted file mode 100644 index 19d7f184..00000000 --- a/packages/ui/panda/src/components/Dialog/CommonDialog.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { css } from '_panda/css'; -import { Dialog } from './Dialog'; - -interface CommonDialogProps { - isOpen: boolean; - onClose: () => void; - title?: string; - description?: string; - children: React.ReactNode; - - size?: 'default' | 'large' | 'screen'; -} - -export function CommonDialog(props: CommonDialogProps) { - return ( - - - {props.title && {props.title}} - {props.description && {props.description}} - {props.children} - - - ); -} - -const headingStyle = css({ display: 'flex', flexDirection: 'column', justifyContent: 'flex-end' }); -const descriptionStyle = css({ marginTop: '16px' }); diff --git a/packages/ui/panda/src/components/Dialog/Dialog.styles.ts b/packages/ui/panda/src/components/Dialog/Dialog.styles.ts deleted file mode 100644 index 720e28a1..00000000 --- a/packages/ui/panda/src/components/Dialog/Dialog.styles.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { css, cva, RecipeVariantProps } from '_panda/css'; - -export const dialogContentCva = cva({ - base: { - background: 'gray.gray_150', - borderRadius: '16px', - border: '1px solid', - borderColor: 'gray.gray_150', - zIndex: 3001, - color: 'white.white_100', - }, - variants: { - size: { - default: { - display: 'flex', - width: '100%', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - gap: '28px', - color: 'white', - '& .dialog-title': { - textStyle: 'glyph20.regular', - textAlign: 'left', - width: '100%', - }, - - _mobile: { - maxWidth: 'calc(100vw - 48px)', - }, - }, - large: { - borderRadius: '16px', - backgroundColor: 'gray.gray_150', - padding: '60px 40px', - - maxWidth: 'calc(100% - 400px)', - maxHeight: 'calc(100% - 240px)', - width: '100%', - height: '100%', - - '@media (max-width: 1200px)': { - padding: '48px 24px', - maxWidth: 'calc(100vw - 240px)', - maxHeight: 'calc(100vh - 120px)', - }, - _mobile: { - height: '100%', - maxWidth: '100vw', - maxHeight: '100vh', - borderRadius: '0px', - }, - }, - screen: { - margin: 'auto', - borderRadius: '0', - backgroundColor: 'gray.gray_150', - padding: '24px', - width: '100vw', - height: '100vh', - maxWidth: '100vw', - maxHeight: '100vh', - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - justifyContent: 'center', - - '@media (min-width: 1920px)': { - borderRadius: '16px', - width: '1400px', - height: 'fit-content', - }, - }, - }, - }, - defaultVariants: { - size: 'default', - }, -}); - -export type DialogContentVariants = RecipeVariantProps; - -export const dialogScrollableStyle = css({ - display: 'flex', - flexDirection: 'column', - overflow: 'hidden', - '& .dialog-title': { flexShrink: 0 }, -}); - -export const dialogTopSlotStyle = css({ - flexShrink: 0, - width: '100%', -}); - -export const dialogBodyStyle = css({ - flex: 1, - minHeight: 0, - overflowY: 'auto', - overflowX: 'hidden', - width: '100%', -}); - -export const dialogTitleStyle = css({ - textStyle: 'glyph48.bold', - color: 'white.white_100', - textAlign: 'center', - '@media (max-width: 1200px)': { - textStyle: 'glyph32.bold', - }, - _mobile: { - textStyle: 'glyph24.bold', - }, -}); diff --git a/packages/ui/panda/src/components/Dialog/Dialog.tsx b/packages/ui/panda/src/components/Dialog/Dialog.tsx deleted file mode 100644 index becac65a..00000000 --- a/packages/ui/panda/src/components/Dialog/Dialog.tsx +++ /dev/null @@ -1,107 +0,0 @@ -'use client'; - -import * as React from 'react'; -import * as DialogPrimitive from '@radix-ui/react-dialog'; -import { X } from 'lucide-react'; -import { createStyleContext } from '@shadow-panda/style-context'; -import { styled } from '_panda/jsx'; -import { css, cx } from '_panda/css'; -import { dialog } from '_panda/recipes'; -import { - dialogContentCva, - DialogContentVariants, - dialogTitleStyle, - dialogScrollableStyle, - dialogTopSlotStyle, - dialogBodyStyle, -} from './Dialog.styles'; - -const { withProvider, withContext } = createStyleContext(dialog); - -const DialogPortal = withContext(styled(DialogPrimitive.Portal), 'portal'); -const DialogOverlay = withContext(styled(DialogPrimitive.Overlay), 'overlay'); -const DialogClose = withContext(styled(DialogPrimitive.Close), 'close'); - -type DialogContentProps = { - isShowClose?: boolean; - scrollable?: boolean; -} & DialogContentVariants & - React.ComponentPropsWithoutRef; - -const Content = React.forwardRef, DialogContentProps>( - ({ children, isShowClose = true, scrollable, ...props }, ref) => ( - - - - {children} - {isShowClose && ( - - - Close - - )} - - - ), -); - -Content.displayName = DialogPrimitive.Content.displayName; - -// TODO: z-index 수정 필요 -const overlayStyle = css({ background: 'black.black_75', zIndex: 3000 }); -const closeStyle = css({ background: 'transparent', outline: 'none', padding: '0' }); - -const Title = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => { - return ( - - {children} - - ); -}); - -Title.displayName = DialogPrimitive.Title.displayName; - -const TopSlot = React.forwardRef>( - ({ className, ...props }, ref) =>
    , -); -TopSlot.displayName = 'DialogTopSlot'; - -const Body = React.forwardRef>( - ({ className, ...props }, ref) =>
    , -); -Body.displayName = 'DialogBody'; - -export const DialogRoot = withProvider(styled(DialogPrimitive.Root), 'root'); -export const DialogTrigger = withContext(styled(DialogPrimitive.Trigger), 'trigger'); -export const DialogContent = withContext(styled(Content), 'content'); -export const DialogHeader = withContext(styled('div'), 'header'); -export const DialogFooter = withContext(styled('div'), 'footer'); -export const DialogTitle = withContext(styled(Title), 'title'); -export const DialogDescription = withContext(styled(DialogPrimitive.Description), 'description'); -export const DialogTopSlot = TopSlot; -export const DialogBody = Body; - -const Dialog = Object.assign(DialogRoot, { - Root: DialogRoot, - Trigger: DialogTrigger, - Content: DialogContent, - Header: DialogHeader, - Footer: DialogFooter, - Title: DialogTitle, - Description: DialogDescription, - TopSlot: DialogTopSlot, - Body: DialogBody, -}); - -export { Dialog }; diff --git a/packages/ui/panda/src/components/Dialog/index.ts b/packages/ui/panda/src/components/Dialog/index.ts deleted file mode 100644 index c7509f44..00000000 --- a/packages/ui/panda/src/components/Dialog/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './Dialog'; -export * from './Dialog.styles'; -export * from './CommonDialog'; diff --git a/packages/ui/panda/src/components/DropdownMenu/DropdownMenu.tsx b/packages/ui/panda/src/components/DropdownMenu/DropdownMenu.tsx deleted file mode 100644 index fecdfdb0..00000000 --- a/packages/ui/panda/src/components/DropdownMenu/DropdownMenu.tsx +++ /dev/null @@ -1,136 +0,0 @@ -'use client'; - -import * as React from 'react'; -import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'; -import { Check, ChevronRight, Circle } from 'lucide-react'; -import { createStyleContext } from '@shadow-panda/style-context'; -import { styled } from '_panda/jsx'; -import { dropdownMenu, icon } from '_panda/recipes'; -import { css, cx } from '_panda/css'; -const { withProvider, withContext } = createStyleContext(dropdownMenu); - -const SubTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - insetLeft?: boolean; - } ->(({ className, insetLeft, children, ...props }, ref) => ( - - {children} - - -)); -SubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName; - -const Content = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ sideOffset = 4, ...props }, ref) => ( - - - -)); -Content.displayName = DropdownMenuPrimitive.Content.displayName; - -const Item = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - insetLeft?: boolean; - } ->(({ className, insetLeft, ...props }, ref) => ( - -)); -Item.displayName = DropdownMenuPrimitive.Item.displayName; - -const ItemIndicator = withContext(styled(DropdownMenuPrimitive.ItemIndicator), 'itemIndicator'); - -const CheckboxItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( - - - - - {children} - -)); -CheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName; - -const RadioItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( - - - - - {children} - -)); -RadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName; - -const Label = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - insetLeft?: boolean; - } ->(({ className, insetLeft, ...props }, ref) => ( - -)); -Label.displayName = DropdownMenuPrimitive.Label.displayName; - -export const DropdownMenu = withProvider(styled(DropdownMenuPrimitive.Root), 'root'); -export const DropdownMenuTrigger = withContext(styled(DropdownMenuPrimitive.Trigger), 'trigger'); -export const DropdownMenuGroup = withContext(styled(DropdownMenuPrimitive.Group), 'group'); -export const DropdownMenuPortal = withContext(styled(DropdownMenuPrimitive.Portal), 'portal'); -export const DropdownMenuSub = withContext(styled(DropdownMenuPrimitive.Sub), 'sub'); -export const DropdownMenuRadioGroup = withContext(styled(DropdownMenuPrimitive.RadioGroup), 'radioGroup'); -export const DropdownMenuSubTrigger = withContext(styled(SubTrigger), 'subTrigger'); -export const DropdownMenuSubContent = withContext(styled(DropdownMenuPrimitive.SubContent), 'subContent'); -export const DropdownMenuContent = withContext(styled(Content), 'content'); -export const DropdownMenuItem = withContext(styled(Item), 'item'); -export const DropdownMenuCheckboxItem = withContext(styled(CheckboxItem), 'checkboxItem'); -export const DropdownMenuRadioItem = withContext(styled(RadioItem), 'radioItem'); -export const DropdownMenuLabel = withContext(styled(Label), 'label'); -export const DropdownMenuSeparator = withContext(styled(DropdownMenuPrimitive.Separator), 'separator'); -export const DropdownMenuShortcut = withContext(styled('span'), 'shortcut'); diff --git a/packages/ui/panda/src/components/DropdownMenu/index.tsx b/packages/ui/panda/src/components/DropdownMenu/index.tsx deleted file mode 100644 index 8aadf2fa..00000000 --- a/packages/ui/panda/src/components/DropdownMenu/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './DropdownMenu'; diff --git a/packages/ui/panda/src/components/Label/Label.tsx b/packages/ui/panda/src/components/Label/Label.tsx deleted file mode 100644 index 6850e574..00000000 --- a/packages/ui/panda/src/components/Label/Label.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { styled, type HTMLStyledProps } from '_panda/jsx'; -import { label } from '_panda/recipes'; - -export const Label = styled('label', label); -export type LabelProps = HTMLStyledProps; diff --git a/packages/ui/panda/src/components/Label/index.tsx b/packages/ui/panda/src/components/Label/index.tsx deleted file mode 100644 index dd0252d8..00000000 --- a/packages/ui/panda/src/components/Label/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { Label } from './Label'; diff --git a/packages/ui/panda/src/components/ScrollArea/ScrollArea.tsx b/packages/ui/panda/src/components/ScrollArea/ScrollArea.tsx deleted file mode 100644 index d6e1df0c..00000000 --- a/packages/ui/panda/src/components/ScrollArea/ScrollArea.tsx +++ /dev/null @@ -1,44 +0,0 @@ -'use client'; - -import * as React from 'react'; -import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area'; -import { createStyleContext } from '@shadow-panda/style-context'; -import { styled } from '_panda/jsx'; -import { scrollArea } from '_panda/recipes'; - -const { withProvider, withContext } = createStyleContext(scrollArea); - -const Viewport = withContext(ScrollAreaPrimitive.Viewport, 'viewport'); -const Corner = withContext(ScrollAreaPrimitive.Corner, 'corner'); -const Thumb = withContext(ScrollAreaPrimitive.ScrollAreaThumb, 'thumb'); - -const BaseScrollBar = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ orientation = 'vertical', ...props }, ref) => ( - - - -)); -BaseScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName; - -export const ScrollBar = withContext(styled(BaseScrollBar), 'scrollbar'); - -const BaseScrollArea = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( - - {children} - - - -)); -BaseScrollArea.displayName = ScrollAreaPrimitive.Root.displayName; - -export const ScrollArea = withProvider(styled(BaseScrollArea), 'root'); diff --git a/packages/ui/panda/src/components/ScrollArea/index.ts b/packages/ui/panda/src/components/ScrollArea/index.ts deleted file mode 100644 index 4ab76e5c..00000000 --- a/packages/ui/panda/src/components/ScrollArea/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './ScrollArea'; diff --git a/packages/ui/panda/src/components/SearchBar/SearchBar.stories.tsx b/packages/ui/panda/src/components/SearchBar/SearchBar.stories.tsx deleted file mode 100644 index 92807799..00000000 --- a/packages/ui/panda/src/components/SearchBar/SearchBar.stories.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { SearchBar } from './SearchBar'; - -const meta: Meta = { - title: 'Components/SearchBar', - component: SearchBar, - tags: ['autodocs'], -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - args: { - placeholder: '검색어를 입력하세요', - }, -}; - -export const WithValue: Story = { - args: { - placeholder: '검색어를 입력하세요', - defaultValue: '검색어', - }, -}; - -export const Disabled: Story = { - args: { - placeholder: '검색어를 입력하세요', - disabled: true, - }, -}; - -export const WithOnSubmit: Story = { - args: { - placeholder: '검색어를 입력하세요', - onSubmit: () => alert('검색이 실행되었습니다!'), - }, -}; diff --git a/packages/ui/panda/src/components/SearchBar/SearchBar.tsx b/packages/ui/panda/src/components/SearchBar/SearchBar.tsx deleted file mode 100644 index a789edf3..00000000 --- a/packages/ui/panda/src/components/SearchBar/SearchBar.tsx +++ /dev/null @@ -1,63 +0,0 @@ -'use client'; - -import { css, cx } from '_panda/css'; -import { flex } from '_panda/patterns'; -import { SearchIcon } from 'lucide-react'; -import { ComponentProps } from 'react'; - -export function SearchBar({ onSubmit, onKeyDown, ...props }: ComponentProps<'input'> & { onSubmit?: () => void }) { - return ( -
    - { - if (e.key === 'Enter') { - onSubmit?.(); - } - onKeyDown?.(e); - }} - /> - -
    - ); -} - -const containerStyle = flex({ - width: '100%', - height: '40px', - alignItems: 'center', - gap: '8px', - borderRadius: '8px', - border: '1px solid', - borderColor: 'white.white_25', - flexShrink: 0, - position: 'relative', - transition: 'border-color 0.1s ease-in-out', - _focusWithin: { - borderColor: 'white.white_75', - }, -}); - -const inputStyle = css({ - width: '100%', - height: '100%', - border: 'none', - outline: 'none', - textStyle: 'glyph16.regular', - padding: '8px 12px', - color: 'white.white_75', - _placeholder: { - color: 'white.white_25', - }, -}); - -const iconStyle = css({ - position: 'absolute', - right: '12px', - top: '50%', - transform: 'translateY(-50%)', -}); diff --git a/packages/ui/panda/src/components/SearchBar/index.ts b/packages/ui/panda/src/components/SearchBar/index.ts deleted file mode 100644 index 3d7e42eb..00000000 --- a/packages/ui/panda/src/components/SearchBar/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './SearchBar'; diff --git a/packages/ui/panda/src/components/Select/Select.stories.tsx b/packages/ui/panda/src/components/Select/Select.stories.tsx deleted file mode 100644 index afe0481c..00000000 --- a/packages/ui/panda/src/components/Select/Select.stories.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { Select } from './Select'; - -const meta: Meta = { - title: 'Components/Select', - component: Select, - tags: ['autodocs'], - parameters: { - layout: 'centered', - }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - render: () => ( - - ), -}; - -export const WithSeparator: Story = { - render: () => ( - - ), -}; diff --git a/packages/ui/panda/src/components/Select/Select.styles.ts b/packages/ui/panda/src/components/Select/Select.styles.ts deleted file mode 100644 index 82ccddc9..00000000 --- a/packages/ui/panda/src/components/Select/Select.styles.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { css, cva, RecipeVariantProps } from '_panda/css'; - -export const selectTriggerStyle = cva({ - base: { - textStyle: 'glyph16.regular', - color: 'white.white_90', - width: 'fit-content', - height: '36px', - padding: '6px 8px', - borderRadius: 10, - backgroundColor: 'white.white_25', - borderColor: 'white.white_25', - }, - - variants: { - size: { - sm: { - height: '30px', - backgroundColor: 'white.white_5', - }, - }, - }, -}); - -export type SelectTriggerStyleProps = RecipeVariantProps; - -export const selectContentStyle = css({ - backgroundColor: 'black.black_75', - borderRadius: 10, - border: '1px solid', - borderColor: 'black.black_50', - color: 'white', -}); - -export const selectItemStyle = css({ - color: 'white', - textStyle: 'glyph16.regular', - - _hover: { - backgroundColor: 'white.white_5', - }, - _focus: { - backgroundColor: 'white.white_5', - }, -}); diff --git a/packages/ui/panda/src/components/Select/Select.tsx b/packages/ui/panda/src/components/Select/Select.tsx deleted file mode 100644 index 9b66581f..00000000 --- a/packages/ui/panda/src/components/Select/Select.tsx +++ /dev/null @@ -1,84 +0,0 @@ -'use client'; - -import * as React from 'react'; -import * as SelectPrimitive from '@radix-ui/react-select'; -import { Check, ChevronDown } from 'lucide-react'; -import { createStyleContext } from '@shadow-panda/style-context'; -import { styled } from '_panda/jsx'; -import { select, icon } from '_panda/recipes'; -import { cx } from '_panda/css'; -import { selectContentStyle, selectItemStyle, selectTriggerStyle, SelectTriggerStyleProps } from './Select.styles'; - -const { withProvider, withContext } = createStyleContext(select); - -const Trigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & SelectTriggerStyleProps ->(({ children, ...props }, ref) => ( - - {children} - - - - -)); -Trigger.displayName = SelectPrimitive.Trigger.displayName; - -const Viewport = withContext(SelectPrimitive.Viewport, 'viewport'); - -const Content = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, position = 'popper', ...props }, ref) => ( - - - {children} - - -)); -Content.displayName = SelectPrimitive.Content.displayName; - -const ItemIndicator = withContext(styled(SelectPrimitive.ItemIndicator), 'itemIndicator'); - -const Item = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ children, ...props }, ref) => ( - - - - - - {children} - -)); -Item.displayName = SelectPrimitive.Item.displayName; - -const SelectRoot = withProvider(styled(SelectPrimitive.Root), 'root'); -const SelectGroup = withContext(styled(SelectPrimitive.Group), 'group'); -const SelectValue = withContext(styled(SelectPrimitive.Value), 'value'); -const SelectTrigger = withContext(styled(Trigger), 'trigger'); -const SelectContent = withContext(styled(Content), 'content'); -const SelectLabel = withContext(styled(SelectPrimitive.Label), 'label'); -const SelectItem = withContext(styled(Item), 'item'); -const SelectSeparator = withContext(styled(SelectPrimitive.Separator), 'separator'); - -export const Select = Object.assign(SelectRoot, { - Group: SelectGroup, - Value: SelectValue, - Trigger: SelectTrigger, - Content: SelectContent, - Label: SelectLabel, - Item: SelectItem, - Separator: SelectSeparator, -}); diff --git a/packages/ui/panda/src/components/Select/index.ts b/packages/ui/panda/src/components/Select/index.ts deleted file mode 100644 index f5430298..00000000 --- a/packages/ui/panda/src/components/Select/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Chip 컴포넌트와 동일합니다. - * 디자인 가이드 상 이름이 Chip임으로 통일하는 것이 좋을 것 같아요. - * @deprecated - */ -export * from './Select'; diff --git a/packages/ui/panda/src/components/Skeleton/Skeleton.tsx b/packages/ui/panda/src/components/Skeleton/Skeleton.tsx deleted file mode 100644 index 996ac221..00000000 --- a/packages/ui/panda/src/components/Skeleton/Skeleton.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import { styled } from '_panda/jsx'; -import { skeletonStyle } from './cva'; - -export const Skeleton = styled('div', skeletonStyle); diff --git a/packages/ui/panda/src/components/Skeleton/cva.tsx b/packages/ui/panda/src/components/Skeleton/cva.tsx deleted file mode 100644 index 65ddbcba..00000000 --- a/packages/ui/panda/src/components/Skeleton/cva.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { cva } from '_panda/css'; - -export const skeletonStyle = cva({ - base: { - overflow: 'hidden', - backgroundSize: '200% 100%', - animation: `skeletonLoading 1.5s infinite linear`, - background: - 'linear-gradient(90deg, token(colors.gray.800) 25%, token(colors.gray.600) 50%, token(colors.gray.200) 75%, token(colors.gray.800) 100%)', - }, - variants: { - color: { - white: { - backgroundColor: 'white_10', - background: - 'linear-gradient(90deg, token(colors.gray.800) 25%, token(colors.gray.600) 50%, token(colors.gray.200) 75%, token(colors.gray.800) 100%)', - }, - black: { - backgroundColor: 'black_10', - }, - }, - }, - defaultVariants: { - color: 'white', - }, -}); diff --git a/packages/ui/panda/src/components/Skeleton/index.ts b/packages/ui/panda/src/components/Skeleton/index.ts deleted file mode 100644 index 0dbc6dac..00000000 --- a/packages/ui/panda/src/components/Skeleton/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Skeleton } from './Skeleton'; -export { skeletonStyle } from './cva'; diff --git a/packages/ui/panda/src/components/Textfield/TextField.stories.tsx b/packages/ui/panda/src/components/Textfield/TextField.stories.tsx deleted file mode 100644 index cb44aaf9..00000000 --- a/packages/ui/panda/src/components/Textfield/TextField.stories.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { TextField } from './TextField'; - -const meta: Meta = { - title: 'Components/TextField', - component: TextField, - tags: ['autodocs'], -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - args: { - placeholder: '텍스트를 입력하세요', - }, -}; - -export const WithValue: Story = { - args: { - placeholder: '텍스트를 입력하세요', - defaultValue: '입력된 텍스트', - }, -}; - -export const WithError: Story = { - args: { - placeholder: '텍스트를 입력하세요', - error: '올바른 텍스트를 입력해주세요', - }, -}; - -export const Disabled: Story = { - args: { - placeholder: '텍스트를 입력하세요', - disabled: true, - }, -}; diff --git a/packages/ui/panda/src/components/Textfield/TextField.tsx b/packages/ui/panda/src/components/Textfield/TextField.tsx deleted file mode 100644 index 433ad002..00000000 --- a/packages/ui/panda/src/components/Textfield/TextField.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { css, cx } from '_panda/css'; -import { ComponentProps } from 'react'; - -interface TextFieldProps extends ComponentProps<'input'> { - error?: string; -} - -export const TextField = ({ error, ...props }: TextFieldProps) => { - return ( -
    - - {error &&

    {error}

    } -
    - ); -}; - -const textFieldStyle = css({ - height: '55px', - padding: '14px 20px', - alignItems: 'flex-start', - gap: '8px', - borderRadius: '8px', - border: '1px solid', - borderColor: 'white.white_25', - color: 'white', - textStyle: 'glyph16.regular', - width: '100%', - _placeholder: { - color: 'white.white_50', - }, -}); - -const errorStyle = css({ - textStyle: 'glyph14.regular', - color: 'brand.coral', - mt: '6px', -}); diff --git a/packages/ui/panda/src/components/Textfield/Textarea.stories.tsx b/packages/ui/panda/src/components/Textfield/Textarea.stories.tsx deleted file mode 100644 index b2d5e2ee..00000000 --- a/packages/ui/panda/src/components/Textfield/Textarea.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { TextArea } from './Textarea'; - -const meta: Meta = { - title: 'Components/TextArea', - component: TextArea, - tags: ['autodocs'], -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - args: { - placeholder: '텍스트를 입력하세요', - }, -}; - -export const WithValue: Story = { - args: { - placeholder: '텍스트를 입력하세요', - defaultValue: '입력된 텍스트입니다.\n여러 줄의 텍스트를 입력할 수 있습니다.', - }, -}; - -export const Disabled: Story = { - args: { - placeholder: '텍스트를 입력하세요', - disabled: true, - }, -}; diff --git a/packages/ui/panda/src/components/Textfield/Textarea.tsx b/packages/ui/panda/src/components/Textfield/Textarea.tsx deleted file mode 100644 index 51e189b1..00000000 --- a/packages/ui/panda/src/components/Textfield/Textarea.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { cx, css } from '_panda/css'; -import { ComponentProps } from 'react'; - -export const TextArea = (props: ComponentProps<'textarea'>) => { - return