From a6271fa7852d058e73e05e839de430370a0987dd Mon Sep 17 00:00:00 2001 From: Stef Williams Date: Tue, 7 Jan 2025 10:52:30 -0500 Subject: [PATCH 1/4] wip(theme-builder): allow custom theme import --- .../themes/_components/base-theme-panel.tsx | 80 +++++++++++++++++-- .../pages/themes/_providers/themeProvider.tsx | 9 ++- 2 files changed, 79 insertions(+), 10 deletions(-) diff --git a/website/src/pages/themes/_components/base-theme-panel.tsx b/website/src/pages/themes/_components/base-theme-panel.tsx index bdbff9dda..6d96528cd 100644 --- a/website/src/pages/themes/_components/base-theme-panel.tsx +++ b/website/src/pages/themes/_components/base-theme-panel.tsx @@ -1,21 +1,60 @@ -import React from "react"; +import React, { useState } from "react"; import Select from "./select"; import { themes, useTheme } from "../_providers/themeProvider"; import { usePreviewOptions } from "../_providers/previewOptionsProvider"; import PanelHeader from "./panel-header"; -const themeOptions = themes.map((theme) => ({ - label: theme.name, - value: theme.name, -})); +const themeOptions = [ + ...themes.map((theme) => ({ + label: theme.name, + value: theme.name, + })), + { label: "Custom", value: "custom" }, +]; const BaseThemePanel = () => { const { baseTheme, onBaseThemeSelect } = useTheme(); const { resetPreviewOptions } = usePreviewOptions(); + const [isCustomTheme, setIsCustomTheme] = useState(false); + const [customTheme, setCustomTheme] = useState(""); + const [error, setError] = useState(null); const handleThemeSelect = (themeName?: string) => { - onBaseThemeSelect(themeName); - resetPreviewOptions(); + if (themeName === "custom") { + setIsCustomTheme(true); + resetPreviewOptions(); + } else { + setIsCustomTheme(false); + onBaseThemeSelect(themeName); + resetPreviewOptions(); + } + }; + + const handleCustomThemeChange = ( + event: React.ChangeEvent, + ) => { + setCustomTheme(event.target.value); + setError(null); + }; + + const applyCustomTheme = () => { + try { + console.log("trying to apply custom theme"); + const parsedTheme = new Function(`return (${customTheme.trim()});`)(); + + if (typeof parsedTheme !== "object" || Array.isArray(parsedTheme)) { + console.log("Invalid theme structure. Must be an object."); + throw new Error("Invalid theme structure. Must be an object."); + } + console.log("parsedTheme", parsedTheme); + onBaseThemeSelect("custom", parsedTheme); + setError(null); + } catch (error) { + console.error(error); + setError( + "Invalid JavaScript object. Please check your theme configuration.", + ); + } }; return ( @@ -26,12 +65,37 @@ const BaseThemePanel = () => { />