From 1954b9d625e809eb7e223a39e697b95cca998f93 Mon Sep 17 00:00:00 2001 From: Charis Lam <26616127+charislam@users.noreply.github.com> Date: Wed, 18 Mar 2026 13:15:33 -0400 Subject: [PATCH] spike: agnostic ui + non-nextjs test app --- apps/ui-vite-test/index.html | 12 + apps/ui-vite-test/package.json | 28 +++ apps/ui-vite-test/src/App.css | 72 ++++++ apps/ui-vite-test/src/App.tsx | 191 +++++++++++++++ apps/ui-vite-test/src/globals.d.ts | 11 + apps/ui-vite-test/src/main.tsx | 15 ++ apps/ui-vite-test/tsconfig.json | 17 ++ apps/ui-vite-test/vite.config.ts | 7 + packages/ui/.gitignore | 1 + packages/ui/base.tsx | 304 ++++++++++++++++++++++++ packages/ui/index.tsx | 309 +------------------------ packages/ui/package.json | 19 ++ packages/ui/postcss.config.js | 10 + packages/ui/postcss.lib.config.js | 7 + packages/ui/scripts/build-merge-css.js | 93 ++++++++ packages/ui/src/base-styles.css | 21 ++ packages/ui/tailwind.lib.config.js | 8 + packages/ui/vite.lib.config.ts | 38 +++ pnpm-lock.yaml | 64 ++++- turbo.json | 11 + 20 files changed, 926 insertions(+), 312 deletions(-) create mode 100644 apps/ui-vite-test/index.html create mode 100644 apps/ui-vite-test/package.json create mode 100644 apps/ui-vite-test/src/App.css create mode 100644 apps/ui-vite-test/src/App.tsx create mode 100644 apps/ui-vite-test/src/globals.d.ts create mode 100644 apps/ui-vite-test/src/main.tsx create mode 100644 apps/ui-vite-test/tsconfig.json create mode 100644 apps/ui-vite-test/vite.config.ts create mode 100644 packages/ui/base.tsx create mode 100644 packages/ui/postcss.config.js create mode 100644 packages/ui/postcss.lib.config.js create mode 100644 packages/ui/scripts/build-merge-css.js create mode 100644 packages/ui/src/base-styles.css create mode 100644 packages/ui/tailwind.lib.config.js create mode 100644 packages/ui/vite.lib.config.ts diff --git a/apps/ui-vite-test/index.html b/apps/ui-vite-test/index.html new file mode 100644 index 00000000000..86f6028e2fb --- /dev/null +++ b/apps/ui-vite-test/index.html @@ -0,0 +1,12 @@ + + + + + + UI Base — Vite Validation + + +
+ + + diff --git a/apps/ui-vite-test/package.json b/apps/ui-vite-test/package.json new file mode 100644 index 00000000000..d9e1e87de29 --- /dev/null +++ b/apps/ui-vite-test/package.json @@ -0,0 +1,28 @@ +{ + "name": "ui-vite-test", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "preinstall": "npx only-allow pnpm", + "dev": "vite", + "build": "tsc --noEmit && vite build", + "preview": "vite preview", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "lucide-react": "^0.436.0", + "next-themes": "^0.3.0", + "react": "catalog:", + "react-dom": "catalog:", + "sonner": "^1.5.0", + "ui": "workspace:*" + }, + "devDependencies": { + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@vitejs/plugin-react": "^4.3.4", + "typescript": "catalog:", + "vite": "catalog:" + } +} diff --git a/apps/ui-vite-test/src/App.css b/apps/ui-vite-test/src/App.css new file mode 100644 index 00000000000..5a8c247ce39 --- /dev/null +++ b/apps/ui-vite-test/src/App.css @@ -0,0 +1,72 @@ +/* Layout styles for the ui-vite-test demo page shell. + Component styles come from ui/base.css — this file only covers + the page wrapper and section spacing used in App.tsx. */ + +.demo-page { + min-height: 100vh; + padding: 4rem 3.5rem; + max-width: 56rem; + margin: 0 auto; +} + +.demo-page h1 { + margin-bottom: 0.75rem; +} + +.demo-subtitle { + margin-bottom: 3.5rem; +} + +.demo-section { + margin-bottom: 4rem; +} + +.demo-section-title { + margin-bottom: 1.5rem; + padding-bottom: 0.75rem; +} + +.demo-badges { + margin-bottom: 1.5rem; +} + +.demo-skeletons { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.demo-form { + display: flex; + flex-direction: column; + gap: 1.5rem; + max-width: 24rem; +} + +.demo-form-field { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.demo-form-row { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.demo-card { + max-width: 24rem; +} + +.demo-alert { + max-width: 32rem; +} + +.demo-accordion { + max-width: 32rem; +} + +.demo-separator { + margin: 2.5rem 0; +} diff --git a/apps/ui-vite-test/src/App.tsx b/apps/ui-vite-test/src/App.tsx new file mode 100644 index 00000000000..34130abc0d2 --- /dev/null +++ b/apps/ui-vite-test/src/App.tsx @@ -0,0 +1,191 @@ +import './App.css' +import { Terminal } from 'lucide-react' +import { + Alert_Shadcn_, + AlertDescription_Shadcn_, + AlertTitle_Shadcn_, + Accordion_Shadcn_, + AccordionContent_Shadcn_, + AccordionItem_Shadcn_, + AccordionTrigger_Shadcn_, + Badge, + Button, + Button_Shadcn_, + Card, + CardContent, + CardHeader, + CardTitle, + Checkbox_Shadcn_, + Input_Shadcn_, + Label_Shadcn_, + Select_Shadcn_, + SelectContent_Shadcn_, + SelectItem_Shadcn_, + SelectTrigger_Shadcn_, + SelectValue_Shadcn_, + Separator, + Skeleton, + Switch, + Tabs_Shadcn_, + TabsContent_Shadcn_, + TabsList_Shadcn_, + TabsTrigger_Shadcn_, + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, + SonnerToaster, +} from 'ui/base' +import { toast } from 'sonner' + +// Proof: none of these imports touch next/image, next/link, or next/navigation. +// If any Next.js module were reachable from ui/base, this file would fail to +// compile in a non-Next.js environment. + +function Section({ title, children }: { title: string; children: React.ReactNode }) { + return ( +
+

+ {title} +

+ {children} +
+ ) +} + +export default function App() { + return ( + +
+

UI Base — Vite Validation

+

+ All components imported from{' '} + ui/base{' '} + (pre-built, no Next.js). +

+ +
+
+ + + + + + Shadcn Button +
+
+ +
+
+ Default + Success + Destructive + Warning +
+
+ + + +
+
+ +
+
+
+ Email + +
+
+ + Accept terms +
+
+ + Enable notifications +
+ + + + + + US East (N. Virginia) + EU West (Ireland) + AP Southeast (Singapore) + + +
+
+ +
+ + + Project settings + + + + + General + Billing + Team + + + General settings content. + + + Billing settings content. + + + Team settings content. + + + + +
+ +
+ + + Build successful + + All base components render correctly without Next.js. + + +
+ +
+ + + What is Supabase? + + An open source Firebase alternative built on top of Postgres. + + + + Is it free? + + Yes — generous free tier with no credit card required. + + + +
+ + + +
+ + + Hover for tooltip + + + Rendered via Radix UI — no Next.js required. + + +
+
+ + +
+ ) +} diff --git a/apps/ui-vite-test/src/globals.d.ts b/apps/ui-vite-test/src/globals.d.ts new file mode 100644 index 00000000000..a7db6a2c1a1 --- /dev/null +++ b/apps/ui-vite-test/src/globals.d.ts @@ -0,0 +1,11 @@ +// Ambient declarations needed when TypeScript follows source files from packages/ui. + +declare module '*.css' { + const styles: Record + export default styles +} + +declare module 'highlightjs-curl' { + const languageFunc: unknown + export = languageFunc +} diff --git a/apps/ui-vite-test/src/main.tsx b/apps/ui-vite-test/src/main.tsx new file mode 100644 index 00000000000..06affa6f296 --- /dev/null +++ b/apps/ui-vite-test/src/main.tsx @@ -0,0 +1,15 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import { ThemeProvider } from 'next-themes' +// Pre-built CSS: design tokens + Tailwind utilities + component CSS modules. +// No Tailwind config needed in this app. +import 'ui/base.css' +import App from './App' + +createRoot(document.getElementById('root')!).render( + + + + + +) diff --git a/apps/ui-vite-test/tsconfig.json b/apps/ui-vite-test/tsconfig.json new file mode 100644 index 00000000000..ef993056103 --- /dev/null +++ b/apps/ui-vite-test/tsconfig.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "target": "ES2021", + "lib": ["dom", "dom.iterable", "esnext"], + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx" + }, + "include": ["src"] +} diff --git a/apps/ui-vite-test/vite.config.ts b/apps/ui-vite-test/vite.config.ts new file mode 100644 index 00000000000..9e039433d05 --- /dev/null +++ b/apps/ui-vite-test/vite.config.ts @@ -0,0 +1,7 @@ +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' + +// No Tailwind or PostCSS needed — all CSS comes pre-built from ui/base.css. +export default defineConfig({ + plugins: [react()], +}) diff --git a/packages/ui/.gitignore b/packages/ui/.gitignore index e985853ed84..4a92b4cfb88 100644 --- a/packages/ui/.gitignore +++ b/packages/ui/.gitignore @@ -1 +1,2 @@ .vercel +dist/ diff --git a/packages/ui/base.tsx b/packages/ui/base.tsx new file mode 100644 index 00000000000..522a1a8db13 --- /dev/null +++ b/packages/ui/base.tsx @@ -0,0 +1,304 @@ +// Next.js-agnostic entry point for packages/ui. +// This is the source of truth for the base bundle. +// +// The following components are intentionally excluded because they import from next/*: +// - src/lib/Markdown (imports next/image) +// - src/components/Image (imports next/image) +// - src/components/TextLink (imports next/link) +// - src/layout/banners (imports next/navigation) +// +// New exports should be added here by default. +// Only add to index.tsx if the component requires Next.js APIs. + +// GENERAL + +export * from './src/components/Button' +export * from './src/components/Icon/IconBackground' + +// DISPLAYS + +export { Card as Card_legacy_ } from './src/components/Card' +export * from './src/components/Tabs' +export * from './src/components/Alert' +export * from './src/components/Accordion' +export * from './src/components/Collapsible' +export * from './src/components/CodeBlock' +export * from './src/components/SimpleCodeBlock' +export * from './src/components/Mermaid' + +// NAV + +export * from './src/components/Menu' +export * from './src/components/NavMenu' + +// OVERLAYS + +export * from './src/components/Modal' +export * from './src/components/SidePanel' +export * from './src/components/Popover' + +// HTML + +export { Heading } from './src/components/CustomHTMLElements' + +// UTILITIES + +export * from './src/components/Space' +export * from './src/components/Loading' +export * from './src/components/LogoLoader' +export * from './src/components/AnimatedCounter' +export * from './src/lib/utils' + +// DATA ENTRY + +export * from './src/components/Select' +export * from './src/components/Listbox' +export * from './src/components/Checkbox' +export * from './src/components/Input' +export * from './src/components/InputNumber' +export * from './src/components/Radio' +export * from './src/components/Toggle' +export * from './src/components/Form' +export * from './src/components/ExpandingTextArea' + +export * from './src/components/PrePostTab' + +// layout +export * from './src/components/LoadingLine' + +// ai icon +export * from './src/layout/ai-icon-animation' + +// theme switcher +export * from './src/components/ThemeProvider/themes' +export * from './src/components/ThemeProvider/singleThemes' + +// shadcn +export * from './src/components/shadcn/ui/dropdown-menu' +export * from './src/components/shadcn/ui/sonner' +export * from './src/components/shadcn/ui/sonner-progress' +export * from './src/components/shadcn/ui/separator' +export * from './src/components/shadcn/ui/sheet' +export * from './src/components/shadcn/ui/badge' +export * from './src/components/shadcn/ui/input-otp' +export * from './src/components/shadcn/ui/alert-dialog' +export * from './src/components/shadcn/ui/avatar' +export * from './src/components/shadcn/ui/drawer' +export * from './src/components/shadcn/ui/menubar' +export * from './src/components/shadcn/ui/navigation-menu' +export * from './src/components/shadcn/ui/progress' +export * from './src/components/shadcn/ui/skeleton' +export * from './src/components/shadcn/ui/slider' +export * from './src/components/shadcn/ui/textarea' +export * from './src/components/shadcn/ui/toggle-group' + +export { Toggle as Toggle_Shadcn_ } from './src/components/shadcn/ui/toggle' + +export * from './src/components/shadcn/ui/card' + +export { + Command as Command_Shadcn_, + CommandDialog as CommandDialog, + CommandInput as CommandInput_Shadcn_, + CommandList as CommandList_Shadcn_, + CommandEmpty as CommandEmpty_Shadcn_, + CommandGroup as CommandGroup_Shadcn_, + CommandItem as CommandItem_Shadcn_, + CommandShortcut as CommandShortcut_Shadcn_, + CommandSeparator as CommandSeparator_Shadcn_, +} from './src/components/shadcn/ui/command' + +export { + ContextMenu as ContextMenu_Shadcn_, + ContextMenuTrigger as ContextMenuTrigger_Shadcn_, + ContextMenuContent as ContextMenuContent_Shadcn_, + ContextMenuItem as ContextMenuItem_Shadcn_, + ContextMenuSeparator as ContextMenuSeparator_Shadcn_, + ContextMenuLabel as ContextMenuLabel_Shadcn_, + ContextMenuRadioGroup as ContextMenuRadioGroup_Shadcn_, + ContextMenuRadioItem as ContextMenuRadioItem_Shadcn_, + ContextMenuShortcut as ContextMenuShortcut_Shadcn_, + ContextMenuSub as ContextMenuSub_Shadcn_, + ContextMenuSubContent as ContextMenuSubContent_Shadcn_, + ContextMenuSubTrigger as ContextMenuSubTrigger_Shadcn_, + ContextMenuCheckboxItem as ContextMenuCheckboxItem_Shadcn_, + ContextMenuGroup as ContextMenuGroup_Shadcn_, + ContextMenuPortal as ContextMenuPortal_Shadcn_, +} from './src/components/shadcn/ui/context-menu' + +export * from './src/components/shadcn/ui/dialog' + +export { + Alert as Alert_Shadcn_, + AlertTitle as AlertTitle_Shadcn_, + AlertDescription as AlertDescription_Shadcn_, +} from './src/components/shadcn/ui/alert' + +export * from './src/components/AlertCollapsible' + +export { + Field as Field_Shadcn_, + FieldContent as FieldContent_Shadcn_, + FieldDescription as FieldDescription_Shadcn_, + FieldError as FieldError_Shadcn_, + FieldGroup as FieldGroup_Shadcn_, + FieldLabel as FieldLabel_Shadcn_, + FieldLegend as FieldLegend_Shadcn_, + FieldSeparator as FieldSeparator_Shadcn_, + FieldSet as FieldSet_Shadcn_, + FieldTitle as FieldTitle_Shadcn_, +} from './src/components/shadcn/ui/field' + +export { + useFormField as useFormField_Shadcn_, + Form as Form_Shadcn_, + FormItem as FormItem_Shadcn_, + FormLabel as FormLabel_Shadcn_, + FormControl as FormControl_Shadcn_, + FormDescription as FormDescription_Shadcn_, + FormMessage as FormMessage_Shadcn_, + FormField as FormField_Shadcn_, + useWatch as useWatch_Shadcn_, +} from './src/components/shadcn/ui/form' + +export { + Popover as Popover_Shadcn_, + PopoverTrigger as PopoverTrigger_Shadcn_, + PopoverContent as PopoverContent_Shadcn_, + PopoverAnchor as PopoverAnchor_Shadcn_, + PopoverSeparator as PopoverSeparator_Shadcn_, +} from './src/components/shadcn/ui/popover' + +export { + Accordion as Accordion_Shadcn_, + AccordionItem as AccordionItem_Shadcn_, + AccordionTrigger as AccordionTrigger_Shadcn_, + AccordionContent as AccordionContent_Shadcn_, +} from './src/components/shadcn/ui/accordion' + +export { + Select as Select_Shadcn_, + SelectContent as SelectContent_Shadcn_, + SelectGroup as SelectGroup_Shadcn_, + SelectItem as SelectItem_Shadcn_, + SelectLabel as SelectLabel_Shadcn_, + SelectSeparator as SelectSeparator_Shadcn_, + SelectTrigger as SelectTrigger_Shadcn_, + SelectValue as SelectValue_Shadcn_, + SelectScrollUpButton as SelectScrollUpButton_Shadcn_, + SelectScrollDownButton as SelectScrollDownButton_Shadcn_, +} from './src/components/shadcn/ui/select' + +export { + RadioGroup as RadioGroup_Shadcn_, + RadioGroupItem as RadioGroupItem_Shadcn_, + RadioGroupLargeItem as RadioGroupLargeItem_Shadcn_, +} from './src/components/shadcn/ui/radio-group' + +export { Slider as Slider_Shadcn_ } from './src/components/shadcn/ui/slider' + +export { Input as Input_Shadcn_ } from './src/components/shadcn/ui/input' + +export { Button as Button_Shadcn_ } from './src/components/shadcn/ui/button' + +export { ButtonGroup, ButtonGroupItem } from './src/components/shadcn/ui/button-group' + +export { + Breadcrumb as Breadcrumb_Shadcn_, + BreadcrumbItem as BreadcrumbItem_Shadcn_, + BreadcrumbLink as BreadcrumbLink_Shadcn_, + BreadcrumbList as BreadcrumbList_Shadcn_, + BreadcrumbEllipsis as BreadcrumbEllipsis_Shadcn_, + BreadcrumbPage as BreadcrumbPage_Shadcn_, + BreadcrumbSeparator as BreadcrumbSeparator_Shadcn_, +} from './src/components/shadcn/ui/breadcrumb' + +export { TextArea as TextArea_Shadcn_ } from './src/components/shadcn/ui/text-area' + +export { Label as Label_Shadcn_ } from './src/components/shadcn/ui/label' + +export * from './src/components/shadcn/ui/switch' + +export { Checkbox as Checkbox_Shadcn_ } from './src/components/shadcn/ui/checkbox' + +export * from './src/components/shadcn/ui/scroll-area' + +export * from './src/components/shadcn/ui/hover-card' + +export * from './src/components/shadcn/ui/aspect-ratio' + +export * from './src/components/shadcn/ui/table' +export * from './src/components/ShadowScrollArea' + +export { + Collapsible as Collapsible_Shadcn_, + CollapsibleTrigger as CollapsibleTrigger_Shadcn_, + CollapsibleContent as CollapsibleContent_Shadcn_, +} from './src/components/shadcn/ui/collapsible' + +export { + Tabs as Tabs_Shadcn_, + TabsContent as TabsContent_Shadcn_, + TabsList as TabsList_Shadcn_, + TabsTrigger as TabsTrigger_Shadcn_, +} from './src/components/shadcn/ui/tabs' + +export { + TooltipProvider, + Tooltip, + TooltipTrigger, + TooltipContent, + TooltipPortal, +} from './src/components/shadcn/ui/tooltip' + +export { + HoverCard as HoverCard_Shadcn_, + HoverCardTrigger as HoverCardTrigger_Shadcn_, + HoverCardContent as HoverCardContent_Shadcn_, +} from './src/components/shadcn/ui/hover-card' + +export * from './src/components/shadcn/ui/calendar' + +export { Toggle as Toggle_Shadcn } from './src/components/shadcn/ui/toggle' + +export { ScrollArea, ScrollBar, ScrollViewport } from './src/components/shadcn/ui/scroll-area' + +export { Separator } from './src/components/shadcn/ui/separator' + +export * from './src/components/shadcn/ui/resizable' + +export * from './src/components/radio-group-stacked' +export * from './src/components/radio-group-card' + +export * from './src/components/TreeView' + +export * from './src/components/shadcn/ui/chart' +export * from './src/components/shadcn/ui/sidebar' + +export * from './src/components/StatusIcon' + +// ICONS +export * from './src/components/Icon/icons/IconBriefcase2' +export * from './src/components/Icon/icons/IconBroadcast' +export * from './src/components/Icon/icons/IconChangelog' +export * from './src/components/Icon/icons/IconDatabaseChanges' +export * from './src/components/Icon/icons/IconDiscord' +export * from './src/components/Icon/icons/IconDiscussions' +export * from './src/components/Icon/icons/IconDocumentation' +export * from './src/components/Icon/icons/IconGitHubSolid' +export * from './src/components/Icon/icons/IconIntegrations' +export * from './src/components/Icon/icons/IconLifeBuoy2' +export * from './src/components/Icon/icons/IconLinkedinSolid' +export * from './src/components/Icon/icons/IconMicSolid' +export * from './src/components/Icon/icons/IconPartners' +export * from './src/components/Icon/icons/IconPresence' +export * from './src/components/Icon/icons/IconProductHunt' +export * from './src/components/Icon/icons/IconTwitterX' +export * from './src/components/Icon/icons/IconYCombinator' +export * from './src/components/Icon/icons/IconYoutubeSolid' + +// Hooks +export * from './src/lib/Hooks' +export * from './src/components/hooks/use-mobile' + +export * from './src/components/KeyboardShortcut/KeyboardShortcut' diff --git a/packages/ui/index.tsx b/packages/ui/index.tsx index 850a633ea39..93701d2934d 100644 --- a/packages/ui/index.tsx +++ b/packages/ui/index.tsx @@ -1,305 +1,14 @@ -// Markdown components +// Full export: everything in base plus Next.js-specific components. +// Existing apps import from this entry (unchanged behaviour). +// +// To add a new export: +// - If it does NOT import from next/*, add it to base.tsx +// - If it DOES import from next/*, add it here only +export * from './base' + +// Next.js-specific components export * from './src/lib/Markdown' - -// GENERAL - -export * from './src/components/Button' -export * from './src/components/Icon/IconBackground' export * from './src/components/Image' - -// DISPLAYS - -export { Card as Card_legacy_ } from './src/components/Card' -export * from './src/components/Tabs' -export * from './src/components/Alert' -export * from './src/components/Accordion' -export * from './src/components/Collapsible' -export * from './src/components/CodeBlock' -export * from './src/components/SimpleCodeBlock' -export * from './src/components/Mermaid' - -// NAV - -export * from './src/components/Menu' -export * from './src/components/NavMenu' - -// OVERLAYS - -export * from './src/components/Modal' -export * from './src/components/SidePanel' -export * from './src/components/Popover' - -// HTML - -export { Heading } from './src/components/CustomHTMLElements' - -// UTILITIES - -export * from './src/components/Space' -export * from './src/components/Loading' -export * from './src/components/LogoLoader' -export * from './src/components/AnimatedCounter' -export * from './src/lib/utils' - -// DATA ENTRY - -export * from './src/components/Select' -export * from './src/components/Listbox' -export * from './src/components/Checkbox' -export * from './src/components/Input' -export * from './src/components/InputNumber' -export * from './src/components/Radio' -export * from './src/components/Toggle' -export * from './src/components/Form' -export * from './src/components/ExpandingTextArea' - -export * from './src/components/PrePostTab' - -// layout -export * from './src/components/LoadingLine' - -// ai icon -export * from './src/layout/ai-icon-animation' - -// theme switcher -export * from './src/components/ThemeProvider/themes' -export * from './src/components/ThemeProvider/singleThemes' - -// shadcn -export * from './src/components/shadcn/ui/dropdown-menu' -export * from './src/components/shadcn/ui/sonner' -export * from './src/components/shadcn/ui/sonner-progress' -export * from './src/components/shadcn/ui/separator' -export * from './src/components/shadcn/ui/sheet' -export * from './src/components/shadcn/ui/badge' -export * from './src/components/shadcn/ui/input-otp' -export * from './src/components/shadcn/ui/alert-dialog' -export * from './src/components/shadcn/ui/avatar' -export * from './src/components/shadcn/ui/drawer' -export * from './src/components/shadcn/ui/menubar' -export * from './src/components/shadcn/ui/navigation-menu' -export * from './src/components/shadcn/ui/progress' -export * from './src/components/shadcn/ui/skeleton' -export * from './src/components/shadcn/ui/slider' -export * from './src/components/shadcn/ui/textarea' -export * from './src/components/shadcn/ui/toggle-group' - -export { Toggle as Toggle_Shadcn_ } from './src/components/shadcn/ui/toggle' - -export * from './src/components/shadcn/ui/card' - -export { - Command as Command_Shadcn_, - CommandDialog as CommandDialog, - CommandInput as CommandInput_Shadcn_, - CommandList as CommandList_Shadcn_, - CommandEmpty as CommandEmpty_Shadcn_, - CommandGroup as CommandGroup_Shadcn_, - CommandItem as CommandItem_Shadcn_, - CommandShortcut as CommandShortcut_Shadcn_, - CommandSeparator as CommandSeparator_Shadcn_, -} from './src/components/shadcn/ui/command' - -export { - ContextMenu as ContextMenu_Shadcn_, - ContextMenuTrigger as ContextMenuTrigger_Shadcn_, - ContextMenuContent as ContextMenuContent_Shadcn_, - ContextMenuItem as ContextMenuItem_Shadcn_, - ContextMenuSeparator as ContextMenuSeparator_Shadcn_, - ContextMenuLabel as ContextMenuLabel_Shadcn_, - ContextMenuRadioGroup as ContextMenuRadioGroup_Shadcn_, - ContextMenuRadioItem as ContextMenuRadioItem_Shadcn_, - ContextMenuShortcut as ContextMenuShortcut_Shadcn_, - ContextMenuSub as ContextMenuSub_Shadcn_, - ContextMenuSubContent as ContextMenuSubContent_Shadcn_, - ContextMenuSubTrigger as ContextMenuSubTrigger_Shadcn_, - ContextMenuCheckboxItem as ContextMenuCheckboxItem_Shadcn_, - ContextMenuGroup as ContextMenuGroup_Shadcn_, - ContextMenuPortal as ContextMenuPortal_Shadcn_, -} from './src/components/shadcn/ui/context-menu' - -export * from './src/components/shadcn/ui/dialog' - -export { - Alert as Alert_Shadcn_, - AlertTitle as AlertTitle_Shadcn_, - AlertDescription as AlertDescription_Shadcn_, -} from './src/components/shadcn/ui/alert' - -export * from './src/components/AlertCollapsible' - -export { - Field as Field_Shadcn_, - FieldContent as FieldContent_Shadcn_, - FieldDescription as FieldDescription_Shadcn_, - FieldError as FieldError_Shadcn_, - FieldGroup as FieldGroup_Shadcn_, - FieldLabel as FieldLabel_Shadcn_, - FieldLegend as FieldLegend_Shadcn_, - FieldSeparator as FieldSeparator_Shadcn_, - FieldSet as FieldSet_Shadcn_, - FieldTitle as FieldTitle_Shadcn_, -} from './src/components/shadcn/ui/field' - -export { - useFormField as useFormField_Shadcn_, - Form as Form_Shadcn_, - FormItem as FormItem_Shadcn_, - FormLabel as FormLabel_Shadcn_, - FormControl as FormControl_Shadcn_, - FormDescription as FormDescription_Shadcn_, - FormMessage as FormMessage_Shadcn_, - FormField as FormField_Shadcn_, - useWatch as useWatch_Shadcn_, -} from './src/components/shadcn/ui/form' - -export { - Popover as Popover_Shadcn_, - PopoverTrigger as PopoverTrigger_Shadcn_, - PopoverContent as PopoverContent_Shadcn_, - PopoverAnchor as PopoverAnchor_Shadcn_, - PopoverSeparator as PopoverSeparator_Shadcn_, -} from './src/components/shadcn/ui/popover' - -export { - Accordion as Accordion_Shadcn_, - AccordionItem as AccordionItem_Shadcn_, - AccordionTrigger as AccordionTrigger_Shadcn_, - AccordionContent as AccordionContent_Shadcn_, -} from './src/components/shadcn/ui/accordion' - -export { - Select as Select_Shadcn_, - SelectContent as SelectContent_Shadcn_, - SelectGroup as SelectGroup_Shadcn_, - SelectItem as SelectItem_Shadcn_, - SelectLabel as SelectLabel_Shadcn_, - SelectSeparator as SelectSeparator_Shadcn_, - SelectTrigger as SelectTrigger_Shadcn_, - SelectValue as SelectValue_Shadcn_, - SelectScrollUpButton as SelectScrollUpButton_Shadcn_, - SelectScrollDownButton as SelectScrollDownButton_Shadcn_, -} from './src/components/shadcn/ui/select' - -export { - RadioGroup as RadioGroup_Shadcn_, - RadioGroupItem as RadioGroupItem_Shadcn_, - RadioGroupLargeItem as RadioGroupLargeItem_Shadcn_, -} from './src/components/shadcn/ui/radio-group' - -export { Slider as Slider_Shadcn_ } from './src/components/shadcn/ui/slider' - -export { Input as Input_Shadcn_ } from './src/components/shadcn/ui/input' - -export { Button as Button_Shadcn_ } from './src/components/shadcn/ui/button' - -export { ButtonGroup, ButtonGroupItem } from './src/components/shadcn/ui/button-group' - -export { - Breadcrumb as Breadcrumb_Shadcn_, - BreadcrumbItem as BreadcrumbItem_Shadcn_, - BreadcrumbLink as BreadcrumbLink_Shadcn_, - BreadcrumbList as BreadcrumbList_Shadcn_, - BreadcrumbEllipsis as BreadcrumbEllipsis_Shadcn_, - BreadcrumbPage as BreadcrumbPage_Shadcn_, - BreadcrumbSeparator as BreadcrumbSeparator_Shadcn_, -} from './src/components/shadcn/ui/breadcrumb' - -export { TextArea as TextArea_Shadcn_ } from './src/components/shadcn/ui/text-area' - -export { Label as Label_Shadcn_ } from './src/components/shadcn/ui/label' - -export * from './src/components/shadcn/ui/switch' - -export { Checkbox as Checkbox_Shadcn_ } from './src/components/shadcn/ui/checkbox' - -export * from './src/components/shadcn/ui/scroll-area' - -export * from './src/components/shadcn/ui/hover-card' - -export * from './src/components/shadcn/ui/aspect-ratio' - -export * from './src/components/shadcn/ui/table' -export * from './src/components/ShadowScrollArea' - -export { - Collapsible as Collapsible_Shadcn_, - CollapsibleTrigger as CollapsibleTrigger_Shadcn_, - CollapsibleContent as CollapsibleContent_Shadcn_, -} from './src/components/shadcn/ui/collapsible' - -export { - Tabs as Tabs_Shadcn_, - TabsContent as TabsContent_Shadcn_, - TabsList as TabsList_Shadcn_, - TabsTrigger as TabsTrigger_Shadcn_, -} from './src/components/shadcn/ui/tabs' - -export { - TooltipProvider, - Tooltip, - TooltipTrigger, - TooltipContent, - TooltipPortal, -} from './src/components/shadcn/ui/tooltip' - -export { - HoverCard as HoverCard_Shadcn_, - HoverCardTrigger as HoverCardTrigger_Shadcn_, - HoverCardContent as HoverCardContent_Shadcn_, -} from './src/components/shadcn/ui/hover-card' - -export * from './src/components/shadcn/ui/calendar' - -export { Toggle as Toggle_Shadcn } from './src/components/shadcn/ui/toggle' - -export { ScrollArea, ScrollBar, ScrollViewport } from './src/components/shadcn/ui/scroll-area' - -export { Separator } from './src/components/shadcn/ui/separator' - -export * from './src/components/shadcn/ui/resizable' - -export * from './src/components/radio-group-stacked' -export * from './src/components/radio-group-card' - -export * from './src/components/TreeView' - -export * from './src/components/shadcn/ui/chart' -export * from './src/components/shadcn/ui/sidebar' - -// links - export * from './src/components/TextLink' - -// used for LW export * from './src/layout/banners' - -export * from './src/components/StatusIcon' - -// ICONS -// export icons -export * from './src/components/Icon/icons/IconBriefcase2' -export * from './src/components/Icon/icons/IconBroadcast' -export * from './src/components/Icon/icons/IconChangelog' -export * from './src/components/Icon/icons/IconDatabaseChanges' -export * from './src/components/Icon/icons/IconDiscord' -export * from './src/components/Icon/icons/IconDiscussions' -export * from './src/components/Icon/icons/IconDocumentation' -export * from './src/components/Icon/icons/IconGitHubSolid' -export * from './src/components/Icon/icons/IconIntegrations' -export * from './src/components/Icon/icons/IconLifeBuoy2' -export * from './src/components/Icon/icons/IconLinkedinSolid' -export * from './src/components/Icon/icons/IconMicSolid' -export * from './src/components/Icon/icons/IconPartners' -export * from './src/components/Icon/icons/IconPresence' -export * from './src/components/Icon/icons/IconProductHunt' -export * from './src/components/Icon/icons/IconTwitterX' -export * from './src/components/Icon/icons/IconYCombinator' -export * from './src/components/Icon/icons/IconYoutubeSolid' - -// Export hooks -export * from './src/lib/Hooks' -export * from './src/components/hooks/use-mobile' - -export * from './src/components/KeyboardShortcut/KeyboardShortcut' diff --git a/packages/ui/package.json b/packages/ui/package.json index 91f3b5dc16e..a98747bc92e 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -3,10 +3,23 @@ "version": "0.0.0", "main": "./index.tsx", "types": "./index.tsx", + "exports": { + ".": { + "types": "./index.tsx", + "default": "./index.tsx" + }, + "./base": { + "types": "./base.tsx", + "import": "./dist/base.js" + }, + "./base.css": "./dist/base.css", + "./src/*": "./src/*" + }, "license": "MIT", "sideEffects": false, "scripts": { "preinstall": "npx only-allow pnpm", + "build": "vite build --config vite.lib.config.ts && tailwindcss -c tailwind.lib.config.js -i src/base-styles.css -o dist/base-tw.css && node scripts/build-merge-css.js", "typecheck": "tsc --noEmit", "generate-demo-tailwind-classes": "node internals/tokens/generate-demo-tailwind-classes.js", "cleanse-css-for-tailwind": "node internals/tokens/cleanse-css-for-tailwind.js", @@ -80,7 +93,13 @@ "tailwindcss": "catalog:", "vaul": "^0.9.9" }, + "peerDependenciesMeta": { + "next": { + "optional": true + } + }, "devDependencies": { + "@vitejs/plugin-react": "^4.3.4", "@ctrl/tinycolor": "^3.4.0", "@testing-library/jest-dom": "^6.6.0", "@testing-library/react": "^16.0.0", diff --git a/packages/ui/postcss.config.js b/packages/ui/postcss.config.js new file mode 100644 index 00000000000..b96175def0a --- /dev/null +++ b/packages/ui/postcss.config.js @@ -0,0 +1,10 @@ +// PostCSS config for packages/ui. +// Used by both: +// - `pnpm build` (vite.lib.config.ts): expands @apply in CSS modules for the +// pre-built base bundle, and generates Tailwind utilities for base-styles.css +// - `pnpm test` (vitest): expands @apply so CSS modules compile correctly in jsdom +module.exports = { + plugins: { + tailwindcss: { config: './tailwind.lib.config.js' }, + }, +} diff --git a/packages/ui/postcss.lib.config.js b/packages/ui/postcss.lib.config.js new file mode 100644 index 00000000000..3750e011892 --- /dev/null +++ b/packages/ui/postcss.lib.config.js @@ -0,0 +1,7 @@ +// PostCSS config used exclusively by vite.lib.config.ts during the library build. +// Tailwind processes @apply directives in CSS modules using the lib content paths. +module.exports = { + plugins: { + tailwindcss: { config: './tailwind.lib.config.js' }, + }, +} diff --git a/packages/ui/scripts/build-merge-css.js b/packages/ui/scripts/build-merge-css.js new file mode 100644 index 00000000000..db048d61dff --- /dev/null +++ b/packages/ui/scripts/build-merge-css.js @@ -0,0 +1,93 @@ +// Merges the two intermediate CSS files produced during the library build into +// the final dist/base.css that consumers import. +// +// Build pipeline: +// 1. vite build → dist/base-components.css (CSS modules, @apply expanded) +// 2. tailwindcss → dist/base-tw.css (Tailwind utilities + design tokens) +// 3. this script → dist/base.css (font-face + combined, intermediates deleted) +// +// Order: font-face first, then utilities, then component-specific rules. + +const fs = require('fs') +const path = require('path') + +const dist = path.resolve(__dirname, '../dist') +const srcFonts = path.resolve(__dirname, '../src/fonts') +const distFonts = path.join(dist, 'fonts') + +// Copy font files to dist/fonts/ so the @font-face urls resolve correctly. +if (!fs.existsSync(distFonts)) fs.mkdirSync(distFonts, { recursive: true }) +for (const file of fs.readdirSync(srcFonts)) { + fs.copyFileSync(path.join(srcFonts, file), path.join(distFonts, file)) +} + +// @font-face declarations — URLs are relative to dist/base.css. +const fontFaceCss = `@font-face { + font-family: 'custom-font'; + src: url('./fonts/CustomFont-Book.woff2') format('woff2'); + font-weight: 400; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'custom-font'; + src: url('./fonts/CustomFont-BookItalic.woff2') format('woff2'); + font-weight: 400; + font-style: italic; + font-display: swap; +} +@font-face { + font-family: 'custom-font'; + src: url('./fonts/CustomFont-Medium.woff2') format('woff2'); + font-weight: 500; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'custom-font'; + src: url('./fonts/CustomFont-Bold.woff2') format('woff2'); + font-weight: 700; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'custom-font'; + src: url('./fonts/CustomFont-BoldItalic.woff2') format('woff2'); + font-weight: 700; + font-style: italic; + font-display: swap; +} +@font-face { + font-family: 'custom-font'; + src: url('./fonts/CustomFont-Black.woff2') format('woff2'); + font-weight: 800; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'custom-font'; + src: url('./fonts/CustomFont-BlackItalic.woff2') format('woff2'); + font-weight: 800; + font-style: italic; + font-display: swap; +} +/* Activate fonts via CSS variables, matching the design-system app's next/font setup. */ +:root { + --font-custom: 'custom-font', Circular, 'Helvetica Neue', Helvetica, Arial, sans-serif; + --font-source-code-pro: 'Source Code Pro', 'Office Code Pro', Menlo, monospace; +} +` + +const twPath = path.join(dist, 'base-tw.css') +const componentsPath = path.join(dist, 'base-components.css') +const outputPath = path.join(dist, 'base.css') + +const tw = fs.existsSync(twPath) ? fs.readFileSync(twPath, 'utf8') : '' +const components = fs.existsSync(componentsPath) ? fs.readFileSync(componentsPath, 'utf8') : '' + +fs.writeFileSync(outputPath, fontFaceCss + '\n' + tw + (components ? '\n' + components : '')) + +if (fs.existsSync(twPath)) fs.rmSync(twPath) +if (fs.existsSync(componentsPath)) fs.rmSync(componentsPath) + +console.log('dist/base.css written (%d bytes)', fs.statSync(outputPath).size) diff --git a/packages/ui/src/base-styles.css b/packages/ui/src/base-styles.css new file mode 100644 index 00000000000..4f4587ad288 --- /dev/null +++ b/packages/ui/src/base-styles.css @@ -0,0 +1,21 @@ +/* Design tokens — CSS custom properties for the Supabase design system */ +@import '../build/css/source/global.css'; +@import '../build/css/themes/dark.css'; +@import '../build/css/themes/light.css'; + +/* Tailwind layers — utilities are generated by scanning src/** during build */ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + * { + @apply border-border; + } + body { + font-synthesis-weight: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } +} diff --git a/packages/ui/tailwind.lib.config.js b/packages/ui/tailwind.lib.config.js new file mode 100644 index 00000000000..824e777ca13 --- /dev/null +++ b/packages/ui/tailwind.lib.config.js @@ -0,0 +1,8 @@ +// Tailwind config for the pre-built base bundle. +// Scans all base component source files so every utility class used in JSX +// or via @apply in CSS modules is included in dist/base.css. +const config = require('config/tailwind.config') + +module.exports = config({ + content: ['./src/**/*.{tsx,ts,js}', './base.tsx'], +}) diff --git a/packages/ui/vite.lib.config.ts b/packages/ui/vite.lib.config.ts new file mode 100644 index 00000000000..6d499b5bda1 --- /dev/null +++ b/packages/ui/vite.lib.config.ts @@ -0,0 +1,38 @@ +import { resolve } from 'path' +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' + +// Types are served from the source base.tsx file directly (via exports["./base"].types). +// No separate .d.ts generation is needed. + +export default defineConfig({ + plugins: [react()], + + css: { + // Point Vite at the package directory so it finds postcss.config.js here. + // This ensures @apply directives in CSS modules are expanded by Tailwind + // during the lib build. + postcss: resolve(__dirname, '.'), + }, + + build: { + lib: { + entry: resolve(__dirname, 'base.tsx'), + formats: ['es'], + fileName: () => 'base.js', + }, + rollupOptions: { + // Externalize every package-level import so the bundle only contains + // the UI component code itself. All runtime deps are provided by the + // consuming app (resolved via pnpm workspace hoisting). + external: (id) => + !id.startsWith('.') && !id.startsWith('/') && !id.startsWith('\0'), + output: { + // Name the extracted CSS distinctly so the merge script can find it. + assetFileNames: 'base-components[extname]', + }, + }, + // All CSS (CSS modules + any imported CSS) lands in a single file. + cssCodeSplit: false, + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cc3f6b1da7b..b0cf5c5495b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -833,7 +833,7 @@ importers: version: 1.1.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@sentry/nextjs': specifier: 'catalog:' - version: 10.27.0(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0) + version: 10.27.0(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0) '@std/path': specifier: npm:@jsr/std__path@^1.0.8 version: '@jsr/std__path@1.0.8' @@ -983,13 +983,13 @@ importers: version: 0.52.2 next: specifier: ~16.1.7 - version: 16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) + version: 16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) next-themes: specifier: ^0.3.0 version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nuqs: specifier: 2.7.1 - version: 2.7.1(@tanstack/react-router@1.158.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 2.7.1(@tanstack/react-router@1.158.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) openai: specifier: ^4.75.1 version: 4.104.0(encoding@0.1.13)(ws@8.18.3)(zod@3.25.76) @@ -1254,7 +1254,7 @@ importers: version: 2.11.3(@types/node@22.13.14)(typescript@5.9.2) next-router-mock: specifier: ^0.9.13 - version: 0.9.13(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1) + version: 0.9.13(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1) node-mocks-http: specifier: ^1.17.2 version: 1.17.2(@types/node@22.13.14) @@ -1587,6 +1587,43 @@ importers: specifier: 'catalog:' version: 7.1.11(@types/node@22.13.14)(jiti@2.5.1)(sass@1.77.4)(terser@5.39.0)(tsx@4.20.3)(yaml@2.8.1) + apps/ui-vite-test: + dependencies: + lucide-react: + specifier: ^0.436.0 + version: 0.436.0(react@18.3.1) + next-themes: + specifier: ^0.3.0 + version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: + specifier: 'catalog:' + version: 18.3.1 + react-dom: + specifier: 'catalog:' + version: 18.3.1(react@18.3.1) + sonner: + specifier: ^1.5.0 + version: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + ui: + specifier: workspace:* + version: link:../../packages/ui + devDependencies: + '@types/react': + specifier: 'catalog:' + version: 18.3.3 + '@types/react-dom': + specifier: 'catalog:' + version: 18.3.0 + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.3.4(supports-color@8.1.1)(vite@7.1.11(@types/node@22.13.14)(jiti@2.5.1)(sass@1.77.4)(terser@5.39.0)(tsx@4.20.3)(yaml@2.8.1)) + typescript: + specifier: 'catalog:' + version: 5.9.2 + vite: + specifier: 'catalog:' + version: 7.1.11(@types/node@22.13.14)(jiti@2.5.1)(sass@1.77.4)(terser@5.39.0)(tsx@4.20.3)(yaml@2.8.1) + apps/www: dependencies: '@bsmnt/scrollytelling': @@ -2201,7 +2238,7 @@ importers: version: 18.3.0 next-router-mock: specifier: ^0.9.13 - version: 0.9.13(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1) + version: 0.9.13(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1) tsconfig: specifier: workspace:* version: link:../tsconfig @@ -2569,6 +2606,9 @@ importers: '@types/react-syntax-highlighter': specifier: ^15.5.13 version: 15.5.13 + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.3.4(supports-color@8.1.1)(vite@7.1.11(@types/node@22.13.14)(jiti@2.5.1)(sass@1.77.4)(terser@5.39.0)(tsx@4.20.3)(yaml@2.8.1)) '@vitest/coverage-v8': specifier: ^3.2.0 version: 3.2.4(supports-color@8.1.1)(vitest@3.2.4) @@ -25208,7 +25248,7 @@ snapshots: - supports-color - webpack - '@sentry/nextjs@10.27.0(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)': + '@sentry/nextjs@10.27.0(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.38.0 @@ -25221,7 +25261,7 @@ snapshots: '@sentry/react': 10.27.0(react@18.3.1) '@sentry/vercel-edge': 10.27.0 '@sentry/webpack-plugin': 4.6.1(encoding@0.1.13)(supports-color@8.1.1)(webpack@5.94.0) - next: 16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) + next: 16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) resolve: 1.22.8 rollup: 4.59.0 stacktrace-parser: 0.1.10 @@ -33431,9 +33471,9 @@ snapshots: next: 15.5.13(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) react: 18.3.1 - next-router-mock@0.9.13(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1): + next-router-mock@0.9.13(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1): dependencies: - next: 16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) + next: 16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) react: 18.3.1 next-seo@6.5.0(next@15.5.13(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): @@ -33475,7 +33515,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4): + next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4): dependencies: '@next/env': 16.1.7 '@swc/helpers': 0.5.15 @@ -33818,13 +33858,13 @@ snapshots: mitt: 3.0.1 next: 15.5.13(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) - nuqs@2.7.1(@tanstack/react-router@1.158.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): + nuqs@2.7.1(@tanstack/react-router@1.158.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): dependencies: '@standard-schema/spec': 1.0.0 react: 18.3.1 optionalDependencies: '@tanstack/react-router': 1.158.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next: 16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) + next: 16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) react-router: 7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nuqs@2.8.1(@tanstack/react-router@1.158.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@15.5.13(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): diff --git a/turbo.json b/turbo.json index 050e48bbb24..6206ec49ec6 100644 --- a/turbo.json +++ b/turbo.json @@ -6,6 +6,17 @@ "dependsOn": ["^build"], "outputs": ["dist/**", ".next/**", "!.next/cache/**/*", "!.next/dev/**/*"] }, + "ui#build": { + "dependsOn": ["^build"], + "outputs": ["dist/**"] + }, + "ui-vite-test#dev": { + "dependsOn": ["ui#build"], + "cache": false + }, + "ui-vite-test#build": { + "dependsOn": ["ui#build"] + }, "design-system#build": { "dependsOn": ["^build"], "env": [