diff --git a/apps/www/src/app/_components/home-tabs.tsx b/apps/www/src/app/_components/home-tabs.tsx index fa604c3be5..48b2d640db 100644 --- a/apps/www/src/app/_components/home-tabs.tsx +++ b/apps/www/src/app/_components/home-tabs.tsx @@ -9,6 +9,7 @@ import { parseAsBoolean, useQueryState } from 'nuqs'; import { BlockPreview } from '@/components/block-preview'; import { settingsStore } from '@/components/context/settings-store'; +import { ThemeWrapper } from '@/components/theme-wrapper'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Button } from '@/registry/default/plate-ui/button'; @@ -68,7 +69,9 @@ export default function HomeTabs() { - + + + diff --git a/apps/www/src/app/layout.tsx b/apps/www/src/app/layout.tsx index 7c9c196590..c42665784a 100644 --- a/apps/www/src/app/layout.tsx +++ b/apps/www/src/app/layout.tsx @@ -4,7 +4,6 @@ import type { Metadata, Viewport } from 'next'; import { cn } from '@udecode/cn'; -import { Body } from '@/components/body'; import { Providers } from '@/components/context/providers'; import { SiteFooter } from '@/components/site-footer'; import { SiteHeader } from '@/components/site-header'; @@ -86,12 +85,11 @@ export default function RootLayout({ children }: RootLayoutProps) { return ( - @@ -106,7 +104,7 @@ export default function RootLayout({ children }: RootLayoutProps) { - + ); } diff --git a/apps/www/src/components/body.tsx b/apps/www/src/components/body.tsx deleted file mode 100644 index 3468b53cb5..0000000000 --- a/apps/www/src/components/body.tsx +++ /dev/null @@ -1,43 +0,0 @@ -'use client'; - -import { cn } from '@udecode/cn'; -import { usePathname } from 'next/navigation'; - -import { useConfig } from '@/hooks/use-config'; -import { useMounted } from '@/hooks/use-mounted'; - -interface ThemeBodyProps extends React.ComponentProps<'body'> { - defaultTheme?: string; -} - -export function Body({ - children, - className, - defaultTheme, - ...props -}: ThemeBodyProps) { - const [config] = useConfig(); - const pathname = usePathname(); - const mounted = useMounted(); - - const theme = - mounted && pathname === '/' - ? `theme-${config.theme ?? defaultTheme}` - : `theme-${defaultTheme}`; - - return ( - - {children} - - ); -} diff --git a/apps/www/src/components/customizer-tabs.tsx b/apps/www/src/components/customizer-tabs.tsx index eef07adaad..fdcf250d64 100644 --- a/apps/www/src/components/customizer-tabs.tsx +++ b/apps/www/src/components/customizer-tabs.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { settingsStore } from './context/settings-store'; import { PluginsTabContent } from './plugins-tab-content'; -import { ThemesTabContent } from './themes-tab-content'; +import { ThemeCustomizer } from './theme-customizer'; import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs'; export function CustomizerTabs() { @@ -33,7 +33,7 @@ export function CustomizerTabs() { className="h-[calc(85vh-90px)] overflow-y-auto overflow-x-hidden overscroll-contain pt-2 md:h-[calc(100vh-64px)]" value="themes" > - + diff --git a/apps/www/src/components/theme-customizer.tsx b/apps/www/src/components/theme-customizer.tsx index 4fc3521e8e..7c7b07c40d 100644 --- a/apps/www/src/components/theme-customizer.tsx +++ b/apps/www/src/components/theme-customizer.tsx @@ -4,172 +4,39 @@ import * as React from 'react'; import { CheckIcon, - CopyIcon, InfoCircledIcon, MoonIcon, ResetIcon, SunIcon, } from '@radix-ui/react-icons'; import { cn } from '@udecode/cn'; -import template from 'lodash.template'; import { useTheme } from 'next-themes'; import { useConfig } from '@/hooks/use-config'; import { Button } from '@/registry/default/plate-ui/button'; -import { - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, - DialogTrigger, -} from '@/registry/default/plate-ui/dialog'; import { Popover, PopoverContent, PopoverTrigger, } from '@/registry/default/plate-ui/popover'; -import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from '@/registry/default/plate-ui/tooltip'; -import { type BaseColor, baseColors } from '@/registry/registry-base-colors'; +import { baseColors } from '@/registry/registry-base-colors'; -import { copyToClipboardWithMeta } from './copy-button'; -import { ThemeWrapper } from './theme-wrapper'; -import { Drawer, DrawerContent, DrawerTrigger } from './ui/drawer'; +import { CopyCodeButton } from './copy-code-button'; import { Label } from './ui/label'; import { Skeleton } from './ui/skeleton'; -import '@/styles/mdx.css'; - export function ThemeCustomizer() { - const [config, setConfig] = useConfig(); - const { resolvedTheme: mode } = useTheme(); const [mounted, setMounted] = React.useState(false); - - React.useEffect(() => { - setMounted(true); - }, []); - - return ( -
- - - - - - - - -
- - - - - - - - -
- {mounted ? ( - <> - {['zinc', 'rose', 'blue', 'green', 'orange'].map((color) => { - const baseColor = baseColors.find( - (baseColor) => baseColor.name === color - ); - const isActive = config.theme === color; - - if (!baseColor) { - return null; - } - - return ( - - - - - - {baseColor.label} - - - ); - })} - - ) : ( -
- - - - - -
- )} -
-
- -
- ); -} - -function Customizer() { - const [mounted, setMounted] = React.useState(false); - const { resolvedTheme: mode, setTheme: setMode } = useTheme(); const [config, setConfig] = useConfig(); + const { resolvedTheme: mode, setTheme: setMode } = useTheme(); React.useEffect(() => { setMounted(true); }, []); return ( - -
+ <> +
Customize @@ -178,21 +45,8 @@ function Customizer() { Pick a style and color for your components.
- + +
@@ -209,27 +63,21 @@ function Customizer() { alignOffset={-20} side="right" > -

- What is the difference between the New York and Default style? -

+

What is a style?

A style comes with its own set of components, animations, icons and more.

The Default style has - larger inputs, uses lucide-react for icons and + large inputs, uses lucide-react for icons and tailwindcss-animate for animations.

-

- The New York style ships - with smaller buttons and cards with shadows. It uses icons - from Radix Icons. -

+

Other styles will be added in the future.

-
+
- {/* */} + + Reset +
@@ -355,313 +209,6 @@ function Customizer() {
-
- ); -} - -function CopyCodeButton({ - className, - ...props -}: React.ComponentProps) { - const [config] = useConfig(); - const activeTheme = baseColors.find((theme) => theme.name === config.theme); - const [hasCopied, setHasCopied] = React.useState(false); - - React.useEffect(() => { - setTimeout(() => { - setHasCopied(false); - }, 2000); - }, [hasCopied]); - - return ( - <> - {activeTheme && ( - - )} - - - - - - - Theme - - Copy and paste the following code into your CSS file. - - - - - {activeTheme && ( - - )} - - - ); } - -function CustomizerCode() { - const [config] = useConfig(); - const activeTheme = baseColors.find((theme) => theme.name === config.theme); - - return ( - -
-
-          
-            @layer base {
-              :root {
-            
-                  --background:{' '}
-              {activeTheme?.cssVars.light.background};
-            
-            
-                  --foreground:{' '}
-              {activeTheme?.cssVars.light.foreground};
-            
-            {[
-              'card',
-              'popover',
-              'primary',
-              'secondary',
-              'muted',
-              'accent',
-              'destructive',
-            ].map((prefix) => (
-              <>
-                
-                      --{prefix}:{' '}
-                  {
-                    activeTheme?.cssVars.light[
-                      prefix as keyof typeof activeTheme.cssVars.light
-                    ]
-                  }
-                  ;
-                
-                
-                      --{prefix}-foreground:{' '}
-                  {
-                    activeTheme?.cssVars.light[
-                      `${prefix}-foreground` as keyof typeof activeTheme.cssVars.light
-                    ]
-                  }
-                  ;
-                
-              
-            ))}
-            
-                  --border:{' '}
-              {activeTheme?.cssVars.light.border};
-            
-            
-                  --input:{' '}
-              {activeTheme?.cssVars.light.input};
-            
-            
-                  --ring: {activeTheme?.cssVars.light.ring};
-            
-            
-                  --radius: {config.radius}rem;
-            
-            {['chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5'].map(
-              (prefix) => (
-                
-                      --{prefix}:{' '}
-                  {
-                    activeTheme?.cssVars.light[
-                      prefix as keyof typeof activeTheme.cssVars.light
-                    ]
-                  }
-                  ;
-                
-              )
-            )}
-              }
-             
-              .dark {
-            
-                  --background:{' '}
-              {activeTheme?.cssVars.dark.background};
-            
-            
-                  --foreground:{' '}
-              {activeTheme?.cssVars.dark.foreground};
-            
-            {[
-              'card',
-              'popover',
-              'primary',
-              'secondary',
-              'muted',
-              'accent',
-              'destructive',
-            ].map((prefix) => (
-              <>
-                
-                      --{prefix}:{' '}
-                  {
-                    activeTheme?.cssVars.dark[
-                      prefix as keyof typeof activeTheme.cssVars.dark
-                    ]
-                  }
-                  ;
-                
-                
-                      --{prefix}-foreground:{' '}
-                  {
-                    activeTheme?.cssVars.dark[
-                      `${prefix}-foreground` as keyof typeof activeTheme.cssVars.dark
-                    ]
-                  }
-                  ;
-                
-              
-            ))}
-            
-                  --border:{' '}
-              {activeTheme?.cssVars.dark.border};
-            
-            
-                  --input: {activeTheme?.cssVars.dark.input}
-              ;
-            
-            
-                  --ring: {activeTheme?.cssVars.dark.ring};
-            
-            {['chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5'].map(
-              (prefix) => (
-                
-                      --{prefix}:{' '}
-                  {
-                    activeTheme?.cssVars.dark[
-                      prefix as keyof typeof activeTheme.cssVars.dark
-                    ]
-                  }
-                  ;
-                
-              )
-            )}
-              }
-            }
-          
-        
-
-
- ); -} - -function getThemeCode(theme: BaseColor, radius: number) { - if (!theme) { - return ''; - } - - return template(BASE_STYLES_WITH_VARIABLES)({ - colors: theme.cssVars, - radius, - }); -} - -const BASE_STYLES_WITH_VARIABLES = ` -@layer base { - :root { - --background: <%- colors.light["background"] %>; - --foreground: <%- colors.light["foreground"] %>; - --card: <%- colors.light["card"] %>; - --card-foreground: <%- colors.light["card-foreground"] %>; - --popover: <%- colors.light["popover"] %>; - --popover-foreground: <%- colors.light["popover-foreground"] %>; - --primary: <%- colors.light["primary"] %>; - --primary-foreground: <%- colors.light["primary-foreground"] %>; - --secondary: <%- colors.light["secondary"] %>; - --secondary-foreground: <%- colors.light["secondary-foreground"] %>; - --muted: <%- colors.light["muted"] %>; - --muted-foreground: <%- colors.light["muted-foreground"] %>; - --accent: <%- colors.light["accent"] %>; - --accent-foreground: <%- colors.light["accent-foreground"] %>; - --destructive: <%- colors.light["destructive"] %>; - --destructive-foreground: <%- colors.light["destructive-foreground"] %>; - --border: <%- colors.light["border"] %>; - --input: <%- colors.light["input"] %>; - --ring: <%- colors.light["ring"] %>; - --radius: <%- radius %>rem; - --chart-1: <%- colors.light["chart-1"] %>; - --chart-2: <%- colors.light["chart-2"] %>; - --chart-3: <%- colors.light["chart-3"] %>; - --chart-4: <%- colors.light["chart-4"] %>; - --chart-5: <%- colors.light["chart-5"] %>; - } - - .dark { - --background: <%- colors.dark["background"] %>; - --foreground: <%- colors.dark["foreground"] %>; - --card: <%- colors.dark["card"] %>; - --card-foreground: <%- colors.dark["card-foreground"] %>; - --popover: <%- colors.dark["popover"] %>; - --popover-foreground: <%- colors.dark["popover-foreground"] %>; - --primary: <%- colors.dark["primary"] %>; - --primary-foreground: <%- colors.dark["primary-foreground"] %>; - --secondary: <%- colors.dark["secondary"] %>; - --secondary-foreground: <%- colors.dark["secondary-foreground"] %>; - --muted: <%- colors.dark["muted"] %>; - --muted-foreground: <%- colors.dark["muted-foreground"] %>; - --accent: <%- colors.dark["accent"] %>; - --accent-foreground: <%- colors.dark["accent-foreground"] %>; - --destructive: <%- colors.dark["destructive"] %>; - --destructive-foreground: <%- colors.dark["destructive-foreground"] %>; - --border: <%- colors.dark["border"] %>; - --input: <%- colors.dark["input"] %>; - --ring: <%- colors.dark["ring"] %>; - --chart-1: <%- colors.dark["chart-1"] %>; - --chart-2: <%- colors.dark["chart-2"] %>; - --chart-3: <%- colors.dark["chart-3"] %>; - --chart-4: <%- colors.dark["chart-4"] %>; - --chart-5: <%- colors.dark["chart-5"] %>; - } -} -`; diff --git a/apps/www/src/components/themes-selector.tsx b/apps/www/src/components/themes-selector.tsx deleted file mode 100644 index 5af81e8fdd..0000000000 --- a/apps/www/src/components/themes-selector.tsx +++ /dev/null @@ -1,122 +0,0 @@ -'use client'; -import * as React from 'react'; - -import { cn } from '@udecode/cn'; -import { useTheme } from 'next-themes'; - -import { useMediaQuery } from '@/hooks/use-media-query'; -import { useThemesConfig } from '@/hooks/use-themes-config'; -import { type Theme, THEMES } from '@/lib/themes'; -import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from '@/registry/default/plate-ui/tooltip'; - -import { Skeleton } from './ui/skeleton'; -import { ToggleGroup, ToggleGroupItem } from './ui/toggle-group'; - -export function ThemesSwitcher({ - className, - themes = THEMES, -}: React.ComponentProps<'div'> & { themes?: Theme[] }) { - const { theme: mode } = useTheme(); - const [mounted, setMounted] = React.useState(false); - const { setThemesConfig, themesConfig } = useThemesConfig(); - const activeTheme = themesConfig.activeTheme; - const isDesktop = useMediaQuery('(min-width: 1024px)'); - React.useEffect(() => { - setMounted(true); - }, []); - - if (!mounted) { - return ( -
- {themes.map((theme) => ( -
- -
- ))} -
- ); - } - - return ( - { - const theme = themes.find((theme) => theme.name === value); - - if (!theme) { - return; - } - - setThemesConfig({ ...themesConfig, activeTheme: theme }); - }} - type="single" - > - {themes.map((theme) => { - const isActive = theme.name === activeTheme.name; - const isDarkTheme = ['Midnight'].includes(theme.name); - const cssVars = - mounted && mode === 'dark' ? theme.cssVars.dark : theme.cssVars.light; - - return ( - - - -
-
- - - - - {theme.name} -
-
-
-
- - {theme.name} - -
- ); - })} -
- ); -} diff --git a/apps/www/src/components/themes-styles.tsx b/apps/www/src/components/themes-styles.tsx deleted file mode 100644 index 62ebee4fb6..0000000000 --- a/apps/www/src/components/themes-styles.tsx +++ /dev/null @@ -1,30 +0,0 @@ -'use client'; - -import { useThemesConfig } from '@/hooks/use-themes-config'; - -export function ThemesStyle() { - const { themesConfig } = useThemesConfig(); - - if (!themesConfig.activeTheme) { - return null; - } - - return ( - - ); -} diff --git a/apps/www/src/components/themes-tab-content.tsx b/apps/www/src/components/themes-tab-content.tsx deleted file mode 100644 index bb5bc18437..0000000000 --- a/apps/www/src/components/themes-tab-content.tsx +++ /dev/null @@ -1,214 +0,0 @@ -'use client'; - -import * as React from 'react'; - -import { - CheckIcon, - InfoCircledIcon, - MoonIcon, - ResetIcon, - SunIcon, -} from '@radix-ui/react-icons'; -import { cn } from '@udecode/cn'; -import { useTheme } from 'next-themes'; - -import { useConfig } from '@/hooks/use-config'; -import { Button } from '@/registry/default/plate-ui/button'; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from '@/registry/default/plate-ui/popover'; -import { baseColors } from '@/registry/registry-base-colors'; - -import { CopyCodeButton } from './copy-code-button'; -import { Label } from './ui/label'; -import { Skeleton } from './ui/skeleton'; - -export function ThemesTabContent() { - const [mounted, setMounted] = React.useState(false); - const [config, setConfig] = useConfig(); - const { resolvedTheme: mode, setTheme: setMode } = useTheme(); - - React.useEffect(() => { - setMounted(true); - }, []); - - return ( - <> -
-
-
- Customize -
-
- Pick a style and color for your components. -
-
- - -
-
-
-
- - - - - About styles - - -

What is a style?

-

- A style comes with its own set of components, animations, - icons and more. -

-

- The Default style has - large inputs, uses lucide-react for icons and - tailwindcss-animate for animations. -

-

Other styles will be added in the future.

-
-
-
-
- - - -
-
-
- -
- {baseColors.map((theme) => { - const isActive = config.theme === theme.name; - - return mounted ? ( - - ) : ( - - ); - })} -
-
-
- -
- {['0', '0.3', '0.5', '0.75', '1.0'].map((value) => { - return ( - - ); - })} -
-
-
- -
- {mounted ? ( - <> - - - - ) : ( - <> - - - - )} -
-
-
- - ); -}