From 5accfd5d30e0f5b7087d698c783b19143cef5dd9 Mon Sep 17 00:00:00 2001 From: hee-suh Date: Sat, 8 Jun 2024 14:51:25 +0900 Subject: [PATCH 1/8] chore: remove tanstack query --- .eslintrc.json | 1 - package-lock.json | 182 ----------------------- package.json | 3 - src/app/(test)/query-test/Components.tsx | 49 ------ src/app/(test)/query-test/page.tsx | 12 -- src/app/layout.tsx | 5 +- src/app/provider.tsx | 61 -------- 7 files changed, 1 insertion(+), 312 deletions(-) delete mode 100644 src/app/(test)/query-test/Components.tsx delete mode 100644 src/app/(test)/query-test/page.tsx delete mode 100644 src/app/provider.tsx diff --git a/.eslintrc.json b/.eslintrc.json index 1fe48191..a9638cc8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,7 +9,6 @@ "next/core-web-vitals", "airbnb-typescript", "prettier", - "plugin:@tanstack/eslint-plugin-query/recommended", "plugin:storybook/recommended" ], "parserOptions": { diff --git a/package-lock.json b/package-lock.json index 97be9aea..494ae0fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,6 @@ "name": "vitamin-c-web", "version": "0.1.0", "dependencies": { - "@tanstack/react-query": "^5.36.0", "next": "14.2.3", "react": "^18", "react-dom": "^18" @@ -26,8 +25,6 @@ "@storybook/react": "^8.1.1", "@storybook/test": "^8.1.1", "@svgr/webpack": "^8.1.0", - "@tanstack/eslint-plugin-query": "^5.35.6", - "@tanstack/react-query-next-experimental": "^5.36.0", "@testing-library/react": "^15.0.7", "@types/node": "^20", "@types/react": "^18", @@ -6458,61 +6455,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@tanstack/eslint-plugin-query": { - "version": "5.35.6", - "resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-5.35.6.tgz", - "integrity": "sha512-XhVRLsJFJMWYNzArPzy1MWSpx2BSUnc8Zof+fvsgaAnWBy9tjNXH3DFftZoNMGA8Mw1dPIdDPkEQcSku3m80Jw==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "^6.20.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "eslint": "^8.0.0" - } - }, - "node_modules/@tanstack/query-core": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.36.0.tgz", - "integrity": "sha512-B5BD3pg/mztDR36i77hGcyySKKeYrbM5mnogOROTBi1SUml5ByRK7PGUUl16vvubvQC+mSnqziFG/VIy/DE3FQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tanstack/react-query": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.36.0.tgz", - "integrity": "sha512-BATvtM0rohwg7pRHUnxgeDiwLWRGZ8OM/4y8LImHVpecQWoH6Uhytu3Z8YV6V7hQ1sMQBFcUrGE1/e4MxR6YiA==", - "dependencies": { - "@tanstack/query-core": "5.36.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^18.0.0" - } - }, - "node_modules/@tanstack/react-query-next-experimental": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-next-experimental/-/react-query-next-experimental-5.36.0.tgz", - "integrity": "sha512-NBYM8HuOjZeDce+fdE9mlf2BTqJgtbSp9VJX+fN6t+wVtoUSN93SeZD/7vRnRv22yKA4PehbPNQ0maX4TWwa/A==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "@tanstack/react-query": "^5.36.0", - "next": "^13 || ^14", - "react": "^18.0.0" - } - }, "node_modules/@testing-library/dom": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", @@ -7209,130 +7151,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/visitor-keys": { "version": "7.10.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.10.0.tgz", diff --git a/package.json b/package.json index f3318c42..e3c55322 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "build-storybook": "storybook build" }, "dependencies": { - "@tanstack/react-query": "^5.36.0", "next": "14.2.3", "react": "^18", "react-dom": "^18" @@ -31,8 +30,6 @@ "@storybook/react": "^8.1.1", "@storybook/test": "^8.1.1", "@svgr/webpack": "^8.1.0", - "@tanstack/eslint-plugin-query": "^5.35.6", - "@tanstack/react-query-next-experimental": "^5.36.0", "@testing-library/react": "^15.0.7", "@types/node": "^20", "@types/react": "^18", diff --git a/src/app/(test)/query-test/Components.tsx b/src/app/(test)/query-test/Components.tsx deleted file mode 100644 index fc338017..00000000 --- a/src/app/(test)/query-test/Components.tsx +++ /dev/null @@ -1,49 +0,0 @@ -'use client' - -import { Suspense } from 'react' -import { useSuspenseQuery } from '@tanstack/react-query' -import { APIError } from '@/app/api/error' - -export function useDelayQuery({ delay }: { delay: number }) { - return useSuspenseQuery({ - queryKey: ['delay', delay], - queryFn: async () => { - const res = await fetch( - `http://localhost:3000/api/delay?delay=${delay}`, - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - const data = await res.json() - if (Reflect.has(data, 'ok') && Reflect.has(data, 'message')) return data - - throw new APIError({ name: 'delay-api', message: 'API Error' }) - }, - }) -} - -const DelayedComponent = ({ delay }: { delay: number }) => { - const query = useDelayQuery({ delay }) - - return
result: {query.data.message}
-} - -export const SingleSuspenseDelays = () => { - return [100, 200, 300, 400, 500].map((delay) => ( - {delay} wait...}> - - - )) -} - -export const CombineSuspenseDelays = () => { - return ( - Combine wait...}> - {[800, 900, 1000].map((delay) => ( - - ))} - - ) -} diff --git a/src/app/(test)/query-test/page.tsx b/src/app/(test)/query-test/page.tsx deleted file mode 100644 index 7fed8db8..00000000 --- a/src/app/(test)/query-test/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -// import { CombineSuspenseDelays, SingleSuspenseDelays } from './Components' - -const QueryTestPage = () => { - return ( -
- {/* - */} -
- ) -} - -export default QueryTestPage diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 7b76389a..678bf482 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -4,7 +4,6 @@ import type { Metadata } from 'next' import { Inter } from 'next/font/google' import './globals.css' -import Providers from './provider' const inter = Inter({ subsets: ['latin'] }) @@ -20,9 +19,7 @@ export default function RootLayout({ }>) { return ( - - {children} - + {children} ) } diff --git a/src/app/provider.tsx b/src/app/provider.tsx deleted file mode 100644 index 2b6bc4f0..00000000 --- a/src/app/provider.tsx +++ /dev/null @@ -1,61 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import { - QueryCache, - QueryClient, - QueryClientProvider, -} from '@tanstack/react-query' -import { ReactQueryStreamedHydration } from '@tanstack/react-query-next-experimental' - -import { APIError } from './api/error' - -interface ProvidersProps { - children: ReactNode -} - -function queryClientFactory() { - return new QueryClient({ - defaultOptions: { - queries: { - retry: false, - refetchOnWindowFocus: false, - // With SSR, we usually want to set some default staleTime - // above 0 to avoid refetching immediately on the client - staleTime: 60 * 1000, - }, - }, - queryCache: new QueryCache({ - onError: (error) => { - // TODO. error 에 따른 처리 - if (error instanceof APIError) { - // console.error('API Error', error.message) - } else { - // console.error('UnExpected Error', error.message) - } - }, - }), - }) -} - -let browserQueryClient: QueryClient | undefined - -function getQueryClient() { - if (typeof window === 'undefined') { - return queryClientFactory() - } - if (!browserQueryClient) browserQueryClient = queryClientFactory() - return browserQueryClient -} - -const Providers = ({ children }: ProvidersProps) => { - const queryClient = getQueryClient() - - return ( - - {children} - - ) -} - -export default Providers From 0798bf0a44ffe935f9cd6e211ca1d92d527bd976 Mon Sep 17 00:00:00 2001 From: hee-suh Date: Sat, 8 Jun 2024 21:00:54 +0900 Subject: [PATCH 2/8] feat: add clsx, twMerge and cva to make css easier --- package-lock.json | 48 +++++++++++++++++++++++++++++++++++++++++++---- package.json | 5 ++++- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 494ae0fd..1202639e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,12 @@ "name": "vitamin-c-web", "version": "0.1.0", "dependencies": { + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", "next": "14.2.3", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "tailwind-merge": "^2.3.0" }, "devDependencies": { "@chromatic-com/storybook": "^1.4.0", @@ -2281,7 +2284,6 @@ "version": "7.24.5", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", - "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -9036,6 +9038,25 @@ "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", "dev": true }, + "node_modules/class-variance-authority": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", + "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", + "dependencies": { + "clsx": "2.0.0" + }, + "funding": { + "url": "https://joebell.co.uk" + } + }, + "node_modules/class-variance-authority/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/clean-css": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", @@ -9165,6 +9186,14 @@ "node": ">=0.10.0" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -16615,8 +16644,7 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regenerator-transform": { "version": "0.15.2", @@ -18100,6 +18128,18 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tailwind-merge": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.3.0.tgz", + "integrity": "sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==", + "dependencies": { + "@babel/runtime": "^7.24.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", diff --git a/package.json b/package.json index e3c55322..887209b6 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,12 @@ "build-storybook": "storybook build" }, "dependencies": { + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", "next": "14.2.3", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "tailwind-merge": "^2.3.0" }, "devDependencies": { "@chromatic-com/storybook": "^1.4.0", From b58becee0ee454c70546acdb19eaed0bc1beb117 Mon Sep 17 00:00:00 2001 From: hee-suh Date: Sat, 8 Jun 2024 21:02:04 +0900 Subject: [PATCH 3/8] feat: implement util function 'cn' --- src/utils/cn.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/utils/cn.ts diff --git a/src/utils/cn.ts b/src/utils/cn.ts new file mode 100644 index 00000000..63918477 --- /dev/null +++ b/src/utils/cn.ts @@ -0,0 +1,8 @@ +import { clsx, type ClassValue } from 'clsx' +import { twMerge } from 'tailwind-merge' + +const cn = (...inputs: ClassValue[]) => { + return twMerge(clsx(inputs)) +} + +export default cn From 709714451af7d1b670c1068cda793b1bb652bd6d Mon Sep 17 00:00:00 2001 From: hee-suh Date: Wed, 12 Jun 2024 12:46:01 +0900 Subject: [PATCH 4/8] feat: apply cn and cva to css --- src/stories/Button.stories.ts | 13 ++++---- src/stories/Button.tsx | 61 ++++++++++++++++++++--------------- src/stories/Header.tsx | 35 ++++++++++++-------- 3 files changed, 64 insertions(+), 45 deletions(-) diff --git a/src/stories/Button.stories.ts b/src/stories/Button.stories.ts index 2f117529..d3a9def8 100644 --- a/src/stories/Button.stories.ts +++ b/src/stories/Button.stories.ts @@ -14,7 +14,7 @@ const meta = { tags: ['autodocs'], // More on argTypes: https://storybook.js.org/docs/api/argtypes argTypes: { - backgroundColor: { control: 'color' }, + bgColor: { control: 'color' }, }, // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args args: { onClick: fn() }, @@ -26,35 +26,36 @@ type Story = StoryObj // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args export const Primary: Story = { args: { - primary: true, label: 'Button', }, } export const Secondary: Story = { args: { + variant: 'secondary', label: 'Button', }, } export const Large: Story = { args: { - size: 'large', + variant: 'secondary', + size: 'lg', label: 'Button', }, } export const Small: Story = { args: { - size: 'small', + variant: 'secondary', + size: 'sm', label: 'Button', }, } export const Warning: Story = { args: { - primary: true, label: 'Delete now', - backgroundColor: 'red', + bgColor: 'red', }, } diff --git a/src/stories/Button.tsx b/src/stories/Button.tsx index bd53ad40..c0453a4e 100644 --- a/src/stories/Button.tsx +++ b/src/stories/Button.tsx @@ -1,18 +1,37 @@ -import React from 'react' +import React, { ButtonHTMLAttributes } from 'react' +import { cva, VariantProps } from 'class-variance-authority' +import cn from '@/utils/cn' -interface ButtonProps { - /** - * Is this the principal call to action on the page? - */ - primary?: boolean +const ButtonVariants = cva( + ` + font-[700] border-0 rounded-[3em] cursor-pointer inline-block leading-normal + `, + { + variants: { + size: { + sm: 'text-[12px] py-[10px] px-[16px]', + md: 'text-[14px] py-[11px] px-[20px]', + lg: 'text-[16px] py-[12px] px-[24px]', + }, + variant: { + primary: 'text-white bg-[#1ea7fd]', + secondary: 'text-[#333] bg-transparent shadow-md', + }, + }, + defaultVariants: { + size: 'md', + variant: 'primary', + }, + }, +) + +interface ButtonProps + extends ButtonHTMLAttributes, + VariantProps { /** * What background color to use */ - backgroundColor?: string - /** - * How large should the button be? - */ - size?: 'small' | 'medium' | 'large' + bgColor?: string /** * Button contents */ @@ -31,28 +50,18 @@ interface ButtonProps { * Primary UI component for user interaction */ export const Button = ({ - primary = false, - size = 'medium', - backgroundColor, + size, + variant, + bgColor, label, className, ...props }: ButtonProps) => { - const mode = primary - ? 'text-white bg-[#1ea7fd]' - : 'text-[#333] bg-transparent shadow-md' return (