From e1443720ebe1ed7cab033977bc0f43f4c1f2bddc Mon Sep 17 00:00:00 2001 From: Naiyuan Qing <145280634+NevilleQingNY@users.noreply.github.com> Date: Fri, 30 Jan 2026 08:31:47 +0800 Subject: [PATCH 01/11] feat(ui): create @multica/ui package skeleton Shared UI package for web, electron, and mobile. Uses subpath exports following the official shadcn monorepo template pattern. Co-Authored-By: Claude Opus 4.5 --- packages/ui/components.json | 20 ++++++++++++++++++++ packages/ui/package.json | 32 ++++++++++++++++++++++++++++++++ packages/ui/postcss.config.mjs | 6 ++++++ packages/ui/src/index.ts | 2 ++ packages/ui/tsconfig.json | 22 ++++++++++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 packages/ui/components.json create mode 100644 packages/ui/package.json create mode 100644 packages/ui/postcss.config.mjs create mode 100644 packages/ui/src/index.ts create mode 100644 packages/ui/tsconfig.json diff --git a/packages/ui/components.json b/packages/ui/components.json new file mode 100644 index 00000000..7723b5bc --- /dev/null +++ b/packages/ui/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "base-nova", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/styles/globals.css", + "baseColor": "zinc", + "cssVariables": true + }, + "iconLibrary": "hugeicons", + "aliases": { + "components": "@multica/ui/components", + "utils": "@multica/ui/lib/utils", + "hooks": "@multica/ui/hooks", + "lib": "@multica/ui/lib", + "ui": "@multica/ui/components" + } +} diff --git a/packages/ui/package.json b/packages/ui/package.json new file mode 100644 index 00000000..9be8b054 --- /dev/null +++ b/packages/ui/package.json @@ -0,0 +1,32 @@ +{ + "name": "@multica/ui", + "version": "0.1.0", + "private": true, + "type": "module", + "exports": { + "./globals.css": "./src/styles/globals.css", + "./postcss.config": "./postcss.config.mjs", + "./lib/*": "./src/lib/*.ts", + "./components/*": "./src/components/*.tsx", + "./hooks/*": "./src/hooks/*.ts" + }, + "dependencies": { + "@base-ui/react": "^1.1.0", + "@hugeicons/core-free-icons": "^3.1.1", + "@hugeicons/react": "^1.1.4", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "shadcn": "^3.7.0", + "tailwind-merge": "^3.4.0", + "tailwindcss": "^4", + "tw-animate-css": "^1.4.0" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4", + "@types/react": "^19", + "@types/react-dom": "^19", + "typescript": "^5" + } +} diff --git a/packages/ui/postcss.config.mjs b/packages/ui/postcss.config.mjs new file mode 100644 index 00000000..4ae682d8 --- /dev/null +++ b/packages/ui/postcss.config.mjs @@ -0,0 +1,6 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { "@tailwindcss/postcss": {} }, +}; + +export default config; diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts new file mode 100644 index 00000000..83ecf197 --- /dev/null +++ b/packages/ui/src/index.ts @@ -0,0 +1,2 @@ +// This package uses subpath exports. +// Import like: @multica/ui/lib/utils, @multica/ui/components/button diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json new file mode 100644 index 00000000..3155609d --- /dev/null +++ b/packages/ui/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist", + "rootDir": "./src", + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"], + "@multica/ui/*": ["./src/*"] + } + }, + "include": ["src"] +} From c1129ff37d85cce824915622c9b60c7328efb417 Mon Sep 17 00:00:00 2001 From: Naiyuan Qing <145280634+NevilleQingNY@users.noreply.github.com> Date: Fri, 30 Jan 2026 08:31:53 +0800 Subject: [PATCH 02/11] feat(ui): extract components, utils, and styles from apps/web Move 13 shadcn UI components, cn() utility, and theme CSS variables to packages/ui for cross-platform reuse. Add @source directives for Tailwind v4 content scanning. Co-Authored-By: Claude Opus 4.5 --- packages/ui/src/components/alert-dialog.tsx | 175 +++++++++++ packages/ui/src/components/badge.tsx | 48 +++ packages/ui/src/components/button.tsx | 53 ++++ packages/ui/src/components/card.tsx | 94 ++++++ packages/ui/src/components/combobox.tsx | 293 +++++++++++++++++++ packages/ui/src/components/dropdown-menu.tsx | 253 ++++++++++++++++ packages/ui/src/components/field.tsx | 227 ++++++++++++++ packages/ui/src/components/input-group.tsx | 149 ++++++++++ packages/ui/src/components/input.tsx | 20 ++ packages/ui/src/components/label.tsx | 20 ++ packages/ui/src/components/select.tsx | 192 ++++++++++++ packages/ui/src/components/separator.tsx | 25 ++ packages/ui/src/components/textarea.tsx | 18 ++ packages/ui/src/components/tooltip.tsx | 70 +++++ packages/ui/src/lib/utils.ts | 6 + packages/ui/src/styles/globals.css | 128 ++++++++ 16 files changed, 1771 insertions(+) create mode 100644 packages/ui/src/components/alert-dialog.tsx create mode 100644 packages/ui/src/components/badge.tsx create mode 100644 packages/ui/src/components/button.tsx create mode 100644 packages/ui/src/components/card.tsx create mode 100644 packages/ui/src/components/combobox.tsx create mode 100644 packages/ui/src/components/dropdown-menu.tsx create mode 100644 packages/ui/src/components/field.tsx create mode 100644 packages/ui/src/components/input-group.tsx create mode 100644 packages/ui/src/components/input.tsx create mode 100644 packages/ui/src/components/label.tsx create mode 100644 packages/ui/src/components/select.tsx create mode 100644 packages/ui/src/components/separator.tsx create mode 100644 packages/ui/src/components/textarea.tsx create mode 100644 packages/ui/src/components/tooltip.tsx create mode 100644 packages/ui/src/lib/utils.ts create mode 100644 packages/ui/src/styles/globals.css diff --git a/packages/ui/src/components/alert-dialog.tsx b/packages/ui/src/components/alert-dialog.tsx new file mode 100644 index 00000000..898a4907 --- /dev/null +++ b/packages/ui/src/components/alert-dialog.tsx @@ -0,0 +1,175 @@ +"use client" + +import * as React from "react" +import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog" + +import { cn } from "@multica/ui/lib/utils" +import { Button } from "@multica/ui/components/button" + +function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) { + return +} + +function AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) { + return ( + + ) +} + +function AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) { + return ( + + ) +} + +function AlertDialogOverlay({ + className, + ...props +}: AlertDialogPrimitive.Backdrop.Props) { + return ( + + ) +} + +function AlertDialogContent({ + className, + size = "default", + ...props +}: AlertDialogPrimitive.Popup.Props & { + size?: "default" | "sm" +}) { + return ( + + + + + ) +} + +function AlertDialogHeader({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertDialogFooter({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertDialogMedia({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertDialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogAction({ + className, + ...props +}: React.ComponentProps) { + return ( +