From a54d14754da7915da0690858d8b49ea696fa2263 Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Thu, 2 Jan 2025 12:09:09 +0100 Subject: [PATCH] Fix theme switcher Signed-off-by: Charles de Dreuille --- microsite-canon/app/layout.tsx | 4 +- .../components/CodeBlock/index.tsx | 4 +- .../ComponentStatus/ComponentStatus.tsx | 99 ------------------- .../components/ComponentStatus/index.ts | 16 --- .../ComponentStatus/styles.module.css | 79 --------------- microsite-canon/components/Sidebar/index.tsx | 4 +- microsite-canon/components/Tabs/actions.ts | 10 +- microsite-canon/components/Tabs/index.tsx | 14 +-- microsite-canon/content/home.mdx | 61 +++++++++--- microsite-canon/mdx-components.tsx | 14 +-- microsite-canon/public/backstage.css | 6 +- microsite-canon/public/core.css | 39 +++++++- .../canon/.storybook/themes/backstage.css | 7 +- packages/canon/src/css/core.css | 54 +++++++++- 14 files changed, 167 insertions(+), 244 deletions(-) delete mode 100644 microsite-canon/components/ComponentStatus/ComponentStatus.tsx delete mode 100644 microsite-canon/components/ComponentStatus/index.ts delete mode 100644 microsite-canon/components/ComponentStatus/styles.module.css diff --git a/microsite-canon/app/layout.tsx b/microsite-canon/app/layout.tsx index 5d3c54f3ef..7a99b36e26 100644 --- a/microsite-canon/app/layout.tsx +++ b/microsite-canon/app/layout.tsx @@ -22,10 +22,10 @@ export default async function RootLayout({ }>) { const cookieStore = await cookies(); const theme = cookieStore.get('theme')?.value || 'light'; - const version = cookieStore.get('version')?.value || 'v2'; + const themeName = cookieStore.get('theme-name')?.value || 'default'; return ( - +
diff --git a/microsite-canon/components/CodeBlock/index.tsx b/microsite-canon/components/CodeBlock/index.tsx index 0604fd46d7..723608fadb 100644 --- a/microsite-canon/components/CodeBlock/index.tsx +++ b/microsite-canon/components/CodeBlock/index.tsx @@ -10,9 +10,9 @@ interface CodeBlockProps { code?: string; } -export async function CodeBlock({ lang, title, code }: CodeBlockProps) { +export async function CodeBlock({ lang = 'tsx', title, code }: CodeBlockProps) { const out = await codeToHtml(code || '', { - lang: lang || 'tsx', + lang: lang, themes: { light: 'min-light', dark: 'min-dark', diff --git a/microsite-canon/components/ComponentStatus/ComponentStatus.tsx b/microsite-canon/components/ComponentStatus/ComponentStatus.tsx deleted file mode 100644 index 9f4a93fd07..0000000000 --- a/microsite-canon/components/ComponentStatus/ComponentStatus.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import styles from './styles.module.css'; - -export const ComponentStatus = () => { - return ( -
- - - - - - - - - - - - - - - -
- ); -}; - -export const Component = ({ - name, - status = 'notStarted', - style, - link, -}: { - name: string; - status: 'notStarted' | 'inProgress' | 'alpha' | 'beta' | 'stable'; - style?: React.CSSProperties; - link?: string; -}) => { - return ( -
- {link ? ( - - {name} - - ) : ( - {name} - )} - - {status === 'notStarted' && 'Not Started'} - {status === 'inProgress' && 'In Progress'} - {status === 'alpha' && 'Alpha'} - {status === 'beta' && 'Beta'} - {status === 'stable' && 'Stable'} - -
- ); -}; diff --git a/microsite-canon/components/ComponentStatus/index.ts b/microsite-canon/components/ComponentStatus/index.ts deleted file mode 100644 index 238c001289..0000000000 --- a/microsite-canon/components/ComponentStatus/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { ComponentStatus } from './ComponentStatus'; diff --git a/microsite-canon/components/ComponentStatus/styles.module.css b/microsite-canon/components/ComponentStatus/styles.module.css deleted file mode 100644 index 4bd8a2e19c..0000000000 --- a/microsite-canon/components/ComponentStatus/styles.module.css +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -.container { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 0px 64px; -} - -.componentStatus { - display: flex; - align-items: center; - justify-content: space-between; - padding: 8px 0; -} - -.title { - color: #3b59ff; - font-size: 16px; - font-weight: 400; - text-decoration: none; -} - -& .pill { - display: inline-flex; - align-items: center; - color: #000; - border-radius: 40px; - padding: 0px 8px; - height: 24px; - font-size: 12px; - font-weight: 600; - border-style: solid; - border-width: 1px; - margin-left: 8px; - - &.notStarted { - background-color: #f2f2f2; - border-color: #cdcdcd; - color: #888888; - } - - &.inProgress { - background-color: #fff2b9; - border-color: #ffd000; - color: #d79927; - } - - &.alpha { - background-color: #d7f9d7; - border-color: #4ed14a; - color: #3a9837; - } - - &.beta { - background-color: #d7f9d7; - border-color: #4ed14a; - color: #3a9837; - } - - &.stable { - background-color: #d7f9d7; - border-color: #4ed14a; - color: #3a9837; - } -} diff --git a/microsite-canon/components/Sidebar/index.tsx b/microsite-canon/components/Sidebar/index.tsx index 2f73013264..ef53c99aa7 100644 --- a/microsite-canon/components/Sidebar/index.tsx +++ b/microsite-canon/components/Sidebar/index.tsx @@ -7,7 +7,7 @@ import { cookies } from 'next/headers'; export const Sidebar = async () => { const cookieStore = await cookies(); const theme = cookieStore.get('theme'); - const version = cookieStore.get('version'); + const themeName = cookieStore.get('theme-name'); return (
@@ -23,7 +23,7 @@ export const Sidebar = async () => {
- +
diff --git a/microsite-canon/components/Tabs/actions.ts b/microsite-canon/components/Tabs/actions.ts index 41812fbab1..f5d35dd860 100644 --- a/microsite-canon/components/Tabs/actions.ts +++ b/microsite-canon/components/Tabs/actions.ts @@ -13,13 +13,13 @@ export async function setThemeCookie() { } } -export async function setVersionCookie() { +export async function setThemeNameCookie() { const cookieStore = await cookies(); - const version = cookieStore.get('version'); + const themeName = cookieStore.get('theme-name'); - if (version?.value === 'v1') { - cookieStore.set('version', 'v2'); + if (themeName?.value === 'legacy') { + cookieStore.set('theme-name', 'default'); } else { - cookieStore.set('version', 'v1'); + cookieStore.set('theme-name', 'legacy'); } } diff --git a/microsite-canon/components/Tabs/index.tsx b/microsite-canon/components/Tabs/index.tsx index 8599b3ff02..cb9b46c1fd 100644 --- a/microsite-canon/components/Tabs/index.tsx +++ b/microsite-canon/components/Tabs/index.tsx @@ -5,26 +5,26 @@ import { Tabs } from '@base-ui-components/react/tabs'; import { Icon, Text } from '@backstage/canon'; import { usePathname } from 'next/navigation'; import { useRouter } from 'next/navigation'; -import { setThemeCookie, setVersionCookie } from './actions'; +import { setThemeCookie, setThemeNameCookie } from './actions'; export const TabsVersion = ({ - version, + themeName, }: { - version?: { value: string; name: string }; + themeName?: { value: string; name: string }; }) => { return ( - + Theme 1 - + Theme 2 diff --git a/microsite-canon/content/home.mdx b/microsite-canon/content/home.mdx index 65afeffebc..1793bc0575 100644 --- a/microsite-canon/content/home.mdx +++ b/microsite-canon/content/home.mdx @@ -1,5 +1,4 @@ -import { Banner } from '@/components/Banner'; -import { ComponentStatus } from '@/components/ComponentStatus'; +import { CodeBlock } from '../components/CodeBlock'; @@ -9,16 +8,54 @@ the API as we go. We are aiming to improve the general UI of Backstage and plugins across Backstage. This new library will take time to build but we are building it incrementally with not conflict with the existing theming system. - +## Installation -## Component Status +### 1. Install canon -We are still in the process of documenting the API and building the -components. You can use the statuses below to see what is ready and what is -coming soon. If there is a component missing that you need, please let us know -by opening an issue on GitHub. +Install Canon using a package manager. - + + +### 2. Import the css files + +Import the global CSS file at the root of your application. + +```tsx +import '@backstage/canon/css/core.css'; +import '@backstage/canon/css/components.css'; +``` + +### 3. Add the theme provider + +Add the theme provider to your application. + +```tsx +import { ThemeProvider } from '@backstage/canon'; + + + +; +``` + +### 4. Start building ✨ + +Now you can start building your plugin using the new design system. + +```tsx +import { Stack, Button } from '@backstage/canon'; + + + Hello World + +; +``` + +## Roadmap + +You can check our roadmap [on GitHub](https://github.com/orgs/backstage/projects/10). We'll do our best to keep you updated on the progress. + +## Next steps + +Now that you have the basics down, you can start building your plugin using the new design system. +Please familiarise yourself first with our theming principles. This will help you understand the core concepts of the design system. +If you have any questions, please reach out to us on [Discord](https://discord.gg/MUpMjP2). diff --git a/microsite-canon/mdx-components.tsx b/microsite-canon/mdx-components.tsx index a9b077c512..f17aa0750a 100644 --- a/microsite-canon/mdx-components.tsx +++ b/microsite-canon/mdx-components.tsx @@ -14,17 +14,17 @@ export function useMDXComponents(components: MDXComponents): MDXComponents { ), h2: ({ children }) => ( - - {children as ReactNode} - - ), - h3: ({ children }) => ( - + {children as ReactNode} ), + h3: ({ children }) => ( + + {children as ReactNode} + + ), p: ({ children }) => ( - + {children as ReactNode} ), diff --git a/microsite-canon/public/backstage.css b/microsite-canon/public/backstage.css index cc7e0bdade..c885f3c635 100644 --- a/microsite-canon/public/backstage.css +++ b/microsite-canon/public/backstage.css @@ -1,4 +1,4 @@ -:root { +[data-theme-name="legacy"][data-theme="light"], [data-theme-name="legacy"][data-theme="dark"] { --canon-font-regular: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; & .cn-button { @@ -45,7 +45,7 @@ } } -[data-theme="backstage-light"] { +[data-theme-name="legacy"][data-theme="light"] { --canon-accent: #2e77d0; --canon-background: #f8f8f8; --canon-surface-1: #fff; @@ -55,7 +55,7 @@ --canon-text-secondary: #646464; } -[data-theme="backstage-dark"] { +[data-theme-name="legacy"][data-theme="dark"] { --canon-accent: #fff; --canon-background: #000; --canon-surface-1: #121212; diff --git a/microsite-canon/public/core.css b/microsite-canon/public/core.css index 64010088dc..62865e3c0b 100644 --- a/microsite-canon/public/core.css +++ b/microsite-canon/public/core.css @@ -5656,7 +5656,7 @@ } } -:root { +[data-theme="light"] { --canon-font-regular: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --canon-font-monospace: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace; --canon-font-weight-regular: 400; @@ -5691,9 +5691,6 @@ --canon-border-radius-2xl: 1.5rem; --canon-container-max-width: 1200px; --canon-container-padding: 1rem; -} - -[data-theme="light"] { --canon-accent: #000; --canon-background: #f8f8f8; --canon-surface-1: #fff; @@ -5711,6 +5708,40 @@ } [data-theme="dark"] { + --canon-font-regular: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --canon-font-monospace: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace; + --canon-font-weight-regular: 400; + --canon-font-weight-bold: 600; + --canon-font-size-label: .625rem; + --canon-font-size-caption: .75rem; + --canon-font-size-body: .875rem; + --canon-font-size-subtitle: 1rem; + --canon-font-size-title5: 1.25rem; + --canon-font-size-title4: 1.5rem; + --canon-font-size-title3: 2rem; + --canon-font-size-title2: 3rem; + --canon-font-size-title1: 4rem; + --canon-font-size-display: 5.75rem; + --canon-spacing-5xs: .125rem; + --canon-spacing-4xs: .25rem; + --canon-spacing-3xs: .375rem; + --canon-spacing-2xs: .5rem; + --canon-spacing-xs: .75rem; + --canon-spacing-sm: 1rem; + --canon-spacing-md: 1.5rem; + --canon-spacing-lg: 2rem; + --canon-spacing-xl: 2.5rem; + --canon-spacing-2xl: 3rem; + --canon-spacing-3xl: 3.5rem; + --canon-border-radius-2xs: .125rem; + --canon-border-radius-xs: .25rem; + --canon-border-radius-sm: .5rem; + --canon-border-radius-md: .75rem; + --canon-border-radius-lg: 1rem; + --canon-border-radius-xl: 1.25rem; + --canon-border-radius-2xl: 1.5rem; + --canon-container-max-width: 1200px; + --canon-container-padding: 1rem; --canon-accent: #fff; --canon-background: #000; --canon-surface-1: #121212; diff --git a/packages/canon/.storybook/themes/backstage.css b/packages/canon/.storybook/themes/backstage.css index 0951607e89..780876501b 100644 --- a/packages/canon/.storybook/themes/backstage.css +++ b/packages/canon/.storybook/themes/backstage.css @@ -1,4 +1,5 @@ -:root { +[data-theme-name='legacy'][data-theme='light'], +[data-theme-name='legacy'][data-theme='dark'] { --canon-font-regular: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; .cn-button { @@ -51,7 +52,7 @@ } } -[data-theme='backstage-light'] { +[data-theme-name='legacy'][data-theme='light'] { /* Colors */ --canon-accent: #2e77d0; --canon-background: #f8f8f8; @@ -64,7 +65,7 @@ --canon-text-secondary: #646464; } -[data-theme='backstage-dark'] { +[data-theme-name='legacy'][data-theme='dark'] { /* Colors */ --canon-accent: #fff; --canon-background: #000; diff --git a/packages/canon/src/css/core.css b/packages/canon/src/css/core.css index e027337401..4f15d571c7 100644 --- a/packages/canon/src/css/core.css +++ b/packages/canon/src/css/core.css @@ -19,7 +19,8 @@ @import './utilities.css'; /* Light theme tokens */ -:root { + +[data-theme='light'] { /* Font families */ --canon-font-regular: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', @@ -68,9 +69,7 @@ /* Container */ --canon-container-max-width: 1200px; --canon-container-padding: 1rem; -} -[data-theme='light'] { /* Colors */ --canon-accent: #000; --canon-background: #f8f8f8; @@ -96,6 +95,55 @@ /* Dark theme tokens */ [data-theme='dark'] { + /* Font families */ + --canon-font-regular: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + 'Helvetica Neue', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', + 'Segoe UI Symbol', 'Noto Color Emoji'; + --canon-font-monospace: ui-monospace, 'Menlo', 'Monaco', 'Consolas', + 'Liberation Mono', 'Courier New', monospace; + + /* Font weights */ + --canon-font-weight-regular: 400; + --canon-font-weight-bold: 600; + + /* Font sizes */ + --canon-font-size-label: 0.625rem; /* 10px */ + --canon-font-size-caption: 0.75rem; /* 12px */ + --canon-font-size-body: 0.875rem; /* 14px */ + --canon-font-size-subtitle: 1rem; /* 16px */ + --canon-font-size-title5: 1.25rem; /* 20px */ + --canon-font-size-title4: 1.5rem; /* 24px */ + --canon-font-size-title3: 2rem; /* 32px */ + --canon-font-size-title2: 3rem; /* 48px */ + --canon-font-size-title1: 4rem; /* 64px */ + --canon-font-size-display: 5.75rem; /* 92px */ + + /* Spacing */ + --canon-spacing-5xs: 0.125rem; /* 2px */ + --canon-spacing-4xs: 0.25rem; /* 4px */ + --canon-spacing-3xs: 0.375rem; /* 6px */ + --canon-spacing-2xs: 0.5rem; /* 8px */ + --canon-spacing-xs: 0.75rem; /* 12px */ + --canon-spacing-sm: 1rem; /* 16px */ + --canon-spacing-md: 1.5rem; /* 24px */ + --canon-spacing-lg: 2rem; /* 32px */ + --canon-spacing-xl: 2.5rem; /* 40px */ + --canon-spacing-2xl: 3rem; /* 48px */ + --canon-spacing-3xl: 3.5rem; /* 56px */ + + /* Border radius */ + --canon-border-radius-2xs: 0.125rem; /* 2px */ + --canon-border-radius-xs: 0.25rem; /* 4px */ + --canon-border-radius-sm: 0.5rem; /* 8px */ + --canon-border-radius-md: 0.75rem; /* 12px */ + --canon-border-radius-lg: 1rem; /* 16px */ + --canon-border-radius-xl: 1.25rem; /* 20px */ + --canon-border-radius-2xl: 1.5rem; /* 24px */ + + /* Container */ + --canon-container-max-width: 1200px; + --canon-container-padding: 1rem; + /* Colors */ --canon-accent: #fff; --canon-background: #000;