From c0eef1af92e71b40631ad669af18933705af9739 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 25 Nov 2022 13:14:14 +1100 Subject: [PATCH 01/10] POC: using targetted styles, not components to style MDX --- code/ui/blocks/src/components/DocsPage.tsx | 54 ++++++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index 651c8c9c6a4f..f36240fa4456 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -45,16 +45,52 @@ export const DocsContent = styled.div({ width: '100%', }); -export const DocsWrapper = styled.div(({ theme }) => ({ - background: theme.background.content, - display: 'flex', - justifyContent: 'center', - padding: '4rem 20px', - minHeight: '100vh', - boxSizing: 'border-box', +export const DocsWrapper = styled.div(({ theme }) => { + const reset = { + fontFamily: theme.typography.fonts.base, + fontSize: theme.typography.size.s3, + margin: 0, - [`@media (min-width: ${breakpoint}px)`]: {}, -})); + WebkitFontSmoothing: 'antialiased', + MozOsxFontSmoothing: 'grayscale', + WebkitTapHighlightColor: 'rgba(0, 0, 0, 0)', + WebkitOverflowScrolling: 'touch', + }; + + return { + background: theme.background.content, + display: 'flex', + justifyContent: 'center', + padding: '4rem 20px', + minHeight: '100vh', + boxSizing: 'border-box', + + [`@media (min-width: ${breakpoint}px)`]: {}, + ...reset, + 'div:not(.sb-story > div)': reset, + 'a:not(.sb-story > a)': { + ...reset, + fontSize: 'inherit', + lineHeight: '24px', + + color: theme.color.secondary, + textDecoration: 'none', + '&.absent': { + color: '#cc0000', + }, + '&.anchor': { + display: 'block', + paddingLeft: 30, + marginLeft: -30, + cursor: 'pointer', + position: 'absolute', + top: 0, + left: 0, + bottom: 0, + }, + }, + }; +}); interface DocsPageWrapperProps { children?: React.ReactNode; From 23d345278e32158aeafa1edfefb5c89180551d83 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 25 Nov 2022 10:26:25 +0100 Subject: [PATCH 02/10] fix types --- code/ui/blocks/src/components/DocsPage.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index f36240fa4456..83c31abb2fff 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -1,4 +1,5 @@ import { withReset } from '@storybook/components'; +import type { CSSObject } from '@storybook/theming'; import { styled } from '@storybook/theming'; import { transparentize } from 'polished'; import type { FC } from 'react'; @@ -54,7 +55,7 @@ export const DocsWrapper = styled.div(({ theme }) => { WebkitFontSmoothing: 'antialiased', MozOsxFontSmoothing: 'grayscale', WebkitTapHighlightColor: 'rgba(0, 0, 0, 0)', - WebkitOverflowScrolling: 'touch', + WebkitOverflowScrolling: 'touch' as CSSObject['WebkitOverflowScrolling'], }; return { From b0fa9d707fc0c9328b6053d741f37a17cd657e8d Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 29 Nov 2022 21:19:45 +0100 Subject: [PATCH 03/10] migrate all custom component styles to global styles --- code/addons/docs/src/DocsRenderer.tsx | 2 - code/ui/.storybook/main.ts | 1 + .../src/components/DocsPage.stories.tsx | 26 ++ code/ui/blocks/src/components/DocsPage.tsx | 346 +++++++++++++++++- 4 files changed, 371 insertions(+), 4 deletions(-) diff --git a/code/addons/docs/src/DocsRenderer.tsx b/code/addons/docs/src/DocsRenderer.tsx index 3dfcb3fe69d7..c3784fa3e2cc 100644 --- a/code/addons/docs/src/DocsRenderer.tsx +++ b/code/addons/docs/src/DocsRenderer.tsx @@ -1,13 +1,11 @@ import React from 'react'; import ReactDOM from 'react-dom'; import type { Renderer, Parameters, DocsContextProps, DocsRenderFunction } from '@storybook/types'; -import { components as htmlComponents } from '@storybook/components'; import { Docs, CodeOrSourceMdx, AnchorMdx, HeadersMdx } from '@storybook/blocks'; import { MDXProvider } from '@mdx-js/react'; // TS doesn't like that we export a component with types that it doesn't know about (TS4203) export const defaultComponents: Record = { - ...htmlComponents, code: CodeOrSourceMdx, a: AnchorMdx, ...HeadersMdx, diff --git a/code/ui/.storybook/main.ts b/code/ui/.storybook/main.ts index cc95657abc94..5f91fadc8065 100644 --- a/code/ui/.storybook/main.ts +++ b/code/ui/.storybook/main.ts @@ -5,6 +5,7 @@ import type { StorybookConfig } from '../../frameworks/react-vite/dist'; const isBlocksOnly = process.env.STORYBOOK_BLOCKS_ONLY === 'true'; const allStories = [ + '../../lib/cli/rendererAssets/common/Introduction.stories.mdx', { directory: '../manager/src', titlePrefix: '@storybook-manager', diff --git a/code/ui/blocks/src/components/DocsPage.stories.tsx b/code/ui/blocks/src/components/DocsPage.stories.tsx index e8453029f20b..51cf15aa1fcd 100644 --- a/code/ui/blocks/src/components/DocsPage.stories.tsx +++ b/code/ui/blocks/src/components/DocsPage.stories.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/anchor-is-valid */ import type { ComponentProps } from 'react'; import React from 'react'; import { Global, css } from '@storybook/theming'; @@ -95,3 +96,28 @@ export const Markdown = () => ( ); + +export const Html = { + name: 'HTML', + render: () => ( + +

Heading 1

+

Heading 2

+ A tag +
pre tag
+
+
Div
+ Nested A tag +
+
+

Unstyled content

+

Heading 2

+ A tag +
+
Div
+ Nested A tag +
+
+
+ ), +}; diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index 83c31abb2fff..1a00a17b8e4d 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -5,6 +5,20 @@ import { transparentize } from 'polished'; import type { FC } from 'react'; import React from 'react'; +/** + * This selector styles all raw elements inside the DocsPage like this example with a `

`: + * :where(p:not(:where(.sb-canvas, .sb-unstyled) p)) + * + * 1. first ':where' ensures this has a specificity of 0, making it easy to override. + * 2. p:not(...) selects all p elements... + * 3. :where(.sb-canvas, .sb-unstyled) p ...that are not inside a .sb-canvas or .sb-unstyled, it is a shorthand for 'sb-canvas p, .sb-unstyled p' + * 4. .sb-canvas ensures that the styles are not applied to any of the stories. + * 5. .sb-unstyled is an escape hatch that allows the user to opt-out of the default styles + * by wrapping their content in an element with this class. + */ +const toGlobalSelector = (element: string): string => + `& :where(${element}:not(:where(.sb-canvas, .sb-unstyled) ${element}))`; + const breakpoint = 600; export interface DocsPageProps { @@ -57,6 +71,42 @@ export const DocsWrapper = styled.div(({ theme }) => { WebkitTapHighlightColor: 'rgba(0, 0, 0, 0)', WebkitOverflowScrolling: 'touch' as CSSObject['WebkitOverflowScrolling'], }; + const headers = { + margin: '20px 0 8px', + padding: 0, + cursor: 'text', + position: 'relative', + color: theme.color.defaultText, + '&:first-of-type': { + marginTop: 0, + paddingTop: 0, + }, + '&:hover a.anchor': { + textDecoration: 'none', + }, + '& code': { + fontSize: 'inherit', + }, + }; + const code = { + lineHeight: 1, + margin: '0 2px', + padding: '3px 5px', + whiteSpace: 'nowrap', + + borderRadius: 3, + fontSize: theme.typography.size.s2 - 1, + + border: + theme.base === 'light' + ? `1px solid ${theme.color.mediumlight}` + : `1px solid ${theme.color.darker}`, + color: + theme.base === 'light' + ? transparentize(0.1, theme.color.defaultText) + : transparentize(0.3, theme.color.defaultText), + backgroundColor: theme.base === 'light' ? theme.color.lighter : theme.color.border, + }; return { background: theme.background.content, @@ -68,8 +118,7 @@ export const DocsWrapper = styled.div(({ theme }) => { [`@media (min-width: ${breakpoint}px)`]: {}, ...reset, - 'div:not(.sb-story > div)': reset, - 'a:not(.sb-story > a)': { + [toGlobalSelector('a')]: { ...reset, fontSize: 'inherit', lineHeight: '24px', @@ -90,6 +139,299 @@ export const DocsWrapper = styled.div(({ theme }) => { bottom: 0, }, }, + [toGlobalSelector('blockquote')]: { + ...reset, + margin: '16px 0', + borderLeft: `4px solid ${theme.color.medium}`, + padding: '0 15px', + color: theme.color.dark, + '& > :first-of-type': { + marginTop: 0, + }, + '& > :last-child': { + marginBottom: 0, + }, + }, + [toGlobalSelector('div')]: reset, + [toGlobalSelector('dl')]: { + ...reset, + margin: '16px 0', + padding: 0, + '& dt': { + fontSize: '14px', + fontWeight: 'bold', + fontStyle: 'italic', + padding: 0, + margin: '16px 0 4px', + }, + '& dt:first-of-type': { + padding: 0, + }, + '& dt > :first-of-type': { + marginTop: 0, + }, + + '& dt > :last-child': { + marginBottom: 0, + }, + + '& dd': { + margin: '0 0 16px', + padding: '0 15px', + }, + + '& dd > :first-of-type': { + marginTop: 0, + }, + + '& dd > :last-child': { + marginBottom: 0, + }, + }, + [toGlobalSelector('h1')]: { + ...reset, + ...headers, + fontSize: `${theme.typography.size.l1}px`, + fontWeight: theme.typography.weight.black, + }, + [toGlobalSelector('h2')]: { + ...reset, + ...headers, + fontSize: `${theme.typography.size.m2}px`, + paddingBottom: 4, + borderBottom: `1px solid ${theme.appBorderColor}`, + }, + [toGlobalSelector('h3')]: { + ...reset, + ...headers, + fontSize: `${theme.typography.size.m1}px`, + }, + [toGlobalSelector('h4')]: { + ...reset, + ...headers, + fontSize: `${theme.typography.size.s3}px`, + }, + [toGlobalSelector('h5')]: { + ...reset, + ...headers, + fontSize: `${theme.typography.size.s2}px`, + }, + [toGlobalSelector('h6')]: { + ...reset, + ...headers, + fontSize: `${theme.typography.size.s2}px`, + color: theme.color.dark, + }, + [toGlobalSelector('hr')]: { + border: '0 none', + borderTop: `1px solid ${theme.appBorderColor}`, + height: 4, + padding: 0, + }, + [toGlobalSelector('img')]: { + maxWidth: '100%', + }, + [toGlobalSelector('li')]: { + ...reset, + fontSize: theme.typography.size.s2, + color: theme.color.defaultText, + lineHeight: '24px', + '& + li': { + marginTop: '.25em', + }, + '& ul, & ol': { + marginTop: '.25em', + marginBottom: 0, + }, + '& code': code, + }, + [toGlobalSelector('ol')]: { + ...reset, + margin: '16px 0', + paddingLeft: 30, + '& :first-of-type': { + marginTop: 0, + }, + '& :last-child': { + marginBottom: 0, + }, + }, + [toGlobalSelector('p')]: { + ...reset, + margin: '16px 0', + fontSize: theme.typography.size.s2, + lineHeight: '24px', + color: theme.color.defaultText, + '& code': code, + }, + [toGlobalSelector('pre')]: { + ...reset, + // reset + fontFamily: theme.typography.fonts.mono, + WebkitFontSmoothing: 'antialiased', + MozOsxFontSmoothing: 'grayscale', + lineHeight: '18px', + padding: '11px 1rem', + whiteSpace: 'pre-wrap', + color: 'inherit', + borderRadius: 3, + margin: '1rem 0', + + '&:not(.prismjs)': { + background: 'transparent', + border: 'none', + borderRadius: 0, + padding: 0, + margin: 0, + }, + '& pre, &.prismjs': { + padding: 15, + margin: 0, + whiteSpace: 'pre-wrap', + color: 'inherit', + fontSize: '13px', + lineHeight: '19px', + code: { + color: 'inherit', + fontSize: 'inherit', + }, + }, + '& code': { + whiteSpace: 'pre', + }, + '& code, & tt': { + border: 'none', + }, + }, + [toGlobalSelector('span')]: { + ...reset, + '&.frame': { + display: 'block', + overflow: 'hidden', + + '& > span': { + border: `1px solid ${theme.color.medium}`, + display: 'block', + float: 'left', + overflow: 'hidden', + margin: '13px 0 0', + padding: 7, + width: 'auto', + }, + '& span img': { + display: 'block', + float: 'left', + }, + '& span span': { + clear: 'both', + color: theme.color.darkest, + display: 'block', + padding: '5px 0 0', + }, + }, + '&.align-center': { + display: 'block', + overflow: 'hidden', + clear: 'both', + + '& > span': { + display: 'block', + overflow: 'hidden', + margin: '13px auto 0', + textAlign: 'center', + }, + '& span img': { + margin: '0 auto', + textAlign: 'center', + }, + }, + '&.align-right': { + display: 'block', + overflow: 'hidden', + clear: 'both', + + '& > span': { + display: 'block', + overflow: 'hidden', + margin: '13px 0 0', + textAlign: 'right', + }, + '& span img': { + margin: 0, + textAlign: 'right', + }, + }, + '&.float-left': { + display: 'block', + marginRight: 13, + overflow: 'hidden', + float: 'left', + '& span': { + margin: '13px 0 0', + }, + }, + '&.float-right': { + display: 'block', + marginLeft: 13, + overflow: 'hidden', + float: 'right', + + '& > span': { + display: 'block', + overflow: 'hidden', + margin: '13px auto 0', + textAlign: 'right', + }, + }, + }, + [toGlobalSelector('table')]: { + ...reset, + margin: '16px 0', + fontSize: theme.typography.size.s2, + lineHeight: '24px', + padding: 0, + borderCollapse: 'collapse', + '& tr': { + borderTop: `1px solid ${theme.appBorderColor}`, + backgroundColor: theme.appContentBg, + margin: 0, + padding: 0, + }, + '& tr:nth-of-type(2n)': { + backgroundColor: theme.base === 'dark' ? theme.color.darker : theme.color.lighter, + }, + '& tr th': { + fontWeight: 'bold', + color: theme.color.defaultText, + border: `1px solid ${theme.appBorderColor}`, + margin: 0, + padding: '6px 13px', + }, + '& tr td': { + border: `1px solid ${theme.appBorderColor}`, + color: theme.color.defaultText, + margin: 0, + padding: '6px 13px', + }, + '& tr th :first-of-type, & tr td :first-of-type': { + marginTop: 0, + }, + '& tr th :last-child, & tr td :last-child': { + marginBottom: 0, + }, + }, + [toGlobalSelector('ul')]: { + ...reset, + margin: '16px 0', + paddingLeft: 30, + '& :first-of-type': { + marginTop: 0, + }, + '& :last-child': { + marginBottom: 0, + }, + listStyle: 'disc', + }, }; }); From 5e4226da4bedf4d577fcb98a7fa74c9948e0b0a0 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 30 Nov 2022 00:45:35 +0100 Subject: [PATCH 04/10] Move styles to DocsContent, add .sb-story to Story block --- code/ui/blocks/src/blocks/Story.tsx | 2 +- code/ui/blocks/src/components/DocsPage.tsx | 49 ++++++++++++---------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/code/ui/blocks/src/blocks/Story.tsx b/code/ui/blocks/src/blocks/Story.tsx index 53f29b738535..5e5abfde5080 100644 --- a/code/ui/blocks/src/blocks/Story.tsx +++ b/code/ui/blocks/src/blocks/Story.tsx @@ -112,7 +112,7 @@ const Story: FC = (props) => { // FIXME: height/style/etc. lifted from PureStory const { height } = storyProps; return ( -

+
{height ? ( ) : null} diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index 1a00a17b8e4d..0e6287c02261 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -6,18 +6,22 @@ import type { FC } from 'react'; import React from 'react'; /** - * This selector styles all raw elements inside the DocsPage like this example with a `

`: - * :where(p:not(:where(.sb-canvas, .sb-unstyled) p)) + * This selector styles all raw elements inside the DocsPage like this example with a `

`: + * :where(div:not(.sb-unstyled, .sb-canvas... :where(.sb-unstyled, .sb-canvas...) div)) * - * 1. first ':where' ensures this has a specificity of 0, making it easy to override. - * 2. p:not(...) selects all p elements... - * 3. :where(.sb-canvas, .sb-unstyled) p ...that are not inside a .sb-canvas or .sb-unstyled, it is a shorthand for 'sb-canvas p, .sb-unstyled p' - * 4. .sb-canvas ensures that the styles are not applied to any of the stories. - * 5. .sb-unstyled is an escape hatch that allows the user to opt-out of the default styles - * by wrapping their content in an element with this class. + * 1. first ':where': ensures this has a specificity of 0, making it easy to override. + * 2. 'div:not(...)': selects all div elements that are not... + * 3. '.sb-unstyled, .sb-canvas...': any of the elements we don't want to style + * 3. ':where(.sb-unstyled, .sb-canvas...) div': or are descendants of an .sb-unstyled or .sb-canvas, etc. It is a shorthand for '.sb-unstyled div, sb-canvas div...' + * 4. .sb-unstyled is an escape hatch that allows the user to opt-out of the default styles + * by wrapping their content in an element with this class: + * 5. the other UNSTYLED_SELECTORS are elements we don't want the styles to bleed into, like canvas, story and source blocks. */ +const UNSTYLED_SELECTORS = ['.sb-unstyled', '.sb-canvas', '.sb-story', '.docblock-source'].join( + ', ' +); const toGlobalSelector = (element: string): string => - `& :where(${element}:not(:where(.sb-canvas, .sb-unstyled) ${element}))`; + `& :where(${element}:not(${UNSTYLED_SELECTORS}, :where(${UNSTYLED_SELECTORS}) ${element}))`; const breakpoint = 600; @@ -55,12 +59,7 @@ export const Subtitle = styled.h2(withReset, ({ theme }) => ({ color: transparentize(0.25, theme.color.defaultText), })); -export const DocsContent = styled.div({ - maxWidth: 1000, - width: '100%', -}); - -export const DocsWrapper = styled.div(({ theme }) => { +export const DocsContent = styled.div(({ theme }) => { const reset = { fontFamily: theme.typography.fonts.base, fontSize: theme.typography.size.s3, @@ -109,14 +108,9 @@ export const DocsWrapper = styled.div(({ theme }) => { }; return { - background: theme.background.content, - display: 'flex', - justifyContent: 'center', - padding: '4rem 20px', - minHeight: '100vh', - boxSizing: 'border-box', + maxWidth: 1000, + width: '100%', - [`@media (min-width: ${breakpoint}px)`]: {}, ...reset, [toGlobalSelector('a')]: { ...reset, @@ -435,6 +429,17 @@ export const DocsWrapper = styled.div(({ theme }) => { }; }); +export const DocsWrapper = styled.div(({ theme }) => ({ + background: theme.background.content, + display: 'flex', + justifyContent: 'center', + padding: '4rem 20px', + minHeight: '100vh', + boxSizing: 'border-box', + + [`@media (min-width: ${breakpoint}px)`]: {}, +})); + interface DocsPageWrapperProps { children?: React.ReactNode; } From 5291762060c803027a7dba40f3e93bd727379d58 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 30 Nov 2022 00:46:23 +0100 Subject: [PATCH 05/10] build Unstyled block, prettier ignore mdx --- .vscode/settings.json | 1 + code/.prettierignore | 1 + code/ui/blocks/src/blocks/Unstyled.mdx | 39 ++++++++++++++++++++++++++ code/ui/blocks/src/blocks/Unstyled.tsx | 3 ++ 4 files changed, 44 insertions(+) create mode 100644 code/.prettierignore create mode 100644 code/ui/blocks/src/blocks/Unstyled.mdx create mode 100644 code/ui/blocks/src/blocks/Unstyled.tsx diff --git a/.vscode/settings.json b/.vscode/settings.json index 75ad91c657f1..2fdbcea4ffaf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,4 +18,5 @@ "editor.defaultFormatter": "dbaeumer.vscode-eslint", "editor.formatOnSave": true }, + "prettier.ignorePath": "./code/.prettierignore" } diff --git a/code/.prettierignore b/code/.prettierignore new file mode 100644 index 000000000000..1b9355bd30fa --- /dev/null +++ b/code/.prettierignore @@ -0,0 +1 @@ +*.mdx diff --git a/code/ui/blocks/src/blocks/Unstyled.mdx b/code/ui/blocks/src/blocks/Unstyled.mdx new file mode 100644 index 000000000000..6eee44f2eda4 --- /dev/null +++ b/code/ui/blocks/src/blocks/Unstyled.mdx @@ -0,0 +1,39 @@ +import { Unstyled } from './Unstyled.tsx'; +import StoriesMeta, {Undefined} from '../controls/Boolean.stories'; +import { Story } from '@storybook/blocks'; +import { Meta } from '@storybook/blocks'; + + + +# The Unstyled Block + +By default most elements in docs have a few default styles applied to ensure the docs look good. This is achieved by applying default styles to most elements like `h1`, `p`, etc.. +However sometimes you might want some of your content to not have these styles applied, this is where the `Unstyled` block is useful. Wrap any content you want in the `Unstyled` block to remove the default styles: + +```md +import { Unstyled } from '@storybook/blocks'; + +> This block quote will be styled + +... and so will this paragraph. + + + > This block quote will not be styled + + ... neither will this paragraph, nor the following component: + + +``` + +Yields: + +> This block quote will be styled + +... and so will this paragraph. + + + > This block quote will not be styled + + ... neither will this paragraph, nor the following component: + + diff --git a/code/ui/blocks/src/blocks/Unstyled.tsx b/code/ui/blocks/src/blocks/Unstyled.tsx new file mode 100644 index 000000000000..3b37da67aeb3 --- /dev/null +++ b/code/ui/blocks/src/blocks/Unstyled.tsx @@ -0,0 +1,3 @@ +import React from 'react'; + +export const Unstyled: React.FC = (props) =>
; From b3baca1bd18f6bb3a78e19916304c068186aac93 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 30 Nov 2022 14:35:20 +0100 Subject: [PATCH 06/10] fix docsPage stories getting global styles --- code/ui/blocks/src/blocks/Anchor.tsx | 4 +++- code/ui/blocks/src/components/Description.tsx | 2 +- code/ui/blocks/src/components/DocsPage.tsx | 18 +++++++++++------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/code/ui/blocks/src/blocks/Anchor.tsx b/code/ui/blocks/src/blocks/Anchor.tsx index 24bb28211282..571c695c577a 100644 --- a/code/ui/blocks/src/blocks/Anchor.tsx +++ b/code/ui/blocks/src/blocks/Anchor.tsx @@ -8,5 +8,7 @@ export interface AnchorProps { } export const Anchor: FC = ({ storyId, children }) => ( -
{children}
+
+ {children} +
); diff --git a/code/ui/blocks/src/components/Description.tsx b/code/ui/blocks/src/components/Description.tsx index fa8d5fff5ae5..b8740851ba4e 100644 --- a/code/ui/blocks/src/components/Description.tsx +++ b/code/ui/blocks/src/components/Description.tsx @@ -13,6 +13,6 @@ export interface DescriptionProps { */ export const Description: FC = ({ markdown }) => ( - {markdown} + {markdown} ); diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index 0e6287c02261..a86d0e845066 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -7,19 +7,23 @@ import React from 'react'; /** * This selector styles all raw elements inside the DocsPage like this example with a `
`: - * :where(div:not(.sb-unstyled, .sb-canvas... :where(.sb-unstyled, .sb-canvas...) div)) + * :where(div:not(.sb-unstyled, .sbdocs-preview... :where(.sb-unstyled, .sbdocs-preview...) div)) * * 1. first ':where': ensures this has a specificity of 0, making it easy to override. * 2. 'div:not(...)': selects all div elements that are not... - * 3. '.sb-unstyled, .sb-canvas...': any of the elements we don't want to style - * 3. ':where(.sb-unstyled, .sb-canvas...) div': or are descendants of an .sb-unstyled or .sb-canvas, etc. It is a shorthand for '.sb-unstyled div, sb-canvas div...' + * 3. '.sb-unstyled, .sbdocs-preview...': any of the elements we don't want to style + * 3. ':where(.sb-unstyled, .sbdocs-preview...) div': or are descendants of an .sb-unstyled or .sbdocs-preview, etc. It is a shorthand for '.sb-unstyled div, sbdocs-preview div...' * 4. .sb-unstyled is an escape hatch that allows the user to opt-out of the default styles * by wrapping their content in an element with this class: * 5. the other UNSTYLED_SELECTORS are elements we don't want the styles to bleed into, like canvas, story and source blocks. */ -const UNSTYLED_SELECTORS = ['.sb-unstyled', '.sb-canvas', '.sb-story', '.docblock-source'].join( - ', ' -); +const UNSTYLED_SELECTORS = [ + '.sb-unstyled', + '.sbdocs-preview', + '.sb-story', + '.docblock-source', + '.sb-anchor', +].join(', '); const toGlobalSelector = (element: string): string => `& :where(${element}:not(${UNSTYLED_SELECTORS}, :where(${UNSTYLED_SELECTORS}) ${element}))`; @@ -146,7 +150,7 @@ export const DocsContent = styled.div(({ theme }) => { marginBottom: 0, }, }, - [toGlobalSelector('div')]: reset, + [toGlobalSelector('div')]: { ...reset, color: 'green' }, [toGlobalSelector('dl')]: { ...reset, margin: '16px 0', From 2820c5a14837f9b4223fe0fbe9f4ed59d95a3bc3 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 30 Nov 2022 14:44:13 +0100 Subject: [PATCH 07/10] make Description not use styled components --- code/ui/blocks/src/components/Description.tsx | 5 +---- code/ui/blocks/src/components/DocsPage.tsx | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/code/ui/blocks/src/components/Description.tsx b/code/ui/blocks/src/components/Description.tsx index b8740851ba4e..1276aa0d5b21 100644 --- a/code/ui/blocks/src/components/Description.tsx +++ b/code/ui/blocks/src/components/Description.tsx @@ -1,7 +1,6 @@ import type { FC } from 'react'; import React from 'react'; import Markdown from 'markdown-to-jsx'; -import { components, ResetWrapper } from '@storybook/components'; export interface DescriptionProps { markdown: string; @@ -12,7 +11,5 @@ export interface DescriptionProps { * components docgen docs. */ export const Description: FC = ({ markdown }) => ( - - {markdown} - + {markdown} ); diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index a86d0e845066..995fd7f4f011 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -150,7 +150,7 @@ export const DocsContent = styled.div(({ theme }) => { marginBottom: 0, }, }, - [toGlobalSelector('div')]: { ...reset, color: 'green' }, + [toGlobalSelector('div')]: reset, [toGlobalSelector('dl')]: { ...reset, margin: '16px 0', From 7d7777a168bf5a1b3b647bee5d52bf2c6c227c09 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 30 Nov 2022 14:47:45 +0100 Subject: [PATCH 08/10] cleanup Unstyled docs --- code/ui/blocks/src/blocks/Unstyled.mdx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/ui/blocks/src/blocks/Unstyled.mdx b/code/ui/blocks/src/blocks/Unstyled.mdx index 6eee44f2eda4..4e66f71287b3 100644 --- a/code/ui/blocks/src/blocks/Unstyled.mdx +++ b/code/ui/blocks/src/blocks/Unstyled.mdx @@ -1,9 +1,4 @@ import { Unstyled } from './Unstyled.tsx'; -import StoriesMeta, {Undefined} from '../controls/Boolean.stories'; -import { Story } from '@storybook/blocks'; -import { Meta } from '@storybook/blocks'; - - # The Unstyled Block @@ -36,4 +31,3 @@ Yields: ... neither will this paragraph, nor the following component: - From 3c3ccba51669226de3dd797e20fd14e0d24ff359 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 1 Dec 2022 15:51:26 +0100 Subject: [PATCH 09/10] migration notes. --- MIGRATION.md | 51 ++++++++++++++++++- .../src/components/DocsPage.stories.tsx | 19 ++++--- prettier.config.js | 1 + 3 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 prettier.config.js diff --git a/MIGRATION.md b/MIGRATION.md index 31a5479bd752..8d4649bfb778 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -21,9 +21,9 @@ - [7.0 feature flags removed](#70-feature-flags-removed) - [CLI option `--use-npm` deprecated](#cli-option---use-npm-deprecated) - [Vite builder uses vite config automatically](#vite-builder-uses-vite-config-automatically) - - [Vite cache moved to node_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook) + - [Vite cache moved to node\_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook) - [Removed docs.getContainer and getPage parameters](#removed-docsgetcontainer-and-getpage-parameters) - - [Removed STORYBOOK_REACT_CLASSES global](#removed-storybook_react_classes-global) + - [Removed STORYBOOK\_REACT\_CLASSES global](#removed-storybook_react_classes-global) - [Icons API changed](#icons-api-changed) - ['config' preset entry replaced with 'previewAnnotations'](#config-preset-entry-replaced-with-previewannotations) - [Dropped support for Angular 12 and below](#dropped-support-for-angular-12-and-below) @@ -37,6 +37,8 @@ - [Configuring the Docs Container](#configuring-the-docs-container) - [External Docs](#external-docs) - [MDX2 upgrade](#mdx2-upgrade) + - [Default docs styles will leak into non-story user components](#default-docs-styles-will-leak-into-non-story-user-components) + - [Explicit `` elements are no longer syntax highlighted](#explicit-code-elements-are-no-longer-syntax-highlighted) - [Dropped source loader / storiesOf static snippets](#dropped-source-loader--storiesof-static-snippets) - [Dropped addon-docs manual configuration](#dropped-addon-docs-manual-configuration) - [Autoplay in docs](#autoplay-in-docs) @@ -756,6 +758,47 @@ We will update this section with specific pointers based on user feedback during As part of the upgrade we deleted the codemod `mdx-to-csf` and will be replacing it with a more sophisticated version prior to release. +#### Default docs styles will leak into non-story user components + +Storybook's default styles in docs are now globally applied to any element instead of using classes. This means that any component that you add directly in a docs file will also get the default styles. + +To mitigate this you need to wrap any content you don't want styled with the `Unstyled` block like this: + +```mdx +import { Unstyled } from '@storybook/blocks'; +import { MyComponent } from './MyComponent'; + +# This is a header + + + + +``` + +Components that are part of your stories or in a canvas will not need this mitigation, as the `Story` and `Canvas` blocks already have this built-in. + +#### Explicit `` elements are no longer syntax highlighted + +Due to how MDX2 works differently from MDX1, manually defined `` elements are no longer transformed to the `Code` component, so it will not be syntax highlighted. This is not the case for markdown \`\`\` code-fences, that will still end up as `Code` with syntax highlighting. + +Luckily [MDX2 supports markdown (like code-fences) inside elements better now](https://mdxjs.com/blog/v2/#improvements-to-the-mdx-format), so most cases where you needed a `` element before, you can use code-fences instead: + + +````md +This will now be an unstyled line of code + +```js +const a = 'This is still a styled code block.'; +``` + +
+ ```js + const a = 'MDX2 supports markdown in elements better now, so this is possible.'; + ``` +
+```` + + #### Dropped source loader / storiesOf static snippets In SB 6.x, Storybook Docs used a webpack loader called `source-loader` to help display static code snippets. This was configurable using the `options.sourceLoaderOptions` field. @@ -3621,3 +3664,7 @@ If you **are** using these addons, it takes two steps to migrate: ``` + +``` + +``` diff --git a/code/ui/blocks/src/components/DocsPage.stories.tsx b/code/ui/blocks/src/components/DocsPage.stories.tsx index 51cf15aa1fcd..f5bab8edf090 100644 --- a/code/ui/blocks/src/components/DocsPage.stories.tsx +++ b/code/ui/blocks/src/components/DocsPage.stories.tsx @@ -9,6 +9,7 @@ import * as Preview from './Preview.stories'; import * as argsTable from './ArgsTable/ArgsTable.stories'; import * as source from './Source.stories'; import * as description from './Description.stories'; +import { Unstyled } from '../blocks/Unstyled'; export default { component: DocsPageWrapper, @@ -109,14 +110,16 @@ export const Html = {
Div
Nested A tag
-
-

Unstyled content

-

Heading 2

- A tag -
-
Div
- Nested A tag -
+
+ +

Unstyled content

+

Heading 2

+ A tag +
+
Div
+ Nested A tag +
+
), diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 000000000000..4fc46b37ac43 --- /dev/null +++ b/prettier.config.js @@ -0,0 +1 @@ +module.exports = require('./scripts/prettier.config'); From 29587c986dbdf5c7710e9eafa8ac990e54df2f2b Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 2 Dec 2022 10:54:18 +0100 Subject: [PATCH 10/10] fix Description code blocks, add docsStyles parameter to SBUI --- code/ui/.storybook/preview.tsx | 14 ++++++++++++++ .../blocks/src/components/Description.stories.tsx | 1 + code/ui/blocks/src/components/Description.tsx | 10 +++++++++- code/ui/blocks/src/components/DocsPage.tsx | 1 + .../ui/components/src/typography/elements/Code.tsx | 1 + 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/code/ui/.storybook/preview.tsx b/code/ui/.storybook/preview.tsx index 931ac9dbf6bb..76f2ec0d4901 100644 --- a/code/ui/.storybook/preview.tsx +++ b/code/ui/.storybook/preview.tsx @@ -17,6 +17,7 @@ import type { ReactRenderer } from '@storybook/react'; import type { Channel } from '@storybook/channels'; import { DocsContainer } from '../blocks/src/blocks/DocsContainer'; +import { DocsContent, DocsWrapper } from '../blocks/src/components'; const { document } = global; @@ -142,6 +143,19 @@ export const decorators = [ ) : ( ), + /** + * This decorator adds wrappers that contains global styles for stories to be targeted by. + * Activated with parameters.docsStyles = true + */ (Story, { parameters: { docsStyles } }) => + docsStyles ? ( + + + + + + ) : ( + + ), /** * This decorator adds Symbols that the sidebar icons references. * Any sidebar story that uses the icons must set the parameter withSymbols: true . diff --git a/code/ui/blocks/src/components/Description.stories.tsx b/code/ui/blocks/src/components/Description.stories.tsx index a3b256a5b53d..d285a988a74f 100644 --- a/code/ui/blocks/src/components/Description.stories.tsx +++ b/code/ui/blocks/src/components/Description.stories.tsx @@ -2,6 +2,7 @@ import { Description } from './Description'; export default { component: Description, + parameters: { docsStyles: true }, }; const textCaption = `That was Wintermute, manipulating the lock the way it had manipulated the drone micro and the amplified breathing of the room where Case waited. The semiotics of the bright void beyond the chain link. The tug Marcus Garvey, a steel drum nine meters long and two in diameter, creaked and shuddered as Maelcum punched for a California gambling cartel, then as a paid killer in the dark, curled in his capsule in some coffin hotel, his hands clawed into the nearest door and watched the other passengers as he rode. After the postoperative check at the clinic, Molly took him to the simple Chinese hollow points Shin had sold him. Still it was a handgun and nine rounds of ammunition, and as he made his way down Shiga from the missionaries, the train reached Case’s station. Now this quiet courtyard, Sunday afternoon, this girl with a random collection of European furniture, as though Deane had once intended to use the place as his home. Case felt the edge of the Flatline as a construct, a hardwired ROM cassette replicating a dead man’s skills, obsessions, kneejerk responses. They were dropping, losing altitude in a canyon of rainbow foliage, a lurid communal mural that completely covered the hull of the console in faded pinks and yellows.`; diff --git a/code/ui/blocks/src/components/Description.tsx b/code/ui/blocks/src/components/Description.tsx index 1276aa0d5b21..a65db41fbf75 100644 --- a/code/ui/blocks/src/components/Description.tsx +++ b/code/ui/blocks/src/components/Description.tsx @@ -1,6 +1,7 @@ import type { FC } from 'react'; import React from 'react'; import Markdown from 'markdown-to-jsx'; +import { components } from '@storybook/components'; export interface DescriptionProps { markdown: string; @@ -11,5 +12,12 @@ export interface DescriptionProps { * components docgen docs. */ export const Description: FC = ({ markdown }) => ( - {markdown} + + {markdown} + ); diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index 995fd7f4f011..67b19a09c906 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -20,6 +20,7 @@ import React from 'react'; const UNSTYLED_SELECTORS = [ '.sb-unstyled', '.sbdocs-preview', + '.sbdocs-pre', '.sb-story', '.docblock-source', '.sb-anchor', diff --git a/code/ui/components/src/typography/elements/Code.tsx b/code/ui/components/src/typography/elements/Code.tsx index 5160297b68e5..d13f91fbc6b8 100644 --- a/code/ui/components/src/typography/elements/Code.tsx +++ b/code/ui/components/src/typography/elements/Code.tsx @@ -24,6 +24,7 @@ const DefaultCodeBlock = styled.code( const StyledSyntaxHighlighter = styled(SyntaxHighlighter)(({ theme }) => ({ // DocBlocks-specific styling and overrides + fontFamily: theme.typography.fonts.mono, fontSize: `${theme.typography.size.s2 - 1}px`, lineHeight: '19px', margin: '25px 0 40px',