diff --git a/packages/ui/.storybook/preview.tsx b/packages/ui/.storybook/preview.tsx index 14d86f9506..bef21b3971 100644 --- a/packages/ui/.storybook/preview.tsx +++ b/packages/ui/.storybook/preview.tsx @@ -6,7 +6,7 @@ import { useGlobals } from '@storybook/preview-api'; import '../src/css/styles.css'; // Custom mocked styles -import '../src/css/storybook.css'; +import './storybook.css'; // Custom themes import './themes/spotify.css'; diff --git a/packages/ui/src/css/storybook.css b/packages/ui/.storybook/storybook.css similarity index 92% rename from packages/ui/src/css/storybook.css rename to packages/ui/.storybook/storybook.css index 57f50dd888..e69c4a8eb1 100644 --- a/packages/ui/src/css/storybook.css +++ b/packages/ui/.storybook/storybook.css @@ -12,7 +12,7 @@ --sb-content-padding-inline: 250px; } -[data-theme='dark'] { +[data-theme-mode='dark'] { --sb-sidebar-bg: var(--bui-bg-surface-1); } @@ -30,7 +30,7 @@ --sb-content-padding-inline: 258px; } -[data-theme-name='spotify'][data-theme='light'] { +[data-theme-name='spotify'][data-theme-mode='light'] { --sb-sidebar-border: 1px solid var(--bui-border); --sb-sidebar-border-right: 1px solid var(--bui-border); --sb-options-border: 1px solid var(--bui-border); diff --git a/packages/ui/src/css/core.css b/packages/ui/src/css/core.css index e74e606acd..088d4d6f2b 100644 --- a/packages/ui/src/css/core.css +++ b/packages/ui/src/css/core.css @@ -143,7 +143,7 @@ } /* Dark theme tokens */ -[data-theme='dark'] { +[data-theme-mode='dark'] { /* Gray scale */ --bui-gray-1: #191919; --bui-gray-2: #242424; diff --git a/storybook/.storybook/preview.tsx b/storybook/.storybook/preview.tsx index dc41d80b14..e8049737b8 100644 --- a/storybook/.storybook/preview.tsx +++ b/storybook/.storybook/preview.tsx @@ -1,38 +1,19 @@ import React, { useEffect } from 'react'; import { TestApiProvider } from '@backstage/test-utils'; import { Content, AlertDisplay } from '@backstage/core-components'; -import { lightTheme, darkTheme } from '@backstage/theme'; -import { CssBaseline, ThemeProvider } from '@material-ui/core'; import { apis } from './apis'; -import { withThemeFromJSXProvider } from '@storybook/addon-themes'; import type { Decorator, Preview, ReactRenderer } from '@storybook/react'; import { useGlobals } from '@storybook/preview-api'; +import { UnifiedThemeProvider, themes } from '@backstage/theme'; -export const withThemes: Decorator = StoryFn => { - const [globals] = useGlobals(); - const selectedTheme = globals.themeMode || 'light'; - const selectedThemeName = globals.themeName || 'default'; +// Default Backstage theme +import '../../packages/ui/src/css/styles.css'; - useEffect(() => { - const htmlElement = document.documentElement; +// Custom mocked styles +import './storybook.css'; - // Remove any existing theme data attributes - htmlElement.removeAttribute('data-theme'); - htmlElement.removeAttribute('data-theme-name'); - - // Add the selected theme data attribute - htmlElement.setAttribute('data-theme', selectedTheme); - htmlElement.setAttribute('data-theme-name', selectedThemeName); - - // Cleanup on unmount - return () => { - htmlElement.removeAttribute('data-theme'); - htmlElement.removeAttribute('data-theme-name'); - }; - }, [selectedTheme, selectedThemeName]); - - return ; -}; +// Custom themes +import './themes/spotify.css'; const preview: Preview = { globalTypes: { @@ -53,11 +34,11 @@ const preview: Preview = { themeName: { name: 'Theme Name', description: 'Global theme name for components', - defaultValue: 'default', + defaultValue: 'backstage', toolbar: { icon: 'paintbrush', items: [ - { value: 'default', title: 'Default (Backstage)' }, + { value: 'backstage', title: 'Backstage' }, { value: 'spotify', title: 'Spotify' }, ], showName: true, @@ -67,9 +48,10 @@ const preview: Preview = { }, initialGlobals: { themeMode: 'light', - themeName: 'default', + themeName: 'backstage', }, parameters: { + layout: 'fullscreen', backgrounds: { disable: true, }, @@ -79,6 +61,11 @@ const preview: Preview = { date: /Date$/i, }, }, + options: { + storySort: { + order: ['Backstage UI', 'Plugins', 'Layout', 'Navigation'], + }, + }, viewport: { viewports: { initial: { @@ -127,33 +114,50 @@ const preview: Preview = { }, }, decorators: [ - withThemeFromJSXProvider({ - themes: { - Light: lightTheme, - Dark: darkTheme, - }, - defaultTheme: 'Light', - Provider: ThemeProvider, - GlobalStyles: CssBaseline, - }), - Story => ( - // @ts-ignore - TODO: Fix this - - - - - - - ), + Story => { + const [globals] = useGlobals(); + const selectedTheme = + globals.themeMode === 'light' ? themes.light : themes.dark; + + const selectedThemeMode = globals.themeMode || 'light'; + const selectedThemeName = globals.themeName || 'backstage'; + + useEffect(() => { + // Remove any existing theme data attributes + document.body.removeAttribute('data-theme-mode'); + document.body.removeAttribute('data-theme-name'); + + // Add the selected theme data attribute + document.body.setAttribute('data-theme-mode', selectedThemeMode); + document.body.setAttribute('data-theme-name', selectedThemeName); + + // Cleanup on unmount + return () => { + document.body.removeAttribute('data-theme-mode'); + document.body.removeAttribute('data-theme-name'); + }; + }, [selectedTheme, selectedThemeName]); + + document.body.style.backgroundColor = 'var(--bui-bg)'; + + const docsStoryElements = document.getElementsByClassName('docs-story'); + Array.from(docsStoryElements).forEach(element => { + (element as HTMLElement).style.backgroundColor = 'var(--bui-bg)'; + }); + + return ( + + {/* @ts-ignore - TODO: Fix this */} + + + + + + + + ); + }, ], }; export default preview; - -export const parameters = { - options: { - storySort: { - order: ['Plugins', 'Layout', 'Navigation'], - }, - }, -}; diff --git a/storybook/.storybook/storybook.css b/storybook/.storybook/storybook.css new file mode 100644 index 0000000000..e69c4a8eb1 --- /dev/null +++ b/storybook/.storybook/storybook.css @@ -0,0 +1,38 @@ +:root { + --sb-panel-radius: 0; + --sb-panel-top: 0; + --sb-panel-bottom: 0; + --sb-panel-left: 0; + --sb-panel-right: 0; + --sb-sidebar-border: none; + --sb-sidebar-border-right: 1px solid var(--bui-border); + --sb-sidebar-bg: #000; + --sb-options-border: none; + --sb-options-border-left: 1px solid var(--bui-border); + --sb-content-padding-inline: 250px; +} + +[data-theme-mode='dark'] { + --sb-sidebar-bg: var(--bui-bg-surface-1); +} + +[data-theme-name='spotify'] { + --sb-panel-radius: var(--bui-radius-3); + --sb-panel-top: 8px; + --sb-panel-bottom: 8px; + --sb-panel-left: 8px; + --sb-panel-right: 8px; + --sb-sidebar-border: none; + --sb-sidebar-border-right: none; + --sb-sidebar-bg: var(--bui-bg-surface-1); + --sb-options-border: none; + --sb-options-border-left: none; + --sb-content-padding-inline: 258px; +} + +[data-theme-name='spotify'][data-theme-mode='light'] { + --sb-sidebar-border: 1px solid var(--bui-border); + --sb-sidebar-border-right: 1px solid var(--bui-border); + --sb-options-border: 1px solid var(--bui-border); + --sb-options-border-left: 1px solid var(--bui-border); +} diff --git a/storybook/.storybook/themes/spotify.css b/storybook/.storybook/themes/spotify.css new file mode 100644 index 0000000000..7544dd183d --- /dev/null +++ b/storybook/.storybook/themes/spotify.css @@ -0,0 +1,284 @@ +@font-face { + font-family: CircularSpTitle; + font-weight: 900; + font-display: swap; + unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-017E, U+018F, U+0192, + U+01A0-01A1, U+01AF-01B0, U+01B5-01B6, U+01C4-01C6, U+01F1-01F3, U+01FA-01FF, + U+0218-021B, U+0237, U+0259, U+02BB-02BC, U+02C6-02C7, U+02C9, U+02D8-02DD, + U+0300-0301, U+0303, U+0309, U+0323, U+0394, U+03A9, U+03BC, U+03C0, + U+1E80-1E85, U+1E8A-1E8B, U+1EA0-1EF9, U+1FD6, U+2007-2008, U+200B, + U+2010-2011, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, + U+2030, U+2032-2033, U+2039-203A, U+2042, U+2044, U+2051, U+2070, + U+2074-2079, U+2080-2089, U+20AB-20AC, U+2113, U+2117, U+2122, U+2126, + U+2160-2169, U+216C-216F, U+2190-2193, U+2196-2199, U+21A9, U+21B0-21B5, + U+21C6, U+2202, U+2206, U+220F, U+2211-2212, U+2215, U+2219-221A, U+221E, + U+222B, U+2248, U+2260, U+2264-2265, U+22C5, U+24C5, U+25A0-25A1, U+25AF, + U+25B2-25B3, U+25CA-25CB, U+25CF, U+262E, U+2713, U+2715, U+2780-2788, + U+E000, U+E002, U+F6C3, U+FB00-FB04, U+FEFF, U+FF0C, U+FF0E, U+FF1A-FF1B, + U+FFFF; + src: url('https://encore.scdn.co/fonts/CircularSpTitle-Black-4588c99025b967475c31695b0743dd1a.woff2') + format('woff2'), + url('https://encore.scdn.co/fonts/CircularSpTitle-Black-506746f387a26f25aa3d023b3e501d34.woff') + format('woff'); +} +@font-face { + font-family: CircularSpTitle; + font-weight: 700; + font-display: swap; + unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-017E, U+018F, U+0192, + U+01A0-01A1, U+01AF-01B0, U+01B5-01B6, U+01C4-01C6, U+01F1-01F3, U+01FA-01FF, + U+0218-021B, U+0237, U+0259, U+02BB-02BC, U+02C6-02C7, U+02C9, U+02D8-02DD, + U+0300-0301, U+0303, U+0309, U+0323, U+0394, U+03A9, U+03BC, U+03C0, + U+1E80-1E85, U+1E8A-1E8B, U+1EA0-1EF9, U+1FD6, U+2007-2008, U+200B, + U+2010-2011, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, + U+2030, U+2032-2033, U+2039-203A, U+2042, U+2044, U+2051, U+2070, + U+2074-2079, U+2080-2089, U+20AB-20AC, U+2113, U+2117, U+2122, U+2126, + U+2160-2169, U+216C-216F, U+2190-2193, U+2196-2199, U+21A9, U+21B0-21B5, + U+21C6, U+2202, U+2206, U+220F, U+2211-2212, U+2215, U+2219-221A, U+221E, + U+222B, U+2248, U+2260, U+2264-2265, U+22C5, U+24C5, U+25A0-25A1, U+25AF, + U+25B2-25B3, U+25CA-25CB, U+25CF, U+262E, U+2713, U+2715, U+2780-2788, + U+E000, U+E002, U+F6C3, U+FB00-FB04, U+FEFF, U+FF0C, U+FF0E, U+FF1A-FF1B, + U+FFFF; + src: url('https://encore.scdn.co/fonts/CircularSpTitle-Bold-b2586b06a2e1522e9d879d84c2792a58.woff2') + format('woff2'), + url('https://encore.scdn.co/fonts/CircularSpTitle-Bold-1624fb2df28c20d7203d7fb86ce8b481.woff') + format('woff'); +} +@font-face { + font-family: CircularSp; + font-weight: 700; + font-display: swap; + unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-017E, U+018F, U+0192, + U+01A0-01A1, U+01AF-01B0, U+01B5-01B6, U+01C4-01C6, U+01F1-01F3, U+01FA-01FF, + U+0218-021B, U+0237, U+0259, U+02BB-02BC, U+02C6-02C7, U+02C9, U+02D8-02DD, + U+0300-0301, U+0303, U+0309, U+0323, U+0394, U+03A9, U+03BC, U+03C0, + U+1E80-1E85, U+1E8A-1E8B, U+1EA0-1EF9, U+1FD6, U+2007-2008, U+200B, + U+2010-2011, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, + U+2030, U+2032-2033, U+2039-203A, U+2042, U+2044, U+2051, U+2070, + U+2074-2079, U+2080-2089, U+20AB-20AC, U+2113, U+2117, U+2122, U+2126, + U+2160-2169, U+216C-216F, U+2190-2193, U+2196-2199, U+21A9, U+21B0-21B5, + U+21C6, U+2202, U+2206, U+220F, U+2211-2212, U+2215, U+2219-221A, U+221E, + U+222B, U+2248, U+2260, U+2264-2265, U+22C5, U+24C5, U+25A0-25A1, U+25AF, + U+25B2-25B3, U+25CA-25CB, U+25CF, U+262E, U+2713, U+2715, U+2780-2788, + U+E000, U+E002, U+F6C3, U+FB00-FB04, U+FEFF, U+FF0C, U+FF0E, U+FF1A-FF1B, + U+FFFF; + src: url('https://encore.scdn.co/fonts/CircularSp-Bold-602e7aefc706aa36c6ec1324b9bbc461.woff2') + format('woff2'), + url('https://encore.scdn.co/fonts/CircularSp-Bold-856afe2da4ba4e61239b129e2c16d633.woff') + format('woff'); +} +@font-face { + font-family: CircularSp; + font-weight: 400; + font-display: swap; + unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-017E, U+018F, U+0192, + U+01A0-01A1, U+01AF-01B0, U+01B5-01B6, U+01C4-01C6, U+01F1-01F3, U+01FA-01FF, + U+0218-021B, U+0237, U+0259, U+02BB-02BC, U+02C6-02C7, U+02C9, U+02D8-02DD, + U+0300-0301, U+0303, U+0309, U+0323, U+0394, U+03A9, U+03BC, U+03C0, + U+1E80-1E85, U+1E8A-1E8B, U+1EA0-1EF9, U+1FD6, U+2007-2008, U+200B, + U+2010-2011, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, + U+2030, U+2032-2033, U+2039-203A, U+2042, U+2044, U+2051, U+2070, + U+2074-2079, U+2080-2089, U+20AB-20AC, U+2113, U+2117, U+2122, U+2126, + U+2160-2169, U+216C-216F, U+2190-2193, U+2196-2199, U+21A9, U+21B0-21B5, + U+21C6, U+2202, U+2206, U+220F, U+2211-2212, U+2215, U+2219-221A, U+221E, + U+222B, U+2248, U+2260, U+2264-2265, U+22C5, U+24C5, U+25A0-25A1, U+25AF, + U+25B2-25B3, U+25CA-25CB, U+25CF, U+262E, U+2713, U+2715, U+2780-2788, + U+E000, U+E002, U+F6C3, U+FB00-FB04, U+FEFF, U+FF0C, U+FF0E, U+FF1A-FF1B, + U+FFFF; + src: url('https://encore.scdn.co/fonts/CircularSp-Book-a00e99ef9996a3a157fb6b746856d04f.woff2') + format('woff2'), + url('https://encore.scdn.co/fonts/CircularSp-Book-3f73da7d35bd81c706bce7bbb84964de.woff') + format('woff'); +} + +@font-face { + font-family: CircularSp; + font-weight: 700; + font-display: swap; + unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-017E, U+018F, U+0192, + U+01A0-01A1, U+01AF-01B0, U+01B5-01B6, U+01C4-01C6, U+01F1-01F3, U+01FA-01FF, + U+0218-021B, U+0237, U+0259, U+02BB-02BC, U+02C6-02C7, U+02C9, U+02D8-02DD, + U+0300-0301, U+0303, U+0309, U+0323, U+0394, U+03A9, U+03BC, U+03C0, + U+1E80-1E85, U+1E8A-1E8B, U+1EA0-1EF9, U+1FD6, U+2007-2008, U+200B, + U+2010-2011, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, + U+2030, U+2032-2033, U+2039-203A, U+2042, U+2044, U+2051, U+2070, + U+2074-2079, U+2080-2089, U+20AB-20AC, U+2113, U+2117, U+2122, U+2126, + U+2160-2169, U+216C-216F, U+2190-2193, U+2196-2199, U+21A9, U+21B0-21B5, + U+21C6, U+2202, U+2206, U+220F, U+2211-2212, U+2215, U+2219-221A, U+221E, + U+222B, U+2248, U+2260, U+2264-2265, U+22C5, U+24C5, U+25A0-25A1, U+25AF, + U+25B2-25B3, U+25CA-25CB, U+25CF, U+262E, U+2713, U+2715, U+2780-2788, + U+E000, U+E002, U+F6C3, U+FB00-FB04, U+FEFF, U+FF0C, U+FF0E, U+FF1A-FF1B, + U+FFFF; + src: url('https://encore.scdn.co/fonts/CircularSp-Bold-602e7aefc706aa36c6ec1324b9bbc461.woff2') + format('woff2'), + url('https://encore.scdn.co/fonts/CircularSp-Bold-856afe2da4ba4e61239b129e2c16d633.woff') + format('woff'); +} + +[data-theme-name='spotify'] { + --bui-font-text: CircularSp, CircularSp-Arab, CircularSp-Hebr, CircularSp-Cyrl, + CircularSp-Grek, CircularSp-Deva; + --bui-font-title: CircularSpTitle, CircularSp-Arab, CircularSp-Hebr, + CircularSp-Cyrl, CircularSp-Grek, CircularSp-Deva; + --bui-font-regular: CircularSp, CircularSp-Arab, CircularSp-Hebr, + CircularSp-Cyrl, CircularSp-Grek, CircularSp-Deva; + + .bui-Button { + border-radius: var(--bui-radius-3); + padding-inline: var(--bui-space-3); + } + + .bui-ButtonIcon { + padding: 0; + } + + .bui-MenuPopup { + box-sizing: border-box; + max-width: 21.25rem; + } + + .bui-MenuSubmenuTrigger, + .bui-MenuItem { + height: auto; + min-height: 2rem; + } + + .bui-Text { + font-family: var(--bui-font-text); + } + + .bui-Heading { + font-family: var(--bui-font-title); + } + + .bui-TableRow { + border: none; + border-radius: var(--bui-radius-4); + } + + .bui-TableRow:hover td:first-child { + border-top-left-radius: var(--bui-radius-2); + border-bottom-left-radius: var(--bui-radius-2); + } + + .bui-TableRow:hover td:last-child { + border-top-right-radius: var(--bui-radius-2); + border-bottom-right-radius: var(--bui-radius-2); + } + + .bui-TableBody:before, + .bui-TableBody:after { + line-height: var(--bui-space-1); + content: '\200C'; + display: block; + } + + .bui-TableHeader .bui-TableRow { + border-bottom: 1px solid var(--bui-border); + } + + .bui-TableHead { + font-size: var(--bui-font-size-2); + color: var(--bui-fg-secondary); + font-weight: var(--bui-font-weight-regular); + } + + .bui-HeaderToolbar { + padding-top: var(--bui-space-2); + padding-inline: var(--bui-space-2); + } + + .bui-HeaderToolbarWrapper { + border-radius: var(--bui-radius-3); + padding-inline: var(--bui-space-3); + border: none; + } + + .bui-HeaderToolbarControls { + right: calc(var(--bui-space-3) - 1px); + } + + .bui-HeaderTabsWrapper { + margin-top: var(--bui-space-2); + margin-inline: var(--bui-space-2); + border-radius: var(--bui-radius-3); + padding-inline: var(--bui-space-1); + border: none; + } + + .bui-Input { + border-radius: var(--bui-radius-3); + } +} + +[data-theme-mode='light'][data-theme-name='spotify'] { + --bui-bg: var(--bui-gray-1); + --bui-bg-surface-1: var(--bui-white); + --bui-bg-surface-2: var(--bui-gray-2); + --bui-bg-solid: #1ed760; + --bui-bg-solid-hover: #3be477; + --bui-bg-solid-pressed: #1abc54; + --bui-bg-solid-disabled: var(--bui-gray-2); + + --bui-fg-primary: var(--bui-black); + --bui-fg-secondary: var(--bui-gray-7); + --bui-fg-solid: var(--bui-black); + + --bui-border: var(--bui-gray-3); + --bui-border-hover: rgba(0, 0, 0, 0.3); + --bui-border-pressed: rgba(0, 0, 0, 0.5); + --bui-border-disabled: rgba(0, 0, 0, 0.1); + --bui-border-danger: #f87a7a; + --bui-border-warning: #e36d05; + --bui-border-success: #53db83; + + --bui-ring: rgba(0, 0, 0, 0.2); + + .bui-HeaderToolbarWrapper { + border: 1px solid var(--bui-border); + } + + .bui-HeaderTabsWrapper { + border: 1px solid var(--bui-border); + } +} + +[data-theme-mode='dark'][data-theme-name='spotify'] { + --bui-bg: var(--bui-black); + --bui-bg-surface-1: var(--bui-gray-1); + --bui-bg-surface-2: var(--bui-gray-2); + --bui-bg-solid: #1ed760; + --bui-bg-solid-hover: #3be477; + --bui-bg-solid-pressed: #1abc54; + --bui-bg-solid-disabled: #0f6c30; + --bui-bg-tint: #242424; + --bui-bg-tint-hover: #202020; + --bui-bg-tint-pressed: #292929; + --bui-bg-tint-disabled: rgba(255, 255, 255, 0.8); + --bui-bg-danger: #3b1219; + --bui-bg-warning: #302008; + --bui-bg-success: #132d21; + + --bui-fg-primary: var(--bui-white); + --bui-fg-secondary: var(--bui-gray-7); + --bui-fg-link: var(--bui-white); + --bui-fg-link-hover: var(--bui-white); + --bui-fg-disabled: var(--bui-gray-5); + --bui-fg-solid: var(--bui-black); + --bui-fg-solid-disabled: #083618; + --bui-fg-tint: var(--bui-white); + --bui-fg-tint-disabled: var(--bui-gray-5); + --bui-fg-danger: #e22b2b; + --bui-fg-warning: #e36d05; + --bui-fg-success: #1db954; + + --bui-border: var(--bui-gray-3); + --bui-border-hover: rgba(255, 255, 255, 0.4); + --bui-border-pressed: rgba(255, 255, 255, 0.5); + --bui-border-disabled: rgba(255, 255, 255, 0.2); + --bui-border-danger: #f87a7a; + --bui-border-warning: #e36d05; + --bui-border-success: #53db83; + + --bui-ring: rgba(255, 255, 255, 0.2); +}