diff --git a/.github/workflows/build-design-system.yml b/.github/workflows/build-design-system.yml new file mode 100644 index 00000000..8f73cabc --- /dev/null +++ b/.github/workflows/build-design-system.yml @@ -0,0 +1,54 @@ +name: Build Design System + +on: + pull_request: + paths: + - "packages/design-system/src/tokens/**" + +jobs: + build-design-system: + runs-on: ubuntu-latest + + steps: + # Step 1: Checkout the repository + - name: Checkout repository + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + + # Step 2: Cache Bun dependencies + - name: Cache Bun dependencies + id: cache-deps + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-bun-dependencies-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun-dependencies- + + # Step 3: Set up Bun + - name: Setup Bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: latest + + # Step 4: Install dependencies only if the cache was not restored + - name: Install dependencies + if: steps.cache-deps.outputs.cache-hit != 'true' + working-directory: ./packages/design-system + run: bun install + + # Step 5: Run the build script + - name: Run build script + working-directory: ./packages/design-system + run: bun run build + + # Step 6: Commit and push changes + - name: Commit and push changes + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: "chore: update design system tokens" + branch: ${{ github.head_ref }} + file_pattern: ./packages/design-system/** + token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} diff --git a/.hintrc b/.hintrc index aa8de6b4..1f143282 100644 --- a/.hintrc +++ b/.hintrc @@ -1,5 +1,8 @@ { "extends": [ "development" - ] + ], + "hints": { + "typescript-config/consistent-casing": "off" + } } \ No newline at end of file diff --git a/apps/core/app/(landing)/_components/addtoCard.tsx b/apps/core/app/(landing)/_components/addtoCard.tsx new file mode 100644 index 00000000..6a67bce6 --- /dev/null +++ b/apps/core/app/(landing)/_components/addtoCard.tsx @@ -0,0 +1,126 @@ +"use client"; + +import Metamaskicon from "@repo/icons/metamask"; +import Card from "./card"; +import Tonconnecticon from "@repo/icons/tonconnect"; +import Paypalicon from "@repo/icons/paypal"; +import { Input } from "@repo/ui/components/input"; +import { Button } from "@repo/ui/components/button"; +import Securityicon from "@repo/icons/security"; +import { Label } from "@repo/ui/components/label"; +import { useState } from "react"; +import CardSkeleton from "./card-cart-skeleton"; +import useCartStore from "../store/cart-store"; + +const Addtocard = () => { + const { isAddToCartOpen, closeAddToCart, addToCart } = useCartStore(); + + const [cards, setCards] = useState([ + { id: 1, title: "Traveler - Travel Agency", price: "$15" }, + { id: 2, title: "Explorer - Adventure Company", price: "$20" }, + { id: 3, title: "Explorer - Adventure Company", price: "$20" }, + { id: 4, title: "Explorer - Adventure Company", price: "$20" }, + { id: 5, title: "Explorer - Adventure Company", price: "$20" }, + ]); + + const temp = [ + { id: 1, title: "temp", price: "t" }, + { id: 1, title: "temp", price: "t" }, + { id: 1, title: "temp", price: "t" }, + ]; + + const activeTemp = temp.splice(cards.length); + + const handleRemove = (id: number) => { + setCards(cards.filter((card) => card.id !== id)); + }; + + if (!isAddToCartOpen) return null; + + return ( +
+
+
+ {cards.map((card) => ( + + ))} + + {activeTemp.map((card) => ( + + ))} +
+ +
+

Checkout

+
+
+ +

Metamask

+
+
+ +

Tonconnect

+
+
+ +

Paypal

+
+
+
+ +
+ {/* to do : # label container */} + + { + // to do : # sign out + }} + > + Sign out + +
+ +
+
+ +
+
+ { + closeAddToCart(); + }} + /> +

+ Your payment is secured by MetaMask +

+
+
+
+ ); +}; + +export default Addtocard; diff --git a/apps/core/app/(landing)/_components/browseMegaMenu/bottomPart/bottom-part-menu.tsx b/apps/core/app/(landing)/_components/browseMegaMenu/bottomPart/bottom-part-menu.tsx new file mode 100644 index 00000000..02ebca56 --- /dev/null +++ b/apps/core/app/(landing)/_components/browseMegaMenu/bottomPart/bottom-part-menu.tsx @@ -0,0 +1,58 @@ +import Typography from "@repo/ui/components/typography"; +import IllustratorIcon from "@repo/icons/Illustrator"; +import Adobexdicon from "@repo/icons/adobexd"; +import Belendericon from "@repo/icons/belender"; +import Sketchicon from "@repo/icons/sketch"; +import Cinema4DIcon from "@repo/icons/cinema4D"; +import Framericon from "@repo/icons/framer"; +import Htmlicon from "@repo/icons/html"; +import Photoshopicon from "@repo/icons/photoshop"; +import AfterEffecticon from "@repo/icons/after-effects"; + +const BottomPartMenu = () => { + return ( +
+ Browse by most popular formats +
+
+ + Adobe XD +
+
+ + Blender +
+
+ + Sketch +
+
+ + After Effects +
+
+ + Cinema 4D +
+
+ + Framer +
+
+ + HTML +
+
+ + Illustrator +
+
+ + Photoshop +
+
+
+ ); +}; + +export { BottomPartMenu }; diff --git a/apps/core/app/(landing)/_components/browseMegaMenu/browse-mega-menu.tsx b/apps/core/app/(landing)/_components/browseMegaMenu/browse-mega-menu.tsx new file mode 100644 index 00000000..9fd6e70d --- /dev/null +++ b/apps/core/app/(landing)/_components/browseMegaMenu/browse-mega-menu.tsx @@ -0,0 +1,15 @@ +import { BottomPartMenu } from "./bottomPart/bottom-part-menu"; +import { TopPartMenu } from "./topPart/top-part-menu"; +import { RetroGrid } from "@repo/ui/components/retroGrid"; + +const BrowseMegaMenu = () => { + return ( +
+ + + +
+ ); +}; + +export { BrowseMegaMenu }; diff --git a/apps/core/app/(landing)/_components/browseMegaMenu/topPart/top-part-menu.tsx b/apps/core/app/(landing)/_components/browseMegaMenu/topPart/top-part-menu.tsx new file mode 100644 index 00000000..9fe5bcc5 --- /dev/null +++ b/apps/core/app/(landing)/_components/browseMegaMenu/topPart/top-part-menu.tsx @@ -0,0 +1,63 @@ +import Asset3dIcon from "@repo/icons/3dAsset"; +import IconSetsIcon from "@repo/icons/icon-sets"; +import IllustrationIcon from "@repo/icons/illustration"; +import MockUpsIcon from "@repo/icons/mockups"; +import PolygonIcon from "@repo/icons/polygon"; +import UiKitIcon from "@repo/icons/ui-kit"; +import WireFrameIcon from "@repo/icons/wire-frame"; +import Typography from "@repo/ui/components/typography"; +import Link from "next/link"; + +interface CategoryItemProps { + title: string; + icon: React.ReactNode; + link: string; +} + +export const CategoryItem = (props: CategoryItemProps) => { + const { title, icon, link } = props; + return ( +
+ + + {icon} + + {title} + + +
+ ); +}; + +const TopPartMenu = () => { + return ( +
+ } + link="#" + /> + } + link="#" + /> + } + link="#" + /> + } + link="#" + /> + } link="#" /> +
+ ); +}; + +export { TopPartMenu }; diff --git a/apps/core/app/(landing)/_components/card-cart-skeleton.tsx b/apps/core/app/(landing)/_components/card-cart-skeleton.tsx new file mode 100644 index 00000000..9f03f81e --- /dev/null +++ b/apps/core/app/(landing)/_components/card-cart-skeleton.tsx @@ -0,0 +1,15 @@ +const CardSkeleton = () => { + return ( +
+
+
+
+
+
+
+
+
+ ); +}; + +export default CardSkeleton; diff --git a/apps/core/app/(landing)/_components/card.tsx b/apps/core/app/(landing)/_components/card.tsx new file mode 100644 index 00000000..819b8ca2 --- /dev/null +++ b/apps/core/app/(landing)/_components/card.tsx @@ -0,0 +1,45 @@ +import Removeicon from "@repo/icons/remove"; +import Image from "next/image"; + +interface CardProps { + id: number; + onRemove: (id: number) => void; + title: string; + price: string; +} + +const Card: React.FC = (props) => { + const { id, onRemove, title, price } = props; + + return ( +
+
+
+
+ card +
+
+

{title}

+

{price}

+
+
+
onRemove(id)} + > + +
+
+
+ ); +}; + +export default Card; diff --git a/apps/core/app/(landing)/_components/desktop-navbar/animated-navbar.tsx b/apps/core/app/(landing)/_components/desktop-navbar/animated-navbar.tsx deleted file mode 100644 index 7e792720..00000000 --- a/apps/core/app/(landing)/_components/desktop-navbar/animated-navbar.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import Link from "next/link"; - -const AnimatedNavBar = () => { - return ( - - -
- - Browse - - - All-Access - - - Become an author - -
- - ); -}; - -export default AnimatedNavBar; diff --git a/apps/core/app/(landing)/_components/desktop-navbar/feather-navbar.tsx b/apps/core/app/(landing)/_components/desktop-navbar/feather-navbar.tsx deleted file mode 100644 index 504be5f2..00000000 --- a/apps/core/app/(landing)/_components/desktop-navbar/feather-navbar.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import Shoppingbagicon from "@repo/icons/shopping-bag"; -import FecherNavbarAuthenticated from "./feather-navbar-authenticated"; -import FecherNavbarGuest from "./feather-navbar-guest"; - -export interface AuthStatusBarProps { - islogin: boolean; -} - -const Fechernabar = (props: AuthStatusBarProps) => { - const { islogin } = props; - return ( -
- - {islogin && } - {!islogin && } -
- ); -}; - -export default Fechernabar; diff --git a/apps/core/app/(landing)/_components/desktop-navbar/feather-navbar-authenticated.tsx b/apps/core/app/(landing)/_components/desktop-navbar/feature-navbar-authenticated.tsx similarity index 71% rename from apps/core/app/(landing)/_components/desktop-navbar/feather-navbar-authenticated.tsx rename to apps/core/app/(landing)/_components/desktop-navbar/feature-navbar-authenticated.tsx index 1a4f3f0d..21968e03 100644 --- a/apps/core/app/(landing)/_components/desktop-navbar/feather-navbar-authenticated.tsx +++ b/apps/core/app/(landing)/_components/desktop-navbar/feature-navbar-authenticated.tsx @@ -1,5 +1,5 @@ import Doorexiticon from "@repo/icons/Doorexiticon"; -import Heart1icon from "@repo/icons/heart1"; +import Heart1icon from "@repo/icons/heart"; import Settingsicon from "@repo/icons/Settingsicon"; import Shoppingbagicon from "@repo/icons/shopping-bag"; import Usercircleicon from "@repo/icons/Usercircleicon"; @@ -11,22 +11,39 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "@repo/ui/components/dropdown-menu"; +import Image from "next/image"; import Link from "next/link"; +import useCartStore from "../../store/cart-store"; import Useractionpixelicon from "@repo/icons/useractionpixel"; +import { + AvatarImage, + AvatarFallback, + Avatar, +} from "@repo/ui/components/avatar"; + +const FeatureNavbarAuthenticated = () => { + const { toggleAddToCart } = useCartStore(); -const FecherNavbarAuthenticated = () => { return (
- + +
+ + + {/* TODO: add badge #erfan*/} +
+ 3 +
+
- avatar + + {/* TODO: Add User info */} + + CN + @@ -73,4 +90,4 @@ const FecherNavbarAuthenticated = () => { ); }; -export default FecherNavbarAuthenticated; +export default FeatureNavbarAuthenticated; diff --git a/apps/core/app/(landing)/_components/desktop-navbar/feather-navbar-guest.tsx b/apps/core/app/(landing)/_components/desktop-navbar/feature-navbar-guest.tsx similarity index 88% rename from apps/core/app/(landing)/_components/desktop-navbar/feather-navbar-guest.tsx rename to apps/core/app/(landing)/_components/desktop-navbar/feature-navbar-guest.tsx index 73894ed0..b0a74c25 100644 --- a/apps/core/app/(landing)/_components/desktop-navbar/feather-navbar-guest.tsx +++ b/apps/core/app/(landing)/_components/desktop-navbar/feature-navbar-guest.tsx @@ -1,6 +1,6 @@ import Typography from "@repo/ui/components/typography"; -const FecherNavbarGuest = () => { +const FeatureNavbarGuest = () => { return (
{ ); }; -export default FecherNavbarGuest; +export default FeatureNavbarGuest; diff --git a/apps/core/app/(landing)/_components/desktop-navbar/features-navbar.tsx b/apps/core/app/(landing)/_components/desktop-navbar/features-navbar.tsx new file mode 100644 index 00000000..ea3842e0 --- /dev/null +++ b/apps/core/app/(landing)/_components/desktop-navbar/features-navbar.tsx @@ -0,0 +1,19 @@ +import Shoppingbagicon from "@repo/icons/shopping-bag"; +import FeatureNavbarAuthenticated from "./feature-navbar-authenticated"; +import FeatureNavbarGuest from "./feature-navbar-guest"; + +export interface AuthStatusBarProps { + islogin: boolean; +} + +const FeaturesNavbar = (props: AuthStatusBarProps) => { + const { islogin } = props; + return ( +
+ {islogin && } + {!islogin && } +
+ ); +}; + +export default FeaturesNavbar; diff --git a/apps/core/app/(landing)/_components/desktop-navbar/navbar-links.tsx b/apps/core/app/(landing)/_components/desktop-navbar/navbar-links.tsx new file mode 100644 index 00000000..3bc38e0a --- /dev/null +++ b/apps/core/app/(landing)/_components/desktop-navbar/navbar-links.tsx @@ -0,0 +1,16 @@ +import Typography from "@repo/ui/components/typography"; + +const NavbarLinks = () => { + return ( +
+ + Browse + + + Become an author + +
+ ); +}; + +export default NavbarLinks; diff --git a/apps/core/app/(landing)/_components/desktop-navbar/navbar.tsx b/apps/core/app/(landing)/_components/desktop-navbar/navbar.tsx index 34b5bdc4..0f9b23be 100644 --- a/apps/core/app/(landing)/_components/desktop-navbar/navbar.tsx +++ b/apps/core/app/(landing)/_components/desktop-navbar/navbar.tsx @@ -1,11 +1,14 @@ "use client"; import PixelIcon from "@repo/icons/pxiel"; import SearchIcon from "@repo/icons/serach"; +import { NavigationMenu } from "@repo/ui/components/navigation-menu"; import { AnimatePresence, motion } from "framer-motion"; import { useRef, useState } from "react"; -import AnimatedNavBar from "./animated-navbar"; -import Fechernabar from "./feather-navbar"; +import Addtocard from "../addtoCard"; +import NavbarLinks from "./navbar-links"; +import FeaturesNavbar from "./features-navbar"; import Searchbar, { RefSearchHandle } from "./search-bar"; +import { BrowseMegaMenu } from "../browseMegaMenu/browse-mega-menu"; const Navbar = ({ islogin }: { islogin: boolean }) => { // isSeaching state @@ -26,11 +29,11 @@ const Navbar = ({ islogin }: { islogin: boolean }) => { setIsSearchActive(false); }; - const isMobile = true; + const isMobile = false; return ( - + + + + {/* */} +
); }; diff --git a/apps/core/app/(landing)/layout.tsx b/apps/core/app/(landing)/layout.tsx index 0d014d06..ffb2fafb 100644 --- a/apps/core/app/(landing)/layout.tsx +++ b/apps/core/app/(landing)/layout.tsx @@ -9,7 +9,7 @@ import Navbar from "./_components/desktop-navbar/navbar"; function Layout({ children }: { children: React.ReactNode }): JSX.Element { return (
- +
{children}
diff --git a/apps/core/app/(landing)/page.tsx b/apps/core/app/(landing)/page.tsx index 7e246a9f..a5c39602 100644 --- a/apps/core/app/(landing)/page.tsx +++ b/apps/core/app/(landing)/page.tsx @@ -91,9 +91,18 @@ export default function Page() { weight="medium" className="text-center" > - Find thousands of meticulously - crafted resources by{" "} - + Find{" "} + + {" "} + thousands + {" "} + of meticulously crafted resources by{" "} + pixel geniuses {" "} to supercharge your creativity. diff --git a/apps/core/app/(landing)/product/[id]/_components/product-footer.tsx b/apps/core/app/(landing)/product/[id]/_components/product-footer.tsx index 9664a8b4..0fd3b97e 100644 --- a/apps/core/app/(landing)/product/[id]/_components/product-footer.tsx +++ b/apps/core/app/(landing)/product/[id]/_components/product-footer.tsx @@ -1,4 +1,4 @@ -import Heart1icon from "@repo/icons/heart1"; +import Heart1icon from "@repo/icons/heart"; import Messagecircleicon from "@repo/icons/message-circle"; import Shopingcartplusicon from "@repo/icons/shopping-cart-plus"; import { SCROLL_TOP_RANGE } from "@repo/ui/components/parallax-scroll-effect"; diff --git a/apps/core/app/(landing)/product/[id]/page.tsx b/apps/core/app/(landing)/product/[id]/page.tsx index d673adda..1c2aced7 100644 --- a/apps/core/app/(landing)/product/[id]/page.tsx +++ b/apps/core/app/(landing)/product/[id]/page.tsx @@ -5,7 +5,7 @@ import Chevronrighticon from "@repo/icons/chevron-right"; import Circlecheckicon from "@repo/icons/Circle-check"; import Clouddownloadicon from "@repo/icons/cloud-download"; import Figmaicon from "@repo/icons/figma"; -import Heart1icon from "@repo/icons/heart1"; +import Heart1icon from "@repo/icons/heart"; import Instagram from "@repo/icons/instagram"; import Messagecircleicon from "@repo/icons/message-circle"; import Shopingcartplusicon from "@repo/icons/shopping-cart-plus"; diff --git a/apps/core/app/(landing)/product/test/page.tsx b/apps/core/app/(landing)/product/test/page.tsx index c3473111..bd7f2d9e 100644 --- a/apps/core/app/(landing)/product/test/page.tsx +++ b/apps/core/app/(landing)/product/test/page.tsx @@ -5,7 +5,7 @@ import Chevronrighticon from "@repo/icons/chevron-right"; import Circlecheckicon from "@repo/icons/Circle-check"; import Clouddownloadicon from "@repo/icons/cloud-download"; import Figmaicon from "@repo/icons/figma"; -import Heart1icon from "@repo/icons/heart1"; +import Heart1icon from "@repo/icons/heart"; import Instagram from "@repo/icons/instagram"; import Messagecircleicon from "@repo/icons/message-circle"; import Shopingcartplusicon from "@repo/icons/shopping-cart-plus"; diff --git a/apps/core/app/(landing)/store/cart-store.ts b/apps/core/app/(landing)/store/cart-store.ts new file mode 100644 index 00000000..82663051 --- /dev/null +++ b/apps/core/app/(landing)/store/cart-store.ts @@ -0,0 +1,31 @@ +import { create } from 'zustand'; + +type CartItem = { + id: string; + name: string; + price: number; + quantity: number; +}; + +type CartState = { + isAddToCartOpen: boolean; + cartItems: CartItem[]; + openAddToCart: () => void; + closeAddToCart: () => void; + addToCart: (item: CartItem) => void; + toggleAddToCart: () => void; +}; + +const useCartStore = create((set) => ({ + isAddToCartOpen: false, + cartItems: [], + openAddToCart: () => set({ isAddToCartOpen: true }), + closeAddToCart: () => set({ isAddToCartOpen: false }), + toggleAddToCart: () => set((state) => ({ isAddToCartOpen: !state.isAddToCartOpen })), + addToCart: (item) => + set((state) => ({ + cartItems: [...state.cartItems, item], + })), +})); + +export default useCartStore; \ No newline at end of file diff --git a/apps/core/app/(landing)/test/megaMenuContent/page.tsx b/apps/core/app/(landing)/test/megaMenuContent/page.tsx new file mode 100644 index 00000000..7332e052 --- /dev/null +++ b/apps/core/app/(landing)/test/megaMenuContent/page.tsx @@ -0,0 +1,9 @@ +import { BrowseMegaMenu } from "../../_components/browseMegaMenu/browse-mega-menu"; + +export default function Page() { + return ( +
+ +
+ ); +} diff --git a/apps/core/app/auth/layout.tsx b/apps/core/app/auth/layout.tsx index 37223c29..77d65b6b 100644 --- a/apps/core/app/auth/layout.tsx +++ b/apps/core/app/auth/layout.tsx @@ -1,4 +1,4 @@ -import "@repo/ui/globals.css"; +import "@repo/ui/globals.scss"; import type { Metadata } from "next"; export const metadata: Metadata = { diff --git a/apps/core/app/foundation/page.tsx b/apps/core/app/foundation/page.tsx index e0e79ffe..ca08fc51 100644 --- a/apps/core/app/foundation/page.tsx +++ b/apps/core/app/foundation/page.tsx @@ -1,8 +1,159 @@ +import Chevrondownicon from "@repo/icons/chevron-down"; +import Hearticon from "@repo/icons/heart"; +import { Button } from "@repo/ui/components/button"; import { FoundationColor } from "@repo/ui/components/foundation-color"; +import { Input } from "@repo/ui/components/input"; +import Typography from "@repo/ui/components/typography"; + +type ButtonGroup = { + label: string; // Describes the group of buttons + variants: Array<"primary" | "secondary" | "tertiary">; // The button variants + sizes: Array<"sm" | "md" | "lg">; // The button sizes + isLoading: boolean; // Indicates if the button is in a loading state + disabled: boolean; // Indicates if the button is disabled + statusColor?: "success" | "warning" | "error"; // Optional status color +}; + + +const buttonData:ButtonGroup[] = [ + { + label: "Default", + variants: ["primary", "secondary", "tertiary"], + sizes: ["sm", "md", "lg"], + isLoading: false, + disabled: false, + statusColor: undefined, + }, + { + label: "Loading", + variants: ["primary", "secondary", "tertiary"], + sizes: ["sm", "md", "lg"], + isLoading: true, + disabled: false, + statusColor: undefined, + }, + { + label: "Disabled", + variants: ["primary", "secondary", "tertiary"], + sizes: ["sm", "md", "lg"], + isLoading: false, + disabled: true, + statusColor: undefined, + }, + { + label: "Success", + variants: ["primary", "secondary", "tertiary"], + sizes: ["sm", "md", "lg"], + isLoading: false, + disabled: false, + statusColor: "success", + }, + { + label: "Success Loading", + variants: ["primary", "secondary", "tertiary"], + sizes: ["sm", "md", "lg"], + isLoading: true, + disabled: false, + statusColor: "success", + }, + { + label: "Success Disabled", + variants: ["primary", "secondary", "tertiary"], + sizes: ["sm", "md", "lg"], + isLoading: false, + disabled: true, + statusColor: "success", + }, + { + label: "Warning", + variants: ["primary", "secondary", "tertiary"], + sizes: ["sm", "md", "lg"], + isLoading: false, + disabled: false, + statusColor: "warning", + }, + { + label: "Error", + variants: ["primary", "secondary", "tertiary"], + sizes: ["sm", "md", "lg"], + isLoading: false, + disabled: false, + statusColor: "error", + }, +]; const Page = () => { return ( -
+
+
+ Foundation Button +
+ {buttonData.map((group, groupIndex) => ( +
+ {/*

{group.label}

*/} + + {group.label} + + {group.variants.map((variant) => + group.sizes.map((size) => ( + + )), + )} +
+ ))} +
+
+ + {/* Input */} + +
+ Foundation Input +
+
+ + + +
+
+ + + +
+
+
+
); diff --git a/apps/core/app/layout.tsx b/apps/core/app/layout.tsx index cd49a80c..d6619102 100644 --- a/apps/core/app/layout.tsx +++ b/apps/core/app/layout.tsx @@ -1,4 +1,4 @@ -import "@repo/ui/globals.css"; +import "@repo/ui/globals.scss"; import { cn } from "@repo/ui/lib/utils"; import type { Metadata } from "next"; import { ThemeProvider } from "next-themes"; diff --git a/apps/core/next.config.mjs b/apps/core/next.config.mjs index c4b5d259..105d8c79 100644 --- a/apps/core/next.config.mjs +++ b/apps/core/next.config.mjs @@ -1,6 +1,13 @@ /** @type {import('next').NextConfig} */ + +// https://s3-alpha-sig.figma.com/img/ce79/f737/ea54458a8146c4935 +//https://images.unsplash.com/photo-1730292422804-5bbb2bd2d3f0?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D +// config src image const nextConfig = { transpilePackages: ["@repo/ui"], + images: { + domains: ["images.unsplash.com"], + }, }; export default nextConfig; diff --git a/apps/core/package.json b/apps/core/package.json index 52443f96..f7819046 100644 --- a/apps/core/package.json +++ b/apps/core/package.json @@ -21,7 +21,8 @@ "react": "^18", "react-dom": "^18", "react-hook-form": "^7.53.1", - "sonner": "^1.5.0" + "sonner": "^1.5.0", + "zustand": "^5.0.2" }, "devDependencies": { "@next/eslint-plugin-next": "14.2.4", diff --git a/bun.lockb b/bun.lockb index 958c41fa..59c7cade 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index db8068dc..1b462703 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "ui:add": "bun --filter @repo/ui ui:add", "gen:api": "turbo gen api", "prepare": "husky", - "deploy": "git pull origin main && git push vercel main" + "deploy": "git pull origin main && git push vercel main", + "rebase:main": "git fetch origin main && git rebase main" }, "devDependencies": { "@repo/eslint-config": "*", diff --git a/packages/apis/src/services/core/base/upload/post/post-uploadfile.schema.ts b/packages/apis/src/services/core/base/upload/post/post-uploadfile.schema.ts new file mode 100644 index 00000000..1e149d88 --- /dev/null +++ b/packages/apis/src/services/core/base/upload/post/post-uploadfile.schema.ts @@ -0,0 +1,35 @@ +import { apiResponseSchema } from "#schema/api-response-schema"; +import { z } from "zod"; + +// Response +export const postUploadfileRequestSchemaTransformed = z + .object({ + file: z.array(z.instanceof(File)), + }) + .transform((data) => { + const form = new FormData(); + data.file.forEach((file) => { + form.append("file", file); + }); + return form; + }); + +// Request +export const postUploadfileResponseSchemaTransofrmed = apiResponseSchema + .extend({ + data: z.array( + z.object({ + id: z.number(), + file: z.string(), + extension: z.string(), + mimetype: z.string(), + created_at: z.string(), + }), + ), + }) + .transform((data) => data); + +export const postUploadfileSchema = { + response: postUploadfileResponseSchemaTransofrmed, + request: postUploadfileRequestSchemaTransformed, +}; diff --git a/packages/apis/src/services/core/base/upload/post/post-uploadfile.ts b/packages/apis/src/services/core/base/upload/post/post-uploadfile.ts new file mode 100644 index 00000000..8c685033 --- /dev/null +++ b/packages/apis/src/services/core/base/upload/post/post-uploadfile.ts @@ -0,0 +1,38 @@ +import { coreApi } from "#instance/core-api"; +import { ApiResponse } from "@repo/apis/types/api.types"; +import { requestHandler } from "@repo/apis/utils/request-handler"; +import path from "path"; +import { postUploadfileSchema as schema } from "./post-uploadfile.schema"; +import { + PostUploadfileRequest, + PostUploadfileResponseTransformed, +} from "./post-uploadfile.types"; + +export const postUploadfileURL = () => path.join("/base/upload/"); + +export const postUploadfile = async ( + props?: PostUploadfileRequest, +): Promise> => { + const payloadParsed = schema.request.parse(props); + + const URL = postUploadfileURL(); + + const response = await requestHandler( + () => + coreApi.post(URL, payloadParsed, { + headers: { + "Content-Type": "multipart/form-data", + Authorization: + "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzM2NTAzMzk0LCJpYXQiOjE3MzU4OTg1OTQsImp0aSI6ImY4NmYwYzc5NjNhZTQwYTlhMGMzNzBiYzIyOTAyMmQ1IiwidXNlcl9pZCI6MX0.8c5Nn3ZtgQGHNJjEy2Ywvl9CWWf8BJLFK-4ab4wavCo", + }, + }), + schema.response._def.schema, + { + isMock: true, + }, + ); + + const dataParsed = schema.response.parse(response.data); + + return { ...response, data: dataParsed }; +}; diff --git a/packages/apis/src/services/core/base/upload/post/post-uploadfile.types.ts b/packages/apis/src/services/core/base/upload/post/post-uploadfile.types.ts new file mode 100644 index 00000000..badfa82c --- /dev/null +++ b/packages/apis/src/services/core/base/upload/post/post-uploadfile.types.ts @@ -0,0 +1,16 @@ +import { z } from "zod"; +import { postUploadfileSchema } from "./post-uploadfile.schema"; + +// Response +export type PostUploadfileRequest = z.input; + +export type PostUploadfileRequestTransofrmed = z.infer< + typeof postUploadfileSchema.request +>; + +// Request +export type PostUploadfileResponse = z.input; + +export type PostUploadfileResponseTransformed = z.infer< + typeof postUploadfileSchema.response +>; diff --git a/packages/apis/src/services/core/base/upload/post/use-post-uploadfile.ts b/packages/apis/src/services/core/base/upload/post/use-post-uploadfile.ts new file mode 100644 index 00000000..6e104810 --- /dev/null +++ b/packages/apis/src/services/core/base/upload/post/use-post-uploadfile.ts @@ -0,0 +1,34 @@ +import { + ApiError, + ApiResponse, + UseMutationProps, +} from "@repo/apis/types/api.types"; +import { useMutation } from "@tanstack/react-query"; +import { postUploadfile } from "./post-uploadfile"; +import {} from "./post-uploadfile.schema"; +import { + PostUploadfileRequest, + PostUploadfileResponseTransformed, +} from "./post-uploadfile.types"; + +export type UsePostUploadfileProps = UseMutationProps< + ApiResponse, + ApiError, + PostUploadfileRequest +>; + +export const postUploadfileQueryKey = () => ["postUploadfile"]; + +export const UsePostUploadfile = (props?: UsePostUploadfileProps) => { + const mutation = useMutation< + ApiResponse, + ApiError, + PostUploadfileRequest + >({ + mutationKey: postUploadfileQueryKey(), + mutationFn: (data) => postUploadfile(data), + ...props, + }); + + return mutation; +}; diff --git a/packages/design-system/package.json b/packages/design-system/package.json new file mode 100644 index 00000000..39a464dd --- /dev/null +++ b/packages/design-system/package.json @@ -0,0 +1,15 @@ +{ + "name": "@repo/design-system", + "version": "1.0.0", + "scripts": { + "build": "bun run src/scripts/build.ts" + }, + "exports": { + "./styles": "./src/styles/main.scss", + "./tailwind": "./src/tailwind/config.ts" + }, + "devDependencies": { + "@repo/typescript-config": "*", + "style-dictionary": "^4.3.2" + } +} diff --git a/packages/design-system/src/scripts/build-colors-style.ts b/packages/design-system/src/scripts/build-colors-style.ts new file mode 100644 index 00000000..355e96fd --- /dev/null +++ b/packages/design-system/src/scripts/build-colors-style.ts @@ -0,0 +1,79 @@ +import * as fs from "fs"; +import * as path from "path"; + +// Paths for token files +const tokensDir = path.join(__dirname, "../tokens"); +const stylesDir = path.join(__dirname, "../styles/base"); +const resolveTokenReference = (value: string): string => { + return value.replace(/{(.+?)}/g, (_, match) => `var(--${match.replace(".", "-")})`); +}; + +// Generate SCSS content for a given theme +const generateScssContent = ( + theme: "dark" | "light", + tokens: Record, +): string => { + const lines: string[] = []; + + const selector = theme === "dark" ? ":root" : ".light"; + + // Add the @use directive + lines.push(`@use "_palette.scss" as *;\n`); + + // Start the layer and class + lines.push(`@layer base {`); + lines.push(` ${selector} {`); + + // Process each token in the "color" group + const colorTokens = tokens.color; + for (const key in colorTokens) { + const value = colorTokens[key].$value; + + // Convert token reference (e.g., {zinc.200}) to CSS variable (e.g., var(--zinc.200)) + const resolvedValue = resolveTokenReference(value); + lines.push(` --${key}: ${resolvedValue};`); + } + + // Close the class and layer + lines.push(` }`); + lines.push(`}`); + + return lines.join("\n"); +}; + +// Function to build and write SCSS for a given theme +export const buildColorsScss = (theme: "dark" | "light"): void => { + // Define the input and output file paths + const partFileName = theme === "dark" ? "default" : "light"; + const inputFilePath = path.join( + tokensDir, + `token_color_${partFileName}.json`, + ); + const outputFilePath = path.join(stylesDir, `_colors-${theme}.scss`); + + // Ensure the input file exists + if (!fs.existsSync(inputFilePath)) { + console.error(`Token file not found: ${inputFilePath}`); + return; + } + + // Read and parse the JSON file + const rawData = fs.readFileSync(inputFilePath, "utf-8"); + const tokens = JSON.parse(rawData); + + // Generate SCSS content + const scssContent = generateScssContent(theme, tokens); + + // Ensure the output directory exists + if (!fs.existsSync(stylesDir)) { + fs.mkdirSync(stylesDir, { recursive: true }); + } + + // Write the SCSS content to the file + fs.writeFileSync(outputFilePath, scssContent, "utf-8"); + console.log(`SCSS file created for ${theme} theme at: ${outputFilePath}`); +}; + +// Reusable calls for light and dark themes +buildColorsScss("light"); +buildColorsScss("dark"); diff --git a/packages/design-system/src/scripts/build-colors-tailwind.ts b/packages/design-system/src/scripts/build-colors-tailwind.ts new file mode 100644 index 00000000..4c680c28 --- /dev/null +++ b/packages/design-system/src/scripts/build-colors-tailwind.ts @@ -0,0 +1,61 @@ +import * as fs from "fs"; +import * as path from "path"; + +// Paths for token files +const tokensDir = path.join(__dirname, "../tokens"); +const outputDir = path.join(__dirname, "../tailwind"); + +// Utility to resolve token references to match the key directly +const resolveTokenReference = (key: string): string => { + return `hsl(var(--${key}))`; +}; + +// Generate TypeScript content for colors +const generateColorsTsContent = (tokens: Record): string => { + const colorTokens = tokens.color; + const lines: string[] = []; + + // Add the TypeScript export header + lines.push(`export const colors = {`); + + // Process each token and use the key for the variable name + for (const key in colorTokens) { + lines.push(` "${key}": "${resolveTokenReference(key)}",`); + } + + // Close the object + lines.push(`};`); + + return lines.join("\n"); +}; + +// Function to build and write colors.ts +export const buildColorsTailwind = (): void => { + const inputFilePath = path.join(tokensDir, `token_color_light.json`); + const outputFilePath = path.join(outputDir, `colors.ts`); + + // Ensure the input file exists + if (!fs.existsSync(inputFilePath)) { + console.error(`Token file not found: ${inputFilePath}`); + return; + } + + // Read and parse the JSON file + const rawData = fs.readFileSync(inputFilePath, "utf-8"); + const tokens = JSON.parse(rawData); + + // Generate TypeScript content + const tsContent = generateColorsTsContent(tokens); + + // Ensure the output directory exists + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + + // Write the TypeScript content to the file + fs.writeFileSync(outputFilePath, tsContent, "utf-8"); + console.log(`colors.ts file created at: ${outputFilePath}`); +}; + +// Build colors.ts +buildColorsTailwind(); diff --git a/packages/design-system/src/scripts/build-config-tailwind.ts b/packages/design-system/src/scripts/build-config-tailwind.ts new file mode 100644 index 00000000..707c2fa7 --- /dev/null +++ b/packages/design-system/src/scripts/build-config-tailwind.ts @@ -0,0 +1,40 @@ +import * as fs from "fs"; +import * as path from "path"; + +// Paths for the output file +const outputDir = path.join(__dirname, "../tailwind"); +const outputFilePath = path.join(outputDir, "config.ts"); + +// Content for the tailwindConfig.ts file +const generateTailwindConfigContent = (): string => { + return ` +import { colors } from "./colors"; +import { palette } from "./palette"; + +export const tailwindConfig = { + theme: { + extend: { + colors: { ...colors, ...palette }, + }, + }, +}; +`.trim(); +}; + +// Function to create the tailwindConfig.ts file +export const buildTailwindConfig = (): void => { + // Generate the content + const configContent = generateTailwindConfigContent(); + + // Ensure the output directory exists + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + + // Write the content to the file + fs.writeFileSync(outputFilePath, configContent, "utf-8"); + console.log(`tailwindConfig.ts file created at: ${outputFilePath}`); +}; + +// Run the script +buildTailwindConfig(); diff --git a/packages/design-system/src/scripts/build-main-style.ts b/packages/design-system/src/scripts/build-main-style.ts new file mode 100644 index 00000000..df13714c --- /dev/null +++ b/packages/design-system/src/scripts/build-main-style.ts @@ -0,0 +1,32 @@ +import * as fs from "fs"; +import * as path from "path"; + +// Paths for the output file +const outputDir = path.join(__dirname, "../styles"); +const outputFilePath = path.join(outputDir, "main.scss"); + +// Content for the main.scss file +const generateMainScssContent = (): string => { + return ` +@use "./base/_colors-dark.scss" as *; +@use "./base/_colors-light.scss" as *; +`.trim(); +}; + +// Function to create the main.scss file +export const buildMainScss = (): void => { + // Generate the content + const scssContent = generateMainScssContent(); + + // Ensure the output directory exists + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + + // Write the content to the file + fs.writeFileSync(outputFilePath, scssContent, "utf-8"); + console.log(`main.scss file created at: ${outputFilePath}`); +}; + +// Run the script +buildMainScss(); diff --git a/packages/design-system/src/scripts/build-palette-style.ts b/packages/design-system/src/scripts/build-palette-style.ts new file mode 100644 index 00000000..e8658e6b --- /dev/null +++ b/packages/design-system/src/scripts/build-palette-style.ts @@ -0,0 +1,54 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { hexToHsl } from './utills.js'; + +// Paths for input and output files +const inputFilePath = path.join(__dirname, '../tokens/token_palette_primitive.json'); +const outputFilePath = path.join(__dirname, '../styles/base/_palette.scss'); + +// Generate SCSS content with groups separated by an empty line +const generateScssContent = (tokens: Record): string => { + const lines: string[] = []; + + for (const group in tokens) { + const groupTokens = tokens[group]; + for (const key in groupTokens) { + const value = groupTokens[key]; + if (value.$type === 'color') { + lines.push(` --${group}-${key}: ${hexToHsl(value.$value)};`); + } + } + lines.push(''); // Add an empty line after each group + } + + return ` +@layer base { + :root { +${lines.join('\n')} + } +} +`.trim(); +}; + +// Function to build and write SCSS content +export const buildPaletteScss = (): void => { + // Read and parse the JSON file + const rawData = fs.readFileSync(inputFilePath, 'utf-8'); + const tokens = JSON.parse(rawData); + + // Generate SCSS content + const scssContent = generateScssContent(tokens); + + // Ensure the output directory exists + const outputDir = path.dirname(outputFilePath); + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + + // Write the SCSS content to the file + fs.writeFileSync(outputFilePath, scssContent, 'utf-8'); + console.log(`SCSS file created at: ${outputFilePath}`); +}; + +// Run the script +buildPaletteScss(); diff --git a/packages/design-system/src/scripts/build-palette-tailwind.ts b/packages/design-system/src/scripts/build-palette-tailwind.ts new file mode 100644 index 00000000..b876c293 --- /dev/null +++ b/packages/design-system/src/scripts/build-palette-tailwind.ts @@ -0,0 +1,54 @@ +import * as fs from "fs"; +import * as path from "path"; + +// Paths for input and output files +const inputFilePath = path.join(__dirname, "../tokens/token_palette_primitive.json"); +const outputFilePath = path.join(__dirname, "../tailwind/palette.ts"); + +// Generate TypeScript content with groups of palette colors +const generatePaletteTsContent = (tokens: Record): string => { + const lines: string[] = []; + + // Start the TypeScript export object + lines.push(`export const palette = {`); + + for (const group in tokens) { + const groupTokens = tokens[group]; + lines.push(` "${group}": {`); + for (const key in groupTokens) { + const value = groupTokens[key]; + if (value.$type === "color") { + // Add a line for each color token + lines.push(` "${key}": "hsl(var(--${group}-${key}))",`); + } + } + lines.push(` },`); // Close the group + } + + lines.push(`};`); // Close the object + + return lines.join("\n"); +}; + +// Function to build and write the palette.ts file +export const buildPaletteTailwind = (): void => { + // Read and parse the JSON file + const rawData = fs.readFileSync(inputFilePath, "utf-8"); + const tokens = JSON.parse(rawData); + + // Generate TypeScript content + const tsContent = generatePaletteTsContent(tokens); + + // Ensure the output directory exists + const outputDir = path.dirname(outputFilePath); + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + + // Write the TypeScript content to the file + fs.writeFileSync(outputFilePath, tsContent, "utf-8"); + console.log(`palette.ts file created at: ${outputFilePath}`); +}; + +// Run the script +buildPaletteTailwind(); diff --git a/packages/design-system/src/scripts/build.ts b/packages/design-system/src/scripts/build.ts new file mode 100644 index 00000000..7fbbb23c --- /dev/null +++ b/packages/design-system/src/scripts/build.ts @@ -0,0 +1,32 @@ +import { buildColorsTailwind } from "./build-colors-tailwind.js"; +import { buildColorsScss } from "./build-colors-style.js"; +import { buildPaletteTailwind } from "./build-palette-tailwind.js"; +import { buildPaletteScss } from "./build-palette-style.js"; +import { buildTailwindConfig } from "./build-config-tailwind.js"; +import { buildMainScss } from "./build-main-style.js"; + +const main = () => { + try { + console.log("🎨 Building design system..."); + + // Styles + console.log("Building SCSS styles..."); + buildPaletteScss(); + buildColorsScss("light"); + buildColorsScss("dark"); + buildMainScss(); + + // Tailwind + console.log("Building Tailwind configurations..."); + buildColorsTailwind(); + buildPaletteTailwind(); + buildTailwindConfig(); + + console.log("✅ Design system built successfully!"); + } catch (error) { + console.error("❌ Build failed:", error); + process.exit(1); + } +}; + +main(); diff --git a/packages/design-system/src/scripts/utills.ts b/packages/design-system/src/scripts/utills.ts new file mode 100644 index 00000000..1394777e --- /dev/null +++ b/packages/design-system/src/scripts/utills.ts @@ -0,0 +1,26 @@ +// Utility to convert HEX to HSL +export const hexToHsl = (hex: string): string => { + const r = parseInt(hex.slice(1, 3), 16) / 255; + const g = parseInt(hex.slice(3, 5), 16) / 255; + const b = parseInt(hex.slice(5, 7), 16) / 255; + + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + const delta = max - min; + + let h = 0; + if (delta !== 0) { + if (max === r) { + h = ((g - b) / delta + (g < b ? 6 : 0)) * 60; + } else if (max === g) { + h = ((b - r) / delta + 2) * 60; + } else { + h = ((r - g) / delta + 4) * 60; + } + } + + const l = (max + min) / 2; + const s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1)); + + return `${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`; + }; \ No newline at end of file diff --git a/packages/design-system/src/styles/base/_colors-dark.scss b/packages/design-system/src/styles/base/_colors-dark.scss new file mode 100644 index 00000000..a3149b18 --- /dev/null +++ b/packages/design-system/src/styles/base/_colors-dark.scss @@ -0,0 +1,41 @@ +@use "_palette.scss" as *; + +@layer base { + :root { + --accent: var(--zinc-800); + --accent-foreground: var(--general-white); + --background: var(--zinc-950); + --black: var(--general-black); + --border: var(--zinc-800); + --card: var(--zinc-900); + --card-foreground: var(--general-white); + --destructive: var(--rose-500); + --destructive-foreground: var(--general-black); + --error: var(--rose-500); + --error-border: var(--red-900); + --error-foreground: var(--red-100); + --foreground: var(--zinc-50); + --information: var(--sky-500); + --information-border: var(--blue-900); + --information-foreground: var(--blue-100); + --input: var(--zinc-800); + --muted: var(--zinc-800); + --muted-foreground: var(--zinc-400); + --popover: var(--zinc-950); + --popover-foreground: var(--general-white); + --primary: var(--purple-500); + --primary-foreground: var(--general-white); + --primary-light: var(--purple-100); + --ring: var(--zinc-600); + --secondary: var(--zinc-800); + --secondary-foreground: var(--general-white); + --success: var(--emerald-500); + --success-border: var(--green-900); + --success-foreground: var(--green-50); + --table-header: rgba(39, 39, 42, 0.5000); + --warning: var(--amber-500); + --warning-border: var(--amber-900); + --warning-foreground: var(--amber-100); + --white: var(--general-white); + } +} \ No newline at end of file diff --git a/packages/design-system/src/styles/base/_colors-light.scss b/packages/design-system/src/styles/base/_colors-light.scss new file mode 100644 index 00000000..1fda683e --- /dev/null +++ b/packages/design-system/src/styles/base/_colors-light.scss @@ -0,0 +1,41 @@ +@use "_palette.scss" as *; + +@layer base { + .light { + --accent: var(--zinc-100); + --accent-foreground: var(--zinc-900); + --background: var(--general-white); + --black: var(--general-black); + --border: var(--zinc-200); + --card: var(--zinc-100); + --card-foreground: var(--slate-900); + --destructive: var(--red-600); + --destructive-foreground: var(--general-white); + --error: var(--red-500); + --error-border: var(--red-200); + --error-foreground: var(--red-600); + --foreground: var(--zinc-950); + --information: var(--blue-100); + --information-border: var(--blue-200); + --information-foreground: var(--blue-700); + --input: var(--zinc-200); + --muted: var(--zinc-100); + --muted-foreground: var(--zinc-500); + --popover: var(--general-white); + --popover-foreground: var(--slate-900); + --primary: var(--purple-500); + --primary-foreground: var(--general-white); + --primary-light: var(--purple-100); + --ring: var(--zinc-400); + --secondary: var(--zinc-100); + --secondary-foreground: var(--zinc-900); + --success: var(--green-100); + --success-border: var(--green-200); + --success-foreground: var(--green-700); + --table-header: rgba(244, 244, 245, 0.5000); + --warning: var(--amber-500); + --warning-border: var(--amber-200); + --warning-foreground: var(--general-white); + --white: var(--general-white); + } +} \ No newline at end of file diff --git a/packages/design-system/src/styles/base/_palette.scss b/packages/design-system/src/styles/base/_palette.scss new file mode 100644 index 00000000..b4139c93 --- /dev/null +++ b/packages/design-system/src/styles/base/_palette.scss @@ -0,0 +1,270 @@ +@layer base { + :root { + --amber-50: 48 100% 96%; + --amber-100: 48 96% 89%; + --amber-200: 48 97% 77%; + --amber-300: 46 97% 65%; + --amber-400: 43 96% 56%; + --amber-500: 38 92% 50%; + --amber-600: 32 95% 44%; + --amber-700: 26 90% 37%; + --amber-800: 23 83% 31%; + --amber-900: 22 78% 26%; + --amber-950: 21 92% 14%; + + --blue-50: 214 100% 97%; + --blue-100: 214 95% 93%; + --blue-200: 213 97% 87%; + --blue-300: 212 96% 78%; + --blue-400: 213 94% 68%; + --blue-500: 217 91% 60%; + --blue-600: 221 83% 53%; + --blue-700: 224 76% 48%; + --blue-800: 226 71% 40%; + --blue-900: 224 64% 33%; + --blue-950: 226 57% 21%; + + --cyan-50: 183 100% 96%; + --cyan-100: 185 96% 90%; + --cyan-200: 186 94% 82%; + --cyan-300: 187 92% 69%; + --cyan-400: 188 86% 53%; + --cyan-500: 189 94% 43%; + --cyan-600: 192 91% 36%; + --cyan-700: 193 82% 31%; + --cyan-800: 194 70% 27%; + --cyan-900: 196 64% 24%; + --cyan-950: 197 79% 15%; + + --emerald-50: 152 81% 96%; + --emerald-100: 149 80% 90%; + --emerald-200: 152 76% 80%; + --emerald-300: 156 72% 67%; + --emerald-400: 158 64% 52%; + --emerald-500: 160 84% 39%; + --emerald-600: 161 94% 30%; + --emerald-700: 163 94% 24%; + --emerald-800: 163 88% 20%; + --emerald-900: 164 86% 16%; + --emerald-950: 166 91% 9%; + + --fuchsia-50: 289 100% 98%; + --fuchsia-100: 287 100% 95%; + --fuchsia-200: 288 96% 91%; + --fuchsia-300: 291 93% 83%; + --fuchsia-400: 292 91% 73%; + --fuchsia-500: 292 84% 61%; + --fuchsia-600: 293 69% 49%; + --fuchsia-700: 295 72% 40%; + --fuchsia-800: 295 70% 33%; + --fuchsia-900: 297 64% 28%; + --fuchsia-950: 297 90% 16%; + + --general-black: 0 0% 0%; + --general-white: 0 0% 100%; + + --gray-50: 210 20% 98%; + --gray-100: 220 14% 96%; + --gray-200: 220 13% 91%; + --gray-300: 216 12% 84%; + --gray-400: 218 11% 65%; + --gray-500: 220 9% 46%; + --gray-600: 215 14% 34%; + --gray-700: 217 19% 27%; + --gray-800: 215 28% 17%; + --gray-900: 221 39% 11%; + --gray-950: 224 71% 4%; + + --green-50: 138 76% 97%; + --green-100: 141 84% 93%; + --green-200: 141 79% 85%; + --green-300: 142 77% 73%; + --green-400: 142 69% 58%; + --green-500: 142 71% 45%; + --green-600: 142 76% 36%; + --green-700: 142 72% 29%; + --green-800: 143 64% 24%; + --green-900: 144 61% 20%; + --green-950: 145 80% 10%; + + --indigo-50: 226 100% 97%; + --indigo-100: 226 100% 94%; + --indigo-200: 228 96% 89%; + --indigo-300: 230 94% 82%; + --indigo-400: 234 89% 74%; + --indigo-500: 239 84% 67%; + --indigo-600: 243 75% 59%; + --indigo-700: 245 58% 51%; + --indigo-800: 244 55% 41%; + --indigo-900: 242 47% 34%; + --indigo-950: 244 47% 20%; + + --lime-50: 78 92% 95%; + --lime-100: 80 89% 89%; + --lime-200: 81 88% 80%; + --lime-300: 82 85% 67%; + --lime-400: 83 78% 55%; + --lime-500: 84 81% 44%; + --lime-600: 85 85% 35%; + --lime-700: 86 78% 27%; + --lime-800: 86 69% 23%; + --lime-900: 88 61% 20%; + --lime-950: 89 80% 10%; + + --neutral-50: 0 0% 98%; + --neutral-100: 0 0% 96%; + --neutral-200: 0 0% 90%; + --neutral-300: 0 0% 83%; + --neutral-400: 0 0% 64%; + --neutral-500: 0 0% 45%; + --neutral-600: 0 0% 32%; + --neutral-700: 0 0% 25%; + --neutral-800: 0 0% 15%; + --neutral-900: 0 0% 9%; + --neutral-950: 0 0% 4%; + + --orange-50: 33 100% 96%; + --orange-100: 34 100% 92%; + --orange-200: 32 98% 83%; + --orange-300: 31 97% 72%; + --orange-400: 27 96% 61%; + --orange-500: 25 95% 53%; + --orange-600: 21 90% 48%; + --orange-700: 17 88% 40%; + --orange-800: 15 79% 34%; + --orange-900: 15 75% 28%; + --orange-950: 13 81% 15%; + + --pink-50: 327 73% 97%; + --pink-100: 326 78% 95%; + --pink-200: 326 85% 90%; + --pink-300: 327 87% 82%; + --pink-400: 329 86% 70%; + --pink-500: 330 81% 60%; + --pink-600: 333 71% 51%; + --pink-700: 335 78% 42%; + --pink-800: 336 74% 35%; + --pink-900: 336 69% 30%; + --pink-950: 336 84% 17%; + + --purple-50: 251 62% 95%; + --purple-100: 250 61% 90%; + --purple-200: 250 63% 80%; + --purple-300: 250 62% 70%; + --purple-400: 250 62% 60%; + --purple-500: 250 62% 58%; + --purple-600: 250 62% 40%; + --purple-700: 250 62% 30%; + --purple-800: 250 63% 20%; + --purple-900: 250 61% 10%; + + --red-50: 0 86% 97%; + --red-100: 0 93% 94%; + --red-200: 0 96% 89%; + --red-300: 0 94% 82%; + --red-400: 0 91% 71%; + --red-500: 0 84% 60%; + --red-600: 0 72% 51%; + --red-700: 0 74% 42%; + --red-800: 0 70% 35%; + --red-900: 0 63% 31%; + --red-950: 0 75% 15%; + + --rose-50: 356 100% 97%; + --rose-100: 356 100% 95%; + --rose-200: 353 96% 90%; + --rose-300: 353 96% 82%; + --rose-400: 351 95% 71%; + --rose-500: 350 89% 60%; + --rose-600: 347 77% 50%; + --rose-700: 345 83% 41%; + --rose-800: 343 80% 35%; + --rose-900: 342 75% 30%; + --rose-950: 343 88% 16%; + + --sky-50: 204 100% 97%; + --sky-100: 204 94% 94%; + --sky-200: 201 94% 86%; + --sky-300: 199 95% 74%; + --sky-400: 198 93% 60%; + --sky-500: 199 89% 48%; + --sky-600: 200 98% 39%; + --sky-700: 201 96% 32%; + --sky-800: 201 90% 27%; + --sky-900: 202 80% 24%; + --sky-950: 204 80% 16%; + + --slate-50: 210 40% 98%; + --slate-100: 210 40% 96%; + --slate-200: 214 32% 91%; + --slate-300: 213 27% 84%; + --slate-400: 215 20% 65%; + --slate-500: 215 16% 47%; + --slate-600: 215 19% 35%; + --slate-700: 215 25% 27%; + --slate-800: 217 33% 17%; + --slate-900: 222 47% 11%; + --slate-950: 229 84% 5%; + + --stone-50: 60 9% 98%; + --stone-100: 60 5% 96%; + --stone-200: 20 6% 90%; + --stone-300: 24 6% 83%; + --stone-400: 24 5% 64%; + --stone-500: 25 5% 45%; + --stone-600: 33 5% 32%; + --stone-700: 30 6% 25%; + --stone-800: 12 6% 15%; + --stone-900: 24 10% 10%; + --stone-950: 20 14% 4%; + + --teal-50: 166 76% 97%; + --teal-100: 167 85% 89%; + --teal-200: 168 84% 78%; + --teal-300: 171 77% 64%; + --teal-400: 172 66% 50%; + --teal-500: 173 80% 40%; + --teal-600: 175 84% 32%; + --teal-700: 175 77% 26%; + --teal-800: 176 69% 22%; + --teal-900: 176 61% 19%; + --teal-950: 179 84% 10%; + + --violet-50: 250 100% 98%; + --violet-100: 251 91% 95%; + --violet-200: 251 95% 92%; + --violet-300: 252 95% 85%; + --violet-400: 255 92% 76%; + --violet-500: 258 90% 66%; + --violet-600: 262 83% 58%; + --violet-700: 263 70% 50%; + --violet-800: 263 69% 42%; + --violet-900: 264 67% 35%; + --violet-950: 261 73% 23%; + + --yellow-50: 55 92% 95%; + --yellow-100: 55 97% 88%; + --yellow-200: 53 98% 77%; + --yellow-300: 50 98% 64%; + --yellow-400: 48 96% 53%; + --yellow-500: 45 93% 47%; + --yellow-600: 41 96% 40%; + --yellow-700: 35 92% 33%; + --yellow-800: 32 81% 29%; + --yellow-900: 28 73% 26%; + --yellow-950: 26 83% 14%; + + --zinc-50: 0 0% 98%; + --zinc-100: 240 5% 96%; + --zinc-200: 240 6% 90%; + --zinc-300: 240 5% 84%; + --zinc-400: 240 5% 65%; + --zinc-500: 240 4% 46%; + --zinc-600: 240 5% 34%; + --zinc-700: 240 5% 26%; + --zinc-800: 240 4% 16%; + --zinc-900: 240 6% 10%; + --zinc-950: 240 10% 4%; + + } +} \ No newline at end of file diff --git a/packages/design-system/src/styles/main.scss b/packages/design-system/src/styles/main.scss new file mode 100644 index 00000000..51866d63 --- /dev/null +++ b/packages/design-system/src/styles/main.scss @@ -0,0 +1,2 @@ +@use "./base/_colors-dark.scss" as *; +@use "./base/_colors-light.scss" as *; \ No newline at end of file diff --git a/packages/design-system/src/tailwind/colors.ts b/packages/design-system/src/tailwind/colors.ts new file mode 100644 index 00000000..d686d64b --- /dev/null +++ b/packages/design-system/src/tailwind/colors.ts @@ -0,0 +1,37 @@ +export const colors = { + "accent": "hsl(var(--accent))", + "accent-foreground": "hsl(var(--accent-foreground))", + "background": "hsl(var(--background))", + "black": "hsl(var(--black))", + "border": "hsl(var(--border))", + "card": "hsl(var(--card))", + "card-foreground": "hsl(var(--card-foreground))", + "destructive": "hsl(var(--destructive))", + "destructive-foreground": "hsl(var(--destructive-foreground))", + "error": "hsl(var(--error))", + "error-border": "hsl(var(--error-border))", + "error-foreground": "hsl(var(--error-foreground))", + "foreground": "hsl(var(--foreground))", + "information": "hsl(var(--information))", + "information-border": "hsl(var(--information-border))", + "information-foreground": "hsl(var(--information-foreground))", + "input": "hsl(var(--input))", + "muted": "hsl(var(--muted))", + "muted-foreground": "hsl(var(--muted-foreground))", + "popover": "hsl(var(--popover))", + "popover-foreground": "hsl(var(--popover-foreground))", + "primary": "hsl(var(--primary))", + "primary-foreground": "hsl(var(--primary-foreground))", + "primary-light": "hsl(var(--primary-light))", + "ring": "hsl(var(--ring))", + "secondary": "hsl(var(--secondary))", + "secondary-foreground": "hsl(var(--secondary-foreground))", + "success": "hsl(var(--success))", + "success-border": "hsl(var(--success-border))", + "success-foreground": "hsl(var(--success-foreground))", + "table-header": "hsl(var(--table-header))", + "warning": "hsl(var(--warning))", + "warning-border": "hsl(var(--warning-border))", + "warning-foreground": "hsl(var(--warning-foreground))", + "white": "hsl(var(--white))", +}; \ No newline at end of file diff --git a/packages/design-system/src/tailwind/config.ts b/packages/design-system/src/tailwind/config.ts new file mode 100644 index 00000000..21fd9148 --- /dev/null +++ b/packages/design-system/src/tailwind/config.ts @@ -0,0 +1,10 @@ +import { colors } from "./colors"; +import { palette } from "./palette"; + +export const tailwindConfig = { + theme: { + extend: { + colors: { ...colors, ...palette }, + }, + }, +}; \ No newline at end of file diff --git a/packages/design-system/src/tailwind/palette.ts b/packages/design-system/src/tailwind/palette.ts new file mode 100644 index 00000000..517eb075 --- /dev/null +++ b/packages/design-system/src/tailwind/palette.ts @@ -0,0 +1,291 @@ +export const palette = { + "amber": { + "50": "hsl(var(--amber-50))", + "100": "hsl(var(--amber-100))", + "200": "hsl(var(--amber-200))", + "300": "hsl(var(--amber-300))", + "400": "hsl(var(--amber-400))", + "500": "hsl(var(--amber-500))", + "600": "hsl(var(--amber-600))", + "700": "hsl(var(--amber-700))", + "800": "hsl(var(--amber-800))", + "900": "hsl(var(--amber-900))", + "950": "hsl(var(--amber-950))", + }, + "blue": { + "50": "hsl(var(--blue-50))", + "100": "hsl(var(--blue-100))", + "200": "hsl(var(--blue-200))", + "300": "hsl(var(--blue-300))", + "400": "hsl(var(--blue-400))", + "500": "hsl(var(--blue-500))", + "600": "hsl(var(--blue-600))", + "700": "hsl(var(--blue-700))", + "800": "hsl(var(--blue-800))", + "900": "hsl(var(--blue-900))", + "950": "hsl(var(--blue-950))", + }, + "cyan": { + "50": "hsl(var(--cyan-50))", + "100": "hsl(var(--cyan-100))", + "200": "hsl(var(--cyan-200))", + "300": "hsl(var(--cyan-300))", + "400": "hsl(var(--cyan-400))", + "500": "hsl(var(--cyan-500))", + "600": "hsl(var(--cyan-600))", + "700": "hsl(var(--cyan-700))", + "800": "hsl(var(--cyan-800))", + "900": "hsl(var(--cyan-900))", + "950": "hsl(var(--cyan-950))", + }, + "emerald": { + "50": "hsl(var(--emerald-50))", + "100": "hsl(var(--emerald-100))", + "200": "hsl(var(--emerald-200))", + "300": "hsl(var(--emerald-300))", + "400": "hsl(var(--emerald-400))", + "500": "hsl(var(--emerald-500))", + "600": "hsl(var(--emerald-600))", + "700": "hsl(var(--emerald-700))", + "800": "hsl(var(--emerald-800))", + "900": "hsl(var(--emerald-900))", + "950": "hsl(var(--emerald-950))", + }, + "fuchsia": { + "50": "hsl(var(--fuchsia-50))", + "100": "hsl(var(--fuchsia-100))", + "200": "hsl(var(--fuchsia-200))", + "300": "hsl(var(--fuchsia-300))", + "400": "hsl(var(--fuchsia-400))", + "500": "hsl(var(--fuchsia-500))", + "600": "hsl(var(--fuchsia-600))", + "700": "hsl(var(--fuchsia-700))", + "800": "hsl(var(--fuchsia-800))", + "900": "hsl(var(--fuchsia-900))", + "950": "hsl(var(--fuchsia-950))", + }, + "general": { + "black": "hsl(var(--general-black))", + "white": "hsl(var(--general-white))", + }, + "gray": { + "50": "hsl(var(--gray-50))", + "100": "hsl(var(--gray-100))", + "200": "hsl(var(--gray-200))", + "300": "hsl(var(--gray-300))", + "400": "hsl(var(--gray-400))", + "500": "hsl(var(--gray-500))", + "600": "hsl(var(--gray-600))", + "700": "hsl(var(--gray-700))", + "800": "hsl(var(--gray-800))", + "900": "hsl(var(--gray-900))", + "950": "hsl(var(--gray-950))", + }, + "green": { + "50": "hsl(var(--green-50))", + "100": "hsl(var(--green-100))", + "200": "hsl(var(--green-200))", + "300": "hsl(var(--green-300))", + "400": "hsl(var(--green-400))", + "500": "hsl(var(--green-500))", + "600": "hsl(var(--green-600))", + "700": "hsl(var(--green-700))", + "800": "hsl(var(--green-800))", + "900": "hsl(var(--green-900))", + "950": "hsl(var(--green-950))", + }, + "indigo": { + "50": "hsl(var(--indigo-50))", + "100": "hsl(var(--indigo-100))", + "200": "hsl(var(--indigo-200))", + "300": "hsl(var(--indigo-300))", + "400": "hsl(var(--indigo-400))", + "500": "hsl(var(--indigo-500))", + "600": "hsl(var(--indigo-600))", + "700": "hsl(var(--indigo-700))", + "800": "hsl(var(--indigo-800))", + "900": "hsl(var(--indigo-900))", + "950": "hsl(var(--indigo-950))", + }, + "lime": { + "50": "hsl(var(--lime-50))", + "100": "hsl(var(--lime-100))", + "200": "hsl(var(--lime-200))", + "300": "hsl(var(--lime-300))", + "400": "hsl(var(--lime-400))", + "500": "hsl(var(--lime-500))", + "600": "hsl(var(--lime-600))", + "700": "hsl(var(--lime-700))", + "800": "hsl(var(--lime-800))", + "900": "hsl(var(--lime-900))", + "950": "hsl(var(--lime-950))", + }, + "neutral": { + "50": "hsl(var(--neutral-50))", + "100": "hsl(var(--neutral-100))", + "200": "hsl(var(--neutral-200))", + "300": "hsl(var(--neutral-300))", + "400": "hsl(var(--neutral-400))", + "500": "hsl(var(--neutral-500))", + "600": "hsl(var(--neutral-600))", + "700": "hsl(var(--neutral-700))", + "800": "hsl(var(--neutral-800))", + "900": "hsl(var(--neutral-900))", + "950": "hsl(var(--neutral-950))", + }, + "orange": { + "50": "hsl(var(--orange-50))", + "100": "hsl(var(--orange-100))", + "200": "hsl(var(--orange-200))", + "300": "hsl(var(--orange-300))", + "400": "hsl(var(--orange-400))", + "500": "hsl(var(--orange-500))", + "600": "hsl(var(--orange-600))", + "700": "hsl(var(--orange-700))", + "800": "hsl(var(--orange-800))", + "900": "hsl(var(--orange-900))", + "950": "hsl(var(--orange-950))", + }, + "pink": { + "50": "hsl(var(--pink-50))", + "100": "hsl(var(--pink-100))", + "200": "hsl(var(--pink-200))", + "300": "hsl(var(--pink-300))", + "400": "hsl(var(--pink-400))", + "500": "hsl(var(--pink-500))", + "600": "hsl(var(--pink-600))", + "700": "hsl(var(--pink-700))", + "800": "hsl(var(--pink-800))", + "900": "hsl(var(--pink-900))", + "950": "hsl(var(--pink-950))", + }, + "purple": { + "50": "hsl(var(--purple-50))", + "100": "hsl(var(--purple-100))", + "200": "hsl(var(--purple-200))", + "300": "hsl(var(--purple-300))", + "400": "hsl(var(--purple-400))", + "500": "hsl(var(--purple-500))", + "600": "hsl(var(--purple-600))", + "700": "hsl(var(--purple-700))", + "800": "hsl(var(--purple-800))", + "900": "hsl(var(--purple-900))", + }, + "red": { + "50": "hsl(var(--red-50))", + "100": "hsl(var(--red-100))", + "200": "hsl(var(--red-200))", + "300": "hsl(var(--red-300))", + "400": "hsl(var(--red-400))", + "500": "hsl(var(--red-500))", + "600": "hsl(var(--red-600))", + "700": "hsl(var(--red-700))", + "800": "hsl(var(--red-800))", + "900": "hsl(var(--red-900))", + "950": "hsl(var(--red-950))", + }, + "rose": { + "50": "hsl(var(--rose-50))", + "100": "hsl(var(--rose-100))", + "200": "hsl(var(--rose-200))", + "300": "hsl(var(--rose-300))", + "400": "hsl(var(--rose-400))", + "500": "hsl(var(--rose-500))", + "600": "hsl(var(--rose-600))", + "700": "hsl(var(--rose-700))", + "800": "hsl(var(--rose-800))", + "900": "hsl(var(--rose-900))", + "950": "hsl(var(--rose-950))", + }, + "sky": { + "50": "hsl(var(--sky-50))", + "100": "hsl(var(--sky-100))", + "200": "hsl(var(--sky-200))", + "300": "hsl(var(--sky-300))", + "400": "hsl(var(--sky-400))", + "500": "hsl(var(--sky-500))", + "600": "hsl(var(--sky-600))", + "700": "hsl(var(--sky-700))", + "800": "hsl(var(--sky-800))", + "900": "hsl(var(--sky-900))", + "950": "hsl(var(--sky-950))", + }, + "slate": { + "50": "hsl(var(--slate-50))", + "100": "hsl(var(--slate-100))", + "200": "hsl(var(--slate-200))", + "300": "hsl(var(--slate-300))", + "400": "hsl(var(--slate-400))", + "500": "hsl(var(--slate-500))", + "600": "hsl(var(--slate-600))", + "700": "hsl(var(--slate-700))", + "800": "hsl(var(--slate-800))", + "900": "hsl(var(--slate-900))", + "950": "hsl(var(--slate-950))", + }, + "stone": { + "50": "hsl(var(--stone-50))", + "100": "hsl(var(--stone-100))", + "200": "hsl(var(--stone-200))", + "300": "hsl(var(--stone-300))", + "400": "hsl(var(--stone-400))", + "500": "hsl(var(--stone-500))", + "600": "hsl(var(--stone-600))", + "700": "hsl(var(--stone-700))", + "800": "hsl(var(--stone-800))", + "900": "hsl(var(--stone-900))", + "950": "hsl(var(--stone-950))", + }, + "teal": { + "50": "hsl(var(--teal-50))", + "100": "hsl(var(--teal-100))", + "200": "hsl(var(--teal-200))", + "300": "hsl(var(--teal-300))", + "400": "hsl(var(--teal-400))", + "500": "hsl(var(--teal-500))", + "600": "hsl(var(--teal-600))", + "700": "hsl(var(--teal-700))", + "800": "hsl(var(--teal-800))", + "900": "hsl(var(--teal-900))", + "950": "hsl(var(--teal-950))", + }, + "violet": { + "50": "hsl(var(--violet-50))", + "100": "hsl(var(--violet-100))", + "200": "hsl(var(--violet-200))", + "300": "hsl(var(--violet-300))", + "400": "hsl(var(--violet-400))", + "500": "hsl(var(--violet-500))", + "600": "hsl(var(--violet-600))", + "700": "hsl(var(--violet-700))", + "800": "hsl(var(--violet-800))", + "900": "hsl(var(--violet-900))", + "950": "hsl(var(--violet-950))", + }, + "yellow": { + "50": "hsl(var(--yellow-50))", + "100": "hsl(var(--yellow-100))", + "200": "hsl(var(--yellow-200))", + "300": "hsl(var(--yellow-300))", + "400": "hsl(var(--yellow-400))", + "500": "hsl(var(--yellow-500))", + "600": "hsl(var(--yellow-600))", + "700": "hsl(var(--yellow-700))", + "800": "hsl(var(--yellow-800))", + "900": "hsl(var(--yellow-900))", + "950": "hsl(var(--yellow-950))", + }, + "zinc": { + "50": "hsl(var(--zinc-50))", + "100": "hsl(var(--zinc-100))", + "200": "hsl(var(--zinc-200))", + "300": "hsl(var(--zinc-300))", + "400": "hsl(var(--zinc-400))", + "500": "hsl(var(--zinc-500))", + "600": "hsl(var(--zinc-600))", + "700": "hsl(var(--zinc-700))", + "800": "hsl(var(--zinc-800))", + "900": "hsl(var(--zinc-900))", + "950": "hsl(var(--zinc-950))", + }, +}; \ No newline at end of file diff --git a/packages/design-system/src/tokens/token_Icon_size_Mode 1.json b/packages/design-system/src/tokens/token_Icon_size_Mode 1.json new file mode 100644 index 00000000..a539571d --- /dev/null +++ b/packages/design-system/src/tokens/token_Icon_size_Mode 1.json @@ -0,0 +1,14 @@ +{ + "LG": { + "$type": "number", + "$value": 24 + }, + "MD": { + "$type": "number", + "$value": 18 + }, + "XS": { + "$type": "number", + "$value": 16 + } +} \ No newline at end of file diff --git a/packages/design-system/src/tokens/token_color_default.json b/packages/design-system/src/tokens/token_color_default.json new file mode 100644 index 00000000..ea9b69c7 --- /dev/null +++ b/packages/design-system/src/tokens/token_color_default.json @@ -0,0 +1,176 @@ +{ + "color": { + "accent": { + "$type": "color", + "$value": "{zinc.800}", + "$description": "Used for accents such as hover effects on , ...etc" + }, + "accent-foreground": { + "$type": "color", + "$value": "{general.white}", + "$description": "Used for accents such as hover effects on , ...etc" + }, + "background": { + "$type": "color", + "$value": "{zinc.950}", + "$description": "Default background color of ...etc" + }, + "black": { + "$type": "color", + "$value": "{general.black}" + }, + "border": { + "$type": "color", + "$value": "{zinc.800}", + "$description": "Default border color" + }, + "card": { + "$type": "color", + "$value": "{zinc.900}", + "$description": "Background color for " + }, + "card-foreground": { + "$type": "color", + "$value": "{general.white}", + "$description": "Foreground color for " + }, + "destructive": { + "$type": "color", + "$value": "{rose.500}", + "$description": "Used for destructive actions such as