From ea49fb52fc35e92464ec319ba34e3e232085e2d3 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Tue, 24 Nov 2020 22:34:53 +0100 Subject: [PATCH] Theme Storybook with global dark and light theme (#14606) --- .storybook/main.js | 3 +- .storybook/manager-head.html | 2 + .storybook/preview-head.html | 10 - .storybook/preview.js | 29 +- .storybook/themes.js | 40 +++ .../branded/src/components/BrandedStory.tsx | 8 +- .../src/components/LoaderInput.story.tsx | 25 +- .../branded/src/components/Toggle.story.tsx | 19 +- .../src/components/ToggleBig.story.tsx | 19 +- .../activation/ActivationDropdown.story.tsx | 3 +- .../shared/src/hover/HoverOverlay.story.tsx | 338 ++++++++---------- .../notifications/NotificationItem.story.tsx | 4 +- client/web/src/components/WebStory.tsx | 12 +- .../campaigns/list/CampaignListPage.story.tsx | 2 +- .../campaigns/list/CampaignListPage.test.tsx | 2 +- .../campaigns/list/CampaignNode.story.tsx | 62 +--- .../src/enterprise/campaigns/list/testData.ts | 62 ++++ .../detail/CodeIntelIndexPage.story.tsx | 2 +- .../detail/CodeIntelUploadPage.story.tsx | 2 +- .../list/CodeIntelIndexesPage.story.tsx | 2 +- .../list/CodeIntelUploadsPage.story.tsx | 2 +- .../src/nav/VersionContextDropdown.story.tsx | 3 +- .../web/src/views/ChartViewContent.story.tsx | 4 +- jest.config.base.js | 1 + package.json | 5 +- ui/assets/img/wildcard-design-system.svg | 11 + yarn.lock | 22 +- 27 files changed, 357 insertions(+), 337 deletions(-) create mode 100644 .storybook/manager-head.html delete mode 100644 .storybook/preview-head.html create mode 100644 .storybook/themes.js create mode 100644 client/web/src/enterprise/campaigns/list/testData.ts create mode 100644 ui/assets/img/wildcard-design-system.svg diff --git a/.storybook/main.js b/.storybook/main.js index 388ceaa5465..659be03449e 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -10,7 +10,8 @@ const isChromatic = !!process.env.CHROMATIC const config = { stories: ['../client/**/*.story.tsx'], - addons: ['@storybook/addon-knobs', '@storybook/addon-actions', 'storybook-addon-designs'], + addons: ['@storybook/addon-knobs', '@storybook/addon-actions', 'storybook-addon-designs', 'storybook-dark-mode'], + /** * @param config {import('webpack').Configuration} * @returns {import('webpack').Configuration} diff --git a/.storybook/manager-head.html b/.storybook/manager-head.html new file mode 100644 index 00000000000..7236a973806 --- /dev/null +++ b/.storybook/manager-head.html @@ -0,0 +1,2 @@ + +Sourcegraph Wildcard design system diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html deleted file mode 100644 index 68a7e00861c..00000000000 --- a/.storybook/preview-head.html +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/.storybook/preview.js b/.storybook/preview.js index a6b88436d80..bebd106051a 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -6,11 +6,30 @@ import { withKnobs } from '@storybook/addon-knobs' import { setLinkComponent, AnchorLink } from '../client/shared/src/components/Link' import { withDesign } from 'storybook-addon-designs' import isChromatic from 'chromatic/isChromatic' +import * as themes from './themes' export const decorators = [withKnobs, withDesign, (storyFn, context) => withConsole()(storyFn)(context)] +export const parameters = { + darkMode: { + stylePreview: true, + darkClass: 'theme-dark', + lightClass: 'theme-light', + light: themes.light, + dark: themes.dark, + }, +} + +configureActions({ depth: 100, limit: 20 }) + setLinkComponent(AnchorLink) +// Default to light theme for Chromatic and "Open canvas in new tab" button. +// addon-dark-mode will override this if it's running. +if (!document.body.classList.contains('theme-dark')) { + document.body.classList.add('theme-light') +} + if (isChromatic()) { const style = document.createElement('style') style.innerHTML = ` @@ -21,4 +40,12 @@ if (isChromatic()) { document.head.append(style) } -configureActions({ depth: 100, limit: 20 }) +// @ts-ignore +window.MonacoEnvironment = { + getWorkerUrl(_, label) { + if (label === 'json') { + return '/json.worker.bundle.js' + } + return '/editor.worker.bundle.js' + }, +} diff --git a/.storybook/themes.js b/.storybook/themes.js new file mode 100644 index 00000000000..55666aeb9a3 --- /dev/null +++ b/.storybook/themes.js @@ -0,0 +1,40 @@ +import { themes } from '@storybook/theming' +import openColor from 'open-color' +// @ts-ignore +import brandImage from '../ui/assets/img/wildcard-design-system.svg' + +// Themes use the colors from our webapp. + +/** @type {Partial} */ +const common = { + colorPrimary: openColor.blue[6], + colorSecondary: openColor.blue[6], + brandImage, + brandTitle: 'Sourcegraph Wildcard design system', + fontBase: + '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"', + fontCode: 'sfmono-regular, consolas, menlo, dejavu sans mono, monospace', +} + +/** @type {import('@storybook/theming').ThemeVars} */ +export const dark = { + ...themes.dark, + ...common, + appBg: '#1c2736', + appContentBg: '#151c28', + appBorderColor: '#2b3750', + barBg: '#0e121b', + barTextColor: '#a2b0cd', + textColor: '#f2f4f8', + inputTextColor: '#ffffff', +} + +/** @type {import('@storybook/theming').ThemeVars} */ +export const light = { + ...themes.light, + ...common, + appBg: '#fbfdff', + textColor: '#2b3750', + barTextColor: '#566e9f', + inputTextColor: '#2b3750', +} diff --git a/client/branded/src/components/BrandedStory.tsx b/client/branded/src/components/BrandedStory.tsx index 6d06b6fae21..74ac19d1aac 100644 --- a/client/branded/src/components/BrandedStory.tsx +++ b/client/branded/src/components/BrandedStory.tsx @@ -1,9 +1,9 @@ -import { radios } from '@storybook/addon-knobs' import React from 'react' import { MemoryRouter, MemoryRouterProps } from 'react-router' import { ThemeProps } from '../../../shared/src/theme' import brandedStyles from '../global-styles/index.scss' import { Tooltip } from './tooltip/Tooltip' +import { useDarkMode } from 'storybook-dark-mode' export interface WebStoryProps extends MemoryRouterProps { children: React.FunctionComponent @@ -18,14 +18,12 @@ export const BrandedStory: React.FunctionComponent< styles?: string } > = ({ children, styles = brandedStyles, ...memoryRouterProps }) => { - const theme = radios('Theme', { Light: 'light', Dark: 'dark' }, 'light') - document.body.classList.toggle('theme-light', theme === 'light') - document.body.classList.toggle('theme-dark', theme === 'dark') + const isLightTheme = !useDarkMode() const Children = children return ( - + ) diff --git a/client/branded/src/components/LoaderInput.story.tsx b/client/branded/src/components/LoaderInput.story.tsx index d95e94a60cb..e04e91dfcce 100644 --- a/client/branded/src/components/LoaderInput.story.tsx +++ b/client/branded/src/components/LoaderInput.story.tsx @@ -1,5 +1,6 @@ +import { boolean } from '@storybook/addon-knobs' import { storiesOf } from '@storybook/react' -import React, { useCallback, useState } from 'react' +import React from 'react' import { LoaderInput } from './LoaderInput' import { BrandedStory } from './BrandedStory' @@ -11,22 +12,10 @@ const { add } = storiesOf('branded/LoaderInput', module).addDecorator(story => ( add('Interactive', () => ( - {() => { - const [loading, setLoading] = useState(true) - const toggleLoading = useCallback(() => setLoading(loading => !loading), []) - - return ( - <> - -

- - - -

- - ) - }} + {() => ( + + + + )}
)) diff --git a/client/branded/src/components/Toggle.story.tsx b/client/branded/src/components/Toggle.story.tsx index 8d5d6084a84..3d41e5efee5 100644 --- a/client/branded/src/components/Toggle.story.tsx +++ b/client/branded/src/components/Toggle.story.tsx @@ -3,22 +3,15 @@ import { storiesOf } from '@storybook/react' import React, { useState } from 'react' import { Toggle } from './Toggle' import webStyles from '../../../web/src/main.scss' -import { radios } from '@storybook/addon-knobs' const onToggle = action('onToggle') -const { add } = storiesOf('branded/Toggle', module).addDecorator(story => { - const theme = radios('Theme', { Light: 'light', Dark: 'dark' }, 'light') - document.body.classList.toggle('theme-light', theme === 'light') - document.body.classList.toggle('theme-dark', theme === 'dark') - - return ( - <> -
{story()}
- - - ) -}) +const { add } = storiesOf('branded/Toggle', module).addDecorator(story => ( + <> +
{story()}
+ + +)) add( 'Interactive', diff --git a/client/branded/src/components/ToggleBig.story.tsx b/client/branded/src/components/ToggleBig.story.tsx index 8582d81abb6..43625787253 100644 --- a/client/branded/src/components/ToggleBig.story.tsx +++ b/client/branded/src/components/ToggleBig.story.tsx @@ -3,22 +3,15 @@ import { storiesOf } from '@storybook/react' import React, { useState } from 'react' import { ToggleBig } from './ToggleBig' import webStyles from '../../../web/src/main.scss' -import { radios } from '@storybook/addon-knobs' const onToggle = action('onToggle') -const { add } = storiesOf('branded/ToggleBig', module).addDecorator(story => { - const theme = radios('Theme', { Light: 'light', Dark: 'dark' }, 'light') - document.body.classList.toggle('theme-light', theme === 'light') - document.body.classList.toggle('theme-dark', theme === 'dark') - - return ( - <> -
{story()}
- - - ) -}) +const { add } = storiesOf('branded/ToggleBig', module).addDecorator(story => ( + <> +
{story()}
+ + +)) add( 'Interactive', diff --git a/client/shared/src/components/activation/ActivationDropdown.story.tsx b/client/shared/src/components/activation/ActivationDropdown.story.tsx index cea435668b8..60fb8eb9860 100644 --- a/client/shared/src/components/activation/ActivationDropdown.story.tsx +++ b/client/shared/src/components/activation/ActivationDropdown.story.tsx @@ -11,7 +11,7 @@ import { subtypeOf } from '../../util/types' const { add } = storiesOf('shared/ActivationDropdown', module).addDecorator(story => ( <> -
{story()}
+
{story()}
)) @@ -52,7 +52,6 @@ const history = H.createMemoryHistory({ keyLength: 0 }) const commonProps = subtypeOf>()({ alwaysShow: true, history, - // Make sure the dropdown is not rendered outside the theme-light container portal: false, }) diff --git a/client/shared/src/hover/HoverOverlay.story.tsx b/client/shared/src/hover/HoverOverlay.story.tsx index 8886cf10669..a13013fae3b 100644 --- a/client/shared/src/hover/HoverOverlay.story.tsx +++ b/client/shared/src/hover/HoverOverlay.story.tsx @@ -118,265 +118,239 @@ const FIXTURE_ACTIONS = [ add('Loading', () => ( <> -
- -
+ )) add('Error', () => ( <> -
- -
+ )) add('Common content', () => ( <> -
- -
+ )) add('Legacy badge', () => ( <> -
- -
+ )) add('Only actions', () => ( <> -
- -
+ )) add('Long code', () => ( <> -
- -
+ )) add('Long text only', () => ( <> -
- -
+ )) add('Multiple MarkupContents', () => ( <> -
- -
+ )) add('With small-text alert', () => ( <> -
- This is a test alert. Enim esse quis commodo ex. Pariatur tempor laborum officiairure est do est laborum nostrud cillum. Cupidatat id consectetur et eiusmod Loremproident cupidatat ullamco dolor nostrud. Cupidatat sit do dolor aliqua labore adlaboris cillum deserunt dolor. Sunt labore veniam Lorem reprehenderit quis occaecatsint do mollit aliquip. Consectetur mollit mollit magna eiusmod duis ex. Sint nisilabore labore nulla laboris.', - }, - type: 'test-alert-type', + This is a test alert. Enim esse quis commodo ex. Pariatur tempor laborum officiairure est do est laborum nostrud cillum. Cupidatat id consectetur et eiusmod Loremproident cupidatat ullamco dolor nostrud. Cupidatat sit do dolor aliqua labore adlaboris cillum deserunt dolor. Sunt labore veniam Lorem reprehenderit quis occaecatsint do mollit aliquip. Consectetur mollit mollit magna eiusmod duis ex. Sint nisilabore labore nulla laboris.', }, - ], - }} - actionsOrError={FIXTURE_ACTIONS} - onAlertDismissed={action('onAlertDismissed')} - /> -
+ type: 'test-alert-type', + }, + ], + }} + actionsOrError={FIXTURE_ACTIONS} + onAlertDismissed={action('onAlertDismissed')} + /> )) add('With one-line alert', () => ( <> -
- -
+ }, + ], + }} + actionsOrError={FIXTURE_ACTIONS} + onAlertDismissed={action('onAlertDismissed')} + /> )) add('With badged alert', () => ( <> -
- -
+ badge: { + kind: 'info', + }, + }, + ], + }} + actionsOrError={FIXTURE_ACTIONS} + onAlertDismissed={action('onAlertDismissed')} + /> )) add('With badged dismissible alert', () => ( <> -
- -
+ type: 'test-alert-type', + badge: { + kind: 'info', + }, + }, + ], + }} + actionsOrError={FIXTURE_ACTIONS} + onAlertDismissed={action('onAlertDismissed')} + /> )) add('With long markdown text badged dismissible alert.', () => ( <> -
- -
+ type: 'test-alert-type', + badge: { + kind: 'info', + }, + }, + ], + }} + actionsOrError={FIXTURE_ACTIONS} + onAlertDismissed={action('onAlertDismissed')} + /> )) diff --git a/client/shared/src/notifications/NotificationItem.story.tsx b/client/shared/src/notifications/NotificationItem.story.tsx index efe26895566..2b45a408639 100644 --- a/client/shared/src/notifications/NotificationItem.story.tsx +++ b/client/shared/src/notifications/NotificationItem.story.tsx @@ -23,9 +23,7 @@ const { add } = storiesOf('shared/NotificationItem', module).addDecorator(story <> -
- {story()} -
+
{story()}
)) diff --git a/client/web/src/components/WebStory.tsx b/client/web/src/components/WebStory.tsx index 364cce7c483..a11a7b978d8 100644 --- a/client/web/src/components/WebStory.tsx +++ b/client/web/src/components/WebStory.tsx @@ -1,5 +1,5 @@ -import { radios } from '@storybook/addon-knobs' import React, { useMemo } from 'react' +import { useDarkMode } from 'storybook-dark-mode' import { MemoryRouter, MemoryRouterProps, RouteComponentProps, withRouter } from 'react-router' import { NOOP_TELEMETRY_SERVICE, TelemetryProps } from '../../../shared/src/telemetry/telemetryService' import { ThemeProps } from '../../../shared/src/theme' @@ -22,19 +22,13 @@ export const WebStory: React.FunctionComponent< webStyles?: string } > = ({ children, webStyles = _webStyles, ...memoryRouterProps }) => { - const theme = radios('Theme', { Light: 'light', Dark: 'dark' }, 'light') - document.body.classList.toggle('theme-light', theme === 'light') - document.body.classList.toggle('theme-dark', theme === 'dark') + const isLightTheme = !useDarkMode() const breadcrumbSetters = useBreadcrumbs() const Children = useMemo(() => withRouter(children), [children]) return ( - + ) diff --git a/client/web/src/enterprise/campaigns/list/CampaignListPage.story.tsx b/client/web/src/enterprise/campaigns/list/CampaignListPage.story.tsx index f43997ddc1e..68967fcaa08 100644 --- a/client/web/src/enterprise/campaigns/list/CampaignListPage.story.tsx +++ b/client/web/src/enterprise/campaigns/list/CampaignListPage.story.tsx @@ -1,7 +1,7 @@ import { storiesOf } from '@storybook/react' import React from 'react' import { CampaignListPage } from './CampaignListPage' -import { nodes } from './CampaignNode.story' +import { nodes } from './testData' import { of } from 'rxjs' import { EnterpriseWebStory } from '../../components/EnterpriseWebStory' import { useCallback } from '@storybook/addons' diff --git a/client/web/src/enterprise/campaigns/list/CampaignListPage.test.tsx b/client/web/src/enterprise/campaigns/list/CampaignListPage.test.tsx index 72f58c1f857..62c9a401eae 100644 --- a/client/web/src/enterprise/campaigns/list/CampaignListPage.test.tsx +++ b/client/web/src/enterprise/campaigns/list/CampaignListPage.test.tsx @@ -4,7 +4,7 @@ import { CampaignListPage } from './CampaignListPage' import { NOOP_TELEMETRY_SERVICE } from '../../../../../shared/src/telemetry/telemetryService' import { of } from 'rxjs' import { shallow } from 'enzyme' -import { nodes } from './CampaignNode.story' +import { nodes } from './testData' const history = H.createMemoryHistory() diff --git a/client/web/src/enterprise/campaigns/list/CampaignNode.story.tsx b/client/web/src/enterprise/campaigns/list/CampaignNode.story.tsx index b10c1073ac5..3c760e5bf47 100644 --- a/client/web/src/enterprise/campaigns/list/CampaignNode.story.tsx +++ b/client/web/src/enterprise/campaigns/list/CampaignNode.story.tsx @@ -3,69 +3,9 @@ import { boolean } from '@storybook/addon-knobs' import React from 'react' import { CampaignNode } from './CampaignNode' import isChromatic from 'chromatic/isChromatic' -import { ListCampaign } from '../../../graphql-operations' import { subDays } from 'date-fns' import { EnterpriseWebStory } from '../../components/EnterpriseWebStory' - -const now = new Date() - -export const nodes: Record = { - 'Open campaign': { - id: 'test', - url: '/users/alice/campaigns/test', - name: 'Awesome campaign', - description: `# What this does - -This is my thorough explanation. And it can also get very long, in that case the UI doesn't break though, which is good. And one more line to finally be longer than the viewport.`, - createdAt: subDays(now, 5).toISOString(), - closedAt: null, - changesetsStats: { - open: 10, - closed: 0, - merged: 5, - }, - namespace: { - namespaceName: 'alice', - url: '/users/alice', - }, - }, - 'No description': { - id: 'test2', - url: '/users/alice/campaigns/test2', - name: 'Awesome campaign', - description: null, - createdAt: subDays(now, 5).toISOString(), - closedAt: null, - changesetsStats: { - open: 10, - closed: 0, - merged: 5, - }, - namespace: { - namespaceName: 'alice', - url: '/users/alice', - }, - }, - 'Closed campaign': { - id: 'test3', - url: '/users/alice/campaigns/test3', - name: 'Awesome campaign', - description: `# My campaign - - This is my thorough explanation.`, - createdAt: subDays(now, 5).toISOString(), - closedAt: subDays(now, 3).toISOString(), - changesetsStats: { - open: 0, - closed: 10, - merged: 5, - }, - namespace: { - namespaceName: 'alice', - url: '/users/alice', - }, - }, -} +import { nodes, now } from './testData' const { add } = storiesOf('web/campaigns/CampaignNode', module).addDecorator(story => (
{story()}
diff --git a/client/web/src/enterprise/campaigns/list/testData.ts b/client/web/src/enterprise/campaigns/list/testData.ts new file mode 100644 index 00000000000..cbadf42c053 --- /dev/null +++ b/client/web/src/enterprise/campaigns/list/testData.ts @@ -0,0 +1,62 @@ +import { subDays } from 'date-fns' +import { ListCampaign } from '../../../graphql-operations' + +export const now = new Date() + +export const nodes: Record = { + 'Open campaign': { + id: 'test', + url: '/users/alice/campaigns/test', + name: 'Awesome campaign', + description: `# What this does + +This is my thorough explanation. And it can also get very long, in that case the UI doesn't break though, which is good. And one more line to finally be longer than the viewport.`, + createdAt: subDays(now, 5).toISOString(), + closedAt: null, + changesetsStats: { + open: 10, + closed: 0, + merged: 5, + }, + namespace: { + namespaceName: 'alice', + url: '/users/alice', + }, + }, + 'No description': { + id: 'test2', + url: '/users/alice/campaigns/test2', + name: 'Awesome campaign', + description: null, + createdAt: subDays(now, 5).toISOString(), + closedAt: null, + changesetsStats: { + open: 10, + closed: 0, + merged: 5, + }, + namespace: { + namespaceName: 'alice', + url: '/users/alice', + }, + }, + 'Closed campaign': { + id: 'test3', + url: '/users/alice/campaigns/test3', + name: 'Awesome campaign', + description: `# My campaign + + This is my thorough explanation.`, + createdAt: subDays(now, 5).toISOString(), + closedAt: subDays(now, 3).toISOString(), + changesetsStats: { + open: 0, + closed: 10, + merged: 5, + }, + namespace: { + namespaceName: 'alice', + url: '/users/alice', + }, + }, +} diff --git a/client/web/src/enterprise/codeintel/detail/CodeIntelIndexPage.story.tsx b/client/web/src/enterprise/codeintel/detail/CodeIntelIndexPage.story.tsx index 212155ea654..c0d76f2d1b7 100644 --- a/client/web/src/enterprise/codeintel/detail/CodeIntelIndexPage.story.tsx +++ b/client/web/src/enterprise/codeintel/detail/CodeIntelIndexPage.story.tsx @@ -13,7 +13,7 @@ window.context = {} as SourcegraphContext & SuiteFunction const { add } = storiesOf('web/Codeintel administration/CodeIntelIndex', module).addDecorator(story => ( <> -
{story()}
+
{story()}
)) diff --git a/client/web/src/enterprise/codeintel/detail/CodeIntelUploadPage.story.tsx b/client/web/src/enterprise/codeintel/detail/CodeIntelUploadPage.story.tsx index c3f4d6085fc..b1f821f8f38 100644 --- a/client/web/src/enterprise/codeintel/detail/CodeIntelUploadPage.story.tsx +++ b/client/web/src/enterprise/codeintel/detail/CodeIntelUploadPage.story.tsx @@ -13,7 +13,7 @@ window.context = {} as SourcegraphContext & SuiteFunction const { add } = storiesOf('web/Codeintel administration/CodeIntelUpload', module).addDecorator(story => ( <> -
{story()}
+
{story()}
)) diff --git a/client/web/src/enterprise/codeintel/list/CodeIntelIndexesPage.story.tsx b/client/web/src/enterprise/codeintel/list/CodeIntelIndexesPage.story.tsx index 82d7991c1f2..1d3cfbca098 100644 --- a/client/web/src/enterprise/codeintel/list/CodeIntelIndexesPage.story.tsx +++ b/client/web/src/enterprise/codeintel/list/CodeIntelIndexesPage.story.tsx @@ -13,7 +13,7 @@ window.context = {} as SourcegraphContext & SuiteFunction const { add } = storiesOf('web/Codeintel administration/CodeIntelIndexes', module).addDecorator(story => ( <> -
{story()}
+
{story()}
)) diff --git a/client/web/src/enterprise/codeintel/list/CodeIntelUploadsPage.story.tsx b/client/web/src/enterprise/codeintel/list/CodeIntelUploadsPage.story.tsx index 9a1ea9b1104..ce2628dcd74 100644 --- a/client/web/src/enterprise/codeintel/list/CodeIntelUploadsPage.story.tsx +++ b/client/web/src/enterprise/codeintel/list/CodeIntelUploadsPage.story.tsx @@ -13,7 +13,7 @@ window.context = {} as SourcegraphContext & SuiteFunction const { add } = storiesOf('web/Codeintel administration/CodeIntelUploads', module).addDecorator(story => ( <> -
{story()}
+
{story()}
)) diff --git a/client/web/src/nav/VersionContextDropdown.story.tsx b/client/web/src/nav/VersionContextDropdown.story.tsx index 01e994f6e3e..054f6c92804 100644 --- a/client/web/src/nav/VersionContextDropdown.story.tsx +++ b/client/web/src/nav/VersionContextDropdown.story.tsx @@ -8,7 +8,7 @@ import { SearchPatternType } from '../graphql-operations' import { WebStory } from '../components/WebStory' const { add } = storiesOf('web/VersionContextDropdown', module).addDecorator(story => ( - {webProps => story()} + {() => story()} )) const setVersionContext = action('setVersionContext') @@ -16,7 +16,6 @@ const history = H.createMemoryHistory({ keyLength: 0 }) const commonProps = subtypeOf>()({ alwaysShow: true, history, - // Make sure the dropdown is not rendered outside the theme-light container portal: false, caseSensitive: false, patternType: SearchPatternType.literal, diff --git a/client/web/src/views/ChartViewContent.story.tsx b/client/web/src/views/ChartViewContent.story.tsx index d876bd1b34b..cfd6d50c917 100644 --- a/client/web/src/views/ChartViewContent.story.tsx +++ b/client/web/src/views/ChartViewContent.story.tsx @@ -17,9 +17,7 @@ const { add } = storiesOf('web/ChartViewContent', module).addDecorator(story => <> {/* Chart will always fill the container, so we need to give the container an explicit size. */} -
- {story()} -
+
{story()}
)) diff --git a/jest.config.base.js b/jest.config.base.js index be9248f72ca..05694c1271e 100644 --- a/jest.config.base.js +++ b/jest.config.base.js @@ -37,6 +37,7 @@ const config = { moduleNameMapper: { '\\.s?css$': 'identity-obj-proxy', '\\.ya?ml$': 'identity-obj-proxy', + '\\.svg$': 'identity-obj-proxy', '^worker-loader': 'identity-obj-proxy', // monaco-editor uses the "module" field in package.json, which isn't supported by Jest // https://github.com/facebook/jest/issues/2702 diff --git a/package.json b/package.json index 57552a82950..2e5b159e3a1 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "cover-integration": "nyc --hook-require=false yarn test-integration", "test-e2e": "TS_NODE_PROJECT=client/web/src/end-to-end/tsconfig.json mocha ./client/web/src/end-to-end/end-to-end.test.ts", "cover-e2e": "nyc --hook-require=false yarn test-e2e", - "storybook": "start-storybook -p 9001 -c .storybook", - "build-storybook": "build-storybook -c .storybook", + "storybook": "start-storybook -p 9001 -c .storybook -s ui/assets", + "build-storybook": "build-storybook -c .storybook -s ui/assets", "cover-storybook": "nyc --hook-require=false yarn jest .storybook/coverage", "deduplicate": "yarn-deduplicate -s fewer" }, @@ -234,6 +234,7 @@ "socket.io": "^2.3.0", "socket.io-client": "^2.3.0", "storybook-addon-designs": "^5.4.2", + "storybook-dark-mode": "^1.0.3", "string-width": "^4.2.0", "style-loader": "^2.0.0", "stylelint": "^13.7.2", diff --git a/ui/assets/img/wildcard-design-system.svg b/ui/assets/img/wildcard-design-system.svg new file mode 100644 index 00000000000..3221e968176 --- /dev/null +++ b/ui/assets/img/wildcard-design-system.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/yarn.lock b/yarn.lock index 08d0e776d78..2870c266a77 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2817,7 +2817,8 @@ integrity sha512-KWxkyphmlwam8kfYPSmoitKQRMGQCsr1ZRmNZgijT7ABKaVyk/+I5ezt2J213tM04Hi0vyg4L7iH1VCkNvm2Jw== "@sourcegraph/extension-api-types@link:client/packages/@sourcegraph/extension-api-types": - version "2.1.0" + version "0.0.0" + uid "" "@sourcegraph/prettierrc@^3.0.3": version "3.0.3" @@ -10427,10 +10428,10 @@ fancy-log@^1.3.2, fancy-log@^1.3.3: parse-node-version "^1.0.0" time-stamp "^1.0.0" -fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== +fast-deep-equal@^3.0.0, fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^2.0.2, fast-glob@^2.2.6: version "2.2.7" @@ -20859,7 +20860,8 @@ sourcegraph@^24.0.0: integrity sha512-PlGvkdBy5r5iHdKAVNY/jsPgWb3oY+2iAdIQ3qR83UHhvBFVgoctDAnyfJ1eMstENY3etBWtAJ8Kleoar3ecaA== "sourcegraph@link:client/packages/sourcegraph-extension-api": - version "24.7.0" + version "0.0.0" + uid "" space-separated-tokens@^1.0.0: version "1.1.2" @@ -21105,6 +21107,14 @@ storybook-addon-designs@^5.4.2: dependencies: react-pdf "^4.0.5" +storybook-dark-mode@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/storybook-dark-mode/-/storybook-dark-mode-1.0.3.tgz#8d58a874b6107ff1a7f29ebb0e6726b8036eee08" + integrity sha512-mjHLrv/dwtqKmbOoQ2CMtGKDttWSnUybutujsIPxLcEC77EujjWiRBFv46LtXAZEyZLm8sGFUz0s6HJJfJ3tSw== + dependencies: + fast-deep-equal "^3.0.0" + memoizerific "^1.11.3" + stream-browserify@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db"