From 7bc5aaab834c87f8a25a88446c6bd61670c62e9f Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Sun, 12 Jan 2025 15:45:27 +0000 Subject: [PATCH] Improve customTheme functionalities Signed-off-by: Charles de Dreuille --- canon-docs/src/app/globals.css | 1 + canon-docs/src/app/layout.tsx | 1 + .../components/CustomTheme/customTheme.tsx | 99 +++++++++++-------- .../components/CustomTheme/styles.module.css | 46 ++++++++- 4 files changed, 102 insertions(+), 45 deletions(-) diff --git a/canon-docs/src/app/globals.css b/canon-docs/src/app/globals.css index e9710c6576..249f05ea8c 100644 --- a/canon-docs/src/app/globals.css +++ b/canon-docs/src/app/globals.css @@ -49,6 +49,7 @@ iframe { display: flex; align-items: center; justify-content: flex-end; + min-width: 34px; } .cm-line { diff --git a/canon-docs/src/app/layout.tsx b/canon-docs/src/app/layout.tsx index 90cd6a9d0d..99b5f22739 100644 --- a/canon-docs/src/app/layout.tsx +++ b/canon-docs/src/app/layout.tsx @@ -13,6 +13,7 @@ import '/public/backstage.css'; export const metadata: Metadata = { title: 'Canon', description: 'UI library for Backstage', + metadataBase: new URL('https://canon.backstage.io'), }; export default function RootLayout({ diff --git a/canon-docs/src/components/CustomTheme/customTheme.tsx b/canon-docs/src/components/CustomTheme/customTheme.tsx index d02f96131b..b29b5458cd 100644 --- a/canon-docs/src/components/CustomTheme/customTheme.tsx +++ b/canon-docs/src/components/CustomTheme/customTheme.tsx @@ -6,28 +6,42 @@ import { sass } from '@codemirror/lang-sass'; import styles from './styles.module.css'; import { usePlayground } from '@/utils/playground-context'; import { AnimatePresence, motion } from 'framer-motion'; +import { Icon } from '../../../../packages/canon'; + +const defaultTheme = `:root { + --canon-accent: #000; +}`; export const CustomTheme = () => { + const [isClient, setIsClient] = useState(false); + const [open, setOpen] = useState(true); const [customTheme, setCustomTheme] = useState(undefined); const { selectedThemeName } = usePlayground(); - const [isClient, setIsClient] = useState(false); + const [savedMessage, setSavedMessage] = useState('Save'); + + const updateStyleElement = (theme: string) => { + let styleElement = document.getElementById( + 'custom-theme-style', + ) as HTMLStyleElement; + + if (!styleElement) { + styleElement = document.createElement('style'); + styleElement.id = 'custom-theme-style'; + document.head.appendChild(styleElement); + } + + styleElement.textContent = theme; + }; useEffect(() => { if (selectedThemeName === 'custom') { - const storedTheme = localStorage.getItem('customThemeCss') || ''; - setCustomTheme(storedTheme); - - let styleElement = document.getElementById( - 'custom-theme-style', - ) as HTMLStyleElement; - - if (!styleElement) { - styleElement = document.createElement('style'); - styleElement.id = 'custom-theme-style'; - document.head.appendChild(styleElement); + let storedTheme = localStorage.getItem('customThemeCss'); + if (!storedTheme) { + storedTheme = defaultTheme; + localStorage.setItem('customThemeCss', storedTheme); } - - styleElement.textContent = storedTheme; + setCustomTheme(storedTheme); + updateStyleElement(storedTheme); } else { const styleElement = document.getElementById( 'custom-theme-style', @@ -45,48 +59,53 @@ export const CustomTheme = () => { const handleSave = () => { if (customTheme) { localStorage.setItem('customThemeCss', customTheme); - - let styleElement = document.getElementById( - 'custom-theme-style', - ) as HTMLStyleElement; - - if (!styleElement) { - styleElement = document.createElement('style'); - styleElement.id = 'custom-theme-style'; - document.head.appendChild(styleElement); - } - - styleElement.textContent = customTheme; + updateStyleElement(customTheme); + setSavedMessage('Saved!'); + setTimeout(() => setSavedMessage('Save'), 1000); } }; - const onChange = useCallback((val: string) => { + const handleChange = useCallback((val: string) => { setCustomTheme(val); }, []); + if (isClient === false) return null; + return ( - {isClient && selectedThemeName === 'custom' && ( + {selectedThemeName === 'custom' && (
Custom Theme
- +
+ {open && ( + + )} + +
+
+
+
-
)}
diff --git a/canon-docs/src/components/CustomTheme/styles.module.css b/canon-docs/src/components/CustomTheme/styles.module.css index 17e6ef18e4..a4f51c8a1d 100644 --- a/canon-docs/src/components/CustomTheme/styles.module.css +++ b/canon-docs/src/components/CustomTheme/styles.module.css @@ -2,21 +2,32 @@ position: fixed; bottom: 16px; right: 16px; - width: 36%; - height: 348px; + width: 240px; + height: 47px; background-color: var(--canon-surface-1); border-radius: 0.375rem; border: 1px solid var(--canon-border-base); display: flex; flex-direction: column; overflow: hidden; - transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out; + transition-property: background-color, border-color, height, width; + transition-duration: 0.2s; + transition-timing-function: ease-in-out; +} + +.open { + width: 36%; + height: 348px; } .editor { flex: 1; } +.editorContainer { + overflow: hidden; +} + .header { height: 46px; flex-shrink: 0; @@ -29,7 +40,16 @@ transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out; } -.button { +.headerLeft { + font-size: 0.875rem; +} + +.headerRight { + display: flex; + gap: 8px; +} + +.buttonSave { all: unset; height: 28px; padding: 0 8px; @@ -37,5 +57,21 @@ background-color: #000; border-radius: 0.25rem; cursor: pointer; - font-size: 0.875rem; + font-size: 0.75rem; +} + +.buttonClose { + all: unset; + height: 28px; + padding: 0 8px; + color: #fff; + background-color: var(--canon-surface-2); + color: var(--canon-text-primary); + transition: background-color 0.2s ease-in-out; + border-radius: 0.25rem; + cursor: pointer; + font-size: 0.875rem; + display: flex; + align-items: center; + justify-content: center; }