diff --git a/README.md b/README.md
index 33ece02..43aaf61 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,7 @@ The following command would forward the API keys from the specified shell enviro
```bash
export ANTHROPIC_API_KEY=xxx
export OPENAI_API_KEY=xxx
-docker run --name openui -p 7878:7878 -e OPENAI_API_KEY -e ANTHROPIC_API_KEY -e OLLAMA_HOST=http://host.docker.internal:11434 gchr.io/wandb/openui
+docker run --rm --name openui -p 7878:7878 -e OPENAI_API_KEY -e ANTHROPIC_API_KEY -e OLLAMA_HOST=http://host.docker.internal:11434 gchr.io/wandb/openui
```
Now you can goto [http://localhost:7878](http://localhost:7878) and generate new UI's!
diff --git a/assets/demo.gif b/assets/demo.gif
index e6c41b2..2ba0c9a 100644
Binary files a/assets/demo.gif and b/assets/demo.gif differ
diff --git a/backend/openui/dist/annotator/index.html b/backend/openui/dist/annotator/index.html
index 734fed2..118b84c 100644
--- a/backend/openui/dist/annotator/index.html
+++ b/backend/openui/dist/annotator/index.html
@@ -621,7 +621,9 @@
How do you want this to change?
return
}
const isDark = document.documentElement.classList.contains('dark')
- const newModeDark = event.data.mode === 'dark' || !isDark
+ const newModeDark =
+ event.data.mode === 'dark' ||
+ (!isDark && event.data.mode !== 'light')
if (newModeDark) {
document.documentElement.classList.add('dark')
} else {
diff --git a/frontend/public/annotator/index.html b/frontend/public/annotator/index.html
index 734fed2..118b84c 100644
--- a/frontend/public/annotator/index.html
+++ b/frontend/public/annotator/index.html
@@ -621,7 +621,9 @@ How do you want this to change?
return
}
const isDark = document.documentElement.classList.contains('dark')
- const newModeDark = event.data.mode === 'dark' || !isDark
+ const newModeDark =
+ event.data.mode === 'dark' ||
+ (!isDark && event.data.mode !== 'light')
if (newModeDark) {
document.documentElement.classList.add('dark')
} else {
diff --git a/frontend/src/api/openai.ts b/frontend/src/api/openai.ts
index 53bf8af..890ab54 100644
--- a/frontend/src/api/openai.ts
+++ b/frontend/src/api/openai.ts
@@ -68,6 +68,7 @@ Prefer using these colors when appropriate, for example:
\`\`\`
*Implementation Rules:*
+- Only implement elements within the \`\` tag, don't bother with \`\` or \`\` tags.
- Avoid using SVGs directly. Instead, use the \`\` tag with a descriptive title as the alt attribute and add .svg to the placehold.co url, for example:
\`\`\`html
diff --git a/frontend/src/components/Settings.tsx b/frontend/src/components/Settings.tsx
index ca57950..2bea780 100644
--- a/frontend/src/components/Settings.tsx
+++ b/frontend/src/components/Settings.tsx
@@ -134,7 +134,7 @@ export default function Settings({ trigger }: { trigger: JSX.Element }) {
Settings
Model:{' '}
- {slugToNiceName(model, false)}
+ {slugToNiceName(model.split('/').at(-1), false)}
Temperature: {temperature}
diff --git a/frontend/src/components/VersionPreview.tsx b/frontend/src/components/VersionPreview.tsx
index 2e13f87..fc25bb4 100644
--- a/frontend/src/components/VersionPreview.tsx
+++ b/frontend/src/components/VersionPreview.tsx
@@ -1,6 +1,7 @@
import { TrashIcon } from '@radix-ui/react-icons'
import { useVersion } from 'hooks'
import { useAtomValue } from 'jotai'
+import { themes } from 'lib/themes'
import { cn } from 'lib/utils'
import { nanoid } from 'nanoid'
import { useEffect, useMemo, useRef, useState } from 'react'
@@ -8,6 +9,8 @@ import {
darkModeAtom,
historySidebarStateAtom,
imageDB,
+ uiStateAtom,
+ uiThemeAtom,
useSaveHistory,
type ItemWrapper
} from 'state'
@@ -27,6 +30,10 @@ export default function VersionPreview({
const iframeRef = useRef(null)
const [isFrameReady, setIsFrameReady] = useState(false)
const isVisible = useAtomValue(historySidebarStateAtom) === 'versions'
+ const uiState = useAtomValue(uiStateAtom)
+ const isRendering = uiState.rendering
+ const uiTheme = useAtomValue(uiThemeAtom)
+ const theme = themes.find(t => t.name === uiTheme) ?? themes[0]
const [html, setHtml] = useState()
const id = useMemo(() => nanoid(8), [])
const saveHistory = useSaveHistory()
@@ -50,7 +57,11 @@ export default function VersionPreview({
'*'
)
}
- }, [darkMode, previewDarkMode])
+ iframeRef.current?.contentWindow?.postMessage(
+ { action: 'theme', theme },
+ '*'
+ )
+ }, [darkMode, previewDarkMode, theme])
useEffect(() => {
item
@@ -80,12 +91,17 @@ export default function VersionPreview({
html,
js: [],
darkMode: previewDarkMode === 'dark',
- action: 'hydrate'
+ action: 'hydrate',
+ rendering: isRendering
},
'*'
)
+ iframeRef.current?.contentWindow?.postMessage(
+ { action: 'theme', theme },
+ '*'
+ )
}
- }, [isFrameReady, html, isVisible, previewDarkMode, id])
+ }, [isFrameReady, html, isVisible, previewDarkMode, id, isRendering, theme])
const W = 1524
const H = 960
diff --git a/frontend/src/lib/constants.ts b/frontend/src/lib/constants.ts
index e47835a..69b22bc 100644
--- a/frontend/src/lib/constants.ts
+++ b/frontend/src/lib/constants.ts
@@ -1,5 +1,5 @@
export const EXAMPLES = [
- // 'Make me a flashy landing page for an AI SaaS startup. Use some gradients and animations on hover. Come up with an exciting name and create a navigation bar up top.',
+ 'Make me a flashy landing page for an AI SaaS startup. Come up with an exciting name and create a navigation bar up top.',
'Create a responsive navigation bar with dropdown menus, using a dark theme.',
'I need a user profile card with an avatar, name, and social media links in Tailwind CSS.',
'Generate a modal popup for user feedback, including text area and submit button.',
diff --git a/frontend/src/lib/markdown.ts b/frontend/src/lib/markdown.ts
index 9016b06..603b15b 100644
--- a/frontend/src/lib/markdown.ts
+++ b/frontend/src/lib/markdown.ts
@@ -70,7 +70,6 @@ export function parseMarkdown(
}
/* This is supposed to prevent us from writing frontmatter to the UI
TODO: this is brittle, and doesn't seem to work consistently :/
- */
if (rendering && cleanMarkdown.slice(0, 1000).includes('---')) {
const offset = cleanMarkdown.split('---').slice(0, -1).join('---').length
cleanMarkdown = cleanMarkdown.slice(offset)
@@ -78,6 +77,7 @@ export function parseMarkdown(
cleanMarkdown = ''
}
}
+ */
const parsed = unified().use(remarkParse).parse(cleanMarkdown)
@@ -103,7 +103,7 @@ export function parseMarkdown(
!rendering &&
htmlBlocks.filter(h => h.value.trim() !== '').length === 0
) {
- console.warn('No HTML found, parse results:', parsed)
+ console.warn('No HTML found, parse results:', parsed.children)
htmlBlocks = [
{
type: 'code',
diff --git a/frontend/src/state/atoms/history.ts b/frontend/src/state/atoms/history.ts
index 6da52ce..e686873 100644
--- a/frontend/src/state/atoms/history.ts
+++ b/frontend/src/state/atoms/history.ts
@@ -497,20 +497,34 @@ export const useSaveHistory = () => {
}
safeValue = JSON.stringify(parsed)
}
+ // TODO: move this shit to indexed DB!!!
for (const key of Object.keys(parsed.historyMap)) {
const item = parsed.historyMap[key] as HistoryItem
const html = item.html ?? ''
if (html !== '') {
delete item.html
- localStorage.setItem(`${key}.html`, html)
+ try {
+ localStorage.setItem(`${key}.html`, html)
+ } catch (error) {
+ console.error('Error saving HTML', error)
+ }
}
const markdown = item.markdown ?? ''
if (markdown !== '') {
delete item.markdown
- localStorage.setItem(`${key}.md`, markdown)
+ try {
+ localStorage.setItem(`${key}.md`, markdown)
+ } catch (error) {
+ console.error('Error saving markdown', error)
+ }
}
}
- localStorage.setItem('serializedHistory', safeValue)
+ console.log('Saving history', safeValue.length)
+ try {
+ localStorage.setItem('serializedHistory', safeValue)
+ } catch (error) {
+ console.error('Error saving history', error)
+ }
}
})
}
diff --git a/frontend/src/state/index.ts b/frontend/src/state/index.ts
index 66d48ba..002e755 100644
--- a/frontend/src/state/index.ts
+++ b/frontend/src/state/index.ts
@@ -21,7 +21,8 @@ export const historySidebarStateAtom = atom<'closed' | 'history' | 'versions'>(
export const screenshotAtom = atom('')
export const facetsAtom = atomWithStorage('facets', [])
export const commentsAtom = atom([])
-export const uiThemeAtom = atomWithStorage('uiTheme', 'zinc')
+const theme = undefined
+export const uiThemeAtom = atomWithStorage('uiTheme', theme)
export const darkModeAtom = atomWithStorage('darkMode', 'system')
export const beastModeAtom = atom(false)
export const draggingAtom = atom(false)