diff --git a/docs/src/pages/addons/using-addons/index.md b/docs/src/pages/addons/using-addons/index.md index a74bc728e9cf..c1da1c398a8e 100644 --- a/docs/src/pages/addons/using-addons/index.md +++ b/docs/src/pages/addons/using-addons/index.md @@ -67,6 +67,7 @@ addParameters({ options: { name: 'CRA Kitchen Sink', isFullScreen: false, + isDarkMode: true, showPanel: true, // more configuration here }, diff --git a/docs/src/pages/configurations/options-parameter/index.md b/docs/src/pages/configurations/options-parameter/index.md index 5ba802c18c34..2533c727e14e 100644 --- a/docs/src/pages/configurations/options-parameter/index.md +++ b/docs/src/pages/configurations/options-parameter/index.md @@ -17,6 +17,11 @@ import { addParameters, configure } from '@storybook/react'; // Option defaults: addParameters({ options: { + /** + * initially render the storybook in dark mode + * @type {Boolean} + */ + isDarkMode: false, /** * show story component as full screen * @type {Boolean} diff --git a/examples/official-storybook/tests/__snapshots__/storyshots.test.js.snap b/examples/official-storybook/tests/__snapshots__/storyshots.test.js.snap index 738cb24100a5..4cb97dd822bb 100644 --- a/examples/official-storybook/tests/__snapshots__/storyshots.test.js.snap +++ b/examples/official-storybook/tests/__snapshots__/storyshots.test.js.snap @@ -5856,7 +5856,7 @@ exports[`Storyshots UI|Settings/SettingsFooter basic 1`] = ` `; exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` -.emotion-100 { +.emotion-105 { width: 100%; height: 100%; box-sizing: border-box; @@ -6003,7 +6003,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` fill: currentColor; } -.emotion-99 { +.emotion-104 { display: block; position: relative; font-size: 13px; @@ -6016,7 +6016,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` overflow: auto; } -.emotion-99 > *:first-child { +.emotion-104 > *:first-child { position: absolute; left: 0; right: 0; @@ -6049,7 +6049,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` width: 15px; } -.emotion-96 { +.emotion-101 { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -6060,11 +6060,11 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` font-weight: 700; } -.emotion-96 > * + * { +.emotion-101 > * + * { margin-left: 20px; } -.emotion-91 { +.emotion-96 { display: inline-block; -webkit-transition: all 150ms ease-out; transition: all 150ms ease-out; @@ -6074,30 +6074,30 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` color: #999999; } -.emotion-91 svg path { +.emotion-96 svg path { fill: #1EA7FD; } -.emotion-91:hover, -.emotion-91:focus { +.emotion-96:hover, +.emotion-96:focus { cursor: pointer; color: #0297f5; } -.emotion-91:hover svg path, -.emotion-91:focus svg path { +.emotion-96:hover svg path, +.emotion-96:focus svg path { fill: #0297f5; } -.emotion-91:active { +.emotion-96:active { color: #028ee6; } -.emotion-91:active svg path { +.emotion-96:active svg path { fill: #028ee6; } -.emotion-91 svg { +.emotion-96 svg { display: inline-block; height: 1em; width: 1em; @@ -6107,31 +6107,31 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` margin-right: 0.4em; } -.emotion-91 svg path { +.emotion-96 svg path { fill: #999999; } -.emotion-91:hover { +.emotion-96:hover { color: #666666; } -.emotion-91:hover svg path { +.emotion-96:hover svg path { fill: #666666; } -.emotion-91:active { +.emotion-96:active { color: #444444; } -.emotion-91:active svg path { +.emotion-96:active svg path { fill: #444444; } -.emotion-98 { +.emotion-103 { display: block; } -.emotion-97 { +.emotion-102 { font-size: 14px; padding: 3rem 20px; max-width: 600px; @@ -6152,7 +6152,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` display: flex; } -.emotion-88 { +.emotion-93 { display: grid; grid-template-columns: 1fr; grid-auto-rows: minmax(auto,auto); @@ -6274,7 +6274,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` width: 14px; } -.emotion-89 { +.emotion-94 { border: 0; border-radius: 3em; cursor: pointer; @@ -6315,7 +6315,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` z-index: 2; } -.emotion-89 svg { +.emotion-94 svg { display: inline-block; height: 14px; width: 14px; @@ -6326,29 +6326,29 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` pointer-events: none; } -.emotion-89 svg path { +.emotion-94 svg path { fill: currentColor; } -.emotion-89:hover { +.emotion-94:hover { background: #f2f2f2; } -.emotion-89:active { +.emotion-94:active { background: #FFFFFF; } -.emotion-89:focus { +.emotion-94:focus { box-shadow: rgba(30,167,253,0.4) 0 0 0 1px inset; } -.emotion-89:hover { +.emotion-94:hover { -webkit-transform: none; -ms-transform: none; transform: none; } -.emotion-100 { +.emotion-105 { width: 100%; height: 100%; box-sizing: border-box; @@ -6495,7 +6495,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` fill: currentColor; } -.emotion-99 { +.emotion-104 { display: block; position: relative; font-size: 13px; @@ -6508,7 +6508,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` overflow: auto; } -.emotion-99 > *:first-child { +.emotion-104 > *:first-child { position: absolute; left: 0; right: 0; @@ -6541,7 +6541,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` width: 15px; } -.emotion-96 { +.emotion-101 { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -6552,11 +6552,11 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` font-weight: 700; } -.emotion-96 > * + * { +.emotion-101 > * + * { margin-left: 20px; } -.emotion-91 { +.emotion-96 { display: inline-block; -webkit-transition: all 150ms ease-out; transition: all 150ms ease-out; @@ -6566,30 +6566,30 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` color: #999999; } -.emotion-91 svg path { +.emotion-96 svg path { fill: #1EA7FD; } -.emotion-91:hover, -.emotion-91:focus { +.emotion-96:hover, +.emotion-96:focus { cursor: pointer; color: #0297f5; } -.emotion-91:hover svg path, -.emotion-91:focus svg path { +.emotion-96:hover svg path, +.emotion-96:focus svg path { fill: #0297f5; } -.emotion-91:active { +.emotion-96:active { color: #028ee6; } -.emotion-91:active svg path { +.emotion-96:active svg path { fill: #028ee6; } -.emotion-91 svg { +.emotion-96 svg { display: inline-block; height: 1em; width: 1em; @@ -6599,31 +6599,31 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` margin-right: 0.4em; } -.emotion-91 svg path { +.emotion-96 svg path { fill: #999999; } -.emotion-91:hover { +.emotion-96:hover { color: #666666; } -.emotion-91:hover svg path { +.emotion-96:hover svg path { fill: #666666; } -.emotion-91:active { +.emotion-96:active { color: #444444; } -.emotion-91:active svg path { +.emotion-96:active svg path { fill: #444444; } -.emotion-98 { +.emotion-103 { display: block; } -.emotion-97 { +.emotion-102 { font-size: 14px; padding: 3rem 20px; max-width: 600px; @@ -6644,7 +6644,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` display: flex; } -.emotion-88 { +.emotion-93 { display: grid; grid-template-columns: 1fr; grid-auto-rows: minmax(auto,auto); @@ -6766,7 +6766,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` width: 14px; } -.emotion-89 { +.emotion-94 { border: 0; border-radius: 3em; cursor: pointer; @@ -6807,7 +6807,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` z-index: 2; } -.emotion-89 svg { +.emotion-94 svg { display: inline-block; height: 14px; width: 14px; @@ -6818,23 +6818,23 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` pointer-events: none; } -.emotion-89 svg path { +.emotion-94 svg path { fill: currentColor; } -.emotion-89:hover { +.emotion-94:hover { background: #f2f2f2; } -.emotion-89:active { +.emotion-94:active { background: #FFFFFF; } -.emotion-89:focus { +.emotion-94:focus { box-shadow: rgba(30,167,253,0.4) 0 0 0 1px inset; } -.emotion-89:hover { +.emotion-94:hover { -webkit-transform: none; -ms-transform: none; transform: none; @@ -6844,7 +6844,7 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = ` style="position:relative;height:calc(100vh);width:calc(100vw)" >
+
+
+ Toggle dark mode +
+ + + + +
@@ -7337,40 +7362,40 @@ exports[`Storyshots UI|Settings/ShortcutsScreen default shortcuts 1`] = `
Docs GitHub Support diff --git a/lib/ui/src/containers/nav.js b/lib/ui/src/containers/nav.js index eb611f12a24d..1266e5184566 100755 --- a/lib/ui/src/containers/nav.js +++ b/lib/ui/src/containers/nav.js @@ -9,7 +9,7 @@ import { shortcutToHumanString } from '../libs/shortcut'; import Sidebar from '../components/sidebar/Sidebar'; import { Consumer } from '../core/context'; -const createMenu = memoize(1)((api, shortcutKeys, isFullscreen, showPanel, showNav) => [ +const createMenu = memoize(1)((api, shortcutKeys, isFullscreen, isDarkMode, showPanel, showNav) => [ { id: 'S', title: 'Show sidebar', @@ -31,6 +31,13 @@ const createMenu = memoize(1)((api, shortcutKeys, isFullscreen, showPanel, showN right: shortcutToHumanString(shortcutKeys.panelPosition), left: , }, + { + id: 'M', + title: 'Toggle dark mode', + onClick: () => api.toggleDarkMode(), + right: shortcutToHumanString(shortcutKeys.toggleDarkMode), + left: isDarkMode ? : , + }, { id: 'F', title: 'Go full screen', @@ -94,7 +101,7 @@ export const mapper = (state, api) => { ui: { name, url }, viewMode, storyId, - layout: { isFullscreen, showPanel, showNav, panelPosition }, + layout: { isFullscreen, isDarkMode, showPanel, showNav, panelPosition }, storiesHash, storiesConfigured, } = state; @@ -107,7 +114,15 @@ export const mapper = (state, api) => { stories: storiesHash, storyId, viewMode, - menu: createMenu(api, shortcutKeys, isFullscreen, showPanel, showNav, panelPosition), + menu: createMenu( + api, + shortcutKeys, + isFullscreen, + isDarkMode, + showPanel, + showNav, + panelPosition + ), menuHighlighted: api.versionUpdateAvailable(), }; }; diff --git a/lib/ui/src/core/layout.js b/lib/ui/src/core/layout.js index d6bf8ef8ce9f..ec7b898b5959 100644 --- a/lib/ui/src/core/layout.js +++ b/lib/ui/src/core/layout.js @@ -74,6 +74,26 @@ export default function({ store }) { }); }, + toggleDarkMode(toggled) { + return store.setState(state => { + const isDarkMode = typeof toggled !== 'undefined' ? toggled : !state.layout.isDarkMode; + const newTheme = isDarkMode ? state.ui.darkTheme : state.ui.lightTheme; + + const updatedUi = { + ...state.ui, + theme: newTheme, + }; + + return { + layout: { + ...state.layout, + isDarkMode, + }, + ui: updatedUi, + }; + }); + }, + togglePanel(toggled) { return store.setState(state => { const value = typeof toggled !== 'undefined' ? toggled : !state.layout.showPanel; @@ -147,6 +167,10 @@ export default function({ store }) { ...checkDeprecatedThemeOptions(options), }; + if (updatedLayout.isDarkMode) { + updatedUi.theme = updatedUi.darkTheme; + } + store.setState( { layout: updatedLayout, @@ -167,8 +191,10 @@ export default function({ store }) { sortStoriesByKind: false, sidebarAnimations: true, theme: themes.normal, + darkTheme: themes.dark, }, layout: { + isDarkMode: false, isToolshown: true, isFullscreen: false, showPanel: true, @@ -178,6 +204,11 @@ export default function({ store }) { }; const state = merge(fromState, initial); + state.ui.lightTheme = state.ui.theme; + + if (state.layout.isDarkMode) { + state.ui.theme = themes.dark; + } return { api, state }; } diff --git a/lib/ui/src/core/shortcuts.js b/lib/ui/src/core/shortcuts.js index 9c07925da757..fc47551704a8 100644 --- a/lib/ui/src/core/shortcuts.js +++ b/lib/ui/src/core/shortcuts.js @@ -11,6 +11,7 @@ export const defaultShortcuts = Object.freeze({ fullScreen: ['F'], togglePanel: ['A'], panelPosition: ['D'], + toggleDarkMode: ['M'], toggleNav: ['S'], toolbar: ['T'], search: ['/'], @@ -166,6 +167,11 @@ export default function initShortcuts({ store }) { break; } + case 'toggleDarkMode': { + fullApi.toggleDarkMode(); + break; + } + case 'togglePanel': { if (isFullscreen) { fullApi.toggleFullscreen(); diff --git a/lib/ui/src/settings/shortcuts.js b/lib/ui/src/settings/shortcuts.js index d313cd5c57c7..bac4c462d04e 100644 --- a/lib/ui/src/settings/shortcuts.js +++ b/lib/ui/src/settings/shortcuts.js @@ -107,6 +107,7 @@ const shortcutLabels = { fullScreen: 'Go full screen', togglePanel: 'Toggle addons', panelPosition: 'Toggle addons orientation', + toggleDarkMode: 'Toggle dark mode', toggleNav: 'Toggle sidebar', toolbar: 'Toggle canvas toolbar', search: 'Focus search',