Skip to content

Commit

Permalink
feat: add dynamic theme
Browse files Browse the repository at this point in the history
  • Loading branch information
byodian committed Nov 24, 2024
1 parent 75f8a52 commit b0f07ce
Show file tree
Hide file tree
Showing 37 changed files with 648 additions and 1,136 deletions.
3 changes: 0 additions & 3 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
@tailwind components;
@tailwind utilities;


@layer base {
:root {
--background: hsl(0 0% 98%);
Expand Down Expand Up @@ -228,8 +227,6 @@
/* } */
}

@layer reset, base, tokens, recipes, utilities;

:root {
--scrollbar-thumb-idle: #c1c1c1;
--scrollbar-thumb-hover: #848484;
Expand Down
1 change: 0 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Metadata, Viewport } from 'next'
import { Noto_Sans_SC } from 'next/font/google'
import '@/app/globals.css'
import '@/app/styles/index.css'
import { headers } from 'next/headers'
import { NextAppDirEmotionCacheProvider } from 'tss-react/next/appDir'
import { cn } from '@/lib/utils'
Expand Down
170 changes: 81 additions & 89 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,45 @@
'use client'
import { useEffect, useRef, useState } from 'react'
import { addContent, deleteContent, getContents, updateContent } from '@/lib/indexed-db'
import { GlobalStyles } from 'tss-react'
import {
CACHE_KEY_TEMPLATE,
CACHE_KEY_THEME,
addContent,
cn,
deleteContent,
generateThemeVariables,
getContents,
updateContent,
} from '@/lib'
import { useToast } from '@/components/ui/use-toast'
import { ToastAction } from '@/components/ui/toast'
import { Workspace } from '@/components/workspace/workspace'
import { Header } from '@/components/header/header'
import { Preview } from '@/components/preview/preview'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'

import type { Content, ContentWithId, PreviewRef, Theme, ThemeContent } from '@/types/common'
import { cn, getPreviewWidthClass, getThemeBaseClass } from '@/lib/utils'
import { defaultTheme, defaultThemeColor } from '@/lib'
import type { Content, ContentWithId, PreviewRef, ThemeContent } from '@/types'
import { DEFAULT_TEMPLATE, DEFAULT_THEME } from '@/theme'
import { CustomThemeContext } from '@/contexts/custom-theme-context'
import { useThemeStore } from '@/store/use-theme-store'

export default function Home() {
const [contents, setContents] = useState<ContentWithId[]>([])
const [theme, setTheme] = useState<Theme>(defaultTheme)
const [themeColor, setThemeColor] = useState(defaultThemeColor.label)
const { templateName, setTemplateName, theme, setTheme, templateMap, themeMap } = useThemeStore()
const [cssVariables, setCssVariables] = useState({})
const [tabValue, setTabValue] = useState('workspace')
const { toast } = useToast()
const previewRef = useRef<PreviewRef>(null)

useEffect(() => {
if (typeof window !== 'undefined') {
const currentTheme = (localStorage.getItem('currentTheme') || defaultTheme) as Theme
const currentTemplate = (localStorage.getItem(CACHE_KEY_TEMPLATE) || DEFAULT_TEMPLATE)
setTemplateName(currentTemplate)

const currentTheme = localStorage.getItem(CACHE_KEY_THEME) || DEFAULT_THEME.label
setTheme(currentTheme)
const currentThemeColor = localStorage.getItem('currentThemeColor') || defaultThemeColor.label
setThemeColor(currentThemeColor)
}
}, [])
}, [setTemplateName, setTheme])

useEffect(() => {
const fetchContents = async () => {
Expand All @@ -46,6 +58,15 @@ export default function Home() {
fetchContents()
}, [toast])

useEffect(() => {
const templateConfig = themeMap[templateName].find(item => item.label === theme)

if (templateConfig) {
const cssVariables = generateThemeVariables(templateConfig.theme!)
setCssVariables(cssVariables)
}
}, [theme, templateName, themeMap])

async function handleThemeContentSubmit(themeContent: ThemeContent) {
try {
if ('id' in themeContent) {
Expand All @@ -62,9 +83,9 @@ export default function Home() {
} as Content
const id = await addContent(newContent)
setContents(prevContents => [...prevContents, { ...newContent, id }])
setTemplateName(themeContent.template)
setTheme(themeContent.theme)
setThemeColor(themeContent.themeColor)
window.localStorage.setItem('currentTheme', themeContent.theme)
window.localStorage.setItem('currentTemplate', themeContent.template)
}
} catch (error) {
toast({
Expand Down Expand Up @@ -136,82 +157,53 @@ export default function Home() {
}

return (
<div className="flex flex-col h-full">
<Header
contents={contents}
setContents={setContents}
previewRef={previewRef}
theme={theme}
setTheme={setTheme}
themeColor={themeColor}
setThemeColor={setThemeColor}
setTableValue={setTabValue}
/>
<main className="h-[calc(100%-58px)]">
{/* desktop */}
<div className="hidden h-full sm:flex sm:flex-row">
<div
className={
cn(
'one w-full h-full mx-auto overflow-y-auto scroll-smooth',
getThemeBaseClass(theme),
theme,
themeColor,
getPreviewWidthClass(theme),
)
}>
<Preview ref={previewRef} contents={contents} className="w-full flex flex-col m-auto" />
</div>
<div className="h-full flex-grow flex items-start bg-card text-card-foreground overflow-y-auto">
<Workspace
contents={contents}
setContents={setContents}
onContentSubmit={handleContentSubmit}
onContentDelete={handleContentDelete}
onThemeContentSubmit={handleThemeContentSubmit}
/>
</div>
</div>

{/* mobile phone */}
<Tabs
defaultValue="workspace"
activationMode="manual"
value={tabValue}
onValueChange={setTabValue}
className="h-full flex flex-col sm:hidden"
>
<TabsList className="grid w-full grid-cols-2">
<TabsTrigger value="workspace">编辑器</TabsTrigger>
<TabsTrigger value="preview">预览</TabsTrigger>
</TabsList>
<TabsContent value="preview" forceMount className="data-[state=inactive]:hidden flex-grow flex-shrink overflow-y-auto mt-0">
<div
className={
cn(
'one w-full scroll-smooth h-full mx-auto',
getThemeBaseClass(theme),
theme,
themeColor,
getPreviewWidthClass(theme),
)
}>
<Preview ref={previewRef} contents={contents} className="w-full flex flex-col m-auto" />
</div>
</TabsContent>
<TabsContent value="workspace" forceMount className="data-[state=inactive]:hidden overflow-auto">
<div className="h-full flex-grow flex justify-center items-start bg-card text-card-foreground">
<Workspace
contents={contents}
setContents={setContents}
onContentSubmit={handleContentSubmit}
onContentDelete={handleContentDelete}
onThemeContentSubmit={handleThemeContentSubmit}
/>
</div>
</TabsContent>
</Tabs>
</main>
</div>
<CustomThemeContext.Provider value={{ theme, template: templateMap[templateName] }}>
<GlobalStyles styles={{ ':root': cssVariables }} />
<div className="flex flex-col h-full">
<Header
contents={contents}
setContents={setContents}
previewRef={previewRef}
templateName={templateName}
setTemplateName={setTemplateName}
theme={theme}
setTheme={setTheme}
setTableValue={setTabValue}
/>
<main className="h-[calc(100%-58px)]">
<Tabs
defaultValue="workspace"
activationMode="manual"
value={tabValue}
onValueChange={setTabValue}
className="h-full flex flex-col sm:flex-row"
>
<TabsList className="grid w-full grid-cols-2 sm:hidden">
<TabsTrigger value="workspace">编辑器</TabsTrigger>
<TabsTrigger value="preview">预览</TabsTrigger>
</TabsList>
<TabsContent value="preview" forceMount className="data-[state=inactive]:hidden sm:!block flex-grow sm:flex-grow-0 flex-shrink sm:flex-shrink-0 overflow-y-auto mt-0">
<div
className={
cn('one scroll-smooth h-full mx-auto w-[375px]')
}>
<Preview ref={previewRef} contents={contents} className="w-full flex flex-col m-auto" />
</div>
</TabsContent>
<TabsContent value="workspace" forceMount className="data-[state=inactive]:hidden sm:flex-grow sm:!block overflow-auto">
<div className="h-full flex-grow flex justify-center items-start bg-card text-card-foreground">
<Workspace
contents={contents}
setContents={setContents}
onContentSubmit={handleContentSubmit}
onContentDelete={handleContentDelete}
onThemeContentSubmit={handleThemeContentSubmit}
/>
</div>
</TabsContent>
</Tabs>
</main>
</div>
</CustomThemeContext.Provider>
)
}
142 changes: 0 additions & 142 deletions src/app/styles/apple-style-theme.css

This file was deleted.

Loading

0 comments on commit b0f07ce

Please sign in to comment.